From: Stephen Rothwell Date: Thu, 11 Feb 2016 02:17:00 +0000 (+1100) Subject: Merge remote-tracking branch 'rcu/rcu/next' X-Git-Tag: next-20160211~28 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=bba722fd63fd78ee85cfc27cf0013b44c01c5027;hp=0dd1befbc663cd8cd2ecc6d4559022eba1ce57af;p=karo-tx-linux.git Merge remote-tracking branch 'rcu/rcu/next' --- diff --git a/.mailmap b/.mailmap index b1e9a97653dc..7e6c5334c337 100644 --- a/.mailmap +++ b/.mailmap @@ -21,6 +21,7 @@ Andrey Ryabinin Andrew Morton Andrew Vasquez Andy Adamson +Antonio Ospite Archit Taneja Arnaud Patard Arnd Bergmann diff --git a/Documentation/ABI/obsolete/sysfs-class-rfkill b/Documentation/ABI/obsolete/sysfs-class-rfkill index ff60ad9eca4c..e736d145085f 100644 --- a/Documentation/ABI/obsolete/sysfs-class-rfkill +++ b/Documentation/ABI/obsolete/sysfs-class-rfkill @@ -18,12 +18,3 @@ Values: A numeric value. 2: RFKILL_STATE_HARD_BLOCKED transmitter is forced off by something outside of the driver's control. - -What: /sys/class/rfkill/rfkill[0-9]+/claim -Date: 09-Jul-2007 -KernelVersion v2.6.22 -Contact: linux-wireless@vger.kernel.org -Description: This file is deprecated because there no longer is a way to - claim just control over a single rfkill instance. - This file is scheduled to be removed in 2012. -Values: 0: Kernel handles events diff --git a/Documentation/ABI/removed/sysfs-class-rfkill b/Documentation/ABI/removed/sysfs-class-rfkill new file mode 100644 index 000000000000..3ce6231f20b2 --- /dev/null +++ b/Documentation/ABI/removed/sysfs-class-rfkill @@ -0,0 +1,13 @@ +rfkill - radio frequency (RF) connector kill switch support + +For details to this subsystem look at Documentation/rfkill.txt. + +What: /sys/class/rfkill/rfkill[0-9]+/claim +Date: 09-Jul-2007 +KernelVersion v2.6.22 +Contact: linux-wireless@vger.kernel.org +Description: This file was deprecated because there no longer was a way to + claim just control over a single rfkill instance. + This file was scheduled to be removed in 2012, and was removed + in 2016. +Values: 0: Kernel handles events diff --git a/Documentation/ABI/stable/sysfs-fs-orangefs b/Documentation/ABI/stable/sysfs-fs-orangefs new file mode 100644 index 000000000000..affdb114bd33 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-fs-orangefs @@ -0,0 +1,87 @@ +What: /sys/fs/orangefs/perf_counters/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Counters and settings for various caches. + Read only. + + +What: /sys/fs/orangefs/perf_counter_reset +Date: June 2015 +Contact: Mike Marshall +Description: + echo a 0 or a 1 into perf_counter_reset to + reset all the counters in + /sys/fs/orangefs/perf_counters + except ones with PINT_PERF_PRESERVE set. + + +What: /sys/fs/orangefs/perf_time_interval_secs +Date: Jun 2015 +Contact: Mike Marshall +Description: + Length of perf counter intervals in + seconds. + + +What: /sys/fs/orangefs/perf_history_size +Date: Jun 2015 +Contact: Mike Marshall +Description: + The perf_counters cache statistics have N, or + perf_history_size, samples. The default is + one. + + Every perf_time_interval_secs the (first) + samples are reset. + + If N is greater than one, the "current" set + of samples is reset, and the samples from the + other N-1 intervals remain available. + + +What: /sys/fs/orangefs/op_timeout_secs +Date: Jun 2015 +Contact: Mike Marshall +Description: + Service operation timeout in seconds. + + +What: /sys/fs/orangefs/slot_timeout_secs +Date: Jun 2015 +Contact: Mike Marshall +Description: + "Slot" timeout in seconds. A "slot" + is an indexed buffer in the shared + memory segment used for communication + between the kernel module and userspace. + Slots are requested and waited for, + the wait times out after slot_timeout_secs. + + +What: /sys/fs/orangefs/acache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Attribute cache configurable settings. + + +What: /sys/fs/orangefs/ncache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Name cache configurable settings. + + +What: /sys/fs/orangefs/capcache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Capability cache configurable settings. + + +What: /sys/fs/orangefs/ccache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Credential cache configurable settings. diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index e5200f354abf..a809f6005f14 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -98,3 +98,17 @@ Date: October 2015 Contact: "Chao Yu" Description: Controls the count of nid pages to be readaheaded. + +What: /sys/fs/f2fs//dirty_nats_ratio +Date: January 2016 +Contact: "Chao Yu" +Description: + Controls dirty nat entries ratio threshold, if current + ratio exceeds configured threshold, checkpoint will + be triggered for flushing dirty nat entries. + +What: /sys/fs/f2fs//lifetime_write_kbytes +Date: January 2016 +Contact: "Shuoran Liu" +Description: + Shows total written kbytes issued to disk. diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle index db653774c0b7..9a70ddd16584 100644 --- a/Documentation/CodingStyle +++ b/Documentation/CodingStyle @@ -640,7 +640,7 @@ Things to avoid when using macros: do { \ if (blah(x) < 0) \ return -EBUGGERED; \ - } while(0) + } while (0) is a _very_ bad idea. It looks like a function call but exits the "calling" function; don't break the internal parsers of those who will read the code. diff --git a/Documentation/DocBook/crypto-API.tmpl b/Documentation/DocBook/crypto-API.tmpl index 07df23ea06e4..866ff082272b 100644 --- a/Documentation/DocBook/crypto-API.tmpl +++ b/Documentation/DocBook/crypto-API.tmpl @@ -1761,19 +1761,6 @@ read(opfd, out, outlen); !Finclude/linux/crypto.h crypto_cipher_setkey !Finclude/linux/crypto.h crypto_cipher_encrypt_one !Finclude/linux/crypto.h crypto_cipher_decrypt_one - - Synchronous Message Digest API -!Pinclude/linux/crypto.h Synchronous Message Digest API -!Finclude/linux/crypto.h crypto_alloc_hash -!Finclude/linux/crypto.h crypto_free_hash -!Finclude/linux/crypto.h crypto_has_hash -!Finclude/linux/crypto.h crypto_hash_blocksize -!Finclude/linux/crypto.h crypto_hash_digestsize -!Finclude/linux/crypto.h crypto_hash_init -!Finclude/linux/crypto.h crypto_hash_update -!Finclude/linux/crypto.h crypto_hash_final -!Finclude/linux/crypto.h crypto_hash_digest -!Finclude/linux/crypto.h crypto_hash_setkey Message Digest Algorithm Definitions !Pinclude/crypto/hash.h Message Digest Algorithm Definitions diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index cdd8b24db68d..184f3c7b5145 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl @@ -229,6 +229,7 @@ X!Isound/sound_firmware.c !Iinclude/media/v4l2-dv-timings.h !Iinclude/media/v4l2-event.h !Iinclude/media/v4l2-flash-led-class.h +!Iinclude/media/v4l2-mc.h !Iinclude/media/v4l2-mediabus.h !Iinclude/media/v4l2-mem2mem.h !Iinclude/media/v4l2-of.h @@ -368,7 +369,7 @@ X!Ilib/fonts/fonts.c !Iinclude/linux/input-polldev.h !Edrivers/input/input-polldev.c - Matrix keyboars/keypads + Matrix keyboards/keypads !Iinclude/linux/input/matrix_keypad.h Sparse keymap support diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index a8669330b456..fe6b36a2fd98 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -2886,52 +2886,8 @@ void (*postclose) (struct drm_device *, struct drm_file *); File Operations - const struct file_operations *fops - File operations for the DRM device node. - - Drivers must define the file operations structure that forms the DRM - userspace API entry point, even though most of those operations are - implemented in the DRM core. The open, - release and ioctl - operations are handled by - - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - #ifdef CONFIG_COMPAT - .compat_ioctl = drm_compat_ioctl, - #endif - - - - Drivers that implement private ioctls that requires 32/64bit - compatibility support must provide their own - compat_ioctl handler that processes private - ioctls and calls drm_compat_ioctl for core ioctls. - - - The read and poll - operations provide support for reading DRM events and polling them. They - are implemented by - - .poll = drm_poll, - .read = drm_read, - .llseek = no_llseek, - - - - The memory mapping implementation varies depending on how the driver - manages memory. Pre-GEM drivers will use drm_mmap, - while GEM-aware drivers will use drm_gem_mmap. See - . - - .mmap = drm_gem_mmap, - - - - No other file operation is supported by the DRM API. - +!Pdrivers/gpu/drm/drm_fops.c file operations +!Edrivers/gpu/drm/drm_fops.c IOCTLs @@ -3319,6 +3275,12 @@ int num_ioctls; !Pdrivers/gpu/drm/i915/intel_csr.c csr support for dmc !Idrivers/gpu/drm/i915/intel_csr.c + + Video BIOS Table (VBT) +!Pdrivers/gpu/drm/i915/intel_bios.c Video BIOS Table (VBT) +!Idrivers/gpu/drm/i915/intel_bios.c +!Idrivers/gpu/drm/i915/intel_bios.h + @@ -3460,6 +3422,7 @@ int num_ioctls; Public constants +!Finclude/linux/vga_switcheroo.h vga_switcheroo_handler_flags_t !Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id !Finclude/linux/vga_switcheroo.h vga_switcheroo_state @@ -3488,6 +3451,10 @@ int num_ioctls; Backlight control !Pdrivers/platform/x86/apple-gmux.c Backlight control + + Public functions +!Iinclude/linux/apple-gmux.h + diff --git a/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml b/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml index 63152ab9efba..e0d49fa329f0 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-g-topology.xml @@ -48,9 +48,6 @@ Description - - NOTE: This new ioctl is programmed to be added on Kernel 4.6. Its definition/arguments may change until its final version. - The typical usage of this ioctl is to call it twice. On the first call, the structure defined at &media-v2-topology; should be zeroed. At return, if no errors happen, this ioctl will return the diff --git a/Documentation/DocBook/media/v4l/media-types.xml b/Documentation/DocBook/media/v4l/media-types.xml index 1af384250910..751c3d027103 100644 --- a/Documentation/DocBook/media/v4l/media-types.xml +++ b/Documentation/DocBook/media/v4l/media-types.xml @@ -84,7 +84,34 @@ MEDIA_ENT_F_TUNER - Digital TV, analog TV, radio and/or software radio tuner. + Digital TV, analog TV, radio and/or software radio tuner, + with consists on a PLL tuning stage that converts radio + frequency (RF) signal into an Intermediate Frequency (IF). + Modern tuners have internally IF-PLL decoders for audio + and video, but older models have those stages implemented + on separate entities. + + + + MEDIA_ENT_F_IF_VID_DECODER + IF-PLL video decoder. It receives the IF from a PLL + and decodes the analog TV video signal. This is commonly + found on some very old analog tuners, like Philips MK3 + designs. They all contain a tda9887 (or some software + compatible similar chip, like tda9885). Those devices + use a different I2C address than the tuner PLL. + + + + MEDIA_ENT_F_IF_AUD_DECODER + IF-PLL sound decoder. It receives the IF from a PLL + and decodes the analog TV audio signal. This is commonly + found on some very old analog hardware, like Micronas + msp3400, Philips tda9840, tda985x, etc. Those devices + use a different I2C address than the tuner PLL and + should be controlled together with the IF-PLL video + decoder. + diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml index e781cc61786c..7d13fe96657d 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml @@ -1,35 +1,43 @@ - + - V4L2_PIX_FMT_YUV420M ('YM12') + V4L2_PIX_FMT_YUV420M ('YM12'), V4L2_PIX_FMT_YVU420M ('YM21') &manvol; - V4L2_PIX_FMT_YUV420M - Variation of V4L2_PIX_FMT_YUV420 - with planes non contiguous in memory. + V4L2_PIX_FMT_YUV420M + V4L2_PIX_FMT_YVU420M + Variation of V4L2_PIX_FMT_YUV420 and + V4L2_PIX_FMT_YVU420 with planes non contiguous + in memory. Description This is a multi-planar format, as opposed to a packed format. -The three components are separated into three sub- images or planes. +The three components are separated into three sub-images or planes. -The Y plane is first. The Y plane has one byte per pixel. The Cb data + The Y plane is first. The Y plane has one byte per pixel. +For V4L2_PIX_FMT_YUV420M the Cb data constitutes the second plane which is half the width and half the height of the Y plane (and of the image). Each Cb belongs to four pixels, a two-by-two square of the image. For example, Cb0 belongs to Y'00, Y'01, Y'10, and Y'11. The Cr data, just like the Cb plane, is -in the third plane. +in the third plane. + + V4L2_PIX_FMT_YVU420M is the same except +the Cr data is stored in the second plane and the Cb data in the third plane. + If the Y plane has pad bytes after each row, then the Cb and Cr planes have half as many pad bytes after their rows. In other words, two Cx rows (including padding) is exactly as long as one Y row (including padding). - V4L2_PIX_FMT_YUV420M is intended to be + V4L2_PIX_FMT_YUV420M and +V4L2_PIX_FMT_YVU420M are intended to be used only in drivers and applications that support the multi-planar API, described in . diff --git a/Documentation/DocBook/media/v4l/pixfmt-yvu420m.xml b/Documentation/DocBook/media/v4l/pixfmt-yvu420m.xml deleted file mode 100644 index 2330667907c7..000000000000 --- a/Documentation/DocBook/media/v4l/pixfmt-yvu420m.xml +++ /dev/null @@ -1,154 +0,0 @@ - - - V4L2_PIX_FMT_YVU420M ('YM21') - &manvol; - - - V4L2_PIX_FMT_YVU420M - Variation of V4L2_PIX_FMT_YVU420 - with planes non contiguous in memory. - - - - Description - - This is a multi-planar format, as opposed to a packed format. -The three components are separated into three sub-images or planes. - -The Y plane is first. The Y plane has one byte per pixel. The Cr data -constitutes the second plane which is half the width and half -the height of the Y plane (and of the image). Each Cr belongs to four -pixels, a two-by-two square of the image. For example, -Cr0 belongs to Y'00, -Y'01, Y'10, and -Y'11. The Cb data, just like the Cr plane, constitutes -the third plane. - - If the Y plane has pad bytes after each row, then the Cr -and Cb planes have half as many pad bytes after their rows. In other -words, two Cx rows (including padding) is exactly as long as one Y row -(including padding). - - V4L2_PIX_FMT_YVU420M is intended to be -used only in drivers and applications that support the multi-planar API, -described in . - - - <constant>V4L2_PIX_FMT_YVU420M</constant> 4 × 4 -pixel image - - - Byte Order. - Each cell is one byte. - - - - - - start0 + 0: - Y'00 - Y'01 - Y'02 - Y'03 - - - start0 + 4: - Y'10 - Y'11 - Y'12 - Y'13 - - - start0 + 8: - Y'20 - Y'21 - Y'22 - Y'23 - - - start0 + 12: - Y'30 - Y'31 - Y'32 - Y'33 - - - - start1 + 0: - Cr00 - Cr01 - - - start1 + 2: - Cr10 - Cr11 - - - - start2 + 0: - Cb00 - Cb01 - - - start2 + 2: - Cb10 - Cb11 - - - - - - - - - Color Sample Location. - - - - - - - 01 - 23 - - - 0 - YY - YY - - - - C - C - - - 1 - YY - YY - - - - - - 2 - YY - YY - - - - C - C - - - 3 - YY - YY - - - - - - - - - diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml index d871245d2973..9e77ff353feb 100644 --- a/Documentation/DocBook/media/v4l/pixfmt.xml +++ b/Documentation/DocBook/media/v4l/pixfmt.xml @@ -1628,7 +1628,6 @@ information. &sub-y41p; &sub-yuv420; &sub-yuv420m; - &sub-yvu420m; &sub-yuv410; &sub-yuv422p; &sub-yuv411p; diff --git a/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml b/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml index e9c70a8f3476..0c93677d16b4 100644 --- a/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml +++ b/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml @@ -60,9 +60,19 @@ input automatically, similar to sensing the video standard. To do so, applications call VIDIOC_QUERY_DV_TIMINGS with a pointer to a &v4l2-dv-timings;. Once the hardware detects the timings, it will fill in the -timings structure. +timings structure. -If the timings could not be detected because there was no signal, then +Please note that drivers shall not switch timings automatically +if new timings are detected. Instead, drivers should send the +V4L2_EVENT_SOURCE_CHANGE event (if they support this) and expect +that userspace will take action by calling VIDIOC_QUERY_DV_TIMINGS. +The reason is that new timings usually mean different buffer sizes as well, and you +cannot change buffer sizes on the fly. In general, applications that receive the +Source Change event will have to call VIDIOC_QUERY_DV_TIMINGS, +and if the detected timings are valid they will have to stop streaming, set the new +timings, allocate new buffers and start streaming again. + +If the timings could not be detected because there was no signal, then ENOLINK is returned. If a signal was detected, but it was unstable and the receiver could not lock to the signal, then ENOLCK is returned. If the receiver could lock to the signal, diff --git a/Documentation/DocBook/media/v4l/vidioc-querystd.xml b/Documentation/DocBook/media/v4l/vidioc-querystd.xml index 222348542182..3ceae35fab03 100644 --- a/Documentation/DocBook/media/v4l/vidioc-querystd.xml +++ b/Documentation/DocBook/media/v4l/vidioc-querystd.xml @@ -59,6 +59,16 @@ then the driver will return V4L2_STD_UNKNOWN. When detection is not possible or fails, the set must contain all standards supported by the current video input or output. +Please note that drivers shall not switch the video standard +automatically if a new video standard is detected. Instead, drivers should send the +V4L2_EVENT_SOURCE_CHANGE event (if they support this) and expect +that userspace will take action by calling VIDIOC_QUERYSTD. +The reason is that a new video standard can mean different buffer sizes as well, and you +cannot change buffer sizes on the fly. In general, applications that receive the +Source Change event will have to call VIDIOC_QUERYSTD, +and if the detected video standard is valid they will have to stop streaming, set the new +standard, allocate new buffers and start streaming again. + diff --git a/Documentation/HOWTO b/Documentation/HOWTO index d5a699d5a551..ef2ff1e9d3e0 100644 --- a/Documentation/HOWTO +++ b/Documentation/HOWTO @@ -187,7 +187,7 @@ apply a patch. If you do not know where you want to start, but you want to look for some task to start doing to join into the kernel development community, go to the Linux Kernel Janitor's project: - http://kernelnewbies.org/KernelJanitors + http://kernelnewbies.org/KernelJanitors It is a great place to start. It describes a list of relatively simple problems that need to be cleaned up and fixed within the Linux kernel source tree. Working with the developers in charge of this project, you @@ -250,11 +250,6 @@ process is as follows: release a new -rc kernel every week. - Process continues until the kernel is considered "ready", the process should last around 6 weeks. - - Known regressions in each release are periodically posted to the - linux-kernel mailing list. The goal is to reduce the length of - that list to zero before declaring the kernel to be "ready," but, in - the real world, a small number of regressions often remain at - release time. It is worth mentioning what Andrew Morton wrote on the linux-kernel mailing list about kernel releases: diff --git a/Documentation/Intel-IOMMU.txt b/Documentation/Intel-IOMMU.txt index 7b57fc087088..49585b6e1ea2 100644 --- a/Documentation/Intel-IOMMU.txt +++ b/Documentation/Intel-IOMMU.txt @@ -3,7 +3,7 @@ Linux IOMMU Support The architecture spec can be obtained from the below location. -http://www.intel.com/technology/virtualization/ +http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/vt-directed-io-spec.pdf This guide gives a quick cheat sheet for some basic understanding. diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index d603fa078235..8c79f1d53731 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -722,7 +722,7 @@ references. -------------------------------- It can be helpful to manually add In-Reply-To: headers to a patch -(e.g., when using "git send email") to associate the patch with +(e.g., when using "git send-email") to associate the patch with previous relevant discussion, e.g. to link a bug fix to the email with the bug report. However, for a multi-patch series, it is generally best to avoid using In-Reply-To: to link to older versions of the diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README index 430d279a8df3..e5a115f24471 100644 --- a/Documentation/arm/sunxi/README +++ b/Documentation/arm/sunxi/README @@ -72,6 +72,5 @@ SunXi family * Octa ARM Cortex-A7 based SoCs - Allwinner A83T - + Not Supported + Datasheet http://dl.linux-sunxi.org/A83T/A83T_datasheet_Revision_1.1.pdf diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt index 701d39d3171a..56d6d8b796db 100644 --- a/Documentation/arm64/booting.txt +++ b/Documentation/arm64/booting.txt @@ -109,7 +109,13 @@ Header notes: 1 - 4K 2 - 16K 3 - 64K - Bits 3-63: Reserved. + Bit 3: Kernel physical placement + 0 - 2MB aligned base should be as close as possible + to the base of DRAM, since memory below it is not + accessible via the linear mapping + 1 - 2MB aligned base may be anywhere in physical + memory + Bits 4-63: Reserved. - When image_size is zero, a bootloader should attempt to keep as much memory as possible free for use by the kernel immediately after the @@ -117,14 +123,14 @@ Header notes: depending on selected features, and is effectively unbound. The Image must be placed text_offset bytes from a 2MB aligned base -address near the start of usable system RAM and called there. Memory -below that base address is currently unusable by Linux, and therefore it -is strongly recommended that this location is the start of system RAM. -The region between the 2 MB aligned base address and the start of the -image has no special significance to the kernel, and may be used for -other purposes. +address anywhere in usable system RAM and called there. The region +between the 2 MB aligned base address and the start of the image has no +special significance to the kernel, and may be used for other purposes. At least image_size bytes from the start of the image must be free for use by the kernel. +NOTE: versions prior to v4.6 cannot make use of memory below the +physical offset of the Image so it is recommended that the Image be +placed as close as possible to the start of system RAM. Any memory described to the kernel (even that below the start of the image) which is not marked as reserved from the kernel (e.g., with a diff --git a/Documentation/cgroup-v2.txt b/Documentation/cgroup-v2.txt index 65b3eac8856c..ff49cf901148 100644 --- a/Documentation/cgroup-v2.txt +++ b/Documentation/cgroup-v2.txt @@ -7,7 +7,7 @@ This is the authoritative documentation on the design, interface and conventions of cgroup v2. It describes all userland-visible aspects of cgroup including core and specific controller behaviors. All future changes must be reflected in this document. Documentation for -v1 is available under Documentation/cgroup-legacy/. +v1 is available under Documentation/cgroup-v1/. CONTENTS @@ -843,6 +843,10 @@ PAGE_SIZE multiple when read back. Amount of memory used to cache filesystem data, including tmpfs and shared memory. + sock + + Amount of memory used in network transmission buffers + file_mapped Amount of cached filesystem data mapped with mmap() diff --git a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt index 8b49302712a8..beda682e8d77 100644 --- a/Documentation/crypto/api-intro.txt +++ b/Documentation/crypto/api-intro.txt @@ -49,28 +49,33 @@ under development. Here's an example of how to use the API: - #include + #include #include #include struct scatterlist sg[2]; char result[128]; - struct crypto_hash *tfm; - struct hash_desc desc; + struct crypto_ahash *tfm; + struct ahash_request *req; - tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC); + tfm = crypto_alloc_ahash("md5", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) fail(); /* ... set up the scatterlists ... */ - desc.tfm = tfm; - desc.flags = 0; - - if (crypto_hash_digest(&desc, sg, 2, result)) + req = ahash_request_alloc(tfm, GFP_ATOMIC); + if (!req) fail(); + + ahash_request_set_callback(req, 0, NULL, NULL); + ahash_request_set_crypt(req, sg, result, 2); - crypto_free_hash(tfm); + if (crypto_ahash_digest(req)) + fail(); + + ahash_request_free(req); + crypto_free_ahash(tfm); Many real examples are available in the regression test module (tcrypt.c). diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index ae9be074d09f..a0884b85abf2 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -178,6 +178,7 @@ nodes to be present and contain the properties described below. "marvell,sheeva-v5" "nvidia,tegra132-denver" "qcom,krait" + "qcom,kryo" "qcom,scorpion" - enable-method Value type: diff --git a/Documentation/devicetree/bindings/arm/keystone/keystone.txt b/Documentation/devicetree/bindings/arm/keystone/keystone.txt index 3090a8a008c0..48f6703a28c8 100644 --- a/Documentation/devicetree/bindings/arm/keystone/keystone.txt +++ b/Documentation/devicetree/bindings/arm/keystone/keystone.txt @@ -22,6 +22,8 @@ SoCs: compatible = "ti,k2l", "ti,keystone" - Keystone 2 Edison compatible = "ti,k2e", "ti,keystone" +- K2G + compatible = "ti,k2g", "ti,keystone" Boards: - Keystone 2 Hawking/Kepler EVM @@ -32,3 +34,6 @@ Boards: - Keystone 2 Edison EVM compatible = "ti,k2e-evm", "ti,k2e", "ti,keystone" + +- K2G EVM + compatible = "ti,k2g-evm", "ti,k2g", "ti-keystone" diff --git a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt index ab0c9cdf388e..7d28fe4bf654 100644 --- a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt +++ b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt @@ -19,9 +19,12 @@ SoC. Currently known SoC compatibles are: And in addition, the compatible shall be extended with the specific board. Currently known boards are: +"buffalo,linkstation-lsqvl" +"buffalo,linkstation-lsvl" +"buffalo,linkstation-lswsxl" +"buffalo,linkstation-lswxl" +"buffalo,linkstation-lswvl" "buffalo,lschlv2" -"buffalo,lswvl" -"buffalo,lswxl" "buffalo,lsxhl" "buffalo,lsxl" "cloudengines,pogo02" diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt new file mode 100644 index 000000000000..e5c18df4d336 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt @@ -0,0 +1,81 @@ +SAMSUNG Exynos SoCs SROM Controller driver. + +Required properties: +- compatible : Should contain "samsung,exynos-srom". + +- reg: offset and length of the register set + +Optional properties: +The SROM controller can be used to attach external peripherals. In this case +extra properties, describing the bus behind it, should be specified as below: + +- #address-cells: Must be set to 2 to allow device address translation. + Address is specified as (bank#, offset). + +- #size-cells: Must be set to 1 to allow device size passing + +- ranges: Must be set up to reflect the memory layout with four integer values + per bank: + 0 + +Sub-nodes: +The actual device nodes should be added as subnodes to the SROMc node. These +subnodes, except regular device specification, should contain the following +properties, describing configuration of the relevant SROM bank: + +Required properties: +- reg: bank number, base address (relative to start of the bank) and size of + the memory mapped for the device. Note that base address will be + typically 0 as this is the start of the bank. + +- samsung,srom-timing : array of 6 integers, specifying bank timings in the + following order: Tacp, Tcah, Tcoh, Tacc, Tcos, Tacs. + Each value is specified in cycles and has the following + meaning and valid range: + Tacp : Page mode access cycle at Page mode (0 - 15) + Tcah : Address holding time after CSn (0 - 15) + Tcoh : Chip selection hold on OEn (0 - 15) + Tacc : Access cycle (0 - 31, the actual time is N + 1) + Tcos : Chip selection set-up before OEn (0 - 15) + Tacs : Address set-up before CSn (0 - 15) + +Optional properties: +- reg-io-width : data width in bytes (1 or 2). If omitted, default of 1 is used. + +- samsung,srom-page-mode : page mode configuration for the bank: + 0 - normal (one data) + 1 - four data + If omitted, default of 0 is used. + +Example: basic definition, no banks are configured + sromc@12570000 { + compatible = "samsung,exynos-srom"; + reg = <0x12570000 0x14>; + }; + +Example: SROMc with SMSC911x ethernet chip on bank 3 + sromc@12570000 { + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0x04000000 0x20000 // Bank0 + 1 0 0x05000000 0x20000 // Bank1 + 2 0 0x06000000 0x20000 // Bank2 + 3 0 0x07000000 0x20000>; // Bank3 + + compatible = "samsung,exynos-srom"; + reg = <0x12570000 0x14>; + + ethernet@3,0 { + compatible = "smsc,lan9115"; + reg = <3 0 0x10000>; // Bank 3, offset = 0 + phy-mode = "mii"; + interrupt-parent = <&gpx0>; + interrupts = <5 8>; + reg-io-width = <2>; + smsc,irq-push-pull; + smsc,force-internal-phy; + + samsung,srom-page-mode = <1>; + samsung,srom-timing = <9 12 1 9 1 1>; + }; + }; diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt index bb9b0faa919d..7e79fcc36b0d 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.txt +++ b/Documentation/devicetree/bindings/arm/sunxi.txt @@ -11,5 +11,6 @@ using one of the following compatible strings: allwinner,sun7i-a20 allwinner,sun8i-a23 allwinner,sun8i-a33 + allwinner,sun8i-a83t allwinner,sun8i-h3 allwinner,sun9i-a80 diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index e59f57b24777..966dcaffcb9c 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -39,6 +39,7 @@ Required properties: "allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31 "allwinner,sun8i-a23-apb0-clk" - for the APB0 clock on A23 "allwinner,sun9i-a80-apb0-clk" - for the APB0 bus clock on A80 + "allwinner,sun8i-a83t-apb0-gates-clk" - for the APB0 gates on A83T "allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10 "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s @@ -57,6 +58,7 @@ Required properties: "allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80 "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 "allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23 + "allwinner,sun8i-a83t-bus-gates-clk" - for the bus gates on A83T "allwinner,sun8i-h3-bus-gates-clk" - for the bus gates on H3 "allwinner,sun9i-a80-apbs-gates-clk" - for the APBS gates on A80 "allwinner,sun4i-a10-dram-gates-clk" - for the DRAM gates on A10 @@ -86,7 +88,7 @@ Required properties for all clocks: - #clock-cells : from common clock binding; shall be set to 0 except for the following compatibles where it shall be set to 1: "allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk", - "allwinner,sun4i-pll6-clk", "allwinner,sun6i-a31-pll6-clk", + "allwinner,sun4i-pll6-clk", "allwinner,*-usb-clk", "allwinner,*-mmc-clk", "allwinner,*-mmc-config-clk" - clock-output-names : shall be the corresponding names of the outputs. diff --git a/Documentation/devicetree/bindings/display/arm,hdlcd.txt b/Documentation/devicetree/bindings/display/arm,hdlcd.txt new file mode 100644 index 000000000000..78bc24296f3e --- /dev/null +++ b/Documentation/devicetree/bindings/display/arm,hdlcd.txt @@ -0,0 +1,79 @@ +ARM HDLCD + +This is a display controller found on several development platforms produced +by ARM Ltd and in more modern of its' Fast Models. The HDLCD is an RGB +streamer that reads the data from a framebuffer and sends it to a single +digital encoder (DVI or HDMI). + +Required properties: + - compatible: "arm,hdlcd" + - reg: Physical base address and length of the controller's registers. + - interrupts: One interrupt used by the display controller to notify the + interrupt controller when any of the interrupt sources programmed in + the interrupt mask register have activated. + - clocks: A list of phandle + clock-specifier pairs, one for each + entry in 'clock-names'. + - clock-names: A list of clock names. For HDLCD it should contain: + - "pxlclk" for the clock feeding the output PLL of the controller. + +Required sub-nodes: + - port: The HDLCD connection to an encoder chip. The connection is modeled + using the OF graph bindings specified in + Documentation/devicetree/bindings/graph.txt. + +Optional properties: + - memory-region: phandle to a node describing memory (see + Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt) to be + used for the framebuffer; if not present, the framebuffer may be located + anywhere in memory. + + +Example: + +/ { + ... + + hdlcd@2b000000 { + compatible = "arm,hdlcd"; + reg = <0 0x2b000000 0 0x1000>; + interrupts = ; + clocks = <&oscclk5>; + clock-names = "pxlclk"; + port { + hdlcd_output: endpoint@0 { + remote-endpoint = <&hdmi_enc_input>; + }; + }; + }; + + /* HDMI encoder on I2C bus */ + i2c@7ffa0000 { + .... + hdmi-transmitter@70 { + compatible = "....."; + reg = <0x70>; + port@0 { + hdmi_enc_input: endpoint { + remote-endpoint = <&hdlcd_output>; + }; + + hdmi_enc_output: endpoint { + remote-endpoint = <&hdmi_1_port>; + }; + }; + }; + + }; + + hdmi1: connector@1 { + compatible = "hdmi-connector"; + type = "a"; + port { + hdmi_1_port: endpoint { + remote-endpoint = <&hdmi_enc_output>; + }; + }; + }; + + ... +}; diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt index 267565894db9..db7e2260f9c5 100644 --- a/Documentation/devicetree/bindings/dma/arm-pl330.txt +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt @@ -15,6 +15,7 @@ Optional properties: cells in the dmas property of client device. - dma-channels: contains the total number of DMA channels supported by the DMAC - dma-requests: contains the total number of DMA requests supported by the DMAC + - arm,pl330-broken-no-flushp: quirk for avoiding to execute DMAFLUSHP Example: diff --git a/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt b/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt index 78e2a31c58d0..1006b0489464 100644 --- a/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt +++ b/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt @@ -16,6 +16,10 @@ Required properties: - regmap-mcba : Regmap of the MCB-A (memory bridge) resource. - regmap-mcbb : Regmap of the MCB-B (memory bridge) resource. - regmap-efuse : Regmap of the PMD efuse resource. +- regmap-rb : Regmap of the register bus resource. This property + is optional only for compatibility. If the RB + error conditions are not cleared, it will + continuously generate interrupt. - reg : First resource shall be the CPU bus (PCP) resource. - interrupts : Interrupt-specifier for MCU, PMD, L3, or SoC error IRQ(s). @@ -64,6 +68,11 @@ Example: reg = <0x0 0x1054a000 0x0 0x20>; }; + rb: rb@7e000000 { + compatible = "apm,xgene-rb", "syscon"; + reg = <0x0 0x7e000000 0x0 0x10>; + }; + edac@78800000 { compatible = "apm,xgene-edac"; #address-cells = <2>; @@ -73,6 +82,7 @@ Example: regmap-mcba = <&mcba>; regmap-mcbb = <&mcbb>; regmap-efuse = <&efuse>; + regmap-rb = <&rb>; reg = <0x0 0x78800000 0x0 0x100>; interrupts = <0x0 0x20 0x4>, <0x0 0x21 0x4>, diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt new file mode 100644 index 000000000000..debcd3266c8a --- /dev/null +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt @@ -0,0 +1,25 @@ +QCOM Secure Channel Manager (SCM) + +Qualcomm processors include an interface to communicate to the secure firmware. +This interface allows for clients to request different types of actions. These +can include CPU power up/down, HDCP requests, loading of firmware, and other +assorted actions. + +Required properties: +- compatible: must contain "qcom,scm" +- clocks: Should contain the core, iface, and bus clocks. +- clock-names: Must contain "core" for the core clock, "iface" for the interface + clock and "bus" for the bus clock. + +Example: + + firmware { + compatible = "simple-bus"; + + scm { + compatible = "qcom,scm"; + clocks = <&gcc GCC_CE1_CLK> , <&gcc GCC_CE1_AXI_CLK>, <&gcc GCC_CE1_AHB_CLK>; + clock-names = "core", "bus", "iface"; + }; + }; + diff --git a/Documentation/devicetree/bindings/input/touchscreen/cyttsp.txt b/Documentation/devicetree/bindings/input/touchscreen/cyttsp.txt new file mode 100644 index 000000000000..b75d4cfd2c36 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/cyttsp.txt @@ -0,0 +1,95 @@ +* Cypress cyttsp touchscreen controller + +Required properties: + - compatible : must be "cypress,cyttsp-i2c" or "cypress,cyttsp-spi" + - reg : Device I2C address or SPI chip select number + - spi-max-frequency : Maximum SPI clocking speed of the device (for cyttsp-spi) + - interrupt-parent : the phandle for the gpio controller + (see interrupt binding[0]). + - interrupts : (gpio) interrupt to which the chip is connected + (see interrupt binding[0]). + - bootloader-key : the 8-byte bootloader key that is required to switch + the chip from bootloader mode (default mode) to + application mode. + This property has to be specified as an array of 8 + '/bits/ 8' values. + +Optional properties: + - reset-gpios : the reset gpio the chip is connected to + (see GPIO binding[1] for more details). + - touchscreen-size-x : horizontal resolution of touchscreen (in pixels) + - touchscreen-size-y : vertical resolution of touchscreen (in pixels) + - touchscreen-fuzz-x : horizontal noise value of the absolute input device + (in pixels) + - touchscreen-fuzz-y : vertical noise value of the absolute input device + (in pixels) + - active-distance : the distance in pixels beyond which a touch must move + before movement is detected and reported by the device. + Valid values: 0-15. + - active-interval-ms : the minimum period in ms between consecutive + scanning/processing cycles when the chip is in active mode. + Valid values: 0-255. + - lowpower-interval-ms : the minimum period in ms between consecutive + scanning/processing cycles when the chip is in low-power mode. + Valid values: 0-2550 + - touch-timeout-ms : minimum time in ms spent in the active power state while no + touches are detected before entering low-power mode. + Valid values: 0-2550 + - use-handshake : enable register-based handshake (boolean). This should + only be used if the chip is configured to use 'blocking + communication with timeout' (in this case the device + generates an interrupt at the end of every + scanning/processing cycle). + +[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +[1]: Documentation/devicetree/bindings/gpio/gpio.txt + +Example: + &i2c1 { + /* ... */ + cyttsp@a { + compatible = "cypress,cyttsp-i2c"; + reg = <0xa>; + interrupt-parent = <&gpio0>; + interrupts = <28 0>; + reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + touchscreen-fuzz-x = <4>; + touchscreen-fuzz-y = <7>; + + bootloader-key = /bits/ 8 <0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08>; + active-distance = <8>; + active-interval-ms = <0>; + lowpower-interval-ms = <200>; + touch-timeout-ms = <100>; + }; + + /* ... */ + }; + + &mcspi1 { + /* ... */ + cyttsp@0 { + compatible = "cypress,cyttsp-spi"; + spi-max-frequency = <6000000>; + reg = <0>; + interrupt-parent = <&gpio0>; + interrupts = <28 0>; + reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + touchscreen-fuzz-x = <4>; + touchscreen-fuzz-y = <7>; + + bootloader-key = /bits/ 8 <0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08>; + active-distance = <8>; + active-interval-ms = <0>; + lowpower-interval-ms = <200>; + touch-timeout-ms = <100>; + }; + + /* ... */ + }; diff --git a/Documentation/devicetree/bindings/media/i2c/mt9v032.txt b/Documentation/devicetree/bindings/media/i2c/mt9v032.txt index 202565313e82..100f0ae43269 100644 --- a/Documentation/devicetree/bindings/media/i2c/mt9v032.txt +++ b/Documentation/devicetree/bindings/media/i2c/mt9v032.txt @@ -20,6 +20,8 @@ Optional Properties: - link-frequencies: List of allowed link frequencies in Hz. Each frequency is expressed as a 64-bit big-endian integer. +- reset-gpios: GPIO handle which is connected to the reset pin of the chip. +- standby-gpios: GPIO handle which is connected to the standby pin of the chip. For further reading on port node refer to Documentation/devicetree/bindings/media/video-interfaces.txt. diff --git a/Documentation/devicetree/bindings/media/i2c/tvp5150.txt b/Documentation/devicetree/bindings/media/i2c/tvp5150.txt new file mode 100644 index 000000000000..8c0fc1a26bf0 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/tvp5150.txt @@ -0,0 +1,45 @@ +* Texas Instruments TVP5150 and TVP5151 video decoders + +The TVP5150 and TVP5151 are video decoders that convert baseband NTSC and PAL +(and also SECAM in the TVP5151 case) video signals to either 8-bit 4:2:2 YUV +with discrete syncs or 8-bit ITU-R BT.656 with embedded syncs output formats. + +Required Properties: +- compatible: value must be "ti,tvp5150" +- reg: I2C slave address + +Optional Properties: +- pdn-gpios: phandle for the GPIO connected to the PDN pin, if any. +- reset-gpios: phandle for the GPIO connected to the RESETB pin, if any. + +The device node must contain one 'port' child node for its digital output +video port, in accordance with the video interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Required Endpoint Properties for parallel synchronization: + +- hsync-active: active state of the HSYNC signal. Must be <1> (HIGH). +- vsync-active: active state of the VSYNC signal. Must be <1> (HIGH). +- field-even-active: field signal level during the even field data + transmission. Must be <0>. + +If none of hsync-active, vsync-active and field-even-active is specified, +the endpoint is assumed to use embedded BT.656 synchronization. + +Example: + +&i2c2 { + ... + tvp5150@5c { + compatible = "ti,tvp5150"; + reg = <0x5c>; + pdn-gpios = <&gpio4 30 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio6 7 GPIO_ACTIVE_LOW>; + + port { + tvp5150_1: endpoint { + remote-endpoint = <&ccdc_ep>; + }; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt index 9dafe6b06cd2..619193ccf7ff 100644 --- a/Documentation/devicetree/bindings/media/rcar_vin.txt +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt @@ -6,6 +6,7 @@ family of devices. The current blocks are always slaves and suppot one input channel which can be either RGB, YUYV or BT656. - compatible: Must be one of the following + - "renesas,vin-r8a7795" for the R8A7795 device - "renesas,vin-r8a7794" for the R8A7794 device - "renesas,vin-r8a7793" for the R8A7793 device - "renesas,vin-r8a7791" for the R8A7791 device diff --git a/Documentation/devicetree/bindings/media/renesas,jpu.txt b/Documentation/devicetree/bindings/media/renesas,jpu.txt index 0cb94201bf92..d3436e5190f9 100644 --- a/Documentation/devicetree/bindings/media/renesas,jpu.txt +++ b/Documentation/devicetree/bindings/media/renesas,jpu.txt @@ -5,11 +5,12 @@ and decoding function conforming to the JPEG baseline process, so that the JPU can encode image data and decode JPEG data quickly. Required properties: - - compatible: should containg one of the following: - - "renesas,jpu-r8a7790" for R-Car H2 - - "renesas,jpu-r8a7791" for R-Car M2-W - - "renesas,jpu-r8a7792" for R-Car V2H - - "renesas,jpu-r8a7793" for R-Car M2-N +- compatible: "renesas,jpu-", "renesas,rcar-gen2-jpu" as fallback. + Examples with soctypes are: + - "renesas,jpu-r8a7790" for R-Car H2 + - "renesas,jpu-r8a7791" for R-Car M2-W + - "renesas,jpu-r8a7792" for R-Car V2H + - "renesas,jpu-r8a7793" for R-Car M2-N - reg: Base address and length of the registers block for the JPU. - interrupts: JPU interrupt specifier. @@ -17,7 +18,7 @@ Required properties: Example: R8A7790 (R-Car H2) JPU node jpeg-codec@fe980000 { - compatible = "renesas,jpu-r8a7790"; + compatible = "renesas,jpu-r8a7790", "renesas,rcar-gen2-jpu"; reg = <0 0xfe980000 0 0x10300>; interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp1_clks R8A7790_CLK_JPU>; diff --git a/Documentation/devicetree/bindings/media/ti-cal.txt b/Documentation/devicetree/bindings/media/ti-cal.txt new file mode 100644 index 000000000000..ae9b52f37576 --- /dev/null +++ b/Documentation/devicetree/bindings/media/ti-cal.txt @@ -0,0 +1,72 @@ +Texas Instruments DRA72x CAMERA ADAPTATION LAYER (CAL) +------------------------------------------------------ + +The Camera Adaptation Layer (CAL) is a key component for image capture +applications. The capture module provides the system interface and the +processing capability to connect CSI2 image-sensor modules to the +DRA72x device. + +Required properties: +- compatible: must be "ti,dra72-cal" +- reg: CAL Top level, Receiver Core #0, Receiver Core #1 and Camera RX + control address space +- reg-names: cal_top, cal_rx_core0, cal_rx_core1, and camerrx_control + registers +- interrupts: should contain IRQ line for the CAL; + +CAL supports 2 camera port nodes on MIPI bus. Each CSI2 camera port nodes +should contain a 'port' child node with child 'endpoint' node. Please +refer to the bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Example: + cal: cal@4845b000 { + compatible = "ti,dra72-cal"; + ti,hwmods = "cal"; + reg = <0x4845B000 0x400>, + <0x4845B800 0x40>, + <0x4845B900 0x40>, + <0x4A002e94 0x4>; + reg-names = "cal_top", + "cal_rx_core0", + "cal_rx_core1", + "camerrx_control"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + csi2_0: port@0 { + reg = <0>; + endpoint { + slave-mode; + remote-endpoint = <&ar0330_1>; + }; + }; + csi2_1: port@1 { + reg = <1>; + }; + }; + }; + + i2c5: i2c@4807c000 { + ar0330@10 { + compatible = "ti,ar0330"; + reg = <0x10>; + + port { + #address-cells = <1>; + #size-cells = <0>; + + ar0330_1: endpoint { + reg = <0>; + clock-lanes = <1>; + data-lanes = <0 2 3 4>; + remote-endpoint = <&csi2_0>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/tps65086.txt b/Documentation/devicetree/bindings/mfd/tps65086.txt new file mode 100644 index 000000000000..d3705612a846 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/tps65086.txt @@ -0,0 +1,55 @@ +* TPS65086 Power Management Integrated Circuit (PMIC) bindings + +Required properties: + - compatible : Should be "ti,tps65086". + - 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: buck[1-6], + ldoa[1-3], swa1, swb[1-2], and vtt. Each child + node is defined using the standard binding for + regulators and the optional regulator properties + defined below. + +Optional regulator properties: + - ti,regulator-step-size-25mv : This is applicable for buck[1,2,6], set this + if the regulator is factory set with a 25mv + step voltage mapping. + - ti,regulator-decay : This is applicable for buck[1-6], set this if + the output needs to decay, default is for + the output to slew down. + +Example: + + pmic: tps65086@5e { + compatible = "ti,tps65086"; + reg = <0x5e>; + interrupt-parent = <&gpio1>; + interrupts = <28 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + + regulators { + buck1 { + regulator-name = "vcc1"; + regulator-min-microvolt = <1600000>; + regulator-max-microvolt = <1600000>; + regulator-boot-on; + ti,regulator-decay; + ti,regulator-step-size-25mv; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt b/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt index 72cc9cc95880..be56d2bd474a 100644 --- a/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt +++ b/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt @@ -4,7 +4,10 @@ This file documents differences between the core properties described by mmc.txt and the properties that represent the IPROC SDHCI controller. Required properties: -- compatible : Should be "brcm,sdhci-iproc-cygnus". +- compatible : Should be one of the following + "brcm,bcm2835-sdhci" + "brcm,sdhci-iproc-cygnus" + - clocks : The clock feeding the SDHCI controller. Optional properties: diff --git a/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt new file mode 100644 index 000000000000..71ad57e050b1 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt @@ -0,0 +1,29 @@ +* Microchip PIC32 SDHCI Controller + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci-pic32 driver. + +Required properties: +- compatible: Should be "microchip,pic32mzda-sdhci" +- interrupts: Should contain interrupt +- clock-names: Should be "base_clk", "sys_clk". + See: Documentation/devicetree/bindings/resource-names.txt +- clocks: Phandle to the clock. + See: Documentation/devicetree/bindings/clock/clock-bindings.txt +- pinctrl-names: A pinctrl state names "default" must be defined. +- pinctrl-0: Phandle referencing pin configuration of the SDHCI controller. + See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt + +Example: + + sdhci@1f8ec000 { + compatible = "microchip,pic32mzda-sdhci"; + reg = <0x1f8ec000 0x100>; + interrupts = <191 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&REFCLKO4>, <&PBCLK5>; + clock-names = "base_clk", "sys_clk"; + bus-width = <4>; + cap-sd-highspeed; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdhc1>; + }; diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt index 3dc13b68fc3f..ea5614b6f613 100644 --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt @@ -13,6 +13,8 @@ Required Properties: - "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following, before RK3288 - "rockchip,rk3288-dw-mshc": for Rockchip RK3288 + - "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3036 + - "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3368 Optional Properties: * clocks: from common clock binding: if ciu_drive and ciu_sample are diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt new file mode 100644 index 000000000000..70dd5118a324 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt @@ -0,0 +1,86 @@ +* Qualcomm NAND controller + +Required properties: +- compatible: should be "qcom,ipq806x-nand" +- 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 +- 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 +- dma-names: must be "rxtx" +- qcom,cmd-crci: must contain the ADM command type CRCI block instance + number specified for the NAND controller on the given + platform +- qcom,data-crci: must contain the ADM data type CRCI block instance + number specified for the NAND controller on the given + platform +- #address-cells: <1> - subnodes give the chip-select number +- #size-cells: <0> + +* NAND chip-select + +Each controller may contain one or more subnodes to represent enabled +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 +- #size-cells: see partition.txt +- nand-ecc-strength: see nand.txt +- nand-ecc-step-size: must be 512. see nand.txt for more details. + +Optional properties: +- nand-bus-width: see nand.txt + +Each nandcs device node may optionally contain a 'partitions' sub-node, which +further contains sub-nodes describing the flash partition mapping. See +partition.txt for more detail. + +Example: + +nand@1ac00000 { + compatible = "qcom,ebi2-nandc"; + reg = <0x1ac00000 0x800>; + + clocks = <&gcc EBI2_CLK>, + <&gcc EBI2_AON_CLK>; + clock-names = "core", "aon"; + + dmas = <&adm_dma 3>; + dma-names = "rxtx"; + qcom,cmd-crci = <15>; + qcom,data-crci = <3>; + + #address-cells = <1>; + #size-cells = <0>; + + nandcs@0 { + compatible = "qcom,nandcs"; + 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/net/brcm,bcmgenet.txt b/Documentation/devicetree/bindings/net/brcm,bcmgenet.txt index 451fef26b4df..10587bdadbbe 100644 --- a/Documentation/devicetree/bindings/net/brcm,bcmgenet.txt +++ b/Documentation/devicetree/bindings/net/brcm,bcmgenet.txt @@ -68,7 +68,7 @@ ethernet@f0b60000 { phy1: ethernet-phy@1 { max-speed = <1000>; reg = <0x1>; - compatible = "brcm,28nm-gphy", "ethernet-phy-ieee802.3-c22"; + compatible = "ethernet-phy-ieee802.3-c22"; }; }; }; @@ -115,7 +115,7 @@ ethernet@f0ba0000 { phy0: ethernet-phy@0 { max-speed = <1000>; reg = <0x0>; - compatible = "brcm,bcm53125", "ethernet-phy-ieee802.3-c22"; + compatible = "ethernet-phy-ieee802.3-c22"; }; }; }; diff --git a/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt b/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt index 80411b2f0490..ecacfa44b1eb 100644 --- a/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt +++ b/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt @@ -4,8 +4,6 @@ Required properties: - compatible: should be "hisilicon,hns-dsaf-v1" or "hisilicon,hns-dsaf-v2". "hisilicon,hns-dsaf-v1" is for hip05. "hisilicon,hns-dsaf-v2" is for Hi1610 and Hi1612. -- dsa-name: dsa fabric name who provide this interface. - should be "dsafX", X is the dsaf id. - mode: dsa fabric mode string. only support one of dsaf modes like these: "2port-64vf", "6port-16rss", @@ -26,9 +24,8 @@ Required properties: Example: -dsa: dsa@c7000000 { +dsaf0: dsa@c7000000 { compatible = "hisilicon,hns-dsaf-v1"; - dsa_name = "dsaf0"; mode = "6port-16rss"; interrupt-parent = <&mbigen_dsa>; reg = <0x0 0xC0000000 0x0 0x420000 diff --git a/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt b/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt index 41d19be7011e..e6a9d1c30878 100644 --- a/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt +++ b/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt @@ -4,8 +4,9 @@ Required properties: - compatible: "hisilicon,hns-nic-v1" or "hisilicon,hns-nic-v2". "hisilicon,hns-nic-v1" is for hip05. "hisilicon,hns-nic-v2" is for Hi1610 and Hi1612. -- ae-name: accelerator name who provides this interface, - is simply a name referring to the name of name in the accelerator node. +- ae-handle: accelerator engine handle for hns, + specifies a reference to the associating hardware driver node. + see Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt - port-id: is the index of port provided by DSAF (the accelerator). DSAF can connect to 8 PHYs. Port 0 to 1 are both used for adminstration purpose. They are called debug ports. @@ -41,7 +42,7 @@ Example: ethernet@0{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <0>; local-mac-address = [a2 14 e4 4b 56 76]; }; diff --git a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt index aeea50c84e92..d0cb8693963b 100644 --- a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt +++ b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt @@ -6,12 +6,17 @@ Required properties: - interrupts: interrupt for the device - phy: See ethernet.txt file in the same directory. - phy-mode: See ethernet.txt file in the same directory -- clocks: a pointer to the reference clock for this device. +- clocks: List of clocks for this device. At least one clock is + mandatory for the core clock. If several clocks are given, then the + clock-names property must be used to identify them. Optional properties: - tx-csum-limit: maximum mtu supported by port that allow TX checksum. Value is presented in bytes. If not used, by default 1600B is set for "marvell,armada-370-neta" and 9800B for others. +- clock-names: List of names corresponding to clocks property; shall be + "core" for core clock and "bus" for the optional bus clock. + Example: diff --git a/Documentation/devicetree/bindings/net/mdio-mux-gpio.txt b/Documentation/devicetree/bindings/net/mdio-mux-gpio.txt index 79384113c2b0..694987d3c17a 100644 --- a/Documentation/devicetree/bindings/net/mdio-mux-gpio.txt +++ b/Documentation/devicetree/bindings/net/mdio-mux-gpio.txt @@ -38,7 +38,6 @@ Example : phy11: ethernet-phy@1 { reg = <1>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -48,7 +47,6 @@ Example : }; phy12: ethernet-phy@2 { reg = <2>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -58,7 +56,6 @@ Example : }; phy13: ethernet-phy@3 { reg = <3>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -68,7 +65,6 @@ Example : }; phy14: ethernet-phy@4 { reg = <4>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -85,7 +81,6 @@ Example : phy21: ethernet-phy@1 { reg = <1>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -95,7 +90,6 @@ Example : }; phy22: ethernet-phy@2 { reg = <2>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -105,7 +99,6 @@ Example : }; phy23: ethernet-phy@3 { reg = <3>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -115,7 +108,6 @@ Example : }; phy24: ethernet-phy@4 { reg = <4>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, diff --git a/Documentation/devicetree/bindings/net/mdio-mux.txt b/Documentation/devicetree/bindings/net/mdio-mux.txt index f65606f8d632..491f5bd55203 100644 --- a/Documentation/devicetree/bindings/net/mdio-mux.txt +++ b/Documentation/devicetree/bindings/net/mdio-mux.txt @@ -47,7 +47,6 @@ Example : phy11: ethernet-phy@1 { reg = <1>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -57,7 +56,6 @@ Example : }; phy12: ethernet-phy@2 { reg = <2>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -67,7 +65,6 @@ Example : }; phy13: ethernet-phy@3 { reg = <3>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -77,7 +74,6 @@ Example : }; phy14: ethernet-phy@4 { reg = <4>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -94,7 +90,6 @@ Example : phy21: ethernet-phy@1 { reg = <1>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -104,7 +99,6 @@ Example : }; phy22: ethernet-phy@2 { reg = <2>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -114,7 +108,6 @@ Example : }; phy23: ethernet-phy@3 { reg = <3>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, @@ -124,7 +117,6 @@ Example : }; phy24: ethernet-phy@4 { reg = <4>; - compatible = "marvell,88e1149r"; marvell,reg-init = <3 0x10 0 0x5777>, <3 0x11 0 0x00aa>, <3 0x12 0 0x4105>, diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt index 525e1658f2da..bc1c3c8bf8fa 100644 --- a/Documentation/devicetree/bindings/net/phy.txt +++ b/Documentation/devicetree/bindings/net/phy.txt @@ -17,8 +17,7 @@ Optional Properties: "ethernet-phy-ieee802.3-c22" or "ethernet-phy-ieee802.3-c45" for PHYs that implement IEEE802.3 clause 22 or IEEE802.3 clause 45 specifications. If neither of these are specified, the default is to - assume clause 22. The compatible list may also contain other - elements. + assume clause 22. If the phy's identifier is known then the list may contain an entry of the form: "ethernet-phy-idAAAA.BBBB" where @@ -28,6 +27,9 @@ Optional Properties: 4 hex digits. This is the chip vendor OUI bits 19:24, followed by 10 bits of a vendor specific ID. + The compatible list should not contain other values than those + listed here. + - max-speed: Maximum PHY supported speed (10, 100, 1000...) - broken-turn-around: If set, indicates the PHY device does not correctly diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt new file mode 100644 index 000000000000..9180724e182c --- /dev/null +++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt @@ -0,0 +1,36 @@ +* Texas Instruments wl1271 wireless lan controller + +The wl1271 chip can be connected via SPI or via SDIO. This +document describes the binding for the SPI connected chip. + +Required properties: +- compatible : Should be "ti,wl1271" +- reg : Chip select address of device +- spi-max-frequency : Maximum SPI clocking speed of device in Hz +- ref-clock-frequency : Reference clock frequency +- interrupt-parent, interrupts : + Should contain parameters for 1 interrupt line. + Interrupt parameters: parent, line number, type. +- vwlan-supply : Point the node of the regulator that powers/enable the wl1271 chip + +Optional properties: +- clock-xtal : boolean, clock is generated from XTAL + +- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt + for optional SPI connection related properties, + +Examples: + +&spi1 { + wl1271@1 { + compatible = "ti,wl1271"; + + reg = <1>; + spi-max-frequency = <48000000>; + clock-xtal; + ref-clock-frequency = <38400000>; + interrupt-parent = <&gpio3>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + vwlan-supply = <&vwlan_fixed>; + }; +}; diff --git a/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt b/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt index 4e8b90e43dd8..07a75094c5a8 100644 --- a/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt +++ b/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt @@ -8,6 +8,7 @@ OHCI and EHCI controllers. Required properties: - compatible: "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 diff --git a/Documentation/devicetree/bindings/pci/rcar-pci.txt b/Documentation/devicetree/bindings/pci/rcar-pci.txt index 558fe528ae19..6cf99690eef9 100644 --- a/Documentation/devicetree/bindings/pci/rcar-pci.txt +++ b/Documentation/devicetree/bindings/pci/rcar-pci.txt @@ -4,6 +4,7 @@ Required properties: compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC; "renesas,pcie-r8a7790" for the R8A7790 SoC; "renesas,pcie-r8a7791" for the R8A7791 SoC; + "renesas,pcie-r8a7793" for the R8A7793 SoC; "renesas,pcie-r8a7795" for the R8A7795 SoC; "renesas,pcie-rcar-gen2" for a generic R-Car Gen2 compatible device. diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt index add7c38ec7d8..8662f3aaf312 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt @@ -91,6 +91,9 @@ mpp60 60 gpio, dev(ale1), uart1(rxd), sata0(prsnt), pcie(rstout), mpp61 61 gpo, dev(we1), uart1(txd), audio(lrclk) mpp62 62 gpio, dev(a2), uart1(cts), tdm(drx), pcie(clkreq0), audio(mclk), uart0(cts) -mpp63 63 gpo, spi0(sck), tclk +mpp63 63 gpio, spi0(sck), tclk mpp64 64 gpio, spi0(miso), spi0(cs1) mpp65 65 gpio, spi0(mosi), spi0(cs2) + +Note: According to the datasheet mpp63 is a gpo but there is at least +one example of a gpio usage on the board D-Link DNS-327L diff --git a/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt b/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt new file mode 100644 index 000000000000..5c80a7779552 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt @@ -0,0 +1,80 @@ +Device-Tree bindings for regulators of Active-semi ACT8945A Multi-Function Device + +Required properties: + - compatible: "active-semi,act8945a", please refer to ../mfd/act8945a.txt. + +Optional properties: +- active-semi,vsel-high: Indicates if the VSEL pin is set to logic-high. + If this property is missing, assume the VSEL pin is set to logic-low. + +Optional input supply properties: + - vp1-supply: The input supply for REG_DCDC1 + - vp2-supply: The input supply for REG_DCDC2 + - vp3-supply: The input supply for REG_DCDC3 + - inl45-supply: The input supply for REG_LDO1 and REG_LDO2 + - inl67-supply: The input supply for REG_LDO3 and REG_LDO4 + +Any standard regulator properties can be used to configure the single regulator. + +The valid names for regulators are: + REG_DCDC1, REG_DCDC2, REG_DCDC3, REG_LDO1, REG_LDO2, REG_LDO3, REG_LDO4. + +Example: + pmic@5b { + compatible = "active-semi,act8945a"; + reg = <0x5b>; + status = "okay"; + + active-semi,vsel-high; + + regulators { + vdd_1v35_reg: REG_DCDC1 { + regulator-name = "VDD_1V35"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + }; + + vdd_1v2_reg: REG_DCDC2 { + regulator-name = "VDD_1V2"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + }; + + vdd_3v3_reg: REG_DCDC3 { + regulator-name = "VDD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_fuse_reg: REG_LDO1 { + regulator-name = "VDD_FUSE"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + vdd_3v3_lp_reg: REG_LDO2 { + regulator-name = "VDD_3V3_LP"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_led_reg: REG_LDO3 { + regulator-name = "VDD_LED"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_sdhc_1v8_reg: REG_LDO4 { + regulator-name = "VDD_SDHC_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/lp872x.txt b/Documentation/devicetree/bindings/regulator/lp872x.txt index 78183182dad9..ca58a68ffdf1 100644 --- a/Documentation/devicetree/bindings/regulator/lp872x.txt +++ b/Documentation/devicetree/bindings/regulator/lp872x.txt @@ -28,6 +28,7 @@ Optional properties: - ti,dvs-gpio: GPIO specifier for external DVS pin control of LP872x devices. - ti,dvs-vsel: DVS selector. 0 = SEL_V1, 1 = SEL_V2. - ti,dvs-state: initial DVS pin state. 0 = DVS_LOW, 1 = DVS_HIGH. + - enable-gpios: GPIO specifier for EN pin control of LP872x devices. Sub nodes for regulator_init_data LP8720 has maximum 6 nodes. (child name: ldo1 ~ 5 and buck) diff --git a/Documentation/devicetree/bindings/regulator/max77802.txt b/Documentation/devicetree/bindings/regulator/max77802.txt index 09d796ed48be..879e98d3b9aa 100644 --- a/Documentation/devicetree/bindings/regulator/max77802.txt +++ b/Documentation/devicetree/bindings/regulator/max77802.txt @@ -60,7 +60,7 @@ The possible values for "regulator-initial-mode" and "regulator-mode" are: 1: Normal regulator voltage output mode. 3: Low Power which reduces the quiescent current down to only 1uA -The list of valid modes are defined in the dt-bindings/clock/maxim,max77802.h +The valid modes list is defined in the dt-bindings/regulator/maxim,max77802.h header and can be included by device tree source files. The standard "regulator-mode" property can only be used for regulators that diff --git a/Documentation/devicetree/bindings/regulator/qcom,saw-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,saw-regulator.txt new file mode 100644 index 000000000000..977fec08b2ae --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/qcom,saw-regulator.txt @@ -0,0 +1,31 @@ +Qualcomm SAW Regulators + +SAW (Subsystem Power Manager and Adaptive Voltage Scaling Wrapper) is a hardware +block in the Qualcomm chipsets that regulates the power to the CPU cores on devices +such as APQ8064, MSM8974, APQ8084 and others. + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,apq8064-saw2-v1.1-regulator" + +Example: + saw0: power-controller@2089000 { + compatible = "qcom,apq8064-saw2-v1.1-cpu", "qcom,saw2", "syscon", "simple-mfd"; + reg = <0x02089000 0x1000>, <0x02009000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + saw0_regulator: regulator@2089000 { + compatible = "qcom,apq8064-saw2-v1.1-regulator"; + regulator-always-on; + regulator-min-microvolt = <825000>; + regulator-max-microvolt = <1250000>; + }; + }; + + + &CPU0 { + cpu-supply = <&saw0_regulator>; + }; diff --git a/Documentation/devicetree/bindings/rng/brcm,bcm6368.txt b/Documentation/devicetree/bindings/rng/brcm,bcm6368.txt new file mode 100644 index 000000000000..4b5ac600bfbd --- /dev/null +++ b/Documentation/devicetree/bindings/rng/brcm,bcm6368.txt @@ -0,0 +1,17 @@ +BCM6368 Random number generator + +Required properties: + +- compatible : should be "brcm,bcm6368-rng" +- reg : Specifies base physical address and size of the registers +- clocks : phandle to clock-controller plus clock-specifier pair +- clock-names : "ipsec" as a clock name + +Example: + random: rng@10004180 { + compatible = "brcm,bcm6368-rng"; + reg = <0x10004180 0x14>; + + clocks = <&periph_clk 18>; + clock-names = "ipsec"; + }; diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt index 112756e11802..13dc6a3fdb4a 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt +++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt @@ -6,6 +6,7 @@ powered up/down by software based on different application scenes to save power. Required properties for power domain controller: - compatible: Should be one of the following. "rockchip,rk3288-power-controller" - for RK3288 SoCs. + "rockchip,rk3368-power-controller" - for RK3368 SoCs. - #power-domain-cells: Number of cells in a power-domain specifier. Should be 1 for multiple PM domains. - #address-cells: Should be 1. @@ -14,6 +15,7 @@ Required properties for power domain controller: 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/rk3368-power.h" - for RK3368 type power domain. - clocks (optional): phandles to clocks which need to be enabled while power domain switches state. @@ -31,11 +33,24 @@ Example: }; }; + power: power-controller { + compatible = "rockchip,rk3368-power-controller"; + #power-domain-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + pd_gpu_1 { + reg = ; + clocks = <&cru ACLK_GPU_CFG>; + }; + }; + Node of a device using power domains must have a power-domains property, containing a phandle to the power device node and an index specifying which 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/rk3368-power.h" - for rk3368 type power domain. Example of the node using power domain: @@ -44,3 +59,9 @@ Example of the node using power domain: power-domains = <&power RK3288_PD_GPU>; /* ... */ }; + + node { + /* ... */ + power-domains = <&power RK3368_PD_GPU_1>; + /* ... */ + }; diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt index ce55c0a6f757..ceaef5126989 100644 --- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt +++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt @@ -24,12 +24,17 @@ The compatible list for this generic sound card currently: "fsl,imx-audio-cs42888" + "fsl,imx-audio-cs427x" + (compatible with CS4271 and CS4272) + "fsl,imx-audio-wm8962" (compatible with Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt) "fsl,imx-audio-sgtl5000" (compatible with Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt) + "fsl,imx-audio-wm8960" + Required properties: - compatible : Contains one of entries in the compatible list. @@ -61,6 +66,12 @@ Optional properties: - audio-asrc : The phandle of ASRC. It can be absent if there's no need to add ASRC support via DPCM. +Optional unless SSI is selected as a CPU DAI: + + - mux-int-port : The internal port of the i.MX audio muxer (AUDMUX) + + - mux-ext-port : The external port of the i.MX audio muxer + Example: sound-cs42888 { compatible = "fsl,imx-audio-cs42888"; diff --git a/Documentation/devicetree/bindings/sound/max98926.txt b/Documentation/devicetree/bindings/sound/max98926.txt new file mode 100644 index 000000000000..0b7f4e4d5f9a --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max98926.txt @@ -0,0 +1,32 @@ +max98926 audio CODEC + +This device supports I2C. + +Required properties: + + - compatible : "maxim,max98926" + + - vmon-slot-no : slot number used to send voltage information + or in inteleave mode this will be used as + interleave slot. + + - imon-slot-no : slot number used to send current information + + - interleave-mode : When using two MAX98926 in a system it is + possible to create ADC data that that will + overflow the frame size. Digital Audio Interleave + mode provides a means to output VMON and IMON data + from two devices on a single DOUT line when running + smaller frames sizes such as 32 BCLKS per LRCLK or + 48 BCLKS per LRCLK. + + - reg : the I2C address of the device for I2C + +Example: + +codec: max98926@1a { + compatible = "maxim,max98926"; + vmon-slot-no = <0>; + imon-slot-no = <2>; + reg = <0x1a>; +}; diff --git a/Documentation/devicetree/bindings/sound/pcm179x.txt b/Documentation/devicetree/bindings/sound/pcm179x.txt index 4ae70d3462d6..436c2b247693 100644 --- a/Documentation/devicetree/bindings/sound/pcm179x.txt +++ b/Documentation/devicetree/bindings/sound/pcm179x.txt @@ -1,6 +1,6 @@ Texas Instruments pcm179x DT bindings -This driver supports the SPI bus. +This driver supports both the I2C and SPI bus. Required properties: @@ -9,6 +9,11 @@ Required properties: For required properties on SPI, please consult Documentation/devicetree/bindings/spi/spi-bus.txt +Required properties on I2C: + + - reg: the I2C address + + Examples: codec_spi: 1792a@0 { @@ -16,3 +21,7 @@ Examples: spi-max-frequency = <600000>; }; + codec_i2c: 1792a@4c { + compatible = "ti,pcm1792a"; + reg = <0x4c>; + }; diff --git a/Documentation/devicetree/bindings/sound/rt5514.txt b/Documentation/devicetree/bindings/sound/rt5514.txt new file mode 100644 index 000000000000..e24436fc5ea9 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt5514.txt @@ -0,0 +1,25 @@ +RT5514 audio CODEC + +This device supports I2C only. + +Required properties: + +- compatible : "realtek,rt5514". + +- reg : The I2C address of the device. + +Pins on the device (for linking into audio routes) for RT5514: + + * DMIC1L + * DMIC1R + * DMIC2L + * DMIC2R + * AMICL + * AMICR + +Example: + +codec: rt5514@57 { + compatible = "realtek,rt5514"; + reg = <0x57>; +}; diff --git a/Documentation/devicetree/bindings/sound/rt5616.txt b/Documentation/devicetree/bindings/sound/rt5616.txt index efc48c65198d..e41085818559 100644 --- a/Documentation/devicetree/bindings/sound/rt5616.txt +++ b/Documentation/devicetree/bindings/sound/rt5616.txt @@ -8,6 +8,12 @@ Required properties: - reg : The I2C address of the device. +Optional properties: + +- clocks: The phandle of the master clock to the CODEC. + +- clock-names: Should be "mclk". + Pins on the device (for linking into audio routes) for RT5616: * IN1P diff --git a/Documentation/devicetree/bindings/sparc_sun_oracle_rng.txt b/Documentation/devicetree/bindings/sparc_sun_oracle_rng.txt new file mode 100644 index 000000000000..b0b211194c71 --- /dev/null +++ b/Documentation/devicetree/bindings/sparc_sun_oracle_rng.txt @@ -0,0 +1,30 @@ +HWRNG support for the n2_rng driver + +Required properties: +- reg : base address to sample from +- compatible : should contain one of the following + RNG versions: + - 'SUNW,n2-rng' for Niagara 2 Platform (SUN UltraSPARC T2 CPU) + - 'SUNW,vf-rng' for Victoria Falls Platform (SUN UltraSPARC T2 Plus CPU) + - 'SUNW,kt-rng' for Rainbow/Yosemite Falls Platform (SUN SPARC T3/T4), (UltraSPARC KT/Niagara 3 - development names) + more recent systems (after Oracle acquisition of SUN) + - 'ORCL,m4-rng' for SPARC T5/M5 + - 'ORCL,m7-rng' for SPARC T7/M7 + +Examples: +/* linux LDOM on SPARC T5-2 */ +Node 0xf029a4f4 + .node: f029a4f4 + rng-#units: 00000002 + compatible: 'ORCL,m4-rng' + reg: 0000000e + name: 'random-number-generator' + +/* solaris on SPARC M7-8 */ +Node 0xf028c08c + rng-#units: 00000003 + compatible: 'ORCL,m7-rng' + reg: 0000000e + name: 'random-number-generator' + +PS: see as well prtconfs.git by DaveM diff --git a/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.txt b/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.txt new file mode 100644 index 000000000000..8a18d71e6879 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.txt @@ -0,0 +1,31 @@ +Analog Devices AXI SPI Engine controller Device Tree Bindings + +Required properties: +- compatible : Must be "adi,axi-spi-engine-1.00.a"" +- reg : Physical base address and size of the register map. +- interrupts : Property with a value describing the interrupt + number. +- clock-names : List of input clock names - "s_axi_aclk", "spi_clk" +- clocks : Clock phandles and specifiers (See clock bindings for + details on clock-names and clocks). +- #address-cells : Must be <1> +- #size-cells : Must be <0> + +Optional subnodes: + Subnodes are use to represent the SPI slave devices connected to the SPI + master. They follow the generic SPI bindings as outlined in spi-bus.txt. + +Example: + + spi@@44a00000 { + compatible = "adi,axi-spi-engine-1.00.a"; + reg = <0x44a00000 0x1000>; + interrupts = <0 56 4>; + clocks = <&clkc 15 &clkc 15>; + clock-names = "s_axi_aclk", "spi_clk"; + + #address-cells = <1>; + #size-cells = <0>; + + /* SPI devices */ + }; diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt index 332e625f6ed0..e5ee3f159893 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt @@ -1,8 +1,9 @@ * Renesas R-Car Thermal Required properties: -- compatible : "renesas,thermal-", "renesas,rcar-thermal" - as fallback. +- compatible : "renesas,thermal-", + "renesas,rcar-gen2-thermal" (with thermal-zone) or + "renesas,rcar-thermal" (without thermal-zone) as fallback. Examples with soctypes are: - "renesas,thermal-r8a73a4" (R-Mobile APE6) - "renesas,thermal-r8a7779" (R-Car H1) @@ -36,3 +37,35 @@ thermal@e61f0000 { 0xe61f0300 0x38>; interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; }; + +Example (with thermal-zone): + +thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <1000>; + polling-delay = <5000>; + + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + cooling-maps { + }; + }; +}; + +thermal: thermal@e61f0000 { + compatible = "renesas,thermal-r8a7790", + "renesas,rcar-gen2-thermal", + "renesas,rcar-thermal"; + reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; + interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp5_clks R8A7790_CLK_THERMAL>; + power-domains = <&cpg_clocks>; + #thermal-sensor-cells = <0>; +}; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 72e2c5a2b327..e00029d66d66 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -170,6 +170,7 @@ opencores OpenCores.org option Option NV ortustech Ortus Technology Co., Ltd. ovti OmniVision Technologies +ORCL Oracle Corporation panasonic Panasonic Corporation parade Parade Technologies Inc. pericom Pericom Technology Inc. @@ -227,6 +228,7 @@ startek Startek ste ST-Ericsson stericsson ST-Ericsson synology Synology, Inc. +SUNW Sun Microsystems, Inc tbs TBS Technologies tcl Toby Churchill Ltd. technologic Technologic Systems diff --git a/Documentation/dma-buf-sharing.txt b/Documentation/dma-buf-sharing.txt index 480c8de3c2c4..4f4a84b6903a 100644 --- a/Documentation/dma-buf-sharing.txt +++ b/Documentation/dma-buf-sharing.txt @@ -257,17 +257,15 @@ Access to a dma_buf from the kernel context involves three steps: Interface: int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - size_t start, size_t len, enum dma_data_direction direction) This allows the exporter to ensure that the memory is actually available for cpu access - the exporter might need to allocate or swap-in and pin the backing storage. The exporter also needs to ensure that cpu access is - coherent for the given range and access direction. The range and access - direction can be used by the exporter to optimize the cache flushing, i.e. - access outside of the range or with a different direction (read instead of - write) might return stale or even bogus data (e.g. when the exporter needs to - copy the data to temporary storage). + coherent for the access direction. The direction can be used by the exporter + to optimize the cache flushing, i.e. access with a different direction (read + instead of write) might return stale or even bogus data (e.g. when the + exporter needs to copy the data to temporary storage). This step might fail, e.g. in oom conditions. @@ -322,14 +320,13 @@ Access to a dma_buf from the kernel context involves three steps: 3. Finish access - When the importer is done accessing the range specified in begin_cpu_access, - it needs to announce this to the exporter (to facilitate cache flushing and - unpinning of any pinned resources). The result of any dma_buf kmap calls - after end_cpu_access is undefined. + When the importer is done accessing the CPU, it needs to announce this to + the exporter (to facilitate cache flushing and unpinning of any pinned + resources). The result of any dma_buf kmap calls after end_cpu_access is + undefined. Interface: void dma_buf_end_cpu_access(struct dma_buf *dma_buf, - size_t start, size_t len, enum dma_data_direction dir); diff --git a/Documentation/dvb/README.dvb-usb b/Documentation/dvb/README.dvb-usb index 669dc6ce4330..6f4b12f7b844 100644 --- a/Documentation/dvb/README.dvb-usb +++ b/Documentation/dvb/README.dvb-usb @@ -190,7 +190,7 @@ and watch another one. Patches, comments and suggestions are very very welcome. 3. Acknowledgements - Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for + Amaury Demol (Amaury.Demol@parrot.com) and Francois Kanounnikoff from DiBcom for providing specs, code and help, on which the dvb-dibusb, dib3000mb and dib3000mc are based. diff --git a/Documentation/efi-stub.txt b/Documentation/efi-stub.txt index 7747024d3bb7..e15746988261 100644 --- a/Documentation/efi-stub.txt +++ b/Documentation/efi-stub.txt @@ -10,12 +10,12 @@ arch/x86/boot/header.S and arch/x86/boot/compressed/eboot.c, respectively. For ARM the EFI stub is implemented in arch/arm/boot/compressed/efi-header.S and arch/arm/boot/compressed/efi-stub.c. EFI stub code that is shared -between architectures is in drivers/firmware/efi/efi-stub-helper.c. +between architectures is in drivers/firmware/efi/libstub. For arm64, there is no compressed kernel support, so the Image itself masquerades as a PE/COFF image and the EFI stub is linked into the kernel. The arm64 EFI stub lives in arch/arm64/kernel/efi-entry.S -and arch/arm64/kernel/efi-stub.c. +and drivers/firmware/efi/libstub/arm64-stub.c. By using the EFI boot stub it's possible to boot a Linux kernel without the use of a conventional EFI boot loader, such as grub or diff --git a/Documentation/features/list-arch.sh b/Documentation/features/list-arch.sh index 6065124a072f..c16b5b595688 100755 --- a/Documentation/features/list-arch.sh +++ b/Documentation/features/list-arch.sh @@ -5,7 +5,7 @@ # (If no arguments are given then it will print the host architecture's status.) # -ARCH=${1:-$(arch | sed 's/x86_64/x86/' | sed 's/i386/x86/')} +ARCH=${1:-$(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/')} cd $(dirname $0) echo "#" diff --git a/Documentation/features/vm/huge-vmap/arch-support.txt b/Documentation/features/vm/huge-vmap/arch-support.txt index af6816bccb43..df1d1f3c9af2 100644 --- a/Documentation/features/vm/huge-vmap/arch-support.txt +++ b/Documentation/features/vm/huge-vmap/arch-support.txt @@ -9,7 +9,7 @@ | alpha: | TODO | | arc: | TODO | | arm: | TODO | - | arm64: | TODO | + | arm64: | ok | | avr32: | TODO | | blackfin: | TODO | | c6x: | TODO | diff --git a/Documentation/filesystems/orangefs.txt b/Documentation/filesystems/orangefs.txt new file mode 100644 index 000000000000..925a53e52097 --- /dev/null +++ b/Documentation/filesystems/orangefs.txt @@ -0,0 +1,353 @@ +ORANGEFS +======== + +OrangeFS is an LGPL userspace scale-out parallel storage system. It is ideal +for large storage problems faced by HPC, BigData, Streaming Video, +Genomics, Bioinformatics. + +Orangefs, originally called PVFS, was first developed in 1993 by +Walt Ligon and Eric Blumer as a parallel file system for Parallel +Virtual Machine (PVM) as part of a NASA grant to study the I/O patterns +of parallel programs. + +Orangefs features include: + + * Distributes file data among multiple file servers + * Supports simultaneous access by multiple clients + * Stores file data and metadata on servers using local file system + and access methods + * Userspace implementation is easy to install and maintain + * Direct MPI support + * Stateless + + +MAILING LIST +============ + +http://beowulf-underground.org/mailman/listinfo/pvfs2-users + + +DOCUMENTATION +============= + +http://www.orangefs.org/documentation/ + + +USERSPACE FILESYSTEM SOURCE +=========================== + +http://www.orangefs.org/download + +Orangefs versions prior to 2.9.3 would not be compatible with the +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. + +./configure --prefix=/opt/ofs --with-kernel=/path/to/orangefs/kernel + +make + +make install + +Create an orangefs config file: +/opt/ofs/bin/pvfs2-genconfig /etc/pvfs2.conf + + for "Enter hostnames", use the hostname, don't let it default to + localhost. + +create a pvfs2tab file in /etc: +cat /etc/pvfs2tab +tcp://myhostname:3334/orangefs /mymountpoint pvfs2 defaults,noauto 0 0 + +create the mount point you specified in the tab file if needed: +mkdir /mymountpoint + +bootstrap the server: +/opt/ofs/sbin/pvfs2-server /etc/pvfs2.conf -f + +start the server: +/opt/osf/sbin/pvfs2-server /etc/pvfs2.conf + +Now the server is running. At this point you might like to +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 + +Mount your filesystem. +mount -t pvfs2 tcp://myhostname:3334/orangefs /mymountpoint + + +OPTIONS +======= + +The following mount options are accepted: + + acl + Allow the use of Access Control Lists on files and directories. + + intr + Some operations between the kernel client and the user space + filesystem can be interruptible, such as changes in debug levels + and the setting of tunable parameters. + + local_lock + Enable posix locking from the perspective of "this" kernel. The + default file_operations lock action is to return ENOSYS. Posix + locking kicks in if the filesystem is mounted with -o local_lock. + Distributed locking is being worked on for the future. + + +DEBUGGING +========= + +If you want the debug (GOSSIP) statements in a particular +source file (inode.c for example) go to syslog: + + echo inode > /sys/kernel/debug/orangefs/kernel-debug + +No debugging (the default): + + echo none > /sys/kernel/debug/orangefs/kernel-debug + +Debugging from several source files: + + echo inode,dir > /sys/kernel/debug/orangefs/kernel-debug + +All debugging: + + echo all > /sys/kernel/debug/orangefs/kernel-debug + +Get a list of all debugging keywords: + + cat /sys/kernel/debug/orangefs/debug-help + + +PROTOCOL BETWEEN KERNEL MODULE AND USERSPACE +============================================ + +Orangefs is a user space filesystem and an associated kernel module. +We'll just refer to the user space part of Orangefs as "userspace" +from here on out. Orangefs descends from PVFS, and userspace code +still uses PVFS for function and variable names. Userspace typedefs +many of the important structures. Function and variable names in +the kernel module have been transitioned to "orangefs", and The Linux +Coding Style avoids typedefs, so kernel module structures that +correspond to userspace structures are not typedefed. + +The kernel module implements a pseudo device that userspace +can read from and write to. Userspace can also manipulate the +kernel module through the pseudo device with ioctl. + +THE BUFMAP: + +At startup userspace allocates two page-size-aligned (posix_memalign) +mlocked memory buffers, one is used for IO and one is used for readdir +operations. The IO buffer is 41943040 bytes and the readdir buffer is +4194304 bytes. Each buffer contains logical chunks, or partitions, and +a pointer to each buffer is added to its own PVFS_dev_map_desc structure +which also describes its total size, as well as the size and number of +the partitions. + +A pointer to the IO buffer's PVFS_dev_map_desc structure is sent to a +mapping routine in the kernel module with an ioctl. The structure is +copied from user space to kernel space with copy_from_user and is used +to initialize the kernel module's "bufmap" (struct orangefs_bufmap), which +then contains: + + * refcnt - a reference counter + * desc_size - PVFS2_BUFMAP_DEFAULT_DESC_SIZE (4194304) - the IO buffer's + partition size, which represents the filesystem's block size and + is used for s_blocksize in super blocks. + * desc_count - PVFS2_BUFMAP_DEFAULT_DESC_COUNT (10) - the number of + partitions in the IO buffer. + * desc_shift - log2(desc_size), used for s_blocksize_bits in super blocks. + * total_size - the total size of the IO buffer. + * page_count - the number of 4096 byte pages in the IO buffer. + * page_array - a pointer to page_count * (sizeof(struct page*)) bytes + of kcalloced memory. This memory is used as an array of pointers + to each of the pages in the IO buffer through a call to get_user_pages. + * desc_array - a pointer to desc_count * (sizeof(struct orangefs_bufmap_desc)) + bytes of kcalloced memory. This memory is further intialized: + + user_desc is the kernel's copy of the IO buffer's ORANGEFS_dev_map_desc + structure. user_desc->ptr points to the IO buffer. + + pages_per_desc = bufmap->desc_size / PAGE_SIZE + offset = 0 + + bufmap->desc_array[0].page_array = &bufmap->page_array[offset] + bufmap->desc_array[0].array_count = pages_per_desc = 1024 + bufmap->desc_array[0].uaddr = (user_desc->ptr) + (0 * 1024 * 4096) + offset += 1024 + . + . + . + bufmap->desc_array[9].page_array = &bufmap->page_array[offset] + bufmap->desc_array[9].array_count = pages_per_desc = 1024 + bufmap->desc_array[9].uaddr = (user_desc->ptr) + + (9 * 1024 * 4096) + offset += 1024 + + * buffer_index_array - a desc_count sized array of ints, used to + indicate which of the IO buffer's partitions are available to use. + * buffer_index_lock - a spinlock to protect buffer_index_array during update. + * readdir_index_array - a five (ORANGEFS_READDIR_DEFAULT_DESC_COUNT) element + int array used to indicate which of the readdir buffer's partitions are + available to use. + * readdir_index_lock - a spinlock to protect readdir_index_array during + update. + +OPERATIONS: + +The kernel module builds an "op" (struct orangefs_kernel_op_s) when it +needs to communicate with userspace. Part of the op contains the "upcall" +which expresses the request to userspace. Part of the op eventually +contains the "downcall" which expresses the results of the request. + +The slab allocator is used to keep a cache of op structures handy. + +The life cycle of a typical op goes like this: + + - obtain and initialize an op structure from the op_cache. + + - queue the op to the pvfs device so that its upcall data can be + read by userspace. + + - wait for userspace to write downcall data back to the pvfs device. + + - consume the downcall and return the op struct to the op_cache. + +Some ops are atypical with respect to their payloads: readdir and io ops. + + - readdir ops use the smaller of the two pre-allocated pre-partitioned + memory buffers. The readdir buffer is only available to userspace. + The kernel module obtains an index to a free partition before launching + a readdir op. Userspace deposits the results into the indexed partition + and then writes them to back to the pvfs device. + + - io (read and write) ops use the larger of the two pre-allocated + pre-partitioned memory buffers. The IO buffer is accessible from + both userspace and the kernel module. The kernel module obtains an + index to a free partition before launching an io op. The kernel module + deposits write data into the indexed partition, to be consumed + directly by userspace. Userspace deposits the results of read + requests into the indexed partition, to be consumed directly + by the kernel module. + +Responses to kernel requests are all packaged in pvfs2_downcall_t +structs. Besides a few other members, pvfs2_downcall_t contains a +union of structs, each of which is associated with a particular +response type. + +The several members outside of the union are: + - int32_t type - type of operation. + - int32_t status - return code for the operation. + - int64_t trailer_size - 0 unless readdir operation. + - char *trailer_buf - initialized to NULL, used during readdir operations. + +The appropriate member inside the union is filled out for any +particular response. + + PVFS2_VFS_OP_FILE_IO + fill a pvfs2_io_response_t + + PVFS2_VFS_OP_LOOKUP + fill a PVFS_object_kref + + PVFS2_VFS_OP_CREATE + fill a PVFS_object_kref + + PVFS2_VFS_OP_SYMLINK + fill a PVFS_object_kref + + PVFS2_VFS_OP_GETATTR + fill in a PVFS_sys_attr_s (tons of stuff the kernel doesn't need) + fill in a string with the link target when the object is a symlink. + + PVFS2_VFS_OP_MKDIR + fill a PVFS_object_kref + + PVFS2_VFS_OP_STATFS + fill a pvfs2_statfs_response_t with useless info . It is hard for + us to know, in a timely fashion, these statistics about our + distributed network filesystem. + + PVFS2_VFS_OP_FS_MOUNT + fill a pvfs2_fs_mount_response_t which is just like a PVFS_object_kref + except its members are in a different order and "__pad1" is replaced + with "id". + + PVFS2_VFS_OP_GETXATTR + fill a pvfs2_getxattr_response_t + + PVFS2_VFS_OP_LISTXATTR + fill a pvfs2_listxattr_response_t + + PVFS2_VFS_OP_PARAM + fill a pvfs2_param_response_t + + PVFS2_VFS_OP_PERF_COUNT + fill a pvfs2_perf_count_response_t + + PVFS2_VFS_OP_FSKEY + file a pvfs2_fs_key_response_t + + PVFS2_VFS_OP_READDIR + jamb everything needed to represent a pvfs2_readdir_response_t into + the readdir buffer descriptor specified in the upcall. + +writev() on /dev/pvfs2-req is used to pass responses to the requests +made by the kernel side. + +A buffer_list containing: + - a pointer to the prepared response to the request from the + kernel (struct pvfs2_downcall_t). + - and also, in the case of a readdir request, a pointer to a + buffer containing descriptors for the objects in the target + directory. +... is sent to the function (PINT_dev_write_list) which performs +the writev. + +PINT_dev_write_list has a local iovec array: struct iovec io_array[10]; + +The first four elements of io_array are initialized like this for all +responses: + + io_array[0].iov_base = address of local variable "proto_ver" (int32_t) + io_array[0].iov_len = sizeof(int32_t) + + io_array[1].iov_base = address of global variable "pdev_magic" (int32_t) + io_array[1].iov_len = sizeof(int32_t) + + io_array[2].iov_base = address of parameter "tag" (PVFS_id_gen_t) + io_array[2].iov_len = sizeof(int64_t) + + io_array[3].iov_base = address of out_downcall member (pvfs2_downcall_t) + of global variable vfs_request (vfs_request_t) + io_array[3].iov_len = sizeof(pvfs2_downcall_t) + +Readdir responses initialize the fifth element io_array like this: + + io_array[4].iov_base = contents of member trailer_buf (char *) + from out_downcall member of global variable + vfs_request + io_array[4].iov_len = contents of member trailer_size (PVFS_size) + from out_downcall member of global variable + vfs_request + + diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index fde9fd06fa98..843b045b4069 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -240,8 +240,8 @@ Table 1-2: Contents of the status files (as of 4.1) RssFile size of resident file mappings RssShmem size of resident shmem memory (includes SysV shm, mapping of tmpfs and shared anonymous mappings) - VmData size of data, stack, and text segments - VmStk size of data, stack, and text segments + VmData size of private data segments + VmStk size of stack segments VmExe size of text segment VmLib size of shared library code VmPTE size of page table entries @@ -356,7 +356,7 @@ address perms offset dev inode pathname a7cb1000-a7cb2000 ---p 00000000 00:00 0 a7cb2000-a7eb2000 rw-p 00000000 00:00 0 a7eb2000-a7eb3000 ---p 00000000 00:00 0 -a7eb3000-a7ed5000 rw-p 00000000 00:00 0 [stack:1001] +a7eb3000-a7ed5000 rw-p 00000000 00:00 0 a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6 a8008000-a800a000 r--p 00133000 03:00 4222 /lib/libc.so.6 a800a000-a800b000 rw-p 00135000 03:00 4222 /lib/libc.so.6 @@ -388,7 +388,6 @@ is not associated with a file: [heap] = the heap of the program [stack] = the stack of the main process - [stack:1001] = the stack of the thread with tid 1001 [vdso] = the "virtual dynamic shared object", the kernel system call handler @@ -396,10 +395,8 @@ is not associated with a file: The /proc/PID/task/TID/maps is a view of the virtual memory from the viewpoint of the individual tasks of a process. In this file you will see a mapping marked -as [stack] if that task sees it as a stack. This is a key difference from the -content of /proc/PID/maps, where you will see all mappings that are being used -as stack by all of those tasks. Hence, for the example above, the task-level -map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this: +as [stack] if that task sees it as a stack. Hence, for the example above, the +task-level map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this: 08048000-08049000 r-xp 00000000 03:00 8312 /opt/test 08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990 new file mode 100644 index 000000000000..c25211e90bdc --- /dev/null +++ b/Documentation/hwmon/ltc2990 @@ -0,0 +1,43 @@ +Kernel driver ltc2990 +===================== + +Supported chips: + * Linear Technology LTC2990 + Prefix: 'ltc2990' + Addresses scanned: - + Datasheet: http://www.linear.com/product/ltc2990 + +Author: Mike Looijmans + + +Description +----------- + +LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor. +The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4) +can be combined to measure a differential voltage, which is typically used to +measure current through a series resistor, or a temperature. + +This driver currently uses the 2x differential mode only. In order to support +other modes, the driver will need to be expanded. + + +Usage Notes +----------- + +This driver does not probe for PMBus devices. You will have to instantiate +devices explicitly. + + +Sysfs attributes +---------------- + +The "curr*_input" measurements actually report the voltage drop across the +input pins in microvolts. This is equivalent to the current through a 1mOhm +sense resistor. Divide the reported value by the actual sense resistor value +in mOhm to get the actual value. + +in0_input Voltage at Vcc pin in millivolt (range 2.5V to 5V) +temp1_input Internal chip temperature in millidegrees Celcius +curr1_input Current in mA across v1-v2 assuming a 1mOhm sense resistor. +curr2_input Current in mA across v3-v4 assuming a 1mOhm sense resistor. diff --git a/Documentation/hwmon/max34440 b/Documentation/hwmon/max34440 index 37cbf472a19d..027633246bd8 100644 --- a/Documentation/hwmon/max34440 +++ b/Documentation/hwmon/max34440 @@ -5,17 +5,17 @@ Supported chips: * Maxim MAX34440 Prefixes: 'max34440' Addresses scanned: - - Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX34440.pdf + Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX34440.pdf * Maxim MAX34441 PMBus 5-Channel Power-Supply Manager and Intelligent Fan Controller Prefixes: 'max34441' Addresses scanned: - - Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX34441.pdf + Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX34441.pdf * Maxim MAX34446 PMBus Power-Supply Data Logger Prefixes: 'max34446' Addresses scanned: - - Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX34446.pdf + Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX34446.pdf * Maxim MAX34460 PMBus 12-Channel Voltage Monitor & Sequencer Prefix: 'max34460' diff --git a/Documentation/i2c/dev-interface b/Documentation/i2c/dev-interface index 2ac78ae1039d..bcf919d8625c 100644 --- a/Documentation/i2c/dev-interface +++ b/Documentation/i2c/dev-interface @@ -4,7 +4,7 @@ the /dev interface. You need to load module i2c-dev for this. Each registered i2c adapter gets a number, counting from 0. You can examine /sys/class/i2c-dev/ to see what number corresponds to which adapter. -Alternatively, you can run "i2cdetect -l" to obtain a formated list of all +Alternatively, you can run "i2cdetect -l" to obtain a formatted list of all i2c adapters present on your system at a given time. i2cdetect is part of the i2c-tools package. diff --git a/Documentation/i2c/slave-eeprom-backend b/Documentation/i2c/slave-eeprom-backend index c8444ef82acf..04f8d8a9b817 100644 --- a/Documentation/i2c/slave-eeprom-backend +++ b/Documentation/i2c/slave-eeprom-backend @@ -7,8 +7,8 @@ This is a proof-of-concept backend which acts like an EEPROM on the connected I2C bus. The memory contents can be modified from userspace via this file located in sysfs: - /sys/bus/i2c/devices//slave-eeprom + /sys/bus/i2c/devices//slave-eeprom As of 2015, Linux doesn't support poll on binary sysfs files, so there is no -notfication when another master changed the content. +notification when another master changed the content. diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO index 8d5465d3fdef..52ef02b33da9 100644 --- a/Documentation/ja_JP/HOWTO +++ b/Documentation/ja_JP/HOWTO @@ -440,7 +440,7 @@ MAINTAINERS ファイルにリストがありますので参照してくださ てこの状態を変えようとしないように。人々はそのようなことは好みません。 今までのメールでのやりとりとその間のあなたの発言はそのまま残し、 -"John Kernlehacker wrote ...:" の行をあなたのリプライの先頭行にして、 +"John Kernelhacker wrote ...:" の行をあなたのリプライの先頭行にして、 メールの先頭でなく、各引用行の間にあなたの言いたいことを追加するべきで す。 diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 6c13d2f9dd04..5688b69c26bb 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -666,7 +666,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. clearcpuid=BITNUM [X86] Disable CPUID feature X for the kernel. See - arch/x86/include/asm/cpufeature.h for the valid bit + arch/x86/include/asm/cpufeatures.h for the valid bit numbers. Note the Linux specific bits are not necessarily stable over kernel options, but the vendor specific ones should be. @@ -1496,6 +1496,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. could change it dynamically, usually by /sys/module/printk/parameters/ignore_loglevel. + ignore_rlimit_data + Ignore RLIMIT_DATA setting for data mappings, + print warning at first misuse. Can be changed via + /sys/module/kernel/parameters/ignore_rlimit_data. + ihash_entries= [KNL] Set number of hash buckets for inode cache. @@ -1682,6 +1687,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ip= [IP_PNP] See Documentation/filesystems/nfs/nfsroot.txt. + irqaffinity= [SMP] Set the default irq affinity mask + Format: + ,..., + or + - + (must be a positive range in ascending order) + or a mixture + ,...,- + irqfixup [HW] When an interrupt is not handled search all handlers for it. Intended to get systems with badly broken @@ -2561,6 +2575,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. nointroute [IA-64] + noinvpcid [X86] Disable the INVPCID cpu feature. + nojitter [IA-64] Disables jitter checking for ITC timers. no-kvmclock [X86,KVM] Disable paravirtualized KVM clock driver @@ -3555,6 +3571,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. sched_debug [KNL] Enables verbose scheduler debug messages. + schedstats= [KNL,X86] Enable or disable scheduled statistics. + Allowed values are enable and disable. This feature + incurs a small amount of overhead in the scheduler + but is useful for debugging and performance tuning. + skew_tick= [KNL] Offset the periodic timer tick per cpu to mitigate xtime_lock contention on larger systems, and/or RCU lock contention on all systems with CONFIG_MAXSMP set. @@ -4262,6 +4283,17 @@ bytes respectively. Such letter suffixes can also be entirely omitted. The default value of this parameter is determined by the config option CONFIG_WQ_POWER_EFFICIENT_DEFAULT. + workqueue.debug_force_rr_cpu + Workqueue used to implicitly guarantee that work + items queued without explicit CPU specified are put + on the local CPU. This guarantee is no longer true + and while local CPU is still preferred work items + may be put on foreign CPUs. This debug option + forces round-robin CPU selection to flush out + usages which depend on the now broken guarantee. + When enabled, memory and cache locality will be + impacted. + x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of default x2apic cluster mode on platforms supporting x2apic. diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt index ff23b755f5e4..1b5e7a7f2185 100644 --- a/Documentation/networking/batman-adv.txt +++ b/Documentation/networking/batman-adv.txt @@ -187,7 +187,7 @@ interfaces to the kernel module settings. For more information, please see the manpage (man batctl). -batctl is available on http://www.open-mesh.org/ +batctl is available on https://www.open-mesh.org/ CONTACT diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index ceb44a095a27..73b36d7c7b0d 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -594,7 +594,7 @@ tcp_fastopen - INTEGER tcp_syn_retries - INTEGER Number of times initial SYNs for an active TCP connection attempt - will be retransmitted. Should not be higher than 255. Default value + will be retransmitted. Should not be higher than 127. Default value is 6, which corresponds to 63seconds till the last retransmission with the current initial RTO of 1second. With this the final timeout for an active TCP connection attempt will happen after 127seconds. diff --git a/Documentation/networking/mac80211-injection.txt b/Documentation/networking/mac80211-injection.txt index 3a930072b161..ec8f934c2eb2 100644 --- a/Documentation/networking/mac80211-injection.txt +++ b/Documentation/networking/mac80211-injection.txt @@ -28,6 +28,23 @@ radiotap headers and used to control injection: IEEE80211_RADIOTAP_F_TX_NOACK: frame should be sent without waiting for an ACK even if it is a unicast frame + * IEEE80211_RADIOTAP_RATE + + legacy rate for the transmission (only for devices without own rate control) + + * IEEE80211_RADIOTAP_MCS + + HT rate for the transmission (only for devices without own rate control). + Also some flags are parsed + + IEEE80211_TX_RC_SHORT_GI: use short guard interval + IEEE80211_TX_RC_40_MHZ_WIDTH: send in HT40 mode + + * IEEE80211_RADIOTAP_DATA_RETRIES + + number of retries when either IEEE80211_RADIOTAP_RATE or + IEEE80211_RADIOTAP_MCS was used + The injection code can also skip all other currently defined radiotap fields facilitating replay of captured radiotap headers directly. diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 48148d6d9307..fc53ccd9a629 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1910,6 +1910,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. - Default: 0x0000 ignore_ctl_error - Ignore any USB-controller regarding mixer interface (default: no) + autoclock - Enable auto-clock selection for UAC2 devices + (default: yes) + quirk_alias - Quirk alias list, pass strings like + "0123abcd:5678beef", which applies the existing + quirk for the device 5678:beef to a new device + 0123:abcd. This module supports multiple devices, autoprobe and hotplugging. @@ -1919,6 +1925,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. NB: ignore_ctl_error=1 may help when you get an error at accessing the mixer element such as URB error -22. This happens on some buggy USB device or the controller. + NB: quirk_alias option is provided only for testing / development. + If you want to have a proper support, contact to upstream for + adding the matching quirk in the driver code statically. Module snd-usb-caiaq -------------------- diff --git a/Documentation/sound/alsa/HD-Audio-DP-MST-audio.txt b/Documentation/sound/alsa/HD-Audio-DP-MST-audio.txt new file mode 100644 index 000000000000..82744ac3513d --- /dev/null +++ b/Documentation/sound/alsa/HD-Audio-DP-MST-audio.txt @@ -0,0 +1,74 @@ +To support DP MST audio, HD Audio hdmi codec driver introduces virtual pin +and dynamic pcm assignment. + +Virtual pin is an extension of per_pin. The most difference of DP MST +from legacy is that DP MST introduces device entry. Each pin can contain +several device entries. Each device entry behaves as a pin. + +As each pin may contain several device entries and each codec may contain +several pins, if we use one pcm per per_pin, there will be many PCMs. +The new solution is to create a few PCMs and to dynamically bind pcm to +per_pin. Driver uses spec->dyn_pcm_assign flag to indicate whether to use +the new solution. + +PCM +=== +To be added + + +Jack +==== + +Presume: + - MST must be dyn_pcm_assign, and it is acomp (for Intel scenario); + - NON-MST may or may not be dyn_pcm_assign, it can be acomp or !acomp; + +So there are the following scenarios: + a. MST (&& dyn_pcm_assign && acomp) + b. NON-MST && dyn_pcm_assign && acomp + c. NON-MST && !dyn_pcm_assign && !acomp + +Below discussion will ignore MST and NON-MST difference as it doesn't +impact on jack handling too much. + +Driver uses struct hdmi_pcm pcm[] array in hdmi_spec and snd_jack is +a member of hdmi_pcm. Each pin has one struct hdmi_pcm * pcm pointer. + +For !dyn_pcm_assign, per_pin->pcm will assigned to spec->pcm[n] statically. + +For dyn_pcm_assign, per_pin->pcm will assigned to spec->pcm[n] +when monitor is hotplugged. + + +Build Jack +---------- + +- dyn_pcm_assign +Will not use hda_jack but use snd_jack in spec->pcm_rec[pcm_idx].jack directly. + +- !dyn_pcm_assign +Use hda_jack and assign spec->pcm_rec[pcm_idx].jack = jack->jack statically. + + +Unsolicited Event Enabling +-------------------------- +Enable unsolicited event if !acomp. + + +Monitor Hotplug Event Handling +------------------------------ +- acomp +pin_eld_notify() -> check_presence_and_report() -> hdmi_present_sense() -> +sync_eld_via_acomp(). +Use directly snd_jack_report() on spec->pcm_rec[pcm_idx].jack for +both dyn_pcm_assign and !dyn_pcm_assign + +- !acomp +Hdmi_unsol_event() -> hdmi_intrinsic_event() -> check_presence_and_report() -> +hdmi_present_sense() -> hdmi_prepsent_sense_via_verbs() +Use directly snd_jack_report() on spec->pcm_rec[pcm_idx].jack for dyn_pcm_assign. +Use hda_jack mechanism to handle jack events. + + +Others to be added later +======================== diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index a93b414672a7..f4444c94ff28 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -58,6 +58,8 @@ show up in /proc/sys/kernel: - panic_on_stackoverflow - panic_on_unrecovered_nmi - panic_on_warn +- perf_cpu_time_max_percent +- perf_event_paranoid - pid_max - powersave-nap [ PPC only ] - printk @@ -639,6 +641,17 @@ allowed to execute. ============================================================== +perf_event_paranoid: + +Controls use of the performance events system by unprivileged +users (without CAP_SYS_ADMIN). The default value is 1. + + -1: Allow use of (almost) all events by all users +>=0: Disallow raw tracepoint access by users without CAP_IOC_LOCK +>=1: Disallow CPU event access by users without CAP_SYS_ADMIN +>=2: Disallow kernel profiling by users without CAP_SYS_ADMIN + +============================================================== pid_max: @@ -760,6 +773,14 @@ rtsig-nr shows the number of RT signals currently queued. ============================================================== +sched_schedstats: + +Enables/disables scheduler statistics. Enabling this feature +incurs a small amount of overhead in the scheduler but is +useful for debugging and performance tuning. + +============================================================== + sg-big-buff: This file shows the size of the generic SCSI (sg) buffer. diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 053f613fc9a9..07e4cdf02407 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -3025,7 +3025,7 @@ len must be a multiple of sizeof(struct kvm_s390_irq). It must be > 0 and it must not exceed (max_vcpus + 32) * sizeof(struct kvm_s390_irq), which is the maximum number of possibly pending cpu-local interrupts. -4.90 KVM_SMI +4.96 KVM_SMI Capability: KVM_CAP_X86_SMM Architectures: x86 diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt index 9f9ec9f76039..4e4b6f10d841 100644 --- a/Documentation/watchdog/watchdog-parameters.txt +++ b/Documentation/watchdog/watchdog-parameters.txt @@ -400,3 +400,7 @@ wm8350_wdt: nowayout: Watchdog cannot be stopped once started (default=kernel config parameter) ------------------------------------------------- +sun4v_wdt: +timeout_ms: Watchdog timeout in milliseconds 1..180000, default=60000) +nowayout: Watchdog cannot be stopped once started +------------------------------------------------- diff --git a/Documentation/x86/early-microcode.txt b/Documentation/x86/early-microcode.txt index d62bea6796da..c956d99cf1de 100644 --- a/Documentation/x86/early-microcode.txt +++ b/Documentation/x86/early-microcode.txt @@ -40,3 +40,28 @@ 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. 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/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt index 05712ac83e38..c518dce7da4d 100644 --- a/Documentation/x86/x86_64/mm.txt +++ b/Documentation/x86/x86_64/mm.txt @@ -16,6 +16,8 @@ ffffec0000000000 - fffffc0000000000 (=44 bits) kasan shadow memory (16TB) ... unused hole ... ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks ... unused hole ... +ffffffef00000000 - ffffffff00000000 (=64 GB) EFI region mapping space +... unused hole ... ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0 ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls @@ -32,11 +34,9 @@ reference. Current X86-64 implementations only support 40 bits of address space, but we support up to 46 bits. This expands into MBZ space in the page tables. -->trampoline_pgd: - -We map EFI runtime services in the aforementioned PGD in the virtual -range of 64Gb (arbitrarily set, can be raised if needed) - -0xffffffef00000000 - 0xffffffff00000000 +We map EFI runtime services in the 'efi_pgd' PGD in a 64Gb large virtual +memory window (this size is arbitrary, it can be raised later if needed). +The mappings are not part of any other kernel PGD and are only available +during EFI runtime calls. -Andi Kleen, Jul 2004 diff --git a/MAINTAINERS b/MAINTAINERS index 30aca4aa5467..750f24c94fc0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -223,9 +223,7 @@ F: drivers/scsi/aacraid/ ABI/API L: linux-api@vger.kernel.org -F: Documentation/ABI/ F: include/linux/syscalls.h -F: include/uapi/ F: kernel/sys_ni.c ABIT UGURU 1,2 HARDWARE MONITOR DRIVER @@ -675,24 +673,25 @@ F: drivers/gpu/drm/radeon/radeon_kfd.c F: drivers/gpu/drm/radeon/radeon_kfd.h F: include/uapi/linux/kfd_ioctl.h +AMD SEATTLE DEVICE TREE SUPPORT +M: Brijesh Singh +M: Suravee Suthikulpanit +M: Tom Lendacky +S: Supported +F: arch/arm64/boot/dts/amd/ + AMD XGBE DRIVER M: Tom Lendacky L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/amd/xgbe/ +F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi AMS (Apple Motion Sensor) DRIVER M: Michael Hanselmann S: Supported F: drivers/macintosh/ams/ -AMSO1100 RNIC DRIVER -M: Tom Tucker -M: Steve Wise -L: linux-rdma@vger.kernel.org -S: Maintained -F: drivers/infiniband/hw/amso1100/ - ANALOG DEVICES INC AD9389B DRIVER M: Hans Verkuil L: linux-media@vger.kernel.org @@ -836,6 +835,12 @@ S: Maintained F: drivers/net/arcnet/ F: include/uapi/linux/if_arcnet.h +ARM HDLCD DRM DRIVER +M: Liviu Dudau +S: Supported +F: drivers/gpu/drm/arm/ +F: Documentation/devicetree/bindings/display/arm,hdlcd.txt + ARM MFM AND FLOPPY DRIVERS M: Ian Molton S: Maintained @@ -967,6 +972,8 @@ M: Rob Herring L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-highbank/ +F: arch/arm/boot/dts/highbank.dts +F: arch/arm/boot/dts/ecx-*.dts* ARM/CAVIUM NETWORKS CNS3XXX MACHINE SUPPORT M: Krzysztof Halasa @@ -1042,6 +1049,7 @@ M: Barry Song L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) T: git git://git.kernel.org/pub/scm/linux/kernel/git/baohua/linux.git S: Maintained +F: arch/arm/boot/dts/prima2* F: arch/arm/mach-prima2/ F: drivers/clk/sirf/ F: drivers/clocksource/timer-prima2.c @@ -1143,6 +1151,10 @@ W: http://www.hisilicon.com S: Supported T: git git://github.com/hisilicon/linux-hisi.git F: arch/arm/mach-hisi/ +F: arch/arm/boot/dts/hi3* +F: arch/arm/boot/dts/hip* +F: arch/arm/boot/dts/hisi* +F: arch/arm64/boot/dts/hisilicon/ ARM/HP JORNADA 7XX MACHINE SUPPORT M: Kristoffer Ericson @@ -1219,6 +1231,7 @@ M: Santosh Shilimkar L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-keystone/ +F: arch/arm/boot/dts/k2* T: git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git ARM/TEXAS INSTRUMENT KEYSTONE CLOCK FRAMEWORK @@ -1287,6 +1300,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-berlin/ F: arch/arm/boot/dts/berlin* +F: arch/arm64/boot/dts/marvell/berlin* ARM/Marvell Dove/MV78xx0/Orion SOC support @@ -1425,7 +1439,10 @@ S: Maintained F: arch/arm/boot/dts/qcom-*.dts F: arch/arm/boot/dts/qcom-*.dtsi F: arch/arm/mach-qcom/ +F: arch/arm64/boot/dts/qcom/* +F: drivers/i2c/busses/i2c-qup.c F: drivers/soc/qcom/ +F: drivers/spi/spi-qup.c F: drivers/tty/serial/msm_serial.h F: drivers/tty/serial/msm_serial.c F: drivers/*/pm8???-* @@ -1484,6 +1501,8 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) S: Maintained F: arch/arm/boot/dts/s3c* +F: arch/arm/boot/dts/s5p* +F: arch/arm/boot/dts/samsung* F: arch/arm/boot/dts/exynos* F: arch/arm64/boot/dts/exynos/ F: arch/arm/plat-samsung/ @@ -1493,6 +1512,7 @@ F: arch/arm/mach-s5p*/ F: arch/arm/mach-exynos*/ F: drivers/*/*s3c2410* F: drivers/*/*/*s3c2410* +F: drivers/soc/samsung/* F: drivers/spi/spi-s3c* F: sound/soc/samsung/* F: Documentation/arm/Samsung/ @@ -1563,6 +1583,7 @@ S: Maintained F: arch/arm/mach-socfpga/ F: arch/arm/boot/dts/socfpga* F: arch/arm/configs/socfpga_defconfig +F: arch/arm64/boot/dts/altera/ W: http://www.rocketboards.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git @@ -1716,7 +1737,7 @@ M: Lorenzo Pieralisi L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/boot/dts/vexpress* -F: arch/arm64/boot/dts/arm/vexpress* +F: arch/arm64/boot/dts/arm/ F: arch/arm/mach-vexpress/ F: */*/vexpress* F: */*/*/vexpress* @@ -2147,7 +2168,7 @@ M: Marek Lindner M: Simon Wunderlich M: Antonio Quartulli L: b.a.t.m.a.n@lists.open-mesh.org -W: http://www.open-mesh.org/ +W: https://www.open-mesh.org/ S: Maintained F: net/batman-adv/ @@ -2343,6 +2364,7 @@ F: arch/arm/mach-bcm/ F: arch/arm/boot/dts/bcm113* F: arch/arm/boot/dts/bcm216* F: arch/arm/boot/dts/bcm281* +F: arch/arm64/boot/dts/broadcom/ F: arch/arm/configs/bcm_defconfig F: drivers/mmc/host/sdhci-bcm-kona.c F: drivers/clocksource/bcm_kona_timer.c @@ -2418,6 +2440,7 @@ F: arch/mips/bmips/* F: arch/mips/include/asm/mach-bmips/* F: arch/mips/kernel/*bmips* F: arch/mips/boot/dts/brcm/bcm*.dts* +F: drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* F: include/linux/bcm963xx_nvram.h @@ -3445,7 +3468,7 @@ S: Maintained F: drivers/usb/dwc2/ DESIGNWARE USB3 DRD IP DRIVER -M: Felipe Balbi +M: Felipe Balbi L: linux-usb@vger.kernel.org L: linux-omap@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git @@ -4184,13 +4207,6 @@ W: http://aeschi.ch.eu.org/efs/ S: Orphan F: fs/efs/ -EHCA (IBM GX bus InfiniBand adapter) DRIVER -M: Hoang-Nam Nguyen -M: Christoph Raisch -L: linux-rdma@vger.kernel.org -S: Supported -F: drivers/infiniband/hw/ehca/ - EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER M: Thadeu Lima de Souza Cascardo L: netdev@vger.kernel.org @@ -5809,12 +5825,6 @@ M: Juanjo Ciarlante S: Maintained F: net/ipv4/netfilter/ipt_MASQUERADE.c -IPATH DRIVER -M: Mike Marciniszyn -L: linux-rdma@vger.kernel.org -S: Maintained -F: drivers/staging/rdma/ipath/ - IPMI SUBSYSTEM M: Corey Minyard L: openipmi-developer@lists.sourceforge.net (moderated for non-subscribers) @@ -7370,7 +7380,7 @@ F: drivers/tty/isicom.c F: include/linux/isicom.h MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER -M: Felipe Balbi +M: Felipe Balbi L: linux-usb@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git S: Maintained @@ -7939,7 +7949,7 @@ F: drivers/media/platform/omap3isp/ F: drivers/staging/media/omap4iss/ OMAP USB SUPPORT -M: Felipe Balbi +M: Felipe Balbi L: linux-usb@vger.kernel.org L: linux-omap@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git @@ -8127,6 +8137,14 @@ S: Supported F: fs/overlayfs/ F: Documentation/filesystems/overlayfs.txt +ORANGEFS FILESYSTEM +M: Mike Marshall +L: pvfs2-developers@beowulf-underground.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux.git +S: Supported +F: fs/orangefs/ +F: Documentation/filesystems/orangefs.txt + P54 WIRELESS DRIVER M: Christian Lamparter L: linux-wireless@vger.kernel.org @@ -8818,6 +8836,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) T: git git://github.com/hzhuang1/linux.git T: git git://github.com/rjarzmik/linux.git S: Maintained +F: arch/arm/boot/dts/pxa* F: arch/arm/mach-pxa/ F: drivers/dma/pxa* F: drivers/pcmcia/pxa2xx* @@ -8847,6 +8866,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) T: git git://github.com/hzhuang1/linux.git T: git git://git.linaro.org/people/ycmiao/pxa-linux.git S: Maintained +F: arch/arm/boot/dts/mmp* F: arch/arm/mach-mmp/ PXA MMCI DRIVER @@ -9793,10 +9813,11 @@ S: Supported F: drivers/scsi/be2iscsi/ Emulex 10Gbps NIC BE2, BE3-R, Lancer, Skyhawk-R DRIVER -M: Sathya Perla -M: Ajit Khaparde -M: Padmanabh Ratnakar -M: Sriharsha Basavapatna +M: Sathya Perla +M: Ajit Khaparde +M: Padmanabh Ratnakar +M: Sriharsha Basavapatna +M: Somnath Kotur L: netdev@vger.kernel.org W: http://www.emulex.com S: Supported @@ -10158,6 +10179,7 @@ S: Supported F: drivers/media/pci/solo6x10/ SOFTWARE RAID (Multiple Disks) SUPPORT +M: Shaohua Li L: linux-raid@vger.kernel.org T: git git://neil.brown.name/md S: Supported @@ -10173,7 +10195,7 @@ F: drivers/net/ethernet/natsemi/sonic.* SONICS SILICON BACKPLANE DRIVER (SSB) M: Michael Buesch -L: netdev@vger.kernel.org +L: linux-wireless@vger.kernel.org S: Maintained F: drivers/ssb/ F: include/linux/ssb/ @@ -10291,6 +10313,7 @@ L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear S: Maintained +F: arch/arm/boot/dts/spear* F: arch/arm/mach-spear/ SPEAR CLOCK FRAMEWORK SUPPORT @@ -10853,6 +10876,14 @@ L: linux-omap@vger.kernel.org S: Maintained F: drivers/thermal/ti-soc-thermal/ +TI VPE/CAL DRIVERS +M: Benoit Parrot +L: linux-media@vger.kernel.org +W: http://linuxtv.org/ +Q: http://patchwork.linuxtv.org/project/linux-media/list/ +S: Maintained +F: drivers/media/platform/ti-vpe/ + TI CDCE706 CLOCK DRIVER M: Max Filippov S: Maintained @@ -11318,7 +11349,7 @@ F: Documentation/usb/ehci.txt F: drivers/usb/host/ehci* USB GADGET/PERIPHERAL SUBSYSTEM -M: Felipe Balbi +M: Felipe Balbi L: linux-usb@vger.kernel.org W: http://www.linux-usb.org/gadget T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git @@ -11394,7 +11425,7 @@ S: Maintained F: drivers/net/usb/pegasus.* USB PHY LAYER -M: Felipe Balbi +M: Felipe Balbi L: linux-usb@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git S: Maintained @@ -12133,7 +12164,7 @@ F: drivers/net/hamradio/*scc.c F: drivers/net/hamradio/z8530.h ZBUD COMPRESSED PAGE ALLOCATOR -M: Seth Jennings +M: Seth Jennings L: linux-mm@kvack.org S: Maintained F: mm/zbud.c @@ -12188,7 +12219,7 @@ F: include/linux/zsmalloc.h F: Documentation/vm/zsmalloc.txt ZSWAP COMPRESSED SWAP CACHING -M: Seth Jennings +M: Seth Jennings L: linux-mm@kvack.org S: Maintained F: mm/zswap.c diff --git a/Makefile b/Makefile index c65fe37c99e5..682840850f58 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 5 SUBLEVEL = 0 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc3 NAME = Blurry Fish Butt # *DOCUMENTATION* diff --git a/README b/README index f4756ee1c918..afc4f0d81ee1 100644 --- a/README +++ b/README @@ -59,7 +59,7 @@ DOCUMENTATION: INSTALLING the kernel source: - If you install the full sources, put the kernel tarball in a - directory where you have permissions (eg. your home directory) and + directory where you have permissions (e.g. your home directory) and unpack it: xz -cd linux-4.X.tar.xz | tar xvf - @@ -125,7 +125,7 @@ BUILD directory for the kernel: When compiling the kernel, all output files will per default be stored together with the kernel source code. - Using the option "make O=output/dir" allow you to specify an alternate + Using the option "make O=output/dir" allows you to specify an alternate place for the output files (including .config). Example: @@ -159,9 +159,9 @@ CONFIGURING the kernel: "make nconfig" Enhanced text based color menus. - "make xconfig" X windows (Qt) based configuration tool. + "make xconfig" Qt based configuration tool. - "make gconfig" X windows (GTK+) based configuration tool. + "make gconfig" GTK+ based configuration tool. "make oldconfig" Default all questions based on the contents of your existing ./.config file and asking about @@ -268,8 +268,8 @@ COMPILING the kernel: Normally, the kernel build system runs in a fairly quiet mode (but not totally silent). However, sometimes you or other kernel developers need to see compile, link, or other commands exactly as they are executed. - For this, use "verbose" build mode. This is done by inserting - "V=1" in the "make" command. E.g.: + For this, use "verbose" build mode. This is done by passing + "V=1" to the "make" command, e.g. make V=1 all @@ -300,7 +300,7 @@ COMPILING the kernel: kernel image file is usually /vmlinuz, /boot/vmlinuz, /bzImage or /boot/bzImage. To use the new kernel, save a copy of the old image and copy the new image over the old one. Then, you MUST RERUN LILO - to update the loading map!! If you don't, you won't be able to boot + to update the loading map! If you don't, you won't be able to boot the new kernel image. Reinstalling LILO is usually a matter of running /sbin/lilo. diff --git a/REPORTING-BUGS b/REPORTING-BUGS index 0cb8cdfa63bc..914baf9cf5fa 100644 --- a/REPORTING-BUGS +++ b/REPORTING-BUGS @@ -9,7 +9,7 @@ Please see https://www.kernel.org/ for a list of supported kernels. Any kernel marked with [EOL] is "end of life" and will not have any fixes backported to it. -If you've found a bug on a kernel version isn't listed on kernel.org, +If you've found a bug on a kernel version that isn't listed on kernel.org, contact your Linux distribution or embedded vendor for support. Alternatively, you can attempt to run one of the supported stable or -rc kernels, and see if you can reproduce the bug on that. It's preferable diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h index 98f2eeee8f68..75d8865d763d 100644 --- a/arch/alpha/include/asm/pci.h +++ b/arch/alpha/include/asm/pci.h @@ -7,7 +7,6 @@ #include #include #include -#include /* * The following structure is used to manage multiple PCI busses. diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 76dde9db7934..01392bcdfd23 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -410,7 +410,7 @@ config ARC_HAS_RTC default n depends on !SMP -config ARC_HAS_GRTC +config ARC_HAS_GFRC bool "SMP synchronized 64-bit cycle counter" default y depends on SMP diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig index f36c047b33ca..735985974a31 100644 --- a/arch/arc/configs/vdk_hs38_smp_defconfig +++ b/arch/arc/configs/vdk_hs38_smp_defconfig @@ -16,7 +16,7 @@ CONFIG_ARC_PLAT_AXS10X=y CONFIG_AXS103=y CONFIG_ISA_ARCV2=y CONFIG_SMP=y -# CONFIG_ARC_HAS_GRTC is not set +# CONFIG_ARC_HAS_GFRC is not set CONFIG_ARC_UBOOT_SUPPORT=y CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp" CONFIG_PREEMPT=y diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 7fac7d85ed6a..fdc5be5b1029 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -349,14 +349,13 @@ struct cpuinfo_arc { struct cpuinfo_arc_bpu bpu; struct bcr_identity core; struct bcr_isa isa; - struct bcr_timer timers; unsigned int vec_base; struct cpuinfo_arc_ccm iccm, dccm; struct { unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, pad1:3, fpu_sp:1, fpu_dp:1, pad2:6, debug:1, ap:1, smart:1, rtt:1, pad3:4, - pad4:8; + timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4; } extn; struct bcr_mpy extn_mpy; struct bcr_extn_xymem extn_xymem; diff --git a/arch/arc/include/asm/irqflags-arcv2.h b/arch/arc/include/asm/irqflags-arcv2.h index 258b0e5ad332..1fc18ee06cf2 100644 --- a/arch/arc/include/asm/irqflags-arcv2.h +++ b/arch/arc/include/asm/irqflags-arcv2.h @@ -30,8 +30,11 @@ /* Was Intr taken in User Mode */ #define AUX_IRQ_ACT_BIT_U 31 -/* 0 is highest level, but taken by FIRQs, if present in design */ -#define ARCV2_IRQ_DEF_PRIO 0 +/* + * User space should be interruptable even by lowest prio interrupt + * Safe even if actual interrupt priorities is fewer or even one + */ +#define ARCV2_IRQ_DEF_PRIO 15 /* seed value for status register */ #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \ diff --git a/arch/arc/include/asm/mcip.h b/arch/arc/include/asm/mcip.h index 46f4e5351b2a..847e3bbe387f 100644 --- a/arch/arc/include/asm/mcip.h +++ b/arch/arc/include/asm/mcip.h @@ -39,8 +39,8 @@ struct mcip_cmd { #define CMD_DEBUG_SET_MASK 0x34 #define CMD_DEBUG_SET_SELECT 0x36 -#define CMD_GRTC_READ_LO 0x42 -#define CMD_GRTC_READ_HI 0x43 +#define CMD_GFRC_READ_LO 0x42 +#define CMD_GFRC_READ_HI 0x43 #define CMD_IDU_ENABLE 0x71 #define CMD_IDU_DISABLE 0x72 diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S index cbfec79137bf..b17830294706 100644 --- a/arch/arc/kernel/entry-arcv2.S +++ b/arch/arc/kernel/entry-arcv2.S @@ -211,7 +211,11 @@ debug_marker_syscall: ; (since IRQ NOT allowed in DS in ARCv2, this can only happen if orig ; entry was via Exception in DS which got preempted in kernel). ; -; IRQ RTIE won't reliably restore DE bit and/or BTA, needs handling +; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround +; +; Solution is return from Intr w/o any delay slot quirks into a kernel trampoline +; and from pure kernel mode return to delay slot which handles DS bit/BTA correctly + .Lintr_ret_to_delay_slot: debug_marker_ds: @@ -222,18 +226,23 @@ debug_marker_ds: ld r2, [sp, PT_ret] ld r3, [sp, PT_status32] + ; STAT32 for Int return created from scratch + ; (No delay dlot, disable Further intr in trampoline) + bic r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK st r0, [sp, PT_status32] mov r1, .Lintr_ret_to_delay_slot_2 st r1, [sp, PT_ret] + ; Orig exception PC/STAT32 safekept @orig_r0 and @event stack slots st r2, [sp, 0] st r3, [sp, 4] b .Lisr_ret_fast_path .Lintr_ret_to_delay_slot_2: + ; Trampoline to restore orig exception PC/STAT32/BTA/AUX_USER_SP sub sp, sp, SZ_PT_REGS st r9, [sp, -4] @@ -243,11 +252,19 @@ debug_marker_ds: ld r9, [sp, 4] sr r9, [erstatus] + ; restore AUX_USER_SP if returning to U mode + bbit0 r9, STATUS_U_BIT, 1f + ld r9, [sp, PT_sp] + sr r9, [AUX_USER_SP] + +1: ld r9, [sp, 8] sr r9, [erbta] ld r9, [sp, -4] add sp, sp, SZ_PT_REGS + + ; return from pure kernel mode to delay slot rtie END(ret_from_exception) diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index 0394f9f61b46..942526322ae7 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -14,6 +14,8 @@ #include #include +static int irq_prio; + /* * Early Hardware specific Interrupt setup * -Called very early (start_kernel -> setup_arch -> setup_processor) @@ -24,6 +26,14 @@ void arc_init_IRQ(void) { unsigned int tmp; + struct irq_build { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int pad:3, firq:1, prio:4, exts:8, irqs:8, ver:8; +#else + unsigned int ver:8, irqs:8, exts:8, prio:4, firq:1, pad:3; +#endif + } irq_bcr; + struct aux_irq_ctrl { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int res3:18, save_idx_regs:1, res2:1, @@ -46,28 +56,25 @@ void arc_init_IRQ(void) WRITE_AUX(AUX_IRQ_CTRL, ictrl); - /* setup status32, don't enable intr yet as kernel doesn't want */ - tmp = read_aux_reg(0xa); - tmp |= ISA_INIT_STATUS_BITS; - tmp &= ~STATUS_IE_MASK; - asm volatile("flag %0 \n"::"r"(tmp)); - /* * ARCv2 core intc provides multiple interrupt priorities (upto 16). * Typical builds though have only two levels (0-high, 1-low) * Linux by default uses lower prio 1 for most irqs, reserving 0 for * NMI style interrupts in future (say perf) - * - * Read the intc BCR to confirm that Linux default priority is avail - * in h/w - * - * Note: - * IRQ_BCR[27..24] contains N-1 (for N priority levels) and prio level - * is 0 based. */ - tmp = (read_aux_reg(ARC_REG_IRQ_BCR) >> 24 ) & 0xF; - if (ARCV2_IRQ_DEF_PRIO > tmp) - panic("Linux default irq prio incorrect\n"); + + READ_BCR(ARC_REG_IRQ_BCR, irq_bcr); + + irq_prio = irq_bcr.prio; /* Encoded as N-1 for N levels */ + pr_info("archs-intc\t: %d priority levels (default %d)%s\n", + irq_prio + 1, irq_prio, + irq_bcr.firq ? " FIRQ (not used)":""); + + /* setup status32, don't enable intr yet as kernel doesn't want */ + tmp = read_aux_reg(0xa); + tmp |= STATUS_AD_MASK | (irq_prio << 1); + tmp &= ~STATUS_IE_MASK; + asm volatile("flag %0 \n"::"r"(tmp)); } static void arcv2_irq_mask(struct irq_data *data) @@ -86,7 +93,7 @@ void arcv2_irq_enable(struct irq_data *data) { /* set default priority */ write_aux_reg(AUX_IRQ_SELECT, data->irq); - write_aux_reg(AUX_IRQ_PRIORITY, ARCV2_IRQ_DEF_PRIO); + write_aux_reg(AUX_IRQ_PRIORITY, irq_prio); /* * hw auto enables (linux unmask) all by default diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index bd237acdf4f2..bc771f58fefb 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c @@ -96,13 +96,13 @@ static void mcip_probe_n_setup(void) #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad3:8, idu:1, llm:1, num_cores:6, - iocoh:1, grtc:1, dbg:1, pad2:1, + iocoh:1, gfrc:1, dbg:1, pad2:1, msg:1, sem:1, ipi:1, pad:1, ver:8; #else unsigned int ver:8, pad:1, ipi:1, sem:1, msg:1, - pad2:1, dbg:1, grtc:1, iocoh:1, + pad2:1, dbg:1, gfrc:1, iocoh:1, num_cores:6, llm:1, idu:1, pad3:8; #endif @@ -116,7 +116,7 @@ static void mcip_probe_n_setup(void) IS_AVAIL1(mp.ipi, "IPI "), IS_AVAIL1(mp.idu, "IDU "), IS_AVAIL1(mp.dbg, "DEBUG "), - IS_AVAIL1(mp.grtc, "GRTC")); + IS_AVAIL1(mp.gfrc, "GFRC")); idu_detected = mp.idu; @@ -125,8 +125,8 @@ static void mcip_probe_n_setup(void) __mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf); } - if (IS_ENABLED(CONFIG_ARC_HAS_GRTC) && !mp.grtc) - panic("kernel trying to use non-existent GRTC\n"); + if (IS_ENABLED(CONFIG_ARC_HAS_GFRC) && !mp.gfrc) + panic("kernel trying to use non-existent GFRC\n"); } struct plat_smp_ops plat_smp_ops = { diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index e1b87444ea9a..a7edceba5f84 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -45,6 +45,7 @@ struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; static void read_arc_build_cfg_regs(void) { struct bcr_perip uncached_space; + struct bcr_timer timer; struct bcr_generic bcr; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; unsigned long perip_space; @@ -53,7 +54,11 @@ static void read_arc_build_cfg_regs(void) READ_BCR(AUX_IDENTITY, cpu->core); READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa); - READ_BCR(ARC_REG_TIMERS_BCR, cpu->timers); + READ_BCR(ARC_REG_TIMERS_BCR, timer); + cpu->extn.timer0 = timer.t0; + cpu->extn.timer1 = timer.t1; + cpu->extn.rtc = timer.rtc; + cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE); READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space); @@ -208,9 +213,9 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) (unsigned int)(arc_get_core_freq() / 10000) % 100); n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ", - IS_AVAIL1(cpu->timers.t0, "Timer0 "), - IS_AVAIL1(cpu->timers.t1, "Timer1 "), - IS_AVAIL2(cpu->timers.rtc, "64-bit RTC ", + IS_AVAIL1(cpu->extn.timer0, "Timer0 "), + IS_AVAIL1(cpu->extn.timer1, "Timer1 "), + IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ", CONFIG_ARC_HAS_RTC)); n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s", @@ -293,13 +298,13 @@ static void arc_chk_core_config(void) struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; int fpu_enabled; - if (!cpu->timers.t0) + if (!cpu->extn.timer0) panic("Timer0 is not present!\n"); - if (!cpu->timers.t1) + if (!cpu->extn.timer1) panic("Timer1 is not present!\n"); - if (IS_ENABLED(CONFIG_ARC_HAS_RTC) && !cpu->timers.rtc) + if (IS_ENABLED(CONFIG_ARC_HAS_RTC) && !cpu->extn.rtc) panic("RTC is not present\n"); #ifdef CONFIG_ARC_HAS_DCCM @@ -334,6 +339,7 @@ static void arc_chk_core_config(void) panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n"); if (is_isa_arcv2() && IS_ENABLED(CONFIG_SMP) && cpu->isa.atomic && + IS_ENABLED(CONFIG_ARC_HAS_LLSC) && !IS_ENABLED(CONFIG_ARC_STAR_9000923308)) panic("llock/scond livelock workaround missing\n"); } diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index dfad287f1db1..156d9833ff84 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -62,7 +62,7 @@ /********** Clock Source Device *********/ -#ifdef CONFIG_ARC_HAS_GRTC +#ifdef CONFIG_ARC_HAS_GFRC static int arc_counter_setup(void) { @@ -83,10 +83,10 @@ static cycle_t arc_counter_read(struct clocksource *cs) local_irq_save(flags); - __mcip_cmd(CMD_GRTC_READ_LO, 0); + __mcip_cmd(CMD_GFRC_READ_LO, 0); stamp.l = read_aux_reg(ARC_REG_MCIP_READBACK); - __mcip_cmd(CMD_GRTC_READ_HI, 0); + __mcip_cmd(CMD_GFRC_READ_HI, 0); stamp.h = read_aux_reg(ARC_REG_MCIP_READBACK); local_irq_restore(flags); @@ -95,7 +95,7 @@ static cycle_t arc_counter_read(struct clocksource *cs) } static struct clocksource arc_counter = { - .name = "ARConnect GRTC", + .name = "ARConnect GFRC", .rating = 400, .read = arc_counter_read, .mask = CLOCKSOURCE_MASK(64), diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4f799e567fc8..cc95ff8f07cb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1337,7 +1337,6 @@ config BIG_LITTLE config BL_SWITCHER bool "big.LITTLE switcher support" depends on BIG_LITTLE && MCPM && HOTPLUG_CPU && ARM_GIC - select ARM_CPU_SUSPEND select CPU_PM help The big.LITTLE "switcher" provides the core functionality to @@ -2111,7 +2110,8 @@ config ARCH_SUSPEND_POSSIBLE def_bool y config ARM_CPU_SUSPEND - def_bool PM_SLEEP + def_bool PM_SLEEP || BL_SWITCHER || ARM_PSCI_FW + depends on ARCH_SUSPEND_POSSIBLE config ARCH_HIBERNATION_POSSIBLE bool diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index c6b6175d0203..1098e91d6d3f 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1368,6 +1368,7 @@ config DEBUG_SIRFSOC_UART config DEBUG_LL_INCLUDE string default "debug/sa1100.S" if DEBUG_SA1100 + default "debug/palmchip.S" if DEBUG_UART_8250_PALMCHIP default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 default "debug/at91.S" if DEBUG_AT91_UART default "debug/asm9260.S" if DEBUG_ASM9260_UART @@ -1656,6 +1657,14 @@ config DEBUG_UART_8250_WORD DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \ DEBUG_BRCMSTB_UART +config DEBUG_UART_8250_PALMCHIP + bool "8250 UART is Palmchip BK-310x" + depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 + help + Palmchip provides a UART implementation compatible with 16550 + except for having a different register layout. Say Y here if + the debug UART is of this type. + config DEBUG_UART_8250_FLOW_CONTROL bool "Enable flow control for 8250 UART" depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index fe254108d1d9..c2aedce3fea3 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -147,8 +147,7 @@ textofs-$(CONFIG_PM_H1940) := 0x00108000 ifeq ($(CONFIG_ARCH_SA1100),y) textofs-$(CONFIG_SA1111) := 0x00208000 endif -textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000 -textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000 +textofs-$(CONFIG_ARCH_QCOM_A_FAMILY) := 0x00208000 textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 # Machine directory name. This list is sorted alphanumerically diff --git a/arch/arm/arm-soc-for-next-contents.txt b/arch/arm/arm-soc-for-next-contents.txt new file mode 100644 index 000000000000..983e07b2f823 --- /dev/null +++ b/arch/arm/arm-soc-for-next-contents.txt @@ -0,0 +1,51 @@ +fixes + +next/fixes-non-critical + +next/cleanup + patch + ARM: drop unused Makefile.boot of Multiplatform SoCs + ARM: integrator: remove redundant select in Kconfig + ARM: netx: remove redundant "depends on ARCH_NETX" + renesas/cleanup + git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-cleanup-for-v4.6 + mvebu/cleanup + git://git.infradead.org/linux-mvebu tags/mvebu-cleanup-4.6-1 + +next/soc + patch + ARM: debug: add support for Palmchip BK-310x UART + mvebu/drivers + git://git.infradead.org/linux-mvebu tags/mvebu-drivers-4.6-1 + +next/arm64 + patch + arm64: defconfig: add spmi and usb related configs + +next/dt + +next/dt64 + patch + MAINTAINERS: Adding Maintainers for AMD Seattle Device Tree + dtb: amd: Fix GICv2 hypervisor and virtual interface sizes + dtb: amd: Fix DMA ranges in device tree + dtb: amd: Fix typo in SPI device nodes + dtb: amd: Misc changes for I2C device nodes + dtb: amd: Misc changes for SATA device tree nodes + dtb: amd: Misc changes for GPIO devices + dtb: amd: Add PERF CCN-504 device tree node + dtb: amd: Add KCS device tree node + dtb: amd: Add AMD XGBE device tree file + dtb: amd: Add support for new AMD Overdrive boards + dtb: amd: Add support for AMD/Linaro 96Boards Enterprise Edition Server board + renesas/dt64 + git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-arm64-dt-for-v4.6 + +next/defconfig + renesas/defconfig + git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-defconfig-for-v4.6 + mvebu/defconfig + git://git.infradead.org/linux-mvebu tags/mvebu-defconfig-4.6-1 + +next/drivers + diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 4c23a68a0917..7a6a58ef8aaf 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -106,6 +106,15 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS) KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) endif +# -fstack-protector-strong triggers protection checks in this code, +# but it is being used too early to link to meaningful stack_chk logic. +nossp_flags := $(call cc-option, -fno-stack-protector) +CFLAGS_atags_to_fdt.o := $(nossp_flags) +CFLAGS_fdt.o := $(nossp_flags) +CFLAGS_fdt_ro.o := $(nossp_flags) +CFLAGS_fdt_rw.o := $(nossp_flags) +CFLAGS_fdt_wip.o := $(nossp_flags) + ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj) asflags-y := -DZIMAGE diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index a4a6d70e8b26..b0726b5e3f8f 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -60,6 +60,7 @@ dtb-$(CONFIG_ARCH_AXXIA) += \ axm5516-amarillo.dtb dtb-$(CONFIG_ARCH_BCM2835) += \ bcm2835-rpi-b.dtb \ + bcm2835-rpi-a.dtb \ bcm2835-rpi-b-rev2.dtb \ bcm2835-rpi-b-plus.dtb \ bcm2835-rpi-a-plus.dtb \ @@ -156,7 +157,8 @@ dtb-$(CONFIG_ARCH_INTEGRATOR) += \ dtb-$(CONFIG_ARCH_KEYSTONE) += \ k2hk-evm.dtb \ k2l-evm.dtb \ - k2e-evm.dtb + k2e-evm.dtb \ + k2g-evm.dtb dtb-$(CONFIG_MACH_KIRKWOOD) += \ kirkwood-b3.dtb \ kirkwood-blackarmor-nas220.dtb \ @@ -189,9 +191,12 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \ kirkwood-is2.dtb \ kirkwood-km_kirkwood.dtb \ kirkwood-laplug.dtb \ + kirkwood-linkstation-lsqvl.dtb \ + kirkwood-linkstation-lsvl.dtb \ + kirkwood-linkstation-lswsxl.dtb \ + kirkwood-linkstation-lswvl.dtb \ + kirkwood-linkstation-lswxl.dtb \ kirkwood-lschlv2.dtb \ - kirkwood-lswvl.dtb \ - kirkwood-lswxl.dtb \ kirkwood-lsxhl.dtb \ kirkwood-mplcec4.dtb \ kirkwood-mv88f6281gtw-ge.dtb \ @@ -332,6 +337,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6q-gw551x.dtb \ imx6q-gw552x.dtb \ imx6q-hummingboard.dtb \ + imx6q-icore-rqs.dtb \ imx6q-nitrogen6x.dtb \ imx6q-nitrogen6_max.dtb \ imx6q-novena.dtb \ @@ -514,6 +520,7 @@ dtb-$(CONFIG_SOC_DRA7XX) += \ dtb-$(CONFIG_ARCH_ORION5X) += \ orion5x-lacie-d2-network.dtb \ orion5x-lacie-ethernet-disk-mini-v2.dtb \ + orion5x-linkstation-lsgl.dtb \ orion5x-linkstation-lswtgl.dtb \ orion5x-lswsgl.dtb \ orion5x-maxtor-shared-storage-2.dtb \ @@ -666,6 +673,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \ sun7i-a20-cubieboard2.dtb \ sun7i-a20-cubietruck.dtb \ sun7i-a20-hummingbird.dtb \ + sun7i-a20-itead-ibox.dtb \ sun7i-a20-i12-tvbox.dtb \ sun7i-a20-icnova-swac.dtb \ sun7i-a20-m3.dtb \ @@ -691,6 +699,8 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-a33-ippo-q8h-v1.2.dtb \ sun8i-a33-q8-tablet.dtb \ sun8i-a33-sinlinx-sina33.dtb \ + sun8i-a83t-allwinner-h8homlet-v2.dtb \ + sun8i-a83t-cubietruck-plus.dtb \ sun8i-h3-orangepi-plus.dtb dtb-$(CONFIG_MACH_SUN9I) += \ sun9i-a80-optimus.dtb \ diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts index 42e9b665582a..5d5fb62d8fbe 100644 --- a/arch/arm/boot/dts/am335x-cm-t335.dts +++ b/arch/arm/boot/dts/am335x-cm-t335.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "am33xx.dtsi" +#include / { model = "CompuLab CM-T335"; @@ -40,12 +41,51 @@ regulator-max-microvolt = <3300000>; }; + /* Regulator for WiFi */ + vwlan_fixed: fixedregulator@2 { + compatible = "regulator-fixed"; + regulator-name = "vwlan_fixed"; + gpio = <&gpio0 20 GPIO_ACTIVE_HIGH>; /* gpio0_20 */ + enable-active-high; + regulator-boot-off; + }; + backlight { compatible = "pwm-backlight"; pwms = <&ecap0 0 50000 0>; brightness-levels = <0 51 53 56 62 75 101 152 255>; default-brightness-level = <8>; }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "cm-t335"; + + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Headphone", "Headphone Jack"; + + simple-audio-card,routing = + "Headphone Jack", "LHPOUT", + "Headphone Jack", "RHPOUT", + "LLINEIN", "Line In", + "RLINEIN", "Line In", + "MICIN", "Mic Jack"; + + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&sound_master>; + simple-audio-card,frame-master = <&sound_master>; + + simple-audio-card,cpu { + sound-dai = <&mcasp1>; + }; + + sound_master: simple-audio-card,codec { + sound-dai = <&tlv320aic23>; + system-clock-frequency = <12000000>; + }; + }; }; &am33xx_pinmux { @@ -134,6 +174,24 @@ >; }; + dcan0_pins: pinmux_dcan0_pins { + pinctrl-single,pins = < + /* uart1_ctsn.dcan0_tx */ + AM33XX_IOPAD(0x978, PIN_OUTPUT | MUX_MODE2) + /* uart1_rtsn.dcan0_rx */ + AM33XX_IOPAD(0x97C, PIN_INPUT | MUX_MODE2) + >; + }; + + dcan1_pins: pinmux_dcan1_pins { + pinctrl-single,pins = < + /* uart1_rxd.dcan1_tx */ + AM33XX_IOPAD(0x980, PIN_OUTPUT | MUX_MODE2) + /* uart1_txd.dcan1_rx */ + AM33XX_IOPAD(0x984, PIN_INPUT | MUX_MODE2) + >; + }; + ecap0_pins: pinmux_ecap0_pins { pinctrl-single,pins = < /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */ @@ -223,6 +281,21 @@ >; }; + spi0_pins: pinmux_spi0_pins { + pinctrl-single,pins = < + /* spi0_sclk.spi0_sclk */ + AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE0) + /* spi0_d0.spi0_d0 */ + AM33XX_IOPAD(0x954, PIN_OUTPUT_PULLUP | MUX_MODE0) + /* spi0_d1.spi0_d1 */ + AM33XX_IOPAD(0x958, PIN_INPUT | MUX_MODE0) + /* spi0_cs0.spi0_cs0 */ + AM33XX_IOPAD(0x95C, PIN_OUTPUT | MUX_MODE0) + /* spi0_cs1.spi0_cs1 */ + AM33XX_IOPAD(0x960, PIN_OUTPUT | MUX_MODE0) + >; + }; + /* wl1271 bluetooth */ bluetooth_pins: pinmux_bluetooth_pins { pinctrl-single,pins = < @@ -230,6 +303,30 @@ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE7) >; }; + + /* TLV320AIC23B codec */ + mcasp1_pins: pinmux_mcasp1_pins { + pinctrl-single,pins = < + /* MII1_CRS.mcasp1_aclkx */ + AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4) + /* MII1_RX_ER.mcasp1_fsx */ + AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4) + /* MII1_COL.mcasp1_axr2 */ + AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE4) + /* RMII1_REF_CLK.mcasp1_axr3 */ + AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) + >; + }; + + /* wl1271 WiFi */ + wifi_pins: pinmux_wifi_pins { + pinctrl-single,pins = < + /* EMU1.gpio3_8 - WiFi IRQ */ + AM33XX_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE7) + /* XDMA_EVENT_INTR1.gpio0_20 - WiFi enable */ + AM33XX_IOPAD(0x9b4, PIN_OUTPUT | MUX_MODE7) + >; + }; }; &uart0 { @@ -264,6 +361,13 @@ status = "okay"; compatible = "emmicro,em3027"; reg = <0x56>; }; + /* Audio codec */ + tlv320aic23: codec@1a { + compatible = "ti,tlv320aic23"; + reg = <0x1a>; + #sound-dai-cells= <0>; + status = "okay"; + }; }; &usb { @@ -394,3 +498,70 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; }; + +&dcan0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&dcan0_pins>; +}; + +&dcan1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&dcan1_pins>; +}; + +/* Touschscreen and analog digital converter */ +&tscadc { + status = "okay"; + tsc { + ti,wires = <4>; + ti,x-plate-resistance = <200>; + ti,coordinate-readouts = <5>; + ti,wire-config = <0x01 0x10 0x23 0x32>; + ti,charge-delay = <0x400>; + }; + + adc { + ti,adc-channels = <4 5 6 7>; + }; +}; + +/* CPU audio */ +&mcasp1 { + pinctrl-names = "default"; + pinctrl-0 = <&mcasp1_pins>; + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + /* 16 serializers */ + num-serializer = <16>; + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 + >; + tx-num-evt = <1>; + rx-num-evt = <1>; + + #sound-dai-cells= <0>; + status = "okay"; +}; + +&spi0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + ti,pindir-d0-out-d1-in = <1>; + /* WLS1271 WiFi */ + wlcore: wlcore@1 { + compatible = "ti,wl1271"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_pins>; + reg = <1>; + spi-max-frequency = <48000000>; + clock-xtal; + ref-clock-frequency = <38400000>; + interrupt-parent = <&gpio3>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + vwlan-supply = <&vwlan_fixed>; + }; +}; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 04885f9f959e..1fafaad516ba 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -439,6 +439,7 @@ ti,mbox-num-users = <4>; ti,mbox-num-fifos = <8>; mbox_wkupm3: wkup_m3 { + ti,mbox-send-noirq; ti,mbox-tx = <0 0 0>; ti,mbox-rx = <0 0 3>; }; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index df955ba4dc62..92068fbf8b57 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -73,7 +73,7 @@ global_timer: timer@48240200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x48240200 0x100>; - interrupts = ; + interrupts = ; interrupt-parent = <&gic>; clocks = <&mpu_periphclk>; }; @@ -81,7 +81,7 @@ local_timer: timer@48240600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x48240600 0x100>; - interrupts = ; + interrupts = ; interrupt-parent = <&gic>; clocks = <&mpu_periphclk>; }; @@ -290,6 +290,7 @@ ti,mbox-num-users = <4>; ti,mbox-num-fifos = <8>; mbox_wkupm3: wkup_m3 { + ti,mbox-send-noirq; ti,mbox-tx = <0 0 0>; ti,mbox-rx = <0 0 3>; }; diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts index 64d43325bcbc..ecd09ab6d581 100644 --- a/arch/arm/boot/dts/am437x-gp-evm.dts +++ b/arch/arm/boot/dts/am437x-gp-evm.dts @@ -590,8 +590,6 @@ pinctrl-names = "default"; pinctrl-0 = <&pixcir_ts_pins>; reg = <0x5c>; - interrupt-parent = <&gpio3>; - interrupts = <22 0>; attb-gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; @@ -599,7 +597,7 @@ * 0x264 represents the offset of padconf register of * gpio3_22 from am43xx_pinmux base. */ - interrupts-extended = <&gpio3 22 IRQ_TYPE_NONE>, + interrupts-extended = <&gpio3 22 IRQ_TYPE_EDGE_FALLING>, <&am43xx_pinmux 0x264>; interrupt-names = "tsc", "wakeup"; diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index 746fd2b17958..d580e2b70f9a 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -491,7 +491,7 @@ pinctrl-0 = <&pixcir_ts_pins>; reg = <0x5c>; interrupt-parent = <&gpio1>; - interrupts = <17 0>; + interrupts = <17 IRQ_TYPE_EDGE_FALLING>; attb-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>; diff --git a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts index c53882643ae9..8d93882dc8d5 100644 --- a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts +++ b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts @@ -167,7 +167,7 @@ DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d20.rgmii1_rd3 */ DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d21.rgmii1_rd2 */ DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d22.rgmii1_rd1 */ - DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT_PULLUP | MUX_MODE3) /* vin2a_d23.rgmii1_rd0 */ + DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d23.rgmii1_rd0 */ >; }; @@ -492,14 +492,14 @@ pinctrl-names = "default"; pinctrl-0 = <&qspi1_pins>; - spi-max-frequency = <20000000>; + spi-max-frequency = <48000000>; spi_flash: spi_flash@0 { #address-cells = <1>; #size-cells = <1>; compatible = "spansion,m25p80", "jedec,spi-nor"; reg = <0>; /* CS0 */ - spi-max-frequency = <20000000>; + spi-max-frequency = <48000000>; partition@0 { label = "uboot"; @@ -559,13 +559,13 @@ &cpsw_emac0 { phy_id = <&davinci_mdio>, <0>; - phy-mode = "rgmii"; + phy-mode = "rgmii-txid"; dual_emac_res_vlan = <0>; }; &cpsw_emac1 { phy_id = <&davinci_mdio>, <1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-txid"; dual_emac_res_vlan = <1>; }; @@ -588,7 +588,7 @@ }; &usb2 { - dr_mode = "peripheral"; + dr_mode = "host"; }; &mcasp3 { diff --git a/arch/arm/boot/dts/am57xx-sbc-am57x.dts b/arch/arm/boot/dts/am57xx-sbc-am57x.dts index 77bb8e17401a..988e99632d49 100644 --- a/arch/arm/boot/dts/am57xx-sbc-am57x.dts +++ b/arch/arm/boot/dts/am57xx-sbc-am57x.dts @@ -25,8 +25,8 @@ &dra7_pmx_core { uart3_pins_default: uart3_pins_default { pinctrl-single,pins = < - DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_SLEW | MUX_MODE2) /* uart2_ctsn.uart3_rxd */ - DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_SLEW | MUX_MODE1) /* uart2_rtsn.uart3_txd */ + DRA7XX_CORE_IOPAD(0x3648, PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd */ + DRA7XX_CORE_IOPAD(0x364c, PIN_INPUT_SLEW | MUX_MODE0) /* uart3_txd */ >; }; @@ -108,9 +108,9 @@ pinctrl-0 = <&i2c5_pins_default>; clock-frequency = <400000>; - eeprom_base: atmel@50 { + eeprom_base: atmel@54 { compatible = "atmel,24c08"; - reg = <0x50>; + reg = <0x54>; pagesize = <16>; }; diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts index 3aa980ad64f0..d5e19cd4d256 100644 --- a/arch/arm/boot/dts/armada-370-mirabox.dts +++ b/arch/arm/boot/dts/armada-370-mirabox.dts @@ -200,7 +200,7 @@ &pinctrl { pwr_led_pin: pwr-led-pin { marvell,pins = "mpp63"; - marvell,function = "gpo"; + marvell,function = "gpio"; }; stat_led_pins: stat-led-pins { diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts index faa474874cb8..11565752b9f6 100644 --- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts +++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts @@ -297,7 +297,7 @@ backup_led_pin: backup-led-pin { marvell,pins = "mpp63"; - marvell,function = "gpo"; + marvell,function = "gpio"; }; power_led_pin: power-led-pin { diff --git a/arch/arm/boot/dts/armada-370-synology-ds213j.dts b/arch/arm/boot/dts/armada-370-synology-ds213j.dts index 836bcc07afc5..8ca7a4340c0f 100644 --- a/arch/arm/boot/dts/armada-370-synology-ds213j.dts +++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts @@ -339,7 +339,7 @@ fan_ctrl_high_pin: fan-ctrl-high-pin { marvell,pins = "mpp63"; - marvell,function = "gpo"; + marvell,function = "gpio"; }; fan_alarm_pin: fan-alarm-pin { diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts index acd5b1519edb..86fde0bf552b 100644 --- a/arch/arm/boot/dts/armada-385-db-ap.dts +++ b/arch/arm/boot/dts/armada-385-db-ap.dts @@ -134,18 +134,21 @@ }; }; + /* CON3 */ ethernet@30000 { status = "okay"; phy = <&phy2>; phy-mode = "sgmii"; }; + /* CON2 */ ethernet@34000 { status = "okay"; phy = <&phy1>; phy-mode = "sgmii"; }; + /* CON4 */ ethernet@70000 { pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts index cd316021d6ce..51943598d858 100644 --- a/arch/arm/boot/dts/armada-388-gp.dts +++ b/arch/arm/boot/dts/armada-388-gp.dts @@ -44,8 +44,8 @@ #include / { - model = "Marvell Armada 385 GP"; - compatible = "marvell,a385-gp", "marvell,armada388", "marvell,armada380"; + model = "Marvell Armada 388 DB-88F6820-GP"; + compatible = "marvell,a388-gp", "marvell,armada388", "marvell,armada380"; chosen { stdout-path = "serial0:115200n8"; @@ -229,13 +229,13 @@ /* CON5 */ usb3@f0000 { - vcc-supply = <®_usb2_1_vbus>; + usb-phy = <&usb2_1_phy>; status = "okay"; }; /* CON7 */ usb3@f8000 { - vcc-supply = <®_usb3_vbus>; + usb-phy = <&usb3_phy>; status = "okay"; }; }; @@ -273,13 +273,22 @@ }; }; + usb2_1_phy: usb2_1_phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <®_usb2_1_vbus>; + }; + + usb3_phy: usb3_phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <®_usb3_vbus>; + }; + reg_usb3_vbus: usb3-vbus { compatible = "regulator-fixed"; regulator-name = "usb3-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; enable-active-high; - regulator-always-on; gpio = <&expander1 15 GPIO_ACTIVE_HIGH>; }; @@ -299,7 +308,6 @@ regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; enable-active-high; - regulator-always-on; gpio = <&expander0 4 GPIO_ACTIVE_HIGH>; }; @@ -309,7 +317,7 @@ regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 2 GPIO_ACTIVE_HIGH>; }; @@ -318,7 +326,6 @@ regulator-name = "v5.0-sata0"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata0>; }; @@ -327,7 +334,6 @@ regulator-name = "v12.0-sata0"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata0>; }; @@ -337,7 +343,7 @@ regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 3 GPIO_ACTIVE_HIGH>; }; @@ -346,7 +352,6 @@ regulator-name = "v5.0-sata1"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata1>; }; @@ -355,7 +360,6 @@ regulator-name = "v12.0-sata1"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata1>; }; @@ -363,7 +367,7 @@ compatible = "regulator-fixed"; regulator-name = "pwr_en_sata2"; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 11 GPIO_ACTIVE_HIGH>; }; @@ -372,7 +376,6 @@ regulator-name = "v5.0-sata2"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata2>; }; @@ -381,7 +384,6 @@ regulator-name = "v12.0-sata2"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata2>; }; @@ -389,7 +391,7 @@ compatible = "regulator-fixed"; regulator-name = "pwr_en_sata3"; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 12 GPIO_ACTIVE_HIGH>; }; @@ -398,7 +400,6 @@ regulator-name = "v5.0-sata3"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata3>; }; @@ -407,7 +408,6 @@ regulator-name = "v12.0-sata3"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata3>; }; }; diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index e8b7f6726772..b50784de86e8 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -429,6 +429,27 @@ reg = <0x22000 0x1000>; }; + /* + * As a special exception to the "order by + * register address" rule, the eth0 node is + * placed here to ensure that it gets + * registered as the first interface, since + * the network subsystem doesn't allow naming + * interfaces using DT aliases. Without this, + * the ordering of interfaces is different + * from the one used in U-Boot and the + * labeling of interfaces on the boards, which + * is very confusing for users. + */ + eth0: ethernet@70000 { + compatible = "marvell,armada-370-neta"; + reg = <0x70000 0x4000>; + interrupts-extended = <&mpic 8>; + clocks = <&gateclk 4>; + tx-csum-limit = <9800>; + status = "disabled"; + }; + eth1: ethernet@30000 { compatible = "marvell,armada-370-neta"; reg = <0x30000 0x4000>; @@ -493,15 +514,6 @@ }; }; - eth0: ethernet@70000 { - compatible = "marvell,armada-370-neta"; - reg = <0x70000 0x4000>; - interrupts-extended = <&mpic 8>; - clocks = <&gateclk 4>; - tx-csum-limit = <9800>; - status = "disabled"; - }; - mdio: mdio@72004 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts index 13cf69a8d0fb..fb9e1bbf2338 100644 --- a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts +++ b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts @@ -152,6 +152,7 @@ nand-on-flash-bbt; partitions { + compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts index 77ddff036409..e683856c507c 100644 --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts @@ -114,9 +114,15 @@ macb0: ethernet@f8008000 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb0_default>; + pinctrl-0 = <&pinctrl_macb0_default &pinctrl_macb0_phy_irq>; phy-mode = "rmii"; status = "okay"; + + ethernet-phy@1 { + reg = <0x1>; + interrupt-parent = <&pioA>; + interrupts = <73 IRQ_TYPE_LEVEL_LOW>; + }; }; pdmic@f8018000 { @@ -300,6 +306,10 @@ bias-disable; }; + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + }; + pinctrl_pdmic_default: pdmic_default { pinmux = , ; diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts index 131614f28e75..569026e8f96c 100644 --- a/arch/arm/boot/dts/at91-sama5d4_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts @@ -86,10 +86,12 @@ macb0: ethernet@f8020000 { phy-mode = "rmii"; status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>; phy0: ethernet-phy@1 { interrupt-parent = <&pioE>; - interrupts = <1 IRQ_TYPE_EDGE_FALLING>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; reg = <1>; }; }; @@ -152,6 +154,10 @@ atmel,pins = ; }; + pinctrl_macb0_phy_irq: macb0_phy_irq_0 { + atmel,pins = + ; + }; }; }; }; diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts index 2d4a33100af6..4e98cda97403 100644 --- a/arch/arm/boot/dts/at91-sama5d4ek.dts +++ b/arch/arm/boot/dts/at91-sama5d4ek.dts @@ -160,8 +160,15 @@ }; macb0: ethernet@f8020000 { + pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>; phy-mode = "rmii"; status = "okay"; + + ethernet-phy@1 { + reg = <0x1>; + interrupt-parent = <&pioE>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; + }; }; mmc1: mmc@fc000000 { @@ -193,6 +200,10 @@ pinctrl@fc06a000 { board { + pinctrl_macb0_phy_irq: macb0_phy_irq { + atmel,pins = + ; + }; pinctrl_mmc0_cd: mmc0_cd { atmel,pins = ; diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index ca4ddf86817a..626c67d66626 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts @@ -215,7 +215,7 @@ }; panel: panel { - compatible = "qd,qd43003c0-40", "simple-panel"; + compatible = "qiaodian,qd43003c0-40", "simple-panel"; backlight = <&backlight>; power-supply = <&panel_reg>; #address-cells = <1>; diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts new file mode 100644 index 000000000000..ddbbbbd42dda --- /dev/null +++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts @@ -0,0 +1,24 @@ +/dts-v1/; +#include "bcm2835.dtsi" +#include "bcm2835-rpi.dtsi" + +/ { + compatible = "raspberrypi,model-a", "brcm,bcm2835"; + model = "Raspberry Pi Model A"; + + leds { + act { + gpios = <&gpio 16 1>; + }; + }; +}; + +&gpio { + pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; + + /* I2S interface */ + i2s_alt2: i2s_alt2 { + brcm,pins = <28 29 30 31>; + brcm,function = ; + }; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index 3afb9fefe2d1..76bdbcafab18 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -1,3 +1,5 @@ +#include + / { memory { reg = <0 0x10000000>; @@ -18,6 +20,12 @@ compatible = "raspberrypi,bcm2835-firmware"; mboxes = <&mailbox>; }; + + power: power { + compatible = "raspberrypi,bcm2835-power"; + firmware = <&firmware>; + #power-domain-cells = <1>; + }; }; }; @@ -58,3 +66,11 @@ status = "okay"; bus-width = <4>; }; + +&pwm { + status = "okay"; +}; + +&usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; +}; diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index 971e741e5467..05ff5ce91c95 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi @@ -1,5 +1,6 @@ #include #include +#include #include "skeleton.dtsi" /* This include file covers the common peripherals and configuration between @@ -111,7 +112,7 @@ #interrupt-cells = <2>; }; - uart0: uart@7e201000 { + uart0: serial@7e201000 { compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; reg = <0x7e201000 0x1000>; interrupts = <2 25>; @@ -159,6 +160,36 @@ clocks = <&clocks BCM2835_CLOCK_VPU>; }; + spi1: spi@7e215080 { + compatible = "brcm,bcm2835-aux-spi"; + reg = <0x7e215080 0x40>; + interrupts = <1 29>; + clocks = <&aux BCM2835_AUX_CLOCK_SPI1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@7e2150c0 { + compatible = "brcm,bcm2835-aux-spi"; + reg = <0x7e2150c0 0x40>; + interrupts = <1 29>; + clocks = <&aux BCM2835_AUX_CLOCK_SPI2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pwm: pwm@7e20c000 { + compatible = "brcm,bcm2835-pwm"; + reg = <0x7e20c000 0x28>; + clocks = <&clocks BCM2835_CLOCK_PWM>; + assigned-clocks = <&clocks BCM2835_CLOCK_PWM>; + assigned-clock-rates = <10000000>; + #pwm-cells = <2>; + status = "disabled"; + }; + sdhci: sdhci@7e300000 { compatible = "brcm,bcm2835-sdhci"; reg = <0x7e300000 0x100>; @@ -187,7 +218,7 @@ status = "disabled"; }; - usb@7e980000 { + usb: usb@7e980000 { compatible = "brcm,bcm2835-usb"; reg = <0x7e980000 0x10000>; interrupts = <1 9>; diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi index 57795da616cb..bcce6f50c93d 100644 --- a/arch/arm/boot/dts/emev2.dtsi +++ b/arch/arm/boot/dts/emev2.dtsi @@ -9,6 +9,7 @@ */ #include "skeleton.dtsi" +#include #include / { @@ -53,8 +54,8 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; }; clocks@e0110000 { @@ -158,7 +159,7 @@ timer@e0180000 { compatible = "renesas,em-sti"; reg = <0xe0180000 0x54>; - interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&sti_sclk>; clock-names = "sclk"; }; @@ -166,7 +167,7 @@ uart0: serial@e1020000 { compatible = "renesas,em-uart"; reg = <0xe1020000 0x38>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usia_u0_sclk>; clock-names = "sclk"; }; @@ -174,7 +175,7 @@ uart1: serial@e1030000 { compatible = "renesas,em-uart"; reg = <0xe1030000 0x38>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usib_u1_sclk>; clock-names = "sclk"; }; @@ -182,7 +183,7 @@ uart2: serial@e1040000 { compatible = "renesas,em-uart"; reg = <0xe1040000 0x38>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usib_u2_sclk>; clock-names = "sclk"; }; @@ -190,7 +191,7 @@ uart3: serial@e1050000 { compatible = "renesas,em-uart"; reg = <0xe1050000 0x38>; - interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usib_u3_sclk>; clock-names = "sclk"; }; @@ -203,8 +204,8 @@ gpio0: gpio@e0050000 { compatible = "renesas,em-gio"; reg = <0xe0050000 0x2c>, <0xe0050040 0x20>; - interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>, - <0 68 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 0 32>; #gpio-cells = <2>; @@ -215,8 +216,8 @@ gpio1: gpio@e0050080 { compatible = "renesas,em-gio"; reg = <0xe0050080 0x2c>, <0xe00500c0 0x20>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>, - <0 70 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 32 32>; #gpio-cells = <2>; @@ -227,8 +228,8 @@ gpio2: gpio@e0050100 { compatible = "renesas,em-gio"; reg = <0xe0050100 0x2c>, <0xe0050140 0x20>; - interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>, - <0 72 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 64 32>; #gpio-cells = <2>; @@ -239,8 +240,8 @@ gpio3: gpio@e0050180 { compatible = "renesas,em-gio"; reg = <0xe0050180 0x2c>, <0xe00501c0 0x20>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>, - <0 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 96 32>; #gpio-cells = <2>; @@ -251,8 +252,8 @@ gpio4: gpio@e0050200 { compatible = "renesas,em-gio"; reg = <0xe0050200 0x2c>, <0xe0050240 0x20>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>, - <0 76 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 128 31>; #gpio-cells = <2>; @@ -266,7 +267,7 @@ #size-cells = <0>; compatible = "renesas,iic-emev2"; reg = <0xe0070000 0x28>; - interrupts = <0 32 IRQ_TYPE_EDGE_RISING>; + interrupts = ; clocks = <&iic0_sclk>; clock-names = "sclk"; status = "disabled"; @@ -277,7 +278,7 @@ #size-cells = <0>; compatible = "renesas,iic-emev2"; reg = <0xe10a0000 0x28>; - interrupts = <0 33 IRQ_TYPE_EDGE_RISING>; + interrupts = ; clocks = <&iic1_sclk>; clock-names = "sclk"; status = "disabled"; diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index 443a35085846..9e2840b59ae8 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -43,7 +43,7 @@ linux,code = ; label = "power key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -67,7 +67,7 @@ interrupt-parent = <&gpx1>; interrupts = <5 0>; reg = <0x25>; - wakeup; + wakeup-source; muic: max77836-muic { compatible = "maxim,max77836-muic"; @@ -185,7 +185,7 @@ interrupt-parent = <&gpx0>; interrupts = <7 0>; reg = <0x66>; - wakeup; + wakeup-source; s2mps14_osc: clocks { compatible = "samsung,s2mps14-clk"; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 3e64d5dcdd60..1f102f3a1ab1 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -43,7 +43,7 @@ linux,code = ; label = "power key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -58,7 +58,7 @@ interrupt-parent = <&gpx1>; interrupts = <5 0>; reg = <0x25>; - wakeup; + wakeup-source; muic: max77836-muic { compatible = "maxim,max77836-muic"; @@ -246,7 +246,7 @@ interrupt-parent = <&gpx0>; interrupts = <7 0>; reg = <0x66>; - wakeup; + wakeup-source; s2mps14_osc: clocks { compatible = "samsung,s2mps14-clk"; diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index 045785c44c04..ca621a92319e 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -76,6 +76,11 @@ reg = <0x10000000 0x100>; }; + sromc@12570000 { + compatible = "samsung,exynos-srom"; + reg = <0x12570000 0x14>; + }; + mipi_phy: video-phy@10020710 { compatible = "samsung,s5pv210-mipi-video-phy"; #phy-cells = <1>; diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts index 5821ad87e32c..ad7394c1d67a 100644 --- a/arch/arm/boot/dts/exynos4210-origen.dts +++ b/arch/arm/boot/dts/exynos4210-origen.dts @@ -60,35 +60,35 @@ label = "Up"; gpios = <&gpx2 0 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; down { label = "Down"; gpios = <&gpx2 1 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; back { label = "Back"; gpios = <&gpx1 7 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; home { label = "Home"; gpios = <&gpx1 6 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; menu { label = "Menu"; gpios = <&gpx1 5 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts index 104cbb33d2bb..94ca7d36ab37 100644 --- a/arch/arm/boot/dts/exynos4210-smdkv310.dts +++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts @@ -66,7 +66,7 @@ samsung,keypad-num-rows = <2>; samsung,keypad-num-columns = <8>; linux,keypad-no-autorepeat; - linux,keypad-wakeup; + wakeup-source; pinctrl-names = "default"; pinctrl-0 = <&keypad_rows &keypad_cols>; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts index a50be640f1b0..1df2f0bc1d76 100644 --- a/arch/arm/boot/dts/exynos4210-trats.dts +++ b/arch/arm/boot/dts/exynos4210-trats.dts @@ -112,7 +112,7 @@ linux,code = <116>; label = "power"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; ok-key { diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts index 4f5d37920c8d..9a75e3effbc9 100644 --- a/arch/arm/boot/dts/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts @@ -92,7 +92,7 @@ linux,code = <171>; label = "config"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; camera-key { @@ -107,7 +107,7 @@ linux,code = <116>; label = "power"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; ok-key { diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 395c3ca9601e..5e5d3fecb04c 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -35,7 +35,7 @@ linux,code = ; label = "power key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts index b44bb682e976..bf7b21b817e4 100644 --- a/arch/arm/boot/dts/exynos4412-odroidx.dts +++ b/arch/arm/boot/dts/exynos4412-odroidx.dts @@ -48,7 +48,7 @@ linux,code = ; label = "home key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index 9e2e24c6177a..8bca699b7f20 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -423,7 +423,7 @@ samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <2>; linux,keypad-no-autorepeat; - linux,keypad-wakeup; + wakeup-source; pinctrl-0 = <&keypad_rows &keypad_cols>; pinctrl-names = "default"; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts index a130ab39fa77..a51069f3c03b 100644 --- a/arch/arm/boot/dts/exynos4412-smdk4412.dts +++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts @@ -45,7 +45,7 @@ samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <8>; linux,keypad-no-autorepeat; - linux,keypad-wakeup; + wakeup-source; pinctrl-0 = <&keypad_rows &keypad_cols>; pinctrl-names = "default"; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index a6f78c3da935..ed017cc7b14f 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -119,7 +119,7 @@ linux,code = <116>; label = "power"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; key-ok { @@ -127,7 +127,7 @@ linux,code = <139>; label = "ok"; debounce-inteval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi index e2439e87ee4a..b61d1f637510 100644 --- a/arch/arm/boot/dts/exynos5.dtsi +++ b/arch/arm/boot/dts/exynos5.dtsi @@ -30,6 +30,11 @@ reg = <0x10000000 0x100>; }; + sromc@12250000 { + compatible = "samsung,exynos-srom"; + reg = <0x12250000 0x14>; + }; + combiner: interrupt-controller@10440000 { compatible = "samsung,exynos4210-combiner"; #interrupt-cells = <2>; diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index c000532c1444..8b2acc74aa76 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -34,42 +34,42 @@ label = "SW-TACT2"; gpios = <&gpx1 4 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; home { label = "SW-TACT3"; gpios = <&gpx1 5 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; up { label = "SW-TACT4"; gpios = <&gpx1 6 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; down { label = "SW-TACT5"; gpios = <&gpx1 7 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; back { label = "SW-TACT6"; gpios = <&gpx2 0 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; wakeup { label = "SW-TACT7"; gpios = <&gpx2 1 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi index 5cb33ba5e296..95210ef6a6b5 100644 --- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi +++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi @@ -37,7 +37,7 @@ label = "Power"; gpios = <&gpx1 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -46,7 +46,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts index c1edd6d038a9..0f500cb1eb2d 100644 --- a/arch/arm/boot/dts/exynos5250-spring.dts +++ b/arch/arm/boot/dts/exynos5250-spring.dts @@ -37,7 +37,7 @@ label = "Power"; gpios = <&gpx1 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -46,7 +46,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 33e2d5f7315b..234403422c6f 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -807,7 +807,7 @@ sss@10830000 { compatible = "samsung,exynos4210-secss"; - reg = <0x10830000 0x10000>; + reg = <0x10830000 0x300>; interrupts = <0 112 0>; clocks = <&clock CLK_SSS>; clock-names = "secss"; diff --git a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi new file mode 100644 index 000000000000..f9aa6bb55464 --- /dev/null +++ b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi @@ -0,0 +1,406 @@ +/* + * Exynos5410 SoC pin-mux and pin-config device tree source + * + * Copyright (c) 2013 Hardkernel Co., Ltd. + * http://www.hardkernel.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. + */ + +&pinctrl_0 { + gpa0: gpa0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpa1: gpa1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpa2: gpa2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb0: gpb0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb1: gpb1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb2: gpb2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb3: gpb3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc0: gpc0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc3: gpc3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc1: gpc1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc2: gpc2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpm5: gpm5 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpd1: gpd1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpe0: gpe0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpe1: gpe1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpf0: gpf0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpf1: gpf1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg0: gpg0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg1: gpg1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg2: gpg2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gph0: gph0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gph1: gph1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpm7: gpm7 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy0: gpy0 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy1: gpy1 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy2: gpy2 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy3: gpy3 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy4: gpy4 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy5: gpy5 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy6: gpy6 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy7: gpy7 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpx0: gpx0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + interrupt-parent = <&combiner>; + #interrupt-cells = <2>; + interrupts = <23 0>, + <24 0>, + <25 0>, + <25 1>, + <26 0>, + <26 1>, + <27 0>, + <27 1>; + }; + + gpx1: gpx1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + interrupt-parent = <&combiner>; + #interrupt-cells = <2>; + interrupts = <28 0>, + <28 1>, + <29 0>, + <29 1>, + <30 0>, + <30 1>, + <31 0>, + <31 1>; + }; + + gpx2: gpx2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpx3: gpx3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; + +&pinctrl_1 { + gpj0: gpj0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj1: gpj1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj2: gpj2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj3: gpj3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj4: gpj4 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk0: gpk0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk1: gpk1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk2: gpk2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk3: gpk3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; + +&pinctrl_2 { + gpv0: gpv0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv1: gpv1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv2: gpv2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv3: gpv3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv4: gpv4 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; + +&pinctrl_3 { + gpz: gpz { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts index cebeaab3abec..a731fbe28ebc 100644 --- a/arch/arm/boot/dts/exynos5410-smdk5410.dts +++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "exynos5410.dtsi" +#include / { model = "Samsung SMDK5410 board based on EXYNOS5410"; compatible = "samsung,smdk5410", "samsung,exynos5410", "samsung,exynos5"; @@ -61,6 +62,46 @@ disable-wp; }; +&pinctrl_0 { + srom_ctl: srom-ctl { + samsung,pins = "gpy0-3", "gpy0-4", "gpy0-5", + "gpy1-0", "gpy1-1", "gpy1-2", "gpy1-3"; + samsung,pin-function = <2>; + samsung,pin-drv = <0>; + }; + + srom_ebi: srom-ebi { + samsung,pins = "gpy3-0", "gpy3-1", "gpy3-2", "gpy3-3", + "gpy3-4", "gpy3-5", "gpy3-6", "gpy3-7", + "gpy5-0", "gpy5-1", "gpy5-2", "gpy5-3", + "gpy5-4", "gpy5-5", "gpy5-6", "gpy5-7", + "gpy6-0", "gpy6-1", "gpy6-2", "gpy6-3", + "gpy6-4", "gpy6-5", "gpy6-6", "gpy6-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; +}; + +&sromc { + pinctrl-names = "default"; + pinctrl-0 = <&srom_ctl>, <&srom_ebi>; + + ethernet@3,0 { + compatible = "smsc,lan9115"; + reg = <3 0 0x10000>; + phy-mode = "mii"; + interrupt-parent = <&gpx0>; + interrupts = <5 IRQ_TYPE_LEVEL_LOW>; + reg-io-width = <2>; + smsc,irq-push-pull; + smsc,force-internal-phy; + + samsung,srom-page-mode = <1>; + samsung,srom-timing = <9 12 1 9 1 1>; + }; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi index fad0779b1b6e..f3490f567344 100644 --- a/arch/arm/boot/dts/exynos5410.dtsi +++ b/arch/arm/boot/dts/exynos5410.dtsi @@ -21,6 +21,10 @@ interrupt-parent = <&gic>; aliases { + pinctrl0 = &pinctrl_0; + pinctrl1 = &pinctrl_1; + pinctrl2 = &pinctrl_2; + pinctrl3 = &pinctrl_3; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -97,6 +101,17 @@ reg = <0x10000000 0x100>; }; + sromc: sromc@12250000 { + compatible = "samsung,exynos-srom"; + reg = <0x12250000 0x14>; + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0x04000000 0x20000 + 1 0 0x05000000 0x20000 + 2 0 0x06000000 0x20000 + 3 0 0x07000000 0x20000>; + }; + pmu_system_controller: system-controller@10040000 { compatible = "samsung,exynos5410-pmu", "syscon"; reg = <0x10040000 0x5000>; @@ -205,6 +220,36 @@ status = "disabled"; }; + pinctrl_0: pinctrl@13400000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x13400000 0x1000>; + interrupts = <0 45 0>; + + wakeup-interrupt-controller { + compatible = "samsung,exynos4210-wakeup-eint"; + interrupt-parent = <&gic>; + interrupts = <0 32 0>; + }; + }; + + pinctrl_1: pinctrl@14000000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x14000000 0x1000>; + interrupts = <0 46 0>; + }; + + pinctrl_2: pinctrl@10d10000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x10d10000 0x1000>; + interrupts = <0 50 0>; + }; + + pinctrl_3: pinctrl@03860000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x03860000 0x1000>; + interrupts = <0 47 0>; + }; + uart0: serial@12C00000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C00000 0x100>; @@ -233,3 +278,5 @@ }; }; }; + +#include "exynos5410-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts index 4ecef6981d5c..a103ce8c3985 100644 --- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "exynos5420.dtsi" +#include "exynos5420-cpus.dtsi" #include #include #include @@ -47,11 +48,19 @@ label = "SW-TACT1"; gpios = <&gpx2 7 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &usbdrd_dwc3_1 { dr_mode = "host"; }; diff --git a/arch/arm/boot/dts/exynos5420-cpus.dtsi b/arch/arm/boot/dts/exynos5420-cpus.dtsi new file mode 100644 index 000000000000..261d25173f61 --- /dev/null +++ b/arch/arm/boot/dts/exynos5420-cpus.dtsi @@ -0,0 +1,102 @@ +/* + * SAMSUNG EXYNOS5420 SoC cpu device tree source + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This file provides desired ordering for Exynos5420 and Exynos5800 + * boards: CPU[0123] being the A15. + * + * The Exynos5420, 5422 and 5800 actually share the same CPU configuration + * but particular boards choose different booting order. + * + * Exynos5420 and Exynos5800 always boot from Cortex-A15. On Exynos5422 + * booting cluster (big or LITTLE) is chosen by IROM code by reading + * the gpg2-1 GPIO. By default all Exynos5422 based boards choose booting + * from the LITTLE: Cortex-A7. + * + * 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. + */ + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x0>; + clocks = <&clock CLK_ARM_CLK>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x1>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x2>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x3>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + }; + + cpu4: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x100>; + clocks = <&clock CLK_KFC_CLK>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + }; + + cpu5: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x101>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + }; + + cpu6: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x102>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + }; + + cpu7: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x103>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 35cfb07dc4bb..3981ddb25036 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -15,6 +15,7 @@ #include #include #include "exynos5420.dtsi" +#include "exynos5420-cpus.dtsi" / { model = "Google Peach Pit Rev 6+"; @@ -64,7 +65,7 @@ label = "Power"; gpios = <&gpx1 2 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -73,7 +74,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -143,6 +144,14 @@ vdd-supply = <&ldo9_reg>; }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &dp { status = "okay"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index ac35aefd320f..0785fedf441e 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "exynos5420.dtsi" +#include "exynos5420-cpus.dtsi" #include / { @@ -89,6 +90,14 @@ }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &dp { pinctrl-names = "default"; pinctrl-0 = <&dp_hpd>; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 48a0a55314f5..bb559d0cd956 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -50,75 +50,121 @@ usbdrdphy1 = &usbdrd_phy1; }; - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x0>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + cluster_a15_opp_table: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + opp@1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1250000>; + clock-latency-ns = <140000>; }; - - cpu1: cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x1>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + opp@1700000000 { + opp-hz = /bits/ 64 <1700000000>; + opp-microvolt = <1212500>; + clock-latency-ns = <140000>; }; - - cpu2: cpu@2 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x2>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + opp@1600000000 { + opp-hz = /bits/ 64 <1600000000>; + opp-microvolt = <1175000>; + clock-latency-ns = <140000>; }; - - cpu3: cpu@3 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x3>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + opp@1500000000 { + opp-hz = /bits/ 64 <1500000000>; + opp-microvolt = <1137500>; + clock-latency-ns = <140000>; }; - - cpu4: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x100>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; + opp@1400000000 { + opp-hz = /bits/ 64 <1400000000>; + opp-microvolt = <1112500>; + clock-latency-ns = <140000>; }; - - cpu5: cpu@101 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x101>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; + opp@1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1062500>; + clock-latency-ns = <140000>; }; - - cpu6: cpu@102 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x102>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; + opp@1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1037500>; + clock-latency-ns = <140000>; + }; + opp@1100000000 { + opp-hz = /bits/ 64 <1100000000>; + opp-microvolt = <1012500>; + clock-latency-ns = <140000>; + }; + opp@1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = < 987500>; + clock-latency-ns = <140000>; + }; + opp@900000000 { + opp-hz = /bits/ 64 <900000000>; + opp-microvolt = < 962500>; + clock-latency-ns = <140000>; }; + opp@800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = < 937500>; + clock-latency-ns = <140000>; + }; + opp@700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-microvolt = < 912500>; + clock-latency-ns = <140000>; + }; + }; - cpu7: cpu@103 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x103>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; + cluster_a7_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + opp@1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1275000>; + clock-latency-ns = <140000>; + }; + opp@1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1212500>; + clock-latency-ns = <140000>; + }; + opp@1100000000 { + opp-hz = /bits/ 64 <1100000000>; + opp-microvolt = <1162500>; + clock-latency-ns = <140000>; + }; + opp@1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <1112500>; + clock-latency-ns = <140000>; + }; + opp@900000000 { + opp-hz = /bits/ 64 <900000000>; + opp-microvolt = <1062500>; + clock-latency-ns = <140000>; + }; + opp@800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1025000>; + clock-latency-ns = <140000>; + }; + opp@700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-microvolt = <975000>; + clock-latency-ns = <140000>; + }; + opp@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <937500>; + clock-latency-ns = <140000>; }; }; + /* + * The 'cpus' node is not present here but instead it is provided + * by exynos5420-cpus.dtsi or exynos5422-cpus.dtsi. + */ + cci: cci@10d20000 { compatible = "arm,cci-400"; #address-cells = <1>; @@ -252,8 +298,10 @@ compatible = "samsung,exynos4210-pd"; reg = <0x10044000 0x20>; #power-domain-cells = <0>; - clocks = <&clock CLK_GSCL0>, <&clock CLK_GSCL1>; - clock-names = "asb0", "asb1"; + clocks = <&clock CLK_FIN_PLL>, + <&clock CLK_MOUT_USER_ACLK300_GSCL>, + <&clock CLK_GSCL0>, <&clock CLK_GSCL1>; + clock-names = "oscclk", "clk0", "asb0", "asb1"; }; isp_pd: power-domain@10044020 { @@ -859,7 +907,7 @@ sss: sss@10830000 { compatible = "samsung,exynos4210-secss"; - reg = <0x10830000 0x10000>; + reg = <0x10830000 0x300>; interrupts = <0 112 0>; clocks = <&clock CLK_SSS>; clock-names = "secss"; diff --git a/arch/arm/boot/dts/exynos5422-cpus.dtsi b/arch/arm/boot/dts/exynos5422-cpus.dtsi index b7f60c855459..9b46b9fbac4e 100644 --- a/arch/arm/boot/dts/exynos5422-cpus.dtsi +++ b/arch/arm/boot/dts/exynos5422-cpus.dtsi @@ -4,78 +4,98 @@ * Copyright (c) 2015 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * The only difference between EXYNOS5422 and EXYNOS5800 is cpu ordering. The - * EXYNOS5422 is booting from Cortex-A7 core while the EXYNOS5800 is booting - * from Cortex-A15 core. + * This file provides desired ordering for Exynos5422: CPU[0123] being the A7. * - * EXYNOS5422 based board files can include this file to provide cpu ordering - * which could boot a cortex-a7 from cpu0. + * The Exynos5420, 5422 and 5800 actually share the same CPU configuration + * but particular boards choose different booting order. + * + * Exynos5420 and Exynos5800 always boot from Cortex-A15. On Exynos5422 + * booting cluster (big or LITTLE) is chosen by IROM code by reading + * the gpg2-1 GPIO. By default all Exynos5422 based boards choose booting + * from the LITTLE: Cortex-A7. * * 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. */ -&cpu0 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x100>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; -&cpu1 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x101>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; + cpu0: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x100>; + clocks = <&clock CLK_KFC_CLK>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + }; -&cpu2 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x102>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; + cpu1: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x101>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + }; -&cpu3 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x103>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; + cpu2: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x102>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + }; -&cpu4 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x0>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; -}; + cpu3: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x103>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + }; -&cpu5 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x1>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; -}; + cpu4: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + clocks = <&clock CLK_ARM_CLK>; + reg = <0x0>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + }; -&cpu6 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x2>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; -}; + cpu5: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x1>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + }; + + cpu6: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x2>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + }; -&cpu7 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x3>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + cpu7: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x3>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + }; + }; }; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi index 9134217446b8..1bd507bfa750 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi @@ -67,6 +67,14 @@ <19200000>; }; +&cpu0 { + cpu-supply = <&buck6_reg>; +}; + +&cpu4 { + cpu-supply = <&buck2_reg>; +}; + &hdmi { status = "okay"; hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index 064176f201e7..6e9edc1610c4 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -15,6 +15,7 @@ #include #include #include "exynos5800.dtsi" +#include "exynos5420-cpus.dtsi" / { model = "Google Peach Pi Rev 10+"; @@ -63,7 +64,7 @@ label = "Power"; gpios = <&gpx1 2 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -72,7 +73,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -143,6 +144,14 @@ vdd-supply = <&ldo9_reg>; }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &dp { status = "okay"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi index c0bb3563cac1..8213016803e5 100644 --- a/arch/arm/boot/dts/exynos5800.dtsi +++ b/arch/arm/boot/dts/exynos5800.dtsi @@ -23,6 +23,114 @@ compatible = "samsung,exynos5800-clock"; }; +&cluster_a15_opp_table { + opp@1700000000 { + opp-microvolt = <1250000>; + }; + opp@1600000000 { + opp-microvolt = <1250000>; + }; + opp@1500000000 { + opp-microvolt = <1100000>; + }; + opp@1400000000 { + opp-microvolt = <1100000>; + }; + opp@1300000000 { + opp-microvolt = <1100000>; + }; + opp@1200000000 { + opp-microvolt = <1000000>; + }; + opp@1100000000 { + opp-microvolt = <1000000>; + }; + opp@1000000000 { + opp-microvolt = <1000000>; + }; + opp@900000000 { + opp-microvolt = <1000000>; + }; + opp@800000000 { + opp-microvolt = <900000>; + }; + opp@700000000 { + opp-microvolt = <900000>; + }; + opp@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; +}; + +&cluster_a7_opp_table { + opp@1300000000 { + opp-microvolt = <1250000>; + }; + opp@1200000000 { + opp-microvolt = <1250000>; + }; + opp@1100000000 { + opp-microvolt = <1250000>; + }; + opp@1000000000 { + opp-microvolt = <1100000>; + }; + opp@900000000 { + opp-microvolt = <1100000>; + }; + opp@800000000 { + opp-microvolt = <1100000>; + }; + opp@700000000 { + opp-microvolt = <1000000>; + }; + opp@600000000 { + opp-microvolt = <1000000>; + }; + opp@500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <140000>; + }; + opp@400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <140000>; + }; + opp@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; +}; + &mfc { compatible = "samsung,mfc-v8"; }; diff --git a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts index ed1d0b4578ef..cda6907a27b9 100644 --- a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts +++ b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts @@ -30,7 +30,7 @@ label = "BP1"; gpios = <&gpio3 18 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx28-apf28dev.dts b/arch/arm/boot/dts/imx28-apf28dev.dts index 7ac4f1af16ac..1eaa131e2d18 100644 --- a/arch/arm/boot/dts/imx28-apf28dev.dts +++ b/arch/arm/boot/dts/imx28-apf28dev.dts @@ -225,7 +225,7 @@ label = "User button"; gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; linux,code = <0x100>; - gpio-key,wakeup; + wakeup-source; }; }; }; diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi b/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi index 927b391d2058..88594747f454 100644 --- a/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi +++ b/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi @@ -36,7 +36,7 @@ label = "SW3"; gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; @@ -49,7 +49,7 @@ label = "SW4"; gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx28-tx28.dts b/arch/arm/boot/dts/imx28-tx28.dts index 4ea89344a5ff..fd20e99c777e 100644 --- a/arch/arm/boot/dts/imx28-tx28.dts +++ b/arch/arm/boot/dts/imx28-tx28.dts @@ -130,7 +130,7 @@ compatible = "fixed-clock"; reg = <0>; #clock-cells = <0>; - clock-frequency = <27000000>; + clock-frequency = <26000000>; }; }; @@ -202,7 +202,7 @@ 0x02020049 /* row 2, col 2, KEY_KP9 */ >; gpio-activelow; - linux,wakeup; + wakeup-source; debounce-delay-ms = <100>; col-scan-delay-us = <5000>; linux,no-autorepeat; diff --git a/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts b/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts index 75b036700d31..4727bbb804e1 100644 --- a/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts +++ b/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts @@ -30,7 +30,7 @@ label = "BP1"; gpios = <&gpio3 25 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; linux,input-type = <1>; }; }; diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index 649befeb2cf9..018d24eb9965 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -107,7 +107,7 @@ label = "Power Button"; gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi b/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi index 321662f53e33..16fc69c69ab2 100644 --- a/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi +++ b/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi @@ -156,7 +156,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_esdhc2>; cap-sdio-irq; - enable-sdio-wakeup; + wakeup-source; keep-power-in-suspend; max-frequency = <50000000>; no-1-8-v; diff --git a/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts b/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts index 34599c547459..d270df3e5891 100644 --- a/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts +++ b/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts @@ -41,7 +41,7 @@ label = "BP1"; gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; linux,code = <256>; - gpio-key,wakeup; + wakeup-source; linux,input-type = <1>; }; }; diff --git a/arch/arm/boot/dts/imx53-ard.dts b/arch/arm/boot/dts/imx53-ard.dts index 3bc18835fb4b..4486bc47d140 100644 --- a/arch/arm/boot/dts/imx53-ard.dts +++ b/arch/arm/boot/dts/imx53-ard.dts @@ -69,21 +69,21 @@ label = "Home"; gpios = <&gpio5 10 0>; linux,code = <102>; /* KEY_HOME */ - gpio-key,wakeup; + wakeup-source; }; back { label = "Back"; gpios = <&gpio5 11 0>; linux,code = <158>; /* KEY_BACK */ - gpio-key,wakeup; + wakeup-source; }; program { label = "Program"; gpios = <&gpio5 12 0>; linux,code = <362>; /* KEY_PROGRAM */ - gpio-key,wakeup; + wakeup-source; }; volume-up { diff --git a/arch/arm/boot/dts/imx53-qsb-common.dtsi b/arch/arm/boot/dts/imx53-qsb-common.dtsi index 53fd75c8ffcf..368ccd0a053e 100644 --- a/arch/arm/boot/dts/imx53-qsb-common.dtsi +++ b/arch/arm/boot/dts/imx53-qsb-common.dtsi @@ -67,14 +67,14 @@ label = "Volume Up"; gpios = <&gpio2 14 0>; linux,code = <115>; /* KEY_VOLUMEUP */ - gpio-key,wakeup; + wakeup-source; }; volume-down { label = "Volume Down"; gpios = <&gpio2 15 0>; linux,code = <114>; /* KEY_VOLUMEDOWN */ - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx53-tx53-x03x.dts b/arch/arm/boot/dts/imx53-tx53-x03x.dts index 13e842b0c785..0ecb43d88522 100644 --- a/arch/arm/boot/dts/imx53-tx53-x03x.dts +++ b/arch/arm/boot/dts/imx53-tx53-x03x.dts @@ -231,7 +231,7 @@ interrupts = <26 0>; gpios = <&gpio3 26 GPIO_ACTIVE_LOW>; ti,x-plate-ohms = <660>; - linux,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx53-tx53-x13x.dts b/arch/arm/boot/dts/imx53-tx53-x13x.dts index 64804719f0f4..3cf682a681f4 100644 --- a/arch/arm/boot/dts/imx53-tx53-x13x.dts +++ b/arch/arm/boot/dts/imx53-tx53-x13x.dts @@ -101,7 +101,7 @@ interrupt-parent = <&gpio3>; interrupts = <23 0>; wakeup-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; - linux,wakeup; + wakeup-source; }; }; @@ -126,7 +126,7 @@ interrupt-parent = <&gpio3>; interrupts = <22 0>; wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; - linux,wakeup; + wakeup-source; }; }; @@ -183,13 +183,14 @@ status = "okay"; lvds0: lvds-channel@0 { - fsl,data-mapping = "jeida"; - fsl,data-width = <24>; + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; status = "okay"; display-timings { - native-mode = <&lvds_timing0>; - lvds_timing0: hsd100pxn1 { + native-mode = <&lvds0_timing0>; + + lvds0_timing0: hsd100pxn1 { clock-frequency = <65000000>; hactive = <1024>; vactive = <768>; @@ -202,19 +203,36 @@ hsync-active = <0>; vsync-active = <0>; de-active = <1>; - pixelclk-active = <0>; + pixelclk-active = <1>; + }; + + lvds0_timing1: nl12880bc20 { + clock-frequency = <71000000>; + hactive = <1280>; + vactive = <800>; + hback-porch = <50>; + hsync-len = <60>; + hfront-porch = <50>; + vback-porch = <5>; + vsync-len = <13>; + vfront-porch = <5>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; }; }; }; lvds1: lvds-channel@1 { - fsl,data-mapping = "jeida"; - fsl,data-width = <24>; + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; status = "okay"; display-timings { - native-mode = <&lvds_timing1>; - lvds_timing1: hsd100pxn1 { + native-mode = <&lvds1_timing0>; + + lvds1_timing0: hsd100pxn1 { clock-frequency = <65000000>; hactive = <1024>; vactive = <768>; @@ -227,7 +245,7 @@ hsync-active = <0>; vsync-active = <0>; de-active = <1>; - pixelclk-active = <0>; + pixelclk-active = <1>; }; }; }; diff --git a/arch/arm/boot/dts/imx53-tx53.dtsi b/arch/arm/boot/dts/imx53-tx53.dtsi index d3e50b22064f..bd3dfefa5778 100644 --- a/arch/arm/boot/dts/imx53-tx53.dtsi +++ b/arch/arm/boot/dts/imx53-tx53.dtsi @@ -37,7 +37,7 @@ compatible = "fixed-clock"; reg = <0>; #clock-cells = <0>; - clock-frequency = <27000000>; + clock-frequency = <26000000>; }; }; @@ -50,7 +50,7 @@ label = "Power Button"; gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; linux,code = <116>; /* KEY_POWER */ - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx6dl-tx6u-811x.dts b/arch/arm/boot/dts/imx6dl-tx6u-811x.dts index c275eecc9472..d35a5cdc3229 100644 --- a/arch/arm/boot/dts/imx6dl-tx6u-811x.dts +++ b/arch/arm/boot/dts/imx6dl-tx6u-811x.dts @@ -77,7 +77,7 @@ interrupt-parent = <&gpio3>; interrupts = <22 0>; wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; - linux,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx6q-gk802.dts b/arch/arm/boot/dts/imx6q-gk802.dts index 00bd63e63d0c..b715deb4ea46 100644 --- a/arch/arm/boot/dts/imx6q-gk802.dts +++ b/arch/arm/boot/dts/imx6q-gk802.dts @@ -44,7 +44,7 @@ label = "recovery"; gpios = <&gpio3 16 1>; linux,code = <0x198>; /* KEY_RESTART */ - gpio-key,wakeup; + wakeup-source; }; }; }; diff --git a/arch/arm/boot/dts/imx6q-icore-rqs.dts b/arch/arm/boot/dts/imx6q-icore-rqs.dts new file mode 100644 index 000000000000..005318865f66 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-icore-rqs.dts @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 Amarula Solutions B.V. + * + * 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 , 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 "imx6q.dtsi" +#include "imx6qdl-icore-rqs.dtsi" + +/ { + model = "Engicam i.CoreM6 Quad SOM"; + compatible = "engicam,imx6-icore-rqs", "fsl,imx6q"; + + sound { + compatible = "fsl,imx-audio-sgtl5000"; + model = "imx-audio-sgtl5000"; + ssi-controller = <&ssi1>; + audio-codec = <&codec>; + audio-routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + mux-int-port = <1>; + mux-ext-port = <4>; + }; +}; + +&i2c3 { + codec: sgtl5000@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks IMX6QDL_CLK_CKO>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; + VDDD-supply = <®_1p8v>; + }; +}; + +&sata { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx6q-tx6q-1110.dts b/arch/arm/boot/dts/imx6q-tx6q-1110.dts index 88aa1e4c792d..2792da93db1f 100644 --- a/arch/arm/boot/dts/imx6q-tx6q-1110.dts +++ b/arch/arm/boot/dts/imx6q-tx6q-1110.dts @@ -77,7 +77,7 @@ interrupt-parent = <&gpio3>; interrupts = <22 0>; wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; - linux,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi b/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi index e26ebeb5b45c..a8f3500ee522 100644 --- a/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi +++ b/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi @@ -94,7 +94,7 @@ label = "User button"; gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi index 5cd16f2178b8..9d7ab6cdc9a6 100644 --- a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi @@ -320,13 +320,13 @@ pinctrl_pwm3: pwm3grp { fsl,pins = < - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 >; }; pinctrl_pwm4: pwm4grp { fsl,pins = < - MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x1b0b1 + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi index 9fa8a10c7cc8..8dd74e98ffd6 100644 --- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi @@ -473,7 +473,7 @@ pinctrl_pwm3: pwm3grp { fsl,pins = < - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi index e8375e173873..ec3fe7444e15 100644 --- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi @@ -462,7 +462,7 @@ pinctrl_pwm3: pwm3grp { fsl,pins = < - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi index 66983dc5cbda..367cc49eea0d 100644 --- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi @@ -397,8 +397,9 @@ }; &pwm4 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm4>; + pinctrl-names = "default", "state_dio"; + pinctrl-0 = <&pinctrl_pwm4_backlight>; + pinctrl-1 = <&pinctrl_pwm4_dio>; status = "okay"; }; @@ -573,12 +574,20 @@ >; }; - pinctrl_pwm4: pwm4grp { + pinctrl_pwm4_backlight: pwm4grpbacklight { fsl,pins = < + /* LVDS_PWM J6.5 */ MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1 >; }; + pinctrl_pwm4_dio: pwm4grpdio { + fsl,pins = < + /* DIO3 J16.4 */ + MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x1b0b1 + >; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1 diff --git a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi index cca39f194017..f27f184558fb 100644 --- a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi @@ -262,7 +262,7 @@ pinctrl_pwm3: pwm3grp { fsl,pins = < - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi index 6dd0b764e036..d6c2358ffad4 100644 --- a/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi +++ b/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi @@ -48,7 +48,7 @@ ir_recv: ir-receiver { compatible = "gpio-ir-receiver"; - gpios = <&gpio3 5 1>; + gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard_gpio3_5>; }; @@ -67,7 +67,7 @@ reg_usbh1_vbus: usb-h1-vbus { compatible = "regulator-fixed"; enable-active-high; - gpio = <&gpio1 0 0>; + gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard_usbh1_vbus>; regulator-name = "usb_h1_vbus"; @@ -78,7 +78,7 @@ reg_usbotg_vbus: usb-otg-vbus { compatible = "regulator-fixed"; enable-active-high; - gpio = <&gpio3 22 0>; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard_usbotg_vbus>; regulator-name = "usb_otg_vbus"; @@ -253,7 +253,7 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard_pcie_reset>; - reset-gpio = <&gpio3 4 0>; + reset-gpio = <&gpio3 4 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi new file mode 100644 index 000000000000..f8d945a56525 --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2015 Amarula Solutions B.V. + * + * 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 , 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 + +/ { + memory { + reg = <0x10000000 0x80000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "1P8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_2p5v: regulator-2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_sd3_vmmc: regulator-sd3-vmmc { + compatible = "regulator-fixed"; + regulator-name = "P3V3_SD3_SWITCHED"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 4 GPIO_ACTIVE_LOW>; + enable-active-high; + }; + + reg_sd4_vmmc: regulator-sd4-vmmc { + compatible = "regulator-fixed"; + regulator-name = "P3V3_SD4_SWITCHED"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_usb_h1_vbus: regulator-usb-h1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_usb_otg_vbus: regulator-usb-otg-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; + + usb_hub: usb-hub { + compatible = "smsc,usb3503a"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbhub>; + reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + clocks = <&clks IMX6QDL_CLK_LVDS2_GATE>; + clock-names = "refclk"; + }; +}; + +&clks { + assigned-clocks = <&clks IMX6QDL_CLK_LVDS2_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_OSC>; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-handle = <ð_phy>; + phy-mode = "rgmii"; + status = "okay"; + + mdio { + eth_phy: ethernet-phy { + rxc-skew-ps = <1140>; + txc-skew-ps = <1140>; + txen-skew-ps = <600>; + rxdv-skew-ps = <240>; + rxd0-skew-ps = <420>; + rxd1-skew-ps = <600>; + rxd2-skew-ps = <420>; + rxd3-skew-ps = <240>; + txd0-skew-ps = <60>; + txd1-skew-ps = <60>; + txd2-skew-ps = <60>; + txd3-skew-ps = <240>; + }; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpio = <&gpio3 29 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&ssi1 { + fsl,mode = "i2s-slave"; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_h1_vbus>; + disable-over-current; + clocks = <&clks IMX6QDL_CLK_USBOH3>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + no-1-8-v; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + vmcc-supply = <®_sd3_vmmc>; + cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + bus-witdh=<4>; + no-1-8-v; + status = "okay"; +}; + +&usdhc4 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc4>; + pinctrl-1 = <&pinctrl_usdhc4_100mhz>; + pinctrl-2 = <&pinctrl_usdhc4_200mhz>; + vmcc-supply = <®_sd4_vmmc>; + bus-witdh=<8>; + no-1-8-v; + non-removable; + status = "okay"; +}; + +&iomuxc { + pinctrl_audmux: audmux { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT20__AUD4_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x110b0 + MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x130b0 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 + >; + }; + + pinctrl_pcie: pciegrp { + fsl,pins = < + MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1f059 /* PCIe Reset */ + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbhub: usbhubgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x1f059 /* HUB USB Reset */ + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10071 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17071 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17070 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10070 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17070 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17070 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17070 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17070 + MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x1f059 /* CD */ + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f059 /* PWR */ + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp_100mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170B1 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100B1 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170B1 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170B1 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170B1 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170B1 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp_200mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170F9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100F9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170F9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170F9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170F9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170F9 + >; + }; + + pinctrl_usdhc4: usdhc4grp { + fsl,pins = < + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17070 + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10070 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17070 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17070 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17070 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17070 + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17070 + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17070 + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17070 + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17070 + >; + }; + + pinctrl_usdhc4_100mhz: usdhc4grp_100mhz { + fsl,pins = < + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x170B1 + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x100B1 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x170B1 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x170B1 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x170B1 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x170B1 + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x170B1 + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x170B1 + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x170B1 + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x170B1 + >; + }; + + pinctrl_usdhc4_200mhz: usdhc4grp_200mhz { + fsl,pins = < + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x170F9 + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x100F9 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x170F9 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x170F9 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x170F9 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x170F9 + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x170F9 + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x170F9 + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x170F9 + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x170F9 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-microsom.dtsi b/arch/arm/boot/dts/imx6qdl-microsom.dtsi index 6d4069cc9419..86460e46d055 100644 --- a/arch/arm/boot/dts/imx6qdl-microsom.dtsi +++ b/arch/arm/boot/dts/imx6qdl-microsom.dtsi @@ -154,6 +154,7 @@ bus-width = <4>; mmc-pwrseq = <&usdhc1_pwrseq>; keep-power-in-suspend; + no-1-8-v; non-removable; vmmc-supply = <®_brcm>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi index a35d54fd9cd3..dc74aa395ff5 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi @@ -138,7 +138,7 @@ label = "Power Button"; gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; menu { diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi index caeed56b74a3..c6c590d1e940 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi @@ -119,7 +119,7 @@ label = "Power Button"; gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; menu { diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi index 1a69a3420ac8..0f1aca450fe6 100644 --- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi @@ -105,7 +105,7 @@ label = "Power Button"; gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; menu { diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi index a6d445c17779..26b7a20a0abb 100644 --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -79,21 +79,21 @@ power { label = "Power Button"; gpios = <&gpio3 29 GPIO_ACTIVE_LOW>; - gpio-key,wakeup; + wakeup-source; linux,code = ; }; volume-up { label = "Volume Up"; gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; - gpio-key,wakeup; + wakeup-source; linux,code = ; }; volume-down { label = "Volume Down"; gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; - gpio-key,wakeup; + wakeup-source; linux,code = ; }; }; diff --git a/arch/arm/boot/dts/imx6qdl-tx6.dtsi b/arch/arm/boot/dts/imx6qdl-tx6.dtsi index 13cb7ccfea44..efd06b576f1d 100644 --- a/arch/arm/boot/dts/imx6qdl-tx6.dtsi +++ b/arch/arm/boot/dts/imx6qdl-tx6.dtsi @@ -41,7 +41,7 @@ compatible = "fixed-clock"; reg = <0>; #clock-cells = <0>; - clock-frequency = <27000000>; + clock-frequency = <26000000>; }; }; @@ -52,7 +52,7 @@ label = "Power Button"; gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; @@ -227,6 +227,11 @@ &fec { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; + clocks = <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET_REF>, + <&clks IMX6QDL_CLK_ENET_REF>; + clock-names = "ipg", "ahb", "ptp", "enet_out"; phy-mode = "rmii"; phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_HIGH>; phy-supply = <®_3v3_etn>; @@ -276,7 +281,7 @@ interrupts = <15 IRQ_TYPE_EDGE_FALLING>; reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; wake-gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>; - linux,wakeup; + wakeup-source; }; touchscreen: tsc2007@48 { @@ -288,7 +293,7 @@ interrupts = <26 0>; gpios = <&gpio3 26 GPIO_ACTIVE_LOW>; ti,x-plate-ohms = <660>; - linux,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi index 1211da894ee9..d3e54e40a017 100644 --- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi +++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi @@ -34,6 +34,18 @@ gpio = <&gpio7 12 0>; }; }; + + sound { + compatible = "fsl,imx6q-udoo-ac97", + "fsl,imx-audio-ac97"; + model = "fsl,imx6q-udoo-ac97"; + audio-cpu = <&ssi1>; + audio-routing = + "RX", "Mic Jack", + "Headphone Jack", "TX"; + mux-int-port = <1>; + mux-ext-port = <6>; + }; }; &fec { @@ -109,6 +121,36 @@ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 >; }; + + pinctrl_ac97_running: ac97running { + fsl,pins = < + MX6QDL_PAD_DI0_PIN2__AUD6_TXD 0x1b0b0 + MX6QDL_PAD_DI0_PIN3__AUD6_TXFS 0x1b0b0 + MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x1b0b0 + MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x1b0b0 + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0 + >; + }; + + pinctrl_ac97_warm_reset: ac97warmreset { + fsl,pins = < + MX6QDL_PAD_DI0_PIN2__AUD6_TXD 0x1b0b0 + MX6QDL_PAD_DI0_PIN3__GPIO4_IO19 0x1b0b0 + MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x1b0b0 + MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x1b0b0 + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0 + >; + }; + + pinctrl_ac97_reset: ac97reset { + fsl,pins = < + MX6QDL_PAD_DI0_PIN2__GPIO4_IO18 0x1b0b0 + MX6QDL_PAD_DI0_PIN3__GPIO4_IO19 0x1b0b0 + MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x1b0b0 + MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x1b0b0 + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0 + >; + }; }; }; @@ -132,3 +174,18 @@ non-removable; status = "okay"; }; + +&audmux { + status = "okay"; +}; + +&ssi1 { + cell-index = <0>; + fsl,mode = "ac97-slave"; + pinctrl-names = "ac97-running", "ac97-reset", "ac97-warm-reset"; + pinctrl-0 = <&pinctrl_ac97_running>; + pinctrl-1 = <&pinctrl_ac97_reset>; + pinctrl-2 = <&pinctrl_ac97_warm_reset>; + ac97-gpios = <&gpio4 19 0 &gpio4 18 0 &gpio2 30 0>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 4f6ae921656f..f74d3db4846d 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -896,7 +896,6 @@ #size-cells = <1>; reg = <0x2100000 0x10000>; ranges = <0 0x2100000 0x10000>; - interrupt-parent = <&intc>; clocks = <&clks IMX6QDL_CLK_CAAM_MEM>, <&clks IMX6QDL_CLK_CAAM_ACLK>, <&clks IMX6QDL_CLK_CAAM_IPG>, diff --git a/arch/arm/boot/dts/imx6sl-warp.dts b/arch/arm/boot/dts/imx6sl-warp.dts index 10c69963100f..058bcdceb81a 100644 --- a/arch/arm/boot/dts/imx6sl-warp.dts +++ b/arch/arm/boot/dts/imx6sl-warp.dts @@ -118,7 +118,7 @@ bus-width = <4>; non-removable; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; mmc-pwrseq = <&usdhc3_pwrseq>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts index 115f3fd78971..96ea936eeeb0 100644 --- a/arch/arm/boot/dts/imx6sx-sabreauto.dts +++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts @@ -52,7 +52,7 @@ cd-gpios = <&gpio7 10 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; vmmc-supply = <&vcc_sd3>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6sx-sdb.dtsi b/arch/arm/boot/dts/imx6sx-sdb.dtsi index 94ac4005d9cd..f1d37306e8bf 100644 --- a/arch/arm/boot/dts/imx6sx-sdb.dtsi +++ b/arch/arm/boot/dts/imx6sx-sdb.dtsi @@ -184,6 +184,13 @@ status = "okay"; }; +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; +}; + &i2c4 { clock-frequency = <100000>; pinctrl-names = "default"; @@ -283,7 +290,7 @@ non-removable; no-1-8-v; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; status = "okay"; }; @@ -296,7 +303,7 @@ cd-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; vmmc-supply = <&vcc_sd3>; status = "okay"; }; @@ -378,6 +385,13 @@ >; }; + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6SX_PAD_KEY_ROW4__I2C3_SDA 0x4001b8b1 + MX6SX_PAD_KEY_COL4__I2C3_SCL 0x4001b8b1 + >; + }; + pinctrl_i2c4: i2c4grp { fsl,pins = < MX6SX_PAD_CSI_DATA07__I2C4_SDA 0x4001b8b1 diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts index 6aaa5ec3d846..e06fe978ae3b 100644 --- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts +++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts @@ -131,7 +131,7 @@ pinctrl-2 = <&pinctrl_usdhc1_200mhz>; cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; vmmc-supply = <®_sd1_vmmc>; status = "okay"; }; @@ -141,7 +141,7 @@ pinctrl-0 = <&pinctrl_usdhc2>; no-1-8-v; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx7d-sbc-imx7.dts b/arch/arm/boot/dts/imx7d-sbc-imx7.dts index d63c597c0783..f8a868552707 100644 --- a/arch/arm/boot/dts/imx7d-sbc-imx7.dts +++ b/arch/arm/boot/dts/imx7d-sbc-imx7.dts @@ -22,7 +22,7 @@ pinctrl-0 = <&pinctrl_usdhc1>; cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; - enable-sdio-wakeup; + wakeup-source; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index b2c453662905..b267f79e3059 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts @@ -296,7 +296,7 @@ pinctrl-0 = <&pinctrl_usdhc1>; cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; - enable-sdio-wakeup; + wakeup-source; keep-power-in-suspend; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi index 25ad30978740..b5a50e0e7ff1 100644 --- a/arch/arm/boot/dts/imx7d.dtsi +++ b/arch/arm/boot/dts/imx7d.dtsi @@ -119,6 +119,15 @@ clock-output-names = "osc"; }; + timer { + compatible = "arm,armv7-timer"; + interrupts = , + , + , + ; + interrupt-parent = <&intc>; + }; + etr@30086000 { compatible = "arm,coresight-tmc", "arm,primecell"; reg = <0x30086000 0x1000>; diff --git a/arch/arm/boot/dts/k2g-evm.dts b/arch/arm/boot/dts/k2g-evm.dts new file mode 100644 index 000000000000..99663b3c2f63 --- /dev/null +++ b/arch/arm/boot/dts/k2g-evm.dts @@ -0,0 +1,32 @@ +/* + * Device Tree Source for K2G EVM + * + * Copyright (C) 2016 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. + * + * 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. + */ +/dts-v1/; + +#include "k2g.dtsi" + +/ { + compatible = "ti,k2g-evm", "ti,k2g", "ti,keystone"; + model = "Texas Instruments K2G General Purpose EVM"; + + memory { + device_type = "memory"; + reg = <0x00000008 0x00000000 0x00000000 0x80000000>; + }; + +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/k2g.dtsi b/arch/arm/boot/dts/k2g.dtsi new file mode 100644 index 000000000000..7ff2796ae925 --- /dev/null +++ b/arch/arm/boot/dts/k2g.dtsi @@ -0,0 +1,89 @@ +/* + * Device Tree Source for K2G SOC + * + * Copyright (C) 2016 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. + * + * 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. + */ + +#include +#include "skeleton.dtsi" + +/ { + compatible = "ti,k2g","ti,keystone"; + model = "Texas Instruments K2G SoC"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + aliases { + serial0 = &uart0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a15"; + device_type = "cpu"; + reg = <0>; + }; + }; + + gic: interrupt-controller@02561000 { + compatible = "arm,cortex-a15-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x0 0x02561000 0x0 0x1000>, + <0x0 0x02562000 0x0 0x2000>, + <0x0 0x02564000 0x0 0x1000>, + <0x0 0x02566000 0x0 0x2000>; + interrupts = ; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = + , + , + , + ; + }; + + pmu { + compatible = "arm,cortex-a15-pmu"; + interrupts = ; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ti,keystone","simple-bus"; + ranges = <0x0 0x0 0x0 0xc0000000>; + dma-ranges = <0x80000000 0x8 0x00000000 0x80000000>; + + uart0: serial@02530c00 { + compatible = "ns16550a"; + current-speed = <115200>; + reg-shift = <2>; + reg-io-width = <4>; + reg = <0x02530c00 0x100>; + interrupts = ; + clock-frequency = <200000000>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-ds112.dts b/arch/arm/boot/dts/kirkwood-ds112.dts index bf4143c6cb8f..b84af3da8c84 100644 --- a/arch/arm/boot/dts/kirkwood-ds112.dts +++ b/arch/arm/boot/dts/kirkwood-ds112.dts @@ -14,7 +14,7 @@ #include "kirkwood-synology.dtsi" / { - model = "Synology DS111"; + model = "Synology DS112"; compatible = "synology,ds111", "marvell,kirkwood"; memory { diff --git a/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi b/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi new file mode 100644 index 000000000000..6548e68a20d0 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi @@ -0,0 +1,192 @@ +/* + * Device Tree common file for kirkwood-6282 based Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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 "kirkwood.dtsi" +#include "kirkwood-6282.dtsi" +#include "kirkwood-linkstation.dtsi" + +/ { + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd0: pmx-power-hdd0 { + marvell,pins = "mpp8"; + marvell,function = "gpio"; + }; + pmx_usb_vbus: pmx-usb-vbus { + marvell,pins = "mpp12"; + marvell,function = "gpio"; + }; + pmx_fan_high: pmx-fan-high { + marvell,pins = "mpp16"; + marvell,function = "gpio"; + }; + pmx_fan_low: pmx-fan-low { + marvell,pins = "mpp17"; + marvell,function = "gpio"; + }; + pmx_led_alarm: pmx-led-alarm { + marvell,pins = "mpp36"; + marvell,function = "gpio"; + }; + pmx_led_function_red: pmx-led-function-red { + marvell,pins = "mpp37"; + marvell,function = "gpio"; + }; + pmx_led_info: pmx-led-info { + marvell,pins = "mpp38"; + marvell,function = "gpio"; + }; + pmx_led_function_blue: pmx-led-function-blue { + marvell,pins = "mpp39"; + marvell,function = "gpio"; + }; + pmx_led_power: pmx-led-power { + marvell,pins = "mpp40"; + marvell,function = "gpio"; + }; + pmx_fan_lock: pmx-fan-lock { + marvell,pins = "mpp43"; + marvell,function = "gpio"; + }; + pmx_button_function: pmx-button-function { + marvell,pins = "mpp45"; + marvell,function = "gpio"; + }; + pmx_power_switch: pmx-power-switch { + marvell,pins = "mpp46"; + marvell,function = "gpio"; + }; + pmx_power_auto_switch: pmx-power-auto-switch { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + }; + }; + + gpio_keys { + function-button { + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; + }; + + power-on-switch { + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + }; + + power-auto-switch { + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + }; + }; + + gpio_leds { + red-alarm-led { + label = "linkstation:red:alarm"; + gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + }; + + red-function-led { + label = "linkstation:red:function"; + gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; + }; + + amber-info-led { + label = "linkstation:amber:info"; + gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + }; + + blue-function-led { + label = "linkstation:blue:function"; + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + }; + + blue-power-led { + label = "linkstation:blue:power"; + gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + default-state = "keep"; + }; + }; + + gpio_fan { + compatible = "gpio-fan"; + pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; + pinctrl-names = "default"; + + gpios = <&gpio0 17 GPIO_ACTIVE_LOW + &gpio0 16 GPIO_ACTIVE_LOW>; + + gpio-fan,speed-map = <0 3 + 1500 2 + 3250 1 + 5000 0>; + + alarm-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; + }; + + regulators { + usb_power: regulator@1 { + gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; + }; + + hdd_power0: regulator@2 { + gpio = <&gpio0 8 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&mdio { + status = "okay"; + + ethphy0: ethernet-phy@0 { + device_type = "ethernet-phy"; + reg = <0>; + }; +}; + +ð0 { + status = "okay"; + + ethernet0-port@0 { + phy-handle = <ðphy0>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi b/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi new file mode 100644 index 000000000000..cf2e69f0d54f --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi @@ -0,0 +1,186 @@ +/* + * Device Tree common file for kirkwood-6281 based 2-Bay Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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 "kirkwood.dtsi" +#include "kirkwood-6281.dtsi" +#include "kirkwood-linkstation.dtsi" + +/ { + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd0: pmx-power-hdd0 { + marvell,pins = "mpp28"; + marvell,function = "gpio"; + }; + pmx_power_hdd1: pmx-power-hdd1 { + marvell,pins = "mpp29"; + marvell,function = "gpio"; + }; + pmx_usb_vbus: pmx-usb-vbus { + marvell,pins = "mpp37"; + marvell,function = "gpio"; + }; + pmx_led_alarm: pmx-led-alarm { + marvell,pins = "mpp49"; + marvell,function = "gpio"; + }; + pmx_led_function_red: pmx-led-function-red { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + pmx_led_function_blue: pmx-led-function-blue { + marvell,pins = "mpp36"; + marvell,function = "gpio"; + }; + pmx_led_info: pmx-led-info { + marvell,pins = "mpp38"; + marvell,function = "gpio"; + }; + pmx_led_power: pmx-led-power { + marvell,pins = "mpp39"; + marvell,function = "gpio"; + }; + pmx_button_function: pmx-button-function { + marvell,pins = "mpp41"; + marvell,function = "gpio"; + }; + pmx_power_switch: pmx-power-switch { + marvell,pins = "mpp42"; + marvell,function = "gpio"; + }; + pmx_power_auto_switch: pmx-power-auto-switch { + marvell,pins = "mpp43"; + marvell,function = "gpio"; + }; + }; + + sata@80000 { + nr-ports = <2>; + }; + }; + + gpio_keys { + function-button { + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + }; + + power-on-switch { + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + }; + + power-auto-switch { + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + }; + }; + + gpio_leds { + red-alarm-led { + label = "linkstation:red:alarm"; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; + }; + + red-function-led { + label = "linkstation:red:function"; + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + }; + + amber-info-led { + label = "linkstation:amber:info"; + gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + }; + + blue-function-led { + label = "linkstation:blue:function"; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + }; + + blue-power-led { + label = "linkstation:blue:power"; + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + default-state = "keep"; + }; + }; + + regulators { + pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; + + usb_power: regulator@1 { + gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>; + }; + + hdd_power0: regulator@2 { + gpio = <&gpio0 28 GPIO_ACTIVE_HIGH>; + }; + + hdd_power1: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "HDD1 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&mdio { + status = "okay"; + + ethphy1: ethernet-phy@8 { + device_type = "ethernet-phy"; + reg = <8>; + }; +}; + +ð1 { + status = "okay"; + + ethernet1-port@0 { + phy-handle = <ðphy1>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts new file mode 100644 index 000000000000..6dc0df2969f0 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts @@ -0,0 +1,135 @@ +/* + * Device Tree file for Buffalo Linkstation LS-QVL + * + * Copyright (C) 2016, Mario Lange + * + * Based on kirkwood-linkstation-lswvl.dts, + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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 "kirkwood-linkstation-6282.dtsi" + +/ { + model = "Buffalo Linkstation LS-QVL"; + compatible = "buffalo,lsqvl", "marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd1: pmx-power-hdd1 { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; + pmx_led_hdderr0: pmx-led-hdderr0 { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + pmx_led_hdderr1: pmx-led-hdderr1 { + marvell,pins = "mpp35"; + marvell,function = "gpio"; + }; + pmx_led_hdderr2: pmx-led-hdderr2 { + marvell,pins = "mpp24"; + marvell,function = "gpio"; + }; + pmx_led_hdderr3: pmx-led-hdderr3 { + marvell,pins = "mpp25"; + marvell,function = "gpio"; + }; + }; + + sata@80000 { + nr-ports = <2>; + }; + }; + + gpio_leds { + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue + &pmx_led_hdderr0 + &pmx_led_hdderr1 + &pmx_led_hdderr2 + &pmx_led_hdderr3>; + + red-hdderr0-led { + label = "linkstation:red:hdderr0"; + gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; + }; + + red-hdderr1-led { + label = "linkstation:red:hdderr1"; + gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; + }; + + red-hdderr2-led { + label = "linkstation:red:hdderr2"; + gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; + }; + + red-hdderr3-led { + label = "linkstation:red:hdderr3"; + gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; + }; + }; + + regulators { + pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; + + hdd_power1: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "HDD1 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts new file mode 100644 index 000000000000..edcba5c44b05 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts @@ -0,0 +1,57 @@ +/* + * Device Tree file for Buffalo Linkstation LS-VL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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 "kirkwood-linkstation-6282.dtsi" + +/ { + model = "Buffalo Linkstation LS-VL"; + compatible = "buffalo,lsvl", "marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts new file mode 100644 index 000000000000..4b6450186af5 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts @@ -0,0 +1,57 @@ +/* + * Device Tree file for Buffalo Linkstation LS-WSXL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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 "kirkwood-linkstation-duo-6281.dtsi" + +/ { + model = "Buffalo Linkstation LS-WSXL"; + compatible = "buffalo,lswsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts new file mode 100644 index 000000000000..954ec1d5b6dc --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts @@ -0,0 +1,112 @@ +/* + * Device Tree file for Buffalo Linkstation LS-WVL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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 "kirkwood-linkstation-6282.dtsi" + +/ { + model = "Buffalo Linkstation LS-WVL"; + compatible = "buffalo,lswvl","marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd1: pmx-power-hdd1 { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; + pmx_led_hdderr0: pmx-led-hdderr0 { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + pmx_led_hdderr1: pmx-led-hdderr1 { + marvell,pins = "mpp35"; + marvell,function = "gpio"; + }; + }; + + sata@80000 { + nr-ports = <2>; + }; + }; + + gpio_leds { + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue + &pmx_led_hdderr0 + &pmx_led_hdderr1>; + + red-hdderr0-led { + label = "linkstation:red:hdderr0"; + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + }; + + red-hdderr1-led { + label = "linkstation:red:hdderr1"; + gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; + }; + }; + + regulators { + pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; + + hdd_power1: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "HDD1 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts new file mode 100644 index 000000000000..ecd5c12a805d --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts @@ -0,0 +1,116 @@ +/* + * Device Tree file for Buffalo Linkstation LS-WXL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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 "kirkwood-linkstation-duo-6281.dtsi" + +/ { + model = "Buffalo Linkstation LS-WXL"; + compatible = "buffalo,lswxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_led_hdderr0: pmx-led-hdderr0 { + marvell,pins = "mpp8"; + marvell,function = "gpio"; + }; + pmx_led_hdderr1: pmx-led-hdderr1 { + marvell,pins = "mpp46"; + marvell,function = "gpio"; + }; + pmx_fan_lock: pmx-fan-lock { + marvell,pins = "mpp40"; + marvell,function = "gpio"; + }; + pmx_fan_high: pmx-fan-high { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + pmx_fan_low: pmx-fan-low { + marvell,pins = "mpp48"; + marvell,function = "gpio"; + }; + }; + }; + + gpio_leds { + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue + &pmx_led_hdderr0 + &pmx_led_hdderr1>; + + red-hdderr0-led { + label = "linkstation:red:hdderr0"; + gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; + }; + + red-hdderr1-led { + label = "linkstation:red:hdderr1"; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio_fan { + compatible = "gpio-fan"; + pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; + pinctrl-names = "default"; + + gpios = <&gpio1 16 GPIO_ACTIVE_LOW + &gpio1 15 GPIO_ACTIVE_LOW>; + + gpio-fan,speed-map = <0 3 + 1500 2 + 3250 1 + 5000 0>; + + alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation.dtsi b/arch/arm/boot/dts/kirkwood-linkstation.dtsi new file mode 100644 index 000000000000..69061b6e987b --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation.dtsi @@ -0,0 +1,202 @@ +/* + * Device Tree common file for kirkwood based Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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. + */ + +/ { + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + stdout-path = &uart0; + }; + + mbus { + pcie-controller { + status = "okay"; + pcie@1,0 { + status = "okay"; + }; + }; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd0: pmx-power-hdd0 { + marvell,function = "gpio"; + }; + pmx_usb_vbus: pmx-usb-vbus { + marvell,function = "gpio"; + }; + pmx_led_alarm: pmx-led-alarm { + marvell,function = "gpio"; + }; + pmx_led_function_red: pmx-led-function-red { + marvell,function = "gpio"; + }; + pmx_led_function_blue: pmx-led-function-blue { + marvell,function = "gpio"; + }; + pmx_led_info: pmx-led-info { + marvell,function = "gpio"; + }; + pmx_led_power: pmx-led-power { + marvell,function = "gpio"; + }; + pmx_button_function: pmx-button-function { + marvell,function = "gpio"; + }; + pmx_power_switch: pmx-power-switch { + marvell,function = "gpio"; + }; + pmx_power_auto_switch: pmx-power-auto-switch { + marvell,function = "gpio"; + }; + }; + + serial@12000 { + status = "okay"; + }; + + sata@80000 { + status = "okay"; + nr-ports = <1>; + }; + + spi@10600 { + status = "okay"; + + m25p40@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25p40", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + mode = <0>; + + partition@0 { + reg = <0x0 0x60000>; + label = "uboot"; + read-only; + }; + + partition@60000 { + reg = <0x60000 0x10000>; + label = "dtb"; + read-only; + }; + + partition@70000 { + reg = <0x70000 0x10000>; + label = "uboot_env"; + }; + }; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_button_function &pmx_power_switch + &pmx_power_auto_switch>; + pinctrl-names = "default"; + + function-button { + label = "Function Button"; + linux,code = ; + }; + + power-on-switch { + label = "Power-on Switch"; + linux,code = ; + linux,input-type = <5>; + }; + + power-auto-switch { + label = "Power-auto Switch"; + linux,code = ; + linux,input-type = <5>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue>; + pinctrl-names = "default"; + }; + + restart_poweroff { + compatible = "restart-poweroff"; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_power_hdd0 &pmx_usb_vbus>; + pinctrl-names = "default"; + + usb_power: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "USB Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + }; + + hdd_power0: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "HDD0 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-lswvl.dts b/arch/arm/boot/dts/kirkwood-lswvl.dts deleted file mode 100644 index 09eed3cea0af..000000000000 --- a/arch/arm/boot/dts/kirkwood-lswvl.dts +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Device Tree file for Buffalo Linkstation LS-WVL/VL - * - * Copyright (C) 2015, rogershimizu@gmail.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; either version - * 2 of the License, or (at your option) any later version. - */ - -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6282.dtsi" - -/ { - model = "Buffalo Linkstation LS-WVL/VL"; - compatible = "buffalo,lswvl", "buffalo,lsvl", "marvell,kirkwood-88f6282", "marvell,kirkwood"; - - memory { /* 256 MB */ - device_type = "memory"; - reg = <0x00000000 0x10000000>; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - stdout-path = &uart0; - }; - - mbus { - pcie-controller { - status = "okay"; - pcie@1,0 { - status = "okay"; - }; - }; - }; - - ocp@f1000000 { - pinctrl: pin-controller@10000 { - pmx_power_hdd0: pmx-power-hdd0 { - marvell,pins = "mpp8"; - marvell,function = "gpio"; - }; - pmx_power_hdd1: pmx-power-hdd1 { - marvell,pins = "mpp9"; - marvell,function = "gpio"; - }; - pmx_usb_vbus: pmx-usb-vbus { - marvell,pins = "mpp12"; - marvell,function = "gpio"; - }; - pmx_fan_high: pmx-fan-high { - marvell,pins = "mpp16"; - marvell,function = "gpio"; - }; - pmx_fan_low: pmx-fan-low { - marvell,pins = "mpp17"; - marvell,function = "gpio"; - }; - pmx_led_hdderr0: pmx-led-hdderr0 { - marvell,pins = "mpp34"; - marvell,function = "gpio"; - }; - pmx_led_hdderr1: pmx-led-hdderr1 { - marvell,pins = "mpp35"; - marvell,function = "gpio"; - }; - pmx_led_alarm: pmx-led-alarm { - marvell,pins = "mpp36"; - marvell,function = "gpio"; - }; - pmx_led_function_red: pmx-led-function-red { - marvell,pins = "mpp37"; - marvell,function = "gpio"; - }; - pmx_led_info: pmx-led-info { - marvell,pins = "mpp38"; - marvell,function = "gpio"; - }; - pmx_led_function_blue: pmx-led-function-blue { - marvell,pins = "mpp39"; - marvell,function = "gpio"; - }; - pmx_led_power: pmx-led-power { - marvell,pins = "mpp40"; - marvell,function = "gpio"; - }; - pmx_fan_lock: pmx-fan-lock { - marvell,pins = "mpp43"; - marvell,function = "gpio"; - }; - pmx_button_function: pmx-button-function { - marvell,pins = "mpp45"; - marvell,function = "gpio"; - }; - pmx_power_switch: pmx-power-switch { - marvell,pins = "mpp46"; - marvell,function = "gpio"; - }; - pmx_power_auto_switch: pmx-power-auto-switch { - marvell,pins = "mpp47"; - marvell,function = "gpio"; - }; - }; - - serial@12000 { - status = "okay"; - }; - - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - - spi@10600 { - status = "okay"; - - m25p40@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,m25p40", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <25000000>; - mode = <0>; - - partition@0 { - reg = <0x0 0x60000>; - label = "uboot"; - read-only; - }; - - partition@60000 { - reg = <0x60000 0x10000>; - label = "dtb"; - read-only; - }; - - partition@70000 { - reg = <0x70000 0x10000>; - label = "uboot_env"; - }; - }; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_button_function &pmx_power_switch - &pmx_power_auto_switch>; - pinctrl-names = "default"; - - button@1 { - label = "Function Button"; - linux,code = ; - gpios = <&gpio0 45 GPIO_ACTIVE_LOW>; - }; - - button@2 { - label = "Power-on Switch"; - linux,code = ; - linux,input-type = <5>; - gpios = <&gpio0 46 GPIO_ACTIVE_LOW>; - }; - - button@3 { - label = "Power-auto Switch"; - linux,code = ; - linux,input-type = <5>; - gpios = <&gpio0 47 GPIO_ACTIVE_LOW>; - }; - }; - - gpio_leds { - compatible = "gpio-leds"; - pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm - &pmx_led_info &pmx_led_power - &pmx_led_function_blue - &pmx_led_hdderr0 - &pmx_led_hdderr1>; - pinctrl-names = "default"; - - led@1 { - label = "lswvl:red:alarm"; - gpios = <&gpio0 36 GPIO_ACTIVE_LOW>; - }; - - led@2 { - label = "lswvl:red:func"; - gpios = <&gpio0 37 GPIO_ACTIVE_LOW>; - }; - - led@3 { - label = "lswvl:amber:info"; - gpios = <&gpio0 38 GPIO_ACTIVE_LOW>; - }; - - led@4 { - label = "lswvl:blue:func"; - gpios = <&gpio0 39 GPIO_ACTIVE_LOW>; - }; - - led@5 { - label = "lswvl:blue:power"; - gpios = <&gpio0 40 GPIO_ACTIVE_LOW>; - default-state = "keep"; - }; - - led@6 { - label = "lswvl:red:hdderr0"; - gpios = <&gpio0 34 GPIO_ACTIVE_LOW>; - }; - - led@7 { - label = "lswvl:red:hdderr1"; - gpios = <&gpio0 35 GPIO_ACTIVE_LOW>; - }; - }; - - gpio_fan { - compatible = "gpio-fan"; - pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; - pinctrl-names = "default"; - - gpios = <&gpio0 17 GPIO_ACTIVE_LOW - &gpio0 16 GPIO_ACTIVE_LOW>; - - gpio-fan,speed-map = <0 3 - 1500 2 - 3250 1 - 5000 0>; - - alarm-gpios = <&gpio0 43 GPIO_ACTIVE_HIGH>; - }; - - restart_poweroff { - compatible = "restart-poweroff"; - }; - - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; - pinctrl-names = "default"; - - usb_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; - }; - hdd_power0: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "HDD0 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 8 GPIO_ACTIVE_HIGH>; - }; - hdd_power1: regulator@3 { - compatible = "regulator-fixed"; - reg = <3>; - regulator-name = "HDD1 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; - }; - }; -}; - -&mdio { - status = "okay"; - - ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; - reg = <0>; - }; -}; - -ð0 { - status = "okay"; - - ethernet0-port@0 { - phy-handle = <ðphy0>; - }; -}; diff --git a/arch/arm/boot/dts/kirkwood-lswxl.dts b/arch/arm/boot/dts/kirkwood-lswxl.dts deleted file mode 100644 index f5db16a08597..000000000000 --- a/arch/arm/boot/dts/kirkwood-lswxl.dts +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Device Tree file for Buffalo Linkstation LS-WXL/WSXL - * - * Copyright (C) 2015, rogershimizu@gmail.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; either version - * 2 of the License, or (at your option) any later version. - */ - -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6281.dtsi" - -/ { - model = "Buffalo Linkstation LS-WXL/WSXL"; - compatible = "buffalo,lswxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - memory { /* 128 MB */ - device_type = "memory"; - reg = <0x00000000 0x8000000>; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - stdout-path = &uart0; - }; - - mbus { - pcie-controller { - status = "okay"; - pcie@1,0 { - status = "okay"; - }; - }; - }; - - ocp@f1000000 { - pinctrl: pin-controller@10000 { - pmx_power_hdd0: pmx-power-hdd0 { - marvell,pins = "mpp28"; - marvell,function = "gpio"; - }; - pmx_power_hdd1: pmx-power-hdd1 { - marvell,pins = "mpp29"; - marvell,function = "gpio"; - }; - pmx_usb_vbus: pmx-usb-vbus { - marvell,pins = "mpp37"; - marvell,function = "gpio"; - }; - pmx_fan_high: pmx-fan-high { - marvell,pins = "mpp47"; - marvell,function = "gpio"; - }; - pmx_fan_low: pmx-fan-low { - marvell,pins = "mpp48"; - marvell,function = "gpio"; - }; - pmx_led_hdderr0: pmx-led-hdderr0 { - marvell,pins = "mpp8"; - marvell,function = "gpio"; - }; - pmx_led_hdderr1: pmx-led-hdderr1 { - marvell,pins = "mpp46"; - marvell,function = "gpio"; - }; - pmx_led_alarm: pmx-led-alarm { - marvell,pins = "mpp49"; - marvell,function = "gpio"; - }; - pmx_led_function_red: pmx-led-function-red { - marvell,pins = "mpp34"; - marvell,function = "gpio"; - }; - pmx_led_function_blue: pmx-led-function-blue { - marvell,pins = "mpp36"; - marvell,function = "gpio"; - }; - pmx_led_info: pmx-led-info { - marvell,pins = "mpp38"; - marvell,function = "gpio"; - }; - pmx_led_power: pmx-led-power { - marvell,pins = "mpp39"; - marvell,function = "gpio"; - }; - pmx_fan_lock: pmx-fan-lock { - marvell,pins = "mpp40"; - marvell,function = "gpio"; - }; - pmx_button_function: pmx-button-function { - marvell,pins = "mpp41"; - marvell,function = "gpio"; - }; - pmx_power_switch: pmx-power-switch { - marvell,pins = "mpp42"; - marvell,function = "gpio"; - }; - pmx_power_auto_switch: pmx-power-auto-switch { - marvell,pins = "mpp43"; - marvell,function = "gpio"; - }; - }; - - serial@12000 { - status = "okay"; - }; - - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - - spi@10600 { - status = "okay"; - - m25p40@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,m25p40", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <25000000>; - mode = <0>; - - partition@0 { - reg = <0x0 0x60000>; - label = "uboot"; - read-only; - }; - - partition@60000 { - reg = <0x60000 0x10000>; - label = "dtb"; - read-only; - }; - - partition@70000 { - reg = <0x70000 0x10000>; - label = "uboot_env"; - }; - }; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_button_function &pmx_power_switch - &pmx_power_auto_switch>; - pinctrl-names = "default"; - - button@1 { - label = "Function Button"; - linux,code = ; - gpios = <&gpio1 41 GPIO_ACTIVE_LOW>; - }; - - button@2 { - label = "Power-on Switch"; - linux,code = ; - linux,input-type = <5>; - gpios = <&gpio1 42 GPIO_ACTIVE_LOW>; - }; - - button@3 { - label = "Power-auto Switch"; - linux,code = ; - linux,input-type = <5>; - gpios = <&gpio1 43 GPIO_ACTIVE_LOW>; - }; - }; - - gpio_leds { - compatible = "gpio-leds"; - pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm - &pmx_led_info &pmx_led_power - &pmx_led_function_blue - &pmx_led_hdderr0 - &pmx_led_hdderr1>; - pinctrl-names = "default"; - - led@1 { - label = "lswxl:blue:func"; - gpios = <&gpio1 36 GPIO_ACTIVE_LOW>; - }; - - led@2 { - label = "lswxl:red:alarm"; - gpios = <&gpio1 49 GPIO_ACTIVE_LOW>; - }; - - led@3 { - label = "lswxl:amber:info"; - gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; - }; - - led@4 { - label = "lswxl:blue:power"; - gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; - }; - - led@5 { - label = "lswxl:red:func"; - gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; - default-state = "keep"; - }; - - led@6 { - label = "lswxl:red:hdderr0"; - gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; - }; - - led@7 { - label = "lswxl:red:hdderr1"; - gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; - }; - }; - - gpio_fan { - compatible = "gpio-fan"; - pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; - pinctrl-names = "default"; - - gpios = <&gpio0 47 GPIO_ACTIVE_LOW - &gpio0 48 GPIO_ACTIVE_LOW>; - - gpio-fan,speed-map = <0 3 - 1500 2 - 3250 1 - 5000 0>; - - alarm-gpios = <&gpio1 49 GPIO_ACTIVE_HIGH>; - }; - - restart_poweroff { - compatible = "restart-poweroff"; - }; - - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; - pinctrl-names = "default"; - - usb_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 37 GPIO_ACTIVE_HIGH>; - }; - hdd_power0: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "HDD0 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 28 GPIO_ACTIVE_HIGH>; - }; - hdd_power1: regulator@3 { - compatible = "regulator-fixed"; - reg = <3>; - regulator-name = "HDD1 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>; - }; - }; -}; - -&mdio { - status = "okay"; - - ethphy1: ethernet-phy@8 { - device_type = "ethernet-phy"; - reg = <8>; - }; -}; - -ð1 { - status = "okay"; - - ethernet1-port@0 { - phy-handle = <ðphy1>; - }; -}; diff --git a/arch/arm/boot/dts/kirkwood-openrd-client.dts b/arch/arm/boot/dts/kirkwood-openrd-client.dts index 887b9c1fee43..96ff59d68f44 100644 --- a/arch/arm/boot/dts/kirkwood-openrd-client.dts +++ b/arch/arm/boot/dts/kirkwood-openrd-client.dts @@ -20,6 +20,9 @@ compatible = "marvell,openrd-client", "marvell,openrd", "marvell,kirkwood-88f6281", "marvell,kirkwood"; ocp@f1000000 { + audio-controller@a0000 { + status = "okay"; + }; i2c@11000 { status = "okay"; clock-frequency = <400000>; @@ -27,6 +30,7 @@ cs42l51: cs42l51@4a { compatible = "cirrus,cs42l51"; reg = <0x4a>; + #sound-dai-cells = <0>; }; }; }; @@ -37,7 +41,7 @@ simple-audio-card,mclk-fs = <256>; simple-audio-card,cpu { - sound-dai = <&audio0>; + sound-dai = <&audio0 0>; }; simple-audio-card,codec { diff --git a/arch/arm/boot/dts/kirkwood-openrd.dtsi b/arch/arm/boot/dts/kirkwood-openrd.dtsi index d3330dadf7ed..24f1d30970a0 100644 --- a/arch/arm/boot/dts/kirkwood-openrd.dtsi +++ b/arch/arm/boot/dts/kirkwood-openrd.dtsi @@ -40,7 +40,7 @@ pinctrl-0 = <&pmx_select28 &pmx_sdio_cd &pmx_select34>; pinctrl-names = "default"; - pmx_select28: pmx-select-uart-sd { + pmx_select28: pmx-select-rs232-rs485 { marvell,pins = "mpp28"; marvell,function = "gpio"; }; @@ -48,7 +48,7 @@ marvell,pins = "mpp29"; marvell,function = "gpio"; }; - pmx_select34: pmx-select-rs232-rs484 { + pmx_select34: pmx-select-uart-sd { marvell,pins = "mpp34"; marvell,function = "gpio"; }; @@ -65,6 +65,43 @@ status = "okay"; cd-gpios = <&gpio0 29 9>; }; + gpio@10100 { + p28 { + gpio-hog; + gpios = <28 GPIO_ACTIVE_HIGH>; + /* + * SelRS232or485 selects between RS-232 or RS-485 + * mode for the second UART. + * + * Low: RS-232 + * High: RS-485 + * + * To use the second UART, you need to change also + * the SelUARTorSD. + */ + output-low; + line-name = "SelRS232or485"; + }; + }; + gpio@10140 { + p2 { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>; + /* + * SelUARTorSD selects between the second UART + * (serial@12100) and SD (mvsdio@90000). + * + * Low: UART + * High: SD + * + * When changing this line make sure the newly + * selected device node is enabled and the + * previously selected device node is disabled. + */ + output-high; /* Select SD by default */ + line-name = "SelUARTorSD"; + }; + }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts index 1db6f2c506cc..8082d64266a3 100644 --- a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts +++ b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts @@ -131,6 +131,7 @@ chip-delay = <40>; status = "okay"; partitions { + compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 7b5a4a18f49c..7445a15e259d 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -381,7 +381,7 @@ audio0: audio-controller@a0000 { compatible = "marvell,kirkwood-audio"; - #sound-dai-cells = <0>; + #sound-dai-cells = <1>; reg = <0xa0000 0x2210>; interrupts = <24>; clocks = <&gate_clk 9>; diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi index 7fed0bd4f3de..00805322367e 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi @@ -112,14 +112,6 @@ clock-frequency = <400000>; }; -&i2c2 { - clock-frequency = <400000>; -}; - -&i2c3 { - clock-frequency = <400000>; -}; - /* * Only found on the wireless SOM. For the SOM without wireless, the pins for * MMC3 can be routed with jumpers to the second MMC slot on the devkit and @@ -143,6 +135,7 @@ interrupt-parent = <&gpio5>; interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; /* gpio 152 */ ref-clock-frequency = <26000000>; + tcxo-clock-frequency = <26000000>; }; }; diff --git a/arch/arm/boot/dts/mvebu-linkstation-fan.dtsi b/arch/arm/boot/dts/mvebu-linkstation-fan.dtsi new file mode 100644 index 000000000000..e211a3c47a76 --- /dev/null +++ b/arch/arm/boot/dts/mvebu-linkstation-fan.dtsi @@ -0,0 +1,72 @@ +/* + * Device Tree common file for gpio-fan on Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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. + */ + +/ { + gpio_fan { + compatible = "gpio-fan"; + pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; + pinctrl-names = "default"; + + gpio-fan,speed-map = + <0 3 + 1500 2 + 3250 1 + 5000 0>; + }; +}; + +&pinctrl { + pmx_fan_low: pmx-fan-low { + marvell,function = "gpio"; + }; + + pmx_fan_high: pmx-fan-high { + marvell,function = "gpio"; + }; + + pmx_fan_lock: pmx-fan-lock { + marvell,function = "gpio"; + }; +}; diff --git a/arch/arm/boot/dts/mvebu-linkstation-gpio-simple.dtsi b/arch/arm/boot/dts/mvebu-linkstation-gpio-simple.dtsi new file mode 100644 index 000000000000..68d75e79a360 --- /dev/null +++ b/arch/arm/boot/dts/mvebu-linkstation-gpio-simple.dtsi @@ -0,0 +1,105 @@ +/* + * Device Tree common file for gpio-{keys,leds} on Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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 + +/ { + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_power_switch>; + pinctrl-names = "default"; + + power-on-switch { + label = "Power-on Switch"; + linux,code = ; + linux,input-type = <5>; + }; + + power-auto-switch { + label = "Power-auto Switch"; + linux,code = ; + linux,input-type = <5>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-0 = <&pmx_led_power &pmx_led_alarm &pmx_led_info>; + pinctrl-names = "default"; + + blue-power-led { + label = "linkstation:blue:power"; + default-state = "keep"; + }; + + red-alarm-led { + label = "linkstation:red:alarm"; + }; + + amber-info-led { + label = "linkstation:amber:info"; + }; + }; +}; + +&pinctrl { + pmx_power_switch: pmx-power-switch { + marvell,function = "gpio"; + }; + + pmx_led_power: pmx-leds { + marvell,function = "gpio"; + }; + + pmx_led_alarm: pmx-leds { + marvell,function = "gpio"; + }; + + pmx_led_info: pmx-leds { + marvell,function = "gpio"; + }; +}; diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 74d8f7eb5563..20603f3f9bd0 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -522,6 +522,21 @@ amstaos,cover-comp-gain = <16>; }; + adp1653: led-controller@30 { + compatible = "adi,adp1653"; + reg = <0x30>; + enable-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>; /* 88 */ + + flash { + flash-timeout-us = <500000>; + flash-max-microamp = <320000>; + led-max-microamp = <50000>; + }; + indicator { + led-max-microamp = <17500>; + }; + }; + lp5523: lp5523@32 { compatible = "national,lp5523"; reg = <0x32>; diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi index a2c2b8d8dd2c..ab1174bb409e 100644 --- a/arch/arm/boot/dts/omap3-n950-n9.dtsi +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi @@ -31,6 +31,14 @@ startup-delay-us = <150>; enable-active-high; }; + + vwlan_fixed: fixedregulator@2 { + compatible = "regulator-fixed"; + regulator-name = "VWLAN"; + gpio = <&gpio2 3 GPIO_ACTIVE_HIGH>; /* gpio 35 */ + enable-active-high; + regulator-boot-off; + }; }; &omap3_pmx_core { @@ -44,6 +52,13 @@ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */ >; }; + + wlan_pins: pinmux_wlan_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE4) /* gpio 35 - wlan enable */ + OMAP3_CORE1_IOPAD(0x208a, PIN_INPUT | MUX_MODE4) /* gpio 42 - wlan irq */ + >; + }; }; &i2c1 { diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts index 0885b34d5d7d..e5967262f28b 100644 --- a/arch/arm/boot/dts/omap3-n950.dts +++ b/arch/arm/boot/dts/omap3-n950.dts @@ -17,6 +17,17 @@ compatible = "nokia,omap3-n950", "ti,omap36xx", "ti,omap3"; }; +&omap3_pmx_core { + spi4_pins: pinmux_spi4_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x218c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_clk */ + OMAP3_CORE1_IOPAD(0x2190, PIN_OUTPUT | MUX_MODE1) /* mcspi4_simo */ + OMAP3_CORE1_IOPAD(0x2192, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_somi */ + OMAP3_CORE1_IOPAD(0x2196, PIN_OUTPUT | MUX_MODE1) /* mcspi4_cs0 */ + >; + }; +}; + &i2c2 { smia_1: camera@10 { compatible = "nokia,smia"; @@ -53,3 +64,21 @@ }; }; }; + +&mcspi4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi4_pins>; + + wlcore: wlcore@0 { + compatible = "ti,wl1271"; + pinctrl-names = "default"; + pinctrl-0 = <&wlan_pins>; + reg = <0>; + spi-max-frequency = <48000000>; + clock-xtal; + ref-clock-frequency = <38400000>; + interrupts-extended = <&gpio2 10 IRQ_TYPE_LEVEL_HIGH>; /* gpio 42 */ + vwlan-supply = <&vwlan_fixed>; + }; +}; diff --git a/arch/arm/boot/dts/omap34xx.dtsi b/arch/arm/boot/dts/omap34xx.dtsi index 4f6b2d5b1902..387dc31822fe 100644 --- a/arch/arm/boot/dts/omap34xx.dtsi +++ b/arch/arm/boot/dts/omap34xx.dtsi @@ -54,6 +54,12 @@ #size-cells = <0>; }; }; + + bandgap { + reg = <0x48002524 0x4>; + compatible = "ti,omap34xx-bandgap"; + #thermal-sensor-cells = <0>; + }; }; }; diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi index 86253de5a97a..f19c87bd6bf3 100644 --- a/arch/arm/boot/dts/omap36xx.dtsi +++ b/arch/arm/boot/dts/omap36xx.dtsi @@ -86,6 +86,12 @@ #size-cells = <0>; }; }; + + bandgap { + reg = <0x48002524 0x4>; + compatible = "ti,omap36xx-bandgap"; + #thermal-sensor-cells = <0>; + }; }; }; diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi index 888412c63f97..902657d6713b 100644 --- a/arch/arm/boot/dts/omap5-board-common.dtsi +++ b/arch/arm/boot/dts/omap5-board-common.dtsi @@ -130,6 +130,16 @@ }; }; +&gpio8 { + /* TI trees use GPIO instead of msecure, see also muxing */ + p234 { + gpio-hog; + gpios = <10 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "gpio8_234/msecure"; + }; +}; + &omap5_pmx_core { pinctrl-names = "default"; pinctrl-0 = < @@ -213,6 +223,13 @@ >; }; + /* TI trees use GPIO mode; msecure mode does not work reliably? */ + palmas_msecure_pins: palmas_msecure_pins { + pinctrl-single,pins = < + OMAP5_IOPAD(0x180, PIN_OUTPUT | MUX_MODE6) /* gpio8_234 */ + >; + }; + usbhost_pins: pinmux_usbhost_pins { pinctrl-single,pins = < OMAP5_IOPAD(0x0c4, PIN_INPUT | MUX_MODE0) /* usbb2_hsic_strobe */ @@ -278,6 +295,12 @@ &usbhost_wkup_pins >; + palmas_sys_nirq_pins: pinmux_palmas_sys_nirq_pins { + pinctrl-single,pins = < + OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1 */ + >; + }; + usbhost_wkup_pins: pinmux_usbhost_wkup_pins { pinctrl-single,pins = < OMAP5_IOPAD(0x05a, PIN_OUTPUT | MUX_MODE0) /* fref_clk1_out, USB hub clk */ @@ -345,6 +368,8 @@ interrupt-controller; #interrupt-cells = <2>; ti,system-power-controller; + pinctrl-names = "default"; + pinctrl-0 = <&palmas_sys_nirq_pins &palmas_msecure_pins>; extcon_usb3: palmas_usb { compatible = "ti,palmas-usb-vid"; @@ -358,6 +383,14 @@ #clock-cells = <0>; }; + rtc { + compatible = "ti,palmas-rtc"; + interrupt-parent = <&palmas>; + interrupts = <8 IRQ_TYPE_NONE>; + ti,backup-battery-chargeable; + ti,backup-battery-charge-high-current; + }; + palmas_pmic { compatible = "ti,palmas-pmic"; interrupt-parent = <&palmas>; diff --git a/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts new file mode 100644 index 000000000000..1cf644bfd7ea --- /dev/null +++ b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts @@ -0,0 +1,87 @@ +/* + * Device Tree file for Buffalo Linkstation LS-GL + * (also known as Buffalo Linkstation Pro/Live) + * + * Copyright (C) 2016 + * Roger Shimizu + * + * Based on the board file arch/arm/mach-orion5x/kurobox_pro-setup.c + * Copyright (C) Ronen Shitrit + * + * 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 , 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 "orion5x-linkstation.dtsi" +#include + +/ { + model = "Buffalo Linkstation Pro/Live"; + compatible = "buffalo,lsgl", "marvell,orion5x-88f5182", "marvell,orion5x"; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; +}; + +&pinctrl { + pmx_power_hdd: pmx-power-hdd { + marvell,pins = "mpp1"; + marvell,function = "gpio"; + }; + + pmx_power_usb: pmx-power-usb { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; +}; + +&hdd_power { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; +}; + +&usb_power { + gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; +}; + +&ehci1 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts index 3daec912b4bf..0eead400f427 100644 --- a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts +++ b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts @@ -1,7 +1,8 @@ /* * Device Tree file for Buffalo Linkstation LS-WTGL * - * Copyright (C) 2015, Roger Shimizu + * Copyright (C) 2015, 2016 + * Roger Shimizu * * 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 @@ -44,9 +45,10 @@ /dts-v1/; +#include "orion5x-linkstation.dtsi" +#include "mvebu-linkstation-gpio-simple.dtsi" +#include "mvebu-linkstation-fan.dtsi" #include -#include -#include "orion5x-mv88f5182.dtsi" / { model = "Buffalo Linkstation LS-WTGL"; @@ -57,217 +59,93 @@ reg = <0x00000000 0x4000000>; }; - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - linux,stdout-path = &uart0; - }; - - soc { - ranges = , - , - ; - - internal-regs { - pinctrl: pinctrl@10000 { - pinctrl-0 = <&pmx_usb_power &pmx_power_hdd - &pmx_fan_low &pmx_fan_high &pmx_fan_lock>; - pinctrl-names = "default"; - - pmx_led_power: pmx-leds { - marvell,pins = "mpp0"; - marvell,function = "gpio"; - }; - - pmx_led_alarm: pmx-leds { - marvell,pins = "mpp2"; - marvell,function = "gpio"; - }; - - pmx_led_info: pmx-leds { - marvell,pins = "mpp3"; - marvell,function = "gpio"; - }; - - pmx_power_hdd: pmx-power-hdd { - marvell,pins = "mpp1"; - marvell,function = "gpio"; - }; - - pmx_usb_power: pmx-usb-power { - marvell,pins = "mpp9"; - marvell,function = "gpio"; - }; - - pmx_sata0: pmx-sata0 { - marvell,pins = "mpp12"; - marvell,function = "sata0"; - }; - - pmx_sata1: pmx-sata1 { - marvell,pins = "mpp13"; - marvell,function = "sata1"; - }; - - pmx_fan_high: pmx-fan-high { - marvell,pins = "mpp14"; - marvell,function = "gpio"; - }; - - pmx_fan_low: pmx-fan-low { - marvell,pins = "mpp17"; - marvell,function = "gpio"; - }; - - pmx_fan_lock: pmx-fan-lock { - marvell,pins = "mpp6"; - marvell,function = "gpio"; - }; - - pmx_power_switch: pmx-power-switch { - marvell,pins = "mpp8", "mpp10"; - marvell,function = "gpio"; - }; - }; - }; - }; - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_switch>; - pinctrl-names = "default"; - - button@1 { - label = "Power-on Switch"; - linux,code = ; - linux,input-type = <5>; + power-on-switch { gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; }; - button@2 { - label = "Power-auto Switch"; - linux,code = ; - linux,input-type = <5>; + power-auto-switch { gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; }; }; gpio_leds { - compatible = "gpio-leds"; - pinctrl-0 = <&pmx_led_power &pmx_led_alarm - &pmx_led_info>; - pinctrl-names = "default"; - - led@1 { - label = "lswtgl:blue:power"; + blue-power-led { gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; }; - led@2 { - label = "lswtgl:red:alarm"; + red-alarm-led { gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; }; - led@3 { - label = "lswtgl:amber:info"; + amber-info-led { gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; }; }; gpio_fan { - compatible = "gpio-fan"; - pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; - pinctrl-names = "default"; - gpios = <&gpio0 14 GPIO_ACTIVE_LOW &gpio0 17 GPIO_ACTIVE_LOW>; - gpio-fan,speed-map = <0 3 - 1500 2 - 3250 1 - 5000 0>; - - alarm-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + alarm-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; }; +}; - restart_poweroff { - compatible = "restart-poweroff"; +&pinctrl { + pmx_led_power: pmx-leds { + marvell,pins = "mpp0"; + marvell,function = "gpio"; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_hdd &pmx_usb_power>; - pinctrl-names = "default"; + pmx_power_hdd: pmx-power-hdd { + marvell,pins = "mpp1"; + marvell,function = "gpio"; + }; - usb_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; - }; + pmx_led_alarm: pmx-leds { + marvell,pins = "mpp2"; + marvell,function = "gpio"; + }; - hdd_power: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "HDD Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; - }; + pmx_led_info: pmx-leds { + marvell,pins = "mpp3"; + marvell,function = "gpio"; }; -}; -&mdio { - status = "okay"; + pmx_fan_lock: pmx-fan-lock { + marvell,pins = "mpp6"; + marvell,function = "gpio"; + }; - ethphy: ethernet-phy { - reg = <8>; + pmx_power_switch: pmx-power-switch { + marvell,pins = "mpp8", "mpp10"; + marvell,function = "gpio"; }; -}; -ð { - status = "okay"; + pmx_power_usb: pmx-power-usb { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; - ethernet-port@0 { - phy-handle = <ðphy>; + pmx_fan_high: pmx-fan-high { + marvell,pins = "mpp14"; + marvell,function = "gpio"; }; -}; -&ehci0 { - status = "okay"; + pmx_fan_low: pmx-fan-low { + marvell,pins = "mpp17"; + marvell,function = "gpio"; + }; }; -&i2c { - status = "okay"; - - rtc { - compatible = "ricoh,rs5c372a"; - reg = <0x32>; - }; +&hdd_power { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; }; -&wdt { - status = "disabled"; +&usb_power { + gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; }; &sata { - pinctrl-0 = <&pmx_sata0 &pmx_sata1>; - pinctrl-names = "default"; - status = "okay"; nr-ports = <2>; }; - -&uart0 { - status = "okay"; -}; diff --git a/arch/arm/boot/dts/orion5x-linkstation.dtsi b/arch/arm/boot/dts/orion5x-linkstation.dtsi new file mode 100644 index 000000000000..ed456ab35fd8 --- /dev/null +++ b/arch/arm/boot/dts/orion5x-linkstation.dtsi @@ -0,0 +1,180 @@ +/* + * Device Tree common file for orion5x based Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * 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 , 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 "orion5x-mv88f5182.dtsi" + +/ { + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + linux,stdout-path = &uart0; + }; + + soc { + ranges = , + , + ; + }; + + restart_poweroff { + compatible = "restart-poweroff"; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_power_usb &pmx_power_hdd>; + pinctrl-names = "default"; + + usb_power: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "USB Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + }; + + hdd_power: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "HDD Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + }; + }; +}; + +&pinctrl { + pmx_power_hdd: pmx-power-hdd { + marvell,function = "gpio"; + }; + + pmx_power_usb: pmx-power-usb { + marvell,function = "gpio"; + }; +}; + +&devbus_bootcs { + status = "okay"; + devbus,keep-config; + + flash@0 { + compatible = "jedec-flash"; + reg = <0 0x40000>; + bank-width = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + header@0 { + reg = <0 0x30000>; + read-only; + }; + + uboot@30000 { + reg = <0x30000 0xF000>; + read-only; + }; + + uboot_env@3F000 { + reg = <0x3F000 0x1000>; + }; + }; + }; +}; + +&mdio { + status = "okay"; + + ethphy: ethernet-phy { + reg = <8>; + }; +}; + +ð { + status = "okay"; + + ethernet-port@0 { + phy-handle = <ðphy>; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&i2c { + status = "okay"; + + rtc { + compatible = "ricoh,rs5c372a"; + reg = <0x32>; + }; +}; + +&wdt { + status = "disabled"; +}; + +&sata { + status = "okay"; + nr-ports = <1>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index ed521e85e208..394c43bf0ae7 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -521,6 +521,11 @@ ; interrupt-names = "ack", "err", "wakeup"; + rpmcc: clock-controller { + compatible = "qcom,rpmcc-apq8064", "qcom,rpmcc"; + #clock-cells = <1>; + }; + regulators { compatible = "qcom,rpm-pm8921-regulators"; diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi index 08214cbae16d..a33a09f6821e 100644 --- a/arch/arm/boot/dts/qcom-apq8084.dtsi +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi @@ -91,6 +91,20 @@ interrupts = <1 7 0xf04>; }; + clocks { + xo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + sleep_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + timer { compatible = "arm,armv7-timer"; interrupts = <1 2 0xf08>, diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi index fa698635eea0..2601a907947b 100644 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi @@ -62,6 +62,18 @@ }; clocks { + cxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + pxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + sleep_clk: sleep_clk { compatible = "fixed-clock"; clock-frequency = <32768>; diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi index e5f7f33aa467..a4b184db21d0 100644 --- a/arch/arm/boot/dts/qcom-msm8660.dtsi +++ b/arch/arm/boot/dts/qcom-msm8660.dtsi @@ -42,6 +42,26 @@ interrupts = <1 9 0x304>; }; + clocks { + cxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + pxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + + sleep_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + soc: soc { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index dfdafdcb8aae..c7bd2032a95d 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -14,10 +14,61 @@ #size-cells = <1>; ranges; + mpss@08000000 { + reg = <0x08000000 0x5100000>; + no-map; + }; + + mba@00d100000 { + reg = <0x0d100000 0x100000>; + no-map; + }; + + reserved@0d200000 { + reg = <0x0d200000 0xa00000>; + no-map; + }; + + adsp@0dc00000 { + reg = <0x0dc00000 0x1900000>; + no-map; + }; + + venus@0f500000 { + reg = <0x0f500000 0x500000>; + no-map; + }; + smem_region: smem@fa00000 { reg = <0xfa00000 0x200000>; no-map; }; + + tz@0fc00000 { + reg = <0x0fc00000 0x160000>; + no-map; + }; + + efs@0fd600000 { + reg = <0x0fd60000 0x1a0000>; + no-map; + }; + + unused@0ff00000 { + reg = <0x0ff00000 0x10100000>; + no-map; + }; + }; + + firmware { + compatible = "simple-bus"; + + scm { + compatible = "qcom,scm"; + clocks = <&gcc GCC_CE1_CLK> , <&gcc GCC_CE1_AXI_CLK>, + <&gcc GCC_CE1_AHB_CLK>; + clock-names = "core", "bus", "iface"; + }; }; cpus { @@ -91,6 +142,20 @@ interrupts = <1 7 0xf04>; }; + clocks { + xo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + sleep_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + timer { compatible = "arm,armv7-timer"; interrupts = <1 2 0xf08>, @@ -109,6 +174,73 @@ hwlocks = <&tcsr_mutex 3>; }; + smp2p-wcnss { + compatible = "qcom,smp2p"; + qcom,smem = <451>, <431>; + + interrupt-parent = <&intc>; + interrupts = <0 143 IRQ_TYPE_EDGE_RISING>; + + qcom,ipc = <&apcs 8 18>; + + qcom,local-pid = <0>; + qcom,remote-pid = <4>; + + wcnss_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + + #qcom,state-cells = <1>; + }; + + wcnss_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smsm { + compatible = "qcom,smsm"; + + #address-cells = <1>; + #size-cells = <0>; + + qcom,ipc-1 = <&apcs 8 13>; + qcom,ipc-2 = <&apcs 8 9>; + qcom,ipc-3 = <&apcs 8 19>; + + apps_smsm: apps@0 { + reg = <0>; + + #qcom,state-cells = <1>; + }; + + modem_smsm: modem@1 { + reg = <1>; + interrupts = <0 26 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + adsp_smsm: adsp@2 { + reg = <2>; + interrupts = <0 157 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + wcnss_smsm: wcnss@7 { + reg = <7>; + interrupts = <0 144 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + soc: soc { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi index 4657d7fb5bce..89e46ebef1bc 100644 --- a/arch/arm/boot/dts/r7s72100.dtsi +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -10,6 +10,7 @@ */ #include +#include #include / { @@ -152,12 +153,12 @@ scif0: serial@e8007000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8007000 64>; - interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>, - <0 191 IRQ_TYPE_LEVEL_HIGH>, - <0 192 IRQ_TYPE_LEVEL_HIGH>, - <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -165,12 +166,12 @@ scif1: serial@e8007800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8007800 64>; - interrupts = <0 194 IRQ_TYPE_LEVEL_HIGH>, - <0 195 IRQ_TYPE_LEVEL_HIGH>, - <0 196 IRQ_TYPE_LEVEL_HIGH>, - <0 193 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -178,12 +179,12 @@ scif2: serial@e8008000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8008000 64>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>, - <0 200 IRQ_TYPE_LEVEL_HIGH>, - <0 197 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -191,12 +192,12 @@ scif3: serial@e8008800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8008800 64>; - interrupts = <0 202 IRQ_TYPE_LEVEL_HIGH>, - <0 203 IRQ_TYPE_LEVEL_HIGH>, - <0 204 IRQ_TYPE_LEVEL_HIGH>, - <0 201 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -204,12 +205,12 @@ scif4: serial@e8009000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8009000 64>; - interrupts = <0 206 IRQ_TYPE_LEVEL_HIGH>, - <0 207 IRQ_TYPE_LEVEL_HIGH>, - <0 208 IRQ_TYPE_LEVEL_HIGH>, - <0 205 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -217,12 +218,12 @@ scif5: serial@e8009800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8009800 64>; - interrupts = <0 210 IRQ_TYPE_LEVEL_HIGH>, - <0 211 IRQ_TYPE_LEVEL_HIGH>, - <0 212 IRQ_TYPE_LEVEL_HIGH>, - <0 209 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -230,12 +231,12 @@ scif6: serial@e800a000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe800a000 64>; - interrupts = <0 214 IRQ_TYPE_LEVEL_HIGH>, - <0 215 IRQ_TYPE_LEVEL_HIGH>, - <0 216 IRQ_TYPE_LEVEL_HIGH>, - <0 213 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF6>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -243,12 +244,12 @@ scif7: serial@e800a800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe800a800 64>; - interrupts = <0 218 IRQ_TYPE_LEVEL_HIGH>, - <0 219 IRQ_TYPE_LEVEL_HIGH>, - <0 220 IRQ_TYPE_LEVEL_HIGH>, - <0 217 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF7>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -256,9 +257,9 @@ spi0: spi@e800c800 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800c800 0x24>; - interrupts = <0 238 IRQ_TYPE_LEVEL_HIGH>, - <0 239 IRQ_TYPE_LEVEL_HIGH>, - <0 240 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI0>; power-domains = <&cpg_clocks>; @@ -271,9 +272,9 @@ spi1: spi@e800d000 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800d000 0x24>; - interrupts = <0 241 IRQ_TYPE_LEVEL_HIGH>, - <0 242 IRQ_TYPE_LEVEL_HIGH>, - <0 243 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI1>; power-domains = <&cpg_clocks>; @@ -286,9 +287,9 @@ spi2: spi@e800d800 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800d800 0x24>; - interrupts = <0 244 IRQ_TYPE_LEVEL_HIGH>, - <0 245 IRQ_TYPE_LEVEL_HIGH>, - <0 246 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI2>; power-domains = <&cpg_clocks>; @@ -301,9 +302,9 @@ spi3: spi@e800e000 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800e000 0x24>; - interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>, - <0 248 IRQ_TYPE_LEVEL_HIGH>, - <0 249 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI3>; power-domains = <&cpg_clocks>; @@ -316,9 +317,9 @@ spi4: spi@e800e800 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800e800 0x24>; - interrupts = <0 250 IRQ_TYPE_LEVEL_HIGH>, - <0 251 IRQ_TYPE_LEVEL_HIGH>, - <0 252 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI4>; power-domains = <&cpg_clocks>; @@ -342,14 +343,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfee000 0x44>; - interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>, - <0 158 IRQ_TYPE_EDGE_RISING>, - <0 159 IRQ_TYPE_EDGE_RISING>, - <0 160 IRQ_TYPE_LEVEL_HIGH>, - <0 161 IRQ_TYPE_LEVEL_HIGH>, - <0 162 IRQ_TYPE_LEVEL_HIGH>, - <0 163 IRQ_TYPE_LEVEL_HIGH>, - <0 164 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C0>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -361,14 +362,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfee400 0x44>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>, - <0 166 IRQ_TYPE_EDGE_RISING>, - <0 167 IRQ_TYPE_EDGE_RISING>, - <0 168 IRQ_TYPE_LEVEL_HIGH>, - <0 169 IRQ_TYPE_LEVEL_HIGH>, - <0 170 IRQ_TYPE_LEVEL_HIGH>, - <0 171 IRQ_TYPE_LEVEL_HIGH>, - <0 172 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C1>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -380,14 +381,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfee800 0x44>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>, - <0 174 IRQ_TYPE_EDGE_RISING>, - <0 175 IRQ_TYPE_EDGE_RISING>, - <0 176 IRQ_TYPE_LEVEL_HIGH>, - <0 177 IRQ_TYPE_LEVEL_HIGH>, - <0 178 IRQ_TYPE_LEVEL_HIGH>, - <0 179 IRQ_TYPE_LEVEL_HIGH>, - <0 180 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C2>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -399,14 +400,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfeec00 0x44>; - interrupts = <0 181 IRQ_TYPE_LEVEL_HIGH>, - <0 182 IRQ_TYPE_EDGE_RISING>, - <0 183 IRQ_TYPE_EDGE_RISING>, - <0 184 IRQ_TYPE_LEVEL_HIGH>, - <0 185 IRQ_TYPE_LEVEL_HIGH>, - <0 186 IRQ_TYPE_LEVEL_HIGH>, - <0 187 IRQ_TYPE_LEVEL_HIGH>, - <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C3>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -416,7 +417,7 @@ mtu2: timer@fcff0000 { compatible = "renesas,mtu2-r7s72100", "renesas,mtu2"; reg = <0xfcff0000 0x400>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "tgi0a"; clocks = <&mstp3_clks R7S72100_CLK_MTU2>; clock-names = "fck"; diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index cb4f7b2798fe..138414a7d170 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -39,10 +39,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; dbsc1: memory-controller@e6790000 { @@ -69,27 +69,27 @@ dma0: dma-controller@e6700020 { compatible = "renesas,shdma-r8a73a4"; reg = <0 0xe6700020 0 0x89e0>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH - 0 215 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -106,7 +106,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x428>; - interrupts = <0 179 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A73A4_CLK_IIC5>; power-domains = <&pd_a3sp>; @@ -116,7 +116,7 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a73a4", "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; @@ -131,38 +131,38 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 4 IRQ_TYPE_LEVEL_HIGH>, - <0 5 IRQ_TYPE_LEVEL_HIGH>, - <0 6 IRQ_TYPE_LEVEL_HIGH>, - <0 7 IRQ_TYPE_LEVEL_HIGH>, - <0 8 IRQ_TYPE_LEVEL_HIGH>, - <0 9 IRQ_TYPE_LEVEL_HIGH>, - <0 10 IRQ_TYPE_LEVEL_HIGH>, - <0 11 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>, - <0 18 IRQ_TYPE_LEVEL_HIGH>, - <0 19 IRQ_TYPE_LEVEL_HIGH>, - <0 20 IRQ_TYPE_LEVEL_HIGH>, - <0 21 IRQ_TYPE_LEVEL_HIGH>, - <0 22 IRQ_TYPE_LEVEL_HIGH>, - <0 23 IRQ_TYPE_LEVEL_HIGH>, - <0 24 IRQ_TYPE_LEVEL_HIGH>, - <0 25 IRQ_TYPE_LEVEL_HIGH>, - <0 26 IRQ_TYPE_LEVEL_HIGH>, - <0 27 IRQ_TYPE_LEVEL_HIGH>, - <0 28 IRQ_TYPE_LEVEL_HIGH>, - <0 29 IRQ_TYPE_LEVEL_HIGH>, - <0 30 IRQ_TYPE_LEVEL_HIGH>, - <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A73A4_CLK_IRQC>; power-domains = <&pd_c4>; }; @@ -172,32 +172,32 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0200 0 0x200>; - interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, - <0 33 IRQ_TYPE_LEVEL_HIGH>, - <0 34 IRQ_TYPE_LEVEL_HIGH>, - <0 35 IRQ_TYPE_LEVEL_HIGH>, - <0 36 IRQ_TYPE_LEVEL_HIGH>, - <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>, - <0 39 IRQ_TYPE_LEVEL_HIGH>, - <0 40 IRQ_TYPE_LEVEL_HIGH>, - <0 41 IRQ_TYPE_LEVEL_HIGH>, - <0 42 IRQ_TYPE_LEVEL_HIGH>, - <0 43 IRQ_TYPE_LEVEL_HIGH>, - <0 44 IRQ_TYPE_LEVEL_HIGH>, - <0 45 IRQ_TYPE_LEVEL_HIGH>, - <0 46 IRQ_TYPE_LEVEL_HIGH>, - <0 47 IRQ_TYPE_LEVEL_HIGH>, - <0 48 IRQ_TYPE_LEVEL_HIGH>, - <0 49 IRQ_TYPE_LEVEL_HIGH>, - <0 50 IRQ_TYPE_LEVEL_HIGH>, - <0 51 IRQ_TYPE_LEVEL_HIGH>, - <0 52 IRQ_TYPE_LEVEL_HIGH>, - <0 53 IRQ_TYPE_LEVEL_HIGH>, - <0 54 IRQ_TYPE_LEVEL_HIGH>, - <0 55 IRQ_TYPE_LEVEL_HIGH>, - <0 56 IRQ_TYPE_LEVEL_HIGH>, - <0 57 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A73A4_CLK_IRQC>; power-domains = <&pd_c4>; }; @@ -237,7 +237,7 @@ compatible = "renesas,thermal-r8a73a4", "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>, <0 0xe61f0200 0 0x38>, <0 0xe61f0300 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A73A4_CLK_THERMAL>; power-domains = <&pd_c5>; }; @@ -247,7 +247,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x428>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC0>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -258,7 +258,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x428>; - interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC1>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -269,7 +269,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6520000 0 0x428>; - interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC2>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -280,7 +280,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6530000 0 0x428>; - interrupts = <0 177 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A73A4_CLK_IIC3>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -291,7 +291,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6540000 0 0x428>; - interrupts = <0 178 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A73A4_CLK_IIC4>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -302,7 +302,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6550000 0 0x428>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC6>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -313,7 +313,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6560000 0 0x428>; - interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC7>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -324,7 +324,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6570000 0 0x428>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A73A4_CLK_IIC8>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -333,9 +333,9 @@ scifb0: serial@e6c20000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6c20000 0 0x100>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -343,9 +343,9 @@ scifb1: serial@e6c30000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6c30000 0 0x100>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -353,9 +353,9 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a73a4", "renesas,scifa"; reg = <0 0xe6c40000 0 0x100>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -363,9 +363,9 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-r8a73a4", "renesas,scifa"; reg = <0 0xe6c50000 0 0x100>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -373,9 +373,9 @@ scifb2: serial@e6ce0000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6ce0000 0 0x100>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -383,9 +383,9 @@ scifb3: serial@e6cf0000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6cf0000 0 0x100>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_c4>; status = "disabled"; }; @@ -393,7 +393,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee100000 0 0x100>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_SDHI0>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -403,7 +403,7 @@ sdhi1: sd@ee120000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee120000 0 0x100>; - interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_SDHI1>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -413,7 +413,7 @@ sdhi2: sd@ee140000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_SDHI2>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -423,7 +423,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_MMCIF0>; power-domains = <&pd_a3sp>; reg-io-width = <4>; @@ -433,7 +433,7 @@ mmcif1: mmc@ee220000 { compatible = "renesas,sh-mmcif"; reg = <0 0xee220000 0 0x80>; - interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_MMCIF1>; power-domains = <&pd_a3sp>; reg-io-width = <4>; @@ -449,7 +449,7 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; bsc: bus@fec10000 { diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index 6ef954766eef..995fbda74b7a 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -11,6 +11,7 @@ /include/ "skeleton.dtsi" #include +#include #include / { @@ -41,7 +42,7 @@ L2: cache-controller { compatible = "arm,pl310-cache"; reg = <0xf0100000 0x1000>; - interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; power-domains = <&pd_a3sm>; arm,data-latency = <3 3 3>; arm,tag-latency = <2 2 2>; @@ -58,7 +59,7 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; ptm { @@ -69,7 +70,7 @@ cmt1: timer@e6138000 { compatible = "renesas,cmt-48-r8a7740", "renesas,cmt-48"; reg = <0xe6138000 0x170>; - interrupts = <0 58 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; @@ -89,14 +90,14 @@ <0xe6900020 1>, <0xe6900040 1>, <0xe6900060 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -111,14 +112,14 @@ <0xe6900024 1>, <0xe6900044 1>, <0xe6900064 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -133,14 +134,14 @@ <0xe6900028 1>, <0xe6900048 1>, <0xe6900068 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -155,14 +156,14 @@ <0xe690002c 1>, <0xe690004c 1>, <0xe690006c 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -171,7 +172,7 @@ compatible = "renesas,gether-r8a7740"; reg = <0xe9a00000 0x800>, <0xe9a01800 0x800>; - interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_GETHER>; power-domains = <&pd_a4s>; phy-mode = "mii"; @@ -185,10 +186,10 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7740", "renesas,rmobile-iic"; reg = <0xfff20000 0x425>; - interrupts = <0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7740_CLK_IIC0>; power-domains = <&pd_a4r>; status = "disabled"; @@ -199,10 +200,10 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7740", "renesas,rmobile-iic"; reg = <0xe6c20000 0x425>; - interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH - 0 71 IRQ_TYPE_LEVEL_HIGH - 0 72 IRQ_TYPE_LEVEL_HIGH - 0 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_IIC1>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -211,9 +212,9 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c40000 0x100>; - interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -221,9 +222,9 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c50000 0x100>; - interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -231,9 +232,9 @@ scifa2: serial@e6c60000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c60000 0x100>; - interrupts = <0 102 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -241,9 +242,9 @@ scifa3: serial@e6c70000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c70000 0x100>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -251,9 +252,9 @@ scifa4: serial@e6c80000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c80000 0x100>; - interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -261,9 +262,9 @@ scifa5: serial@e6cb0000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6cb0000 0x100>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -271,9 +272,9 @@ scifa6: serial@e6cc0000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6cc0000 0x100>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA6>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -281,9 +282,9 @@ scifa7: serial@e6cd0000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6cd0000 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA7>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -291,9 +292,9 @@ scifb: serial@e6c30000 { compatible = "renesas,scifb-r8a7740", "renesas,scifb"; reg = <0xe6c30000 0x100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFB>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -329,8 +330,8 @@ mmcif0: mmc@e6bd0000 { compatible = "renesas,mmcif-r8a7740", "renesas,sh-mmcif"; reg = <0xe6bd0000 0x100>; - interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH - 0 57 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_MMC>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -339,9 +340,9 @@ sdhi0: sd@e6850000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6850000 0x100>; - interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH - 0 118 IRQ_TYPE_LEVEL_HIGH - 0 119 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_SDHI0>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -352,9 +353,9 @@ sdhi1: sd@e6860000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6860000 0x100>; - interrupts = <0 121 IRQ_TYPE_LEVEL_HIGH - 0 122 IRQ_TYPE_LEVEL_HIGH - 0 123 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_SDHI1>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -365,9 +366,9 @@ sdhi2: sd@e6870000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6870000 0x100>; - interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH - 0 126 IRQ_TYPE_LEVEL_HIGH - 0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A7740_CLK_SDHI2>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -379,7 +380,7 @@ #sound-dai-cells = <1>; compatible = "renesas,fsi2-r8a7740", "renesas,sh_fsi2"; reg = <0xfe1f0000 0x400>; - interrupts = <0 9 0x4>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_FSI>; power-domains = <&pd_a4mp>; status = "disabled"; @@ -388,9 +389,9 @@ tmu0: timer@fff80000 { compatible = "renesas,tmu-r8a7740", "renesas,tmu"; reg = <0xfff80000 0x2c>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>, - <0 200 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp1_clks R8A7740_CLK_TMU0>; clock-names = "fck"; power-domains = <&pd_a4r>; @@ -403,9 +404,9 @@ tmu1: timer@fff90000 { compatible = "renesas,tmu-r8a7740", "renesas,tmu"; reg = <0xfff90000 0x2c>; - interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>, - <0 171 IRQ_TYPE_LEVEL_HIGH>, - <0 172 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp1_clks R8A7740_CLK_TMU1>; clock-names = "fck"; power-domains = <&pd_a4r>; diff --git a/arch/arm/boot/dts/r8a7778-bockw.dts b/arch/arm/boot/dts/r8a7778-bockw.dts index a52b359e2ae2..21e3b9dda2da 100644 --- a/arch/arm/boot/dts/r8a7778-bockw.dts +++ b/arch/arm/boot/dts/r8a7778-bockw.dts @@ -126,11 +126,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif0_pins: serial0 { renesas,groups = "scif0_data_a", "scif0_ctrl"; renesas,function = "scif0"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + mmc_pins: mmc { renesas,groups = "mmc_data8", "mmc_ctrl"; renesas,function = "mmc"; @@ -217,3 +225,8 @@ status = "okay"; }; + +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index 791aafd310a5..f83a348fc07a 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -17,6 +17,7 @@ /include/ "skeleton.dtsi" #include +#include #include / { @@ -51,7 +52,7 @@ ether: ethernet@fde00000 { compatible = "renesas,ether-r8a7778"; reg = <0xfde00000 0x400>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7778_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -79,17 +80,17 @@ <0xfe780024 4>, <0xfe780044 4>, <0xfe780064 4>; - interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH - 0 28 IRQ_TYPE_LEVEL_HIGH - 0 29 IRQ_TYPE_LEVEL_HIGH - 0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; sense-bitfield-width = <2>; }; gpio0: gpio@ffc40000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc40000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -100,7 +101,7 @@ gpio1: gpio@ffc41000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc41000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 32>; @@ -111,7 +112,7 @@ gpio2: gpio@ffc42000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc42000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -122,7 +123,7 @@ gpio3: gpio@ffc43000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc43000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -133,7 +134,7 @@ gpio4: gpio@ffc44000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc44000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 27>; @@ -151,7 +152,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc70000 0x1000>; - interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -162,7 +163,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc71000 0x1000>; - interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -173,7 +174,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc72000 0x1000>; - interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -184,7 +185,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc73000 0x1000>; - interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C3>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -193,9 +194,9 @@ tmu0: timer@ffd80000 { compatible = "renesas,tmu-r8a7778", "renesas,tmu"; reg = <0xffd80000 0x30>; - interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, - <0 33 IRQ_TYPE_LEVEL_HIGH>, - <0 34 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7778_CLK_TMU0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -208,9 +209,9 @@ tmu1: timer@ffd81000 { compatible = "renesas,tmu-r8a7778", "renesas,tmu"; reg = <0xffd81000 0x30>; - interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>, - <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7778_CLK_TMU1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -223,9 +224,9 @@ tmu2: timer@ffd82000 { compatible = "renesas,tmu-r8a7778", "renesas,tmu"; reg = <0xffd82000 0x30>; - interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>, - <0 41 IRQ_TYPE_LEVEL_HIGH>, - <0 42 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7778_CLK_TMU2>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -285,72 +286,84 @@ }; rcar_sound,ssi { - ssi3: ssi@3 { interrupts = <0 0x85 IRQ_TYPE_LEVEL_HIGH>; }; - ssi4: ssi@4 { interrupts = <0 0x85 IRQ_TYPE_LEVEL_HIGH>; }; - ssi5: ssi@5 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi6: ssi@6 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi7: ssi@7 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi8: ssi@8 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi9: ssi@9 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; + ssi3: ssi@3 { interrupts = ; }; + ssi4: ssi@4 { interrupts = ; }; + ssi5: ssi@5 { interrupts = ; }; + ssi6: ssi@6 { interrupts = ; }; + ssi7: ssi@7 { interrupts = ; }; + ssi8: ssi@8 { interrupts = ; }; + ssi9: ssi@9 { interrupts = ; }; }; }; scif0: serial@ffe40000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe40000 0x100>; - interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF0>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif1: serial@ffe41000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe41000 0x100>; - interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF1>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif2: serial@ffe42000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe42000 0x100>; - interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF2>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif3: serial@ffe43000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe43000 0x100>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF3>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF3>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif4: serial@ffe44000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe44000 0x100>; - interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF4>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF4>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif5: serial@ffe45000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe45000 0x100>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF5>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF5>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -358,7 +371,7 @@ mmcif: mmc@ffe4e000 { compatible = "renesas,sh-mmcif"; reg = <0xffe4e000 0x100>; - interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_MMC>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -367,7 +380,7 @@ sdhi0: sd@ffe4c000 { compatible = "renesas,sdhi-r8a7778"; reg = <0xffe4c000 0x100>; - interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_SDHI0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -376,7 +389,7 @@ sdhi1: sd@ffe4d000 { compatible = "renesas,sdhi-r8a7778"; reg = <0xffe4d000 0x100>; - interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_SDHI1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -385,7 +398,7 @@ sdhi2: sd@ffe4f000 { compatible = "renesas,sdhi-r8a7778"; reg = <0xffe4f000 0x100>; - interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_SDHI2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -394,7 +407,7 @@ hspi0: spi@fffc7000 { compatible = "renesas,hspi-r8a7778", "renesas,hspi"; reg = <0xfffc7000 0x18>; - interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_HSPI>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -405,7 +418,7 @@ hspi1: spi@fffc8000 { compatible = "renesas,hspi-r8a7778", "renesas,hspi"; reg = <0xfffc8000 0x18>; - interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_HSPI>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -416,7 +429,7 @@ hspi2: spi@fffc6000 { compatible = "renesas,hspi-r8a7778", "renesas,hspi"; reg = <0xfffc6000 0x18>; - interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_HSPI>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -437,6 +450,15 @@ clock-output-names = "extal"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: cpg_clocks@ffc80000 { compatible = "renesas,r8a7778-cpg-clocks"; diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts index fe396c8d58db..e111d35d02ae 100644 --- a/arch/arm/boot/dts/r8a7779-marzen.dts +++ b/arch/arm/boot/dts/r8a7779-marzen.dts @@ -165,6 +165,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + du_pins: du { du0 { renesas,groups = "du0_rgb888", "du0_sync_1", "du0_clk_out_0"; @@ -176,6 +179,11 @@ }; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk_b"; + renesas,function = "scif_clk"; + }; + ethernet_pins: ethernet { intc { renesas,groups = "intc_irq1_b"; @@ -222,6 +230,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &sdhi0 { pinctrl-0 = <&sdhi0_pins>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 6afa909865b5..a0cc08e6295b 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -74,7 +74,7 @@ gpio0: gpio@ffc40000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc40000 0x2c>; - interrupts = <0 141 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -85,7 +85,7 @@ gpio1: gpio@ffc41000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc41000 0x2c>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 32>; @@ -96,7 +96,7 @@ gpio2: gpio@ffc42000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc42000 0x2c>; - interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -107,7 +107,7 @@ gpio3: gpio@ffc43000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc43000 0x2c>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -118,7 +118,7 @@ gpio4: gpio@ffc44000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc44000 0x2c>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -129,7 +129,7 @@ gpio5: gpio@ffc45000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc45000 0x2c>; - interrupts = <0 146 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -140,7 +140,7 @@ gpio6: gpio@ffc46000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc46000 0x2c>; - interrupts = <0 147 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 9>; @@ -159,10 +159,10 @@ <0xfe780044 4>, <0xfe780064 4>, <0xfe780000 4>; - interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH - 0 28 IRQ_TYPE_LEVEL_HIGH - 0 29 IRQ_TYPE_LEVEL_HIGH - 0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; sense-bitfield-width = <2>; }; @@ -171,7 +171,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc70000 0x1000>; - interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -182,7 +182,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc71000 0x1000>; - interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -193,7 +193,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc72000 0x1000>; - interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -204,68 +204,80 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc73000 0x1000>; - interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C3>; power-domains = <&cpg_clocks>; status = "disabled"; }; scif0: serial@ffe40000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe40000 0x100>; - interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF0>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif1: serial@ffe41000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe41000 0x100>; - interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF1>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif2: serial@ffe42000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe42000 0x100>; - interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF2>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif3: serial@ffe43000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe43000 0x100>; - interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF3>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF3>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif4: serial@ffe44000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe44000 0x100>; - interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF4>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF4>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif5: serial@ffe45000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe45000 0x100>; - interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF5>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF5>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -283,9 +295,9 @@ tmu0: timer@ffd80000 { compatible = "renesas,tmu-r8a7779", "renesas,tmu"; reg = <0xffd80000 0x30>; - interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, - <0 33 IRQ_TYPE_LEVEL_HIGH>, - <0 34 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7779_CLK_TMU0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -298,9 +310,9 @@ tmu1: timer@ffd81000 { compatible = "renesas,tmu-r8a7779", "renesas,tmu"; reg = <0xffd81000 0x30>; - interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>, - <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7779_CLK_TMU1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -313,9 +325,9 @@ tmu2: timer@ffd82000 { compatible = "renesas,tmu-r8a7779", "renesas,tmu"; reg = <0xffd82000 0x30>; - interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>, - <0 41 IRQ_TYPE_LEVEL_HIGH>, - <0 42 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7779_CLK_TMU2>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -328,7 +340,7 @@ sata: sata@fc600000 { compatible = "renesas,sata-r8a7779", "renesas,rcar-sata"; reg = <0xfc600000 0x2000>; - interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7779_CLK_SATA>; power-domains = <&cpg_clocks>; }; @@ -336,7 +348,7 @@ sdhi0: sd@ffe4c000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4c000 0x100>; - interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -345,7 +357,7 @@ sdhi1: sd@ffe4d000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4d000 0x100>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -354,7 +366,7 @@ sdhi2: sd@ffe4e000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4e000 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -363,7 +375,7 @@ sdhi3: sd@ffe4f000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4f000 0x100>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI3>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -372,7 +384,7 @@ hspi0: spi@fffc7000 { compatible = "renesas,hspi-r8a7779", "renesas,hspi"; reg = <0xfffc7000 0x18>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; clocks = <&mstp0_clks R8A7779_CLK_HSPI>; @@ -383,7 +395,7 @@ hspi1: spi@fffc8000 { compatible = "renesas,hspi-r8a7779", "renesas,hspi"; reg = <0xfffc8000 0x18>; - interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; clocks = <&mstp0_clks R8A7779_CLK_HSPI>; @@ -394,7 +406,7 @@ hspi2: spi@fffc6000 { compatible = "renesas,hspi-r8a7779", "renesas,hspi"; reg = <0xfffc6000 0x18>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; clocks = <&mstp0_clks R8A7779_CLK_HSPI>; @@ -405,7 +417,7 @@ du: display@fff80000 { compatible = "renesas,du-r8a7779"; reg = <0 0xfff80000 0 0x40000>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7779_CLK_DU>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -441,6 +453,15 @@ clock-output-names = "extal"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: clocks@ffc80000 { compatible = "renesas,r8a7779-cpg-clocks"; diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 052dcee4790d..cdc0414f5f07 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -291,6 +291,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + du_pins: du { renesas,groups = "du_rgb666", "du_sync_1", "du_clk_out_0"; renesas,function = "du"; @@ -301,6 +304,11 @@ renesas,function = "scif0"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -485,6 +493,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &msiof1 { pinctrl-0 = <&msiof1_pins>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 7dfd393bfc7e..c9583fa6cae7 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -121,13 +121,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -140,7 +140,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 30>; @@ -153,7 +153,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 30>; @@ -166,7 +166,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -179,7 +179,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -192,7 +192,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -205,24 +205,24 @@ thermal@e61f0000 { compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A7790_CLK_THERMAL>; power-domains = <&cpg_clocks>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7790_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -235,14 +235,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2"; 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>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7790_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -257,10 +257,10 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R8A7790_CLK_IRQC>; power-domains = <&cpg_clocks>; }; @@ -268,22 +268,22 @@ dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -299,22 +299,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -330,20 +330,20 @@ audma0: dma-controller@ec700000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xec700000 0 0x10000>; - interrupts = <0 346 IRQ_TYPE_LEVEL_HIGH - 0 320 IRQ_TYPE_LEVEL_HIGH - 0 321 IRQ_TYPE_LEVEL_HIGH - 0 322 IRQ_TYPE_LEVEL_HIGH - 0 323 IRQ_TYPE_LEVEL_HIGH - 0 324 IRQ_TYPE_LEVEL_HIGH - 0 325 IRQ_TYPE_LEVEL_HIGH - 0 326 IRQ_TYPE_LEVEL_HIGH - 0 327 IRQ_TYPE_LEVEL_HIGH - 0 328 IRQ_TYPE_LEVEL_HIGH - 0 329 IRQ_TYPE_LEVEL_HIGH - 0 330 IRQ_TYPE_LEVEL_HIGH - 0 331 IRQ_TYPE_LEVEL_HIGH - 0 332 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -359,20 +359,20 @@ audma1: dma-controller@ec720000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xec720000 0 0x10000>; - interrupts = <0 347 IRQ_TYPE_LEVEL_HIGH - 0 333 IRQ_TYPE_LEVEL_HIGH - 0 334 IRQ_TYPE_LEVEL_HIGH - 0 335 IRQ_TYPE_LEVEL_HIGH - 0 336 IRQ_TYPE_LEVEL_HIGH - 0 337 IRQ_TYPE_LEVEL_HIGH - 0 338 IRQ_TYPE_LEVEL_HIGH - 0 339 IRQ_TYPE_LEVEL_HIGH - 0 340 IRQ_TYPE_LEVEL_HIGH - 0 341 IRQ_TYPE_LEVEL_HIGH - 0 342 IRQ_TYPE_LEVEL_HIGH - 0 343 IRQ_TYPE_LEVEL_HIGH - 0 344 IRQ_TYPE_LEVEL_HIGH - 0 345 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -388,8 +388,8 @@ usb_dmac0: dma-controller@e65a0000 { compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65a0000 0 0x100>; - interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH - 0 109 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7790_CLK_USBDMAC0>; power-domains = <&cpg_clocks>; @@ -400,8 +400,8 @@ usb_dmac1: dma-controller@e65b0000 { compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65b0000 0 0x100>; - interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH - 0 110 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7790_CLK_USBDMAC1>; power-domains = <&cpg_clocks>; @@ -414,7 +414,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C0>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <110>; @@ -426,7 +426,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6518000 0 0x40>; - interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C1>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -438,7 +438,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6530000 0 0x40>; - interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C2>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -450,7 +450,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6540000 0 0x40>; - interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C3>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <110>; @@ -462,7 +462,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x425>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_IIC0>; dmas = <&dmac0 0x61>, <&dmac0 0x62>; dma-names = "tx", "rx"; @@ -475,7 +475,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x425>; - interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_IIC1>; dmas = <&dmac0 0x65>, <&dmac0 0x66>; dma-names = "tx", "rx"; @@ -488,7 +488,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe6520000 0 0x425>; - interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_IIC2>; dmas = <&dmac0 0x69>, <&dmac0 0x6a>; dma-names = "tx", "rx"; @@ -501,7 +501,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x425>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_IICDVFS>; dmas = <&dmac0 0x77>, <&dmac0 0x78>; dma-names = "tx", "rx"; @@ -512,7 +512,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>; dmas = <&dmac0 0xd1>, <&dmac0 0xd2>; dma-names = "tx", "rx"; @@ -525,7 +525,7 @@ mmcif1: mmc@ee220000 { compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif"; reg = <0 0xee220000 0 0x80>; - interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>; dmas = <&dmac0 0xe1>, <&dmac0 0xe2>; dma-names = "tx", "rx"; @@ -543,7 +543,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee100000 0 0x328>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI0>; dmas = <&dmac1 0xcd>, <&dmac1 0xce>; dma-names = "tx", "rx"; @@ -554,7 +554,7 @@ sdhi1: sd@ee120000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee120000 0 0x328>; - interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI1>; dmas = <&dmac1 0xc9>, <&dmac1 0xca>; dma-names = "tx", "rx"; @@ -565,7 +565,7 @@ sdhi2: sd@ee140000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI2>; dmas = <&dmac1 0xc1>, <&dmac1 0xc2>; dma-names = "tx", "rx"; @@ -576,7 +576,7 @@ sdhi3: sd@ee160000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee160000 0 0x100>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI3>; dmas = <&dmac1 0xd3>, <&dmac1 0xd4>; dma-names = "tx", "rx"; @@ -585,11 +585,12 @@ }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa"; + compatible = "renesas,scifa-r8a7790", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -597,11 +598,12 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa"; + compatible = "renesas,scifa-r8a7790", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -609,11 +611,12 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa"; + compatible = "renesas,scifa-r8a7790", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -621,11 +624,12 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7790", "renesas,scifb"; + compatible = "renesas,scifb-r8a7790", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -633,11 +637,12 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7790", "renesas,scifb"; + compatible = "renesas,scifb-r8a7790", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -645,11 +650,12 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7790", "renesas,scifb"; + compatible = "renesas,scifb-r8a7790", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -657,11 +663,13 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7790", "renesas,scif"; + compatible = "renesas,scif-r8a7790", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7790_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7790_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -669,11 +677,13 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7790", "renesas,scif"; + compatible = "renesas,scif-r8a7790", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7790_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7790_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -681,11 +691,13 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7790", "renesas,hscif"; + compatible = "renesas,hscif-r8a7790", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -693,11 +705,13 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7790", "renesas,hscif"; + compatible = "renesas,hscif-r8a7790", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -707,7 +721,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7790"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -719,7 +733,7 @@ avb: ethernet@e6800000 { compatible = "renesas,etheravb-r8a7790"; reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>; - interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_ETHERAVB>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -730,7 +744,7 @@ sata0: sata@ee300000 { compatible = "renesas,sata-r8a7790"; reg = <0 0xee300000 0 0x2000>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_SATA0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -739,16 +753,16 @@ sata1: sata@ee500000 { compatible = "renesas,sata-r8a7790"; reg = <0 0xee500000 0 0x2000>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_SATA1>; power-domains = <&cpg_clocks>; status = "disabled"; }; hsusb: usb@e6590000 { - compatible = "renesas,usbhs-r8a7790"; + compatible = "renesas,usbhs-r8a7790", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_HSUSB>; dmas = <&usb_dmac0 0>, <&usb_dmac0 1>, <&usb_dmac1 0>, <&usb_dmac1 1>; @@ -783,7 +797,7 @@ vin0: video@e6ef0000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef0000 0 0x1000>; - interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -792,7 +806,7 @@ vin1: video@e6ef1000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef1000 0 0x1000>; - interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -801,7 +815,7 @@ vin2: video@e6ef2000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef2000 0 0x1000>; - interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -810,7 +824,7 @@ vin3: video@e6ef3000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef3000 0 0x1000>; - interrupts = <0 191 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN3>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -819,7 +833,7 @@ vsp1@fe920000 { compatible = "renesas,vsp1"; reg = <0 0xfe920000 0 0x8000>; - interrupts = <0 266 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_R>; power-domains = <&cpg_clocks>; @@ -832,7 +846,7 @@ vsp1@fe928000 { compatible = "renesas,vsp1"; reg = <0 0xfe928000 0 0x8000>; - interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>; power-domains = <&cpg_clocks>; @@ -846,7 +860,7 @@ vsp1@fe930000 { compatible = "renesas,vsp1"; reg = <0 0xfe930000 0 0x8000>; - interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU0>; power-domains = <&cpg_clocks>; @@ -860,7 +874,7 @@ vsp1@fe938000 { compatible = "renesas,vsp1"; reg = <0 0xfe938000 0 0x8000>; - interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU1>; power-domains = <&cpg_clocks>; @@ -877,9 +891,9 @@ <0 0xfeb90000 0 0x1c>, <0 0xfeb94000 0 0x1c>; reg-names = "du", "lvds.0", "lvds.1"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>, - <0 269 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp7_clks R8A7790_CLK_DU0>, <&mstp7_clks R8A7790_CLK_DU1>, <&mstp7_clks R8A7790_CLK_DU2>, @@ -913,7 +927,7 @@ can0: can@e6e80000 { compatible = "renesas,can-r8a7790"; reg = <0 0xe6e80000 0 0x1000>; - interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_RCAN0>, <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -924,7 +938,7 @@ can1: can@e6e88000 { compatible = "renesas,can-r8a7790"; reg = <0 0xe6e88000 0 0x1000>; - interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_RCAN1>, <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -935,7 +949,7 @@ jpu: jpeg-codec@fe980000 { compatible = "renesas,jpu-r8a7790"; reg = <0 0xfe980000 0 0x10300>; - interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_JPU>; power-domains = <&cpg_clocks>; }; @@ -986,6 +1000,15 @@ clock-output-names = "audio_clk_c"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* External USB clock - can be overridden by the board */ usb_extal_clk: usb_extal_clk { compatible = "fixed-clock"; @@ -1401,7 +1424,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7790", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -1415,7 +1438,7 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6e20000 0 0x0064>; - interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7790_CLK_MSIOF0>; dmas = <&dmac0 0x51>, <&dmac0 0x52>; dma-names = "tx", "rx"; @@ -1428,7 +1451,7 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6e10000 0 0x0064>; - interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_MSIOF1>; dmas = <&dmac0 0x55>, <&dmac0 0x56>; dma-names = "tx", "rx"; @@ -1441,7 +1464,7 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6e00000 0 0x0064>; - interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_MSIOF2>; dmas = <&dmac0 0x41>, <&dmac0 0x42>; dma-names = "tx", "rx"; @@ -1454,7 +1477,7 @@ msiof3: spi@e6c90000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6c90000 0 0x0064>; - interrupts = <0 159 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_MSIOF3>; dmas = <&dmac0 0x45>, <&dmac0 0x46>; dma-names = "tx", "rx"; @@ -1467,7 +1490,7 @@ xhci: usb@ee000000 { compatible = "renesas,xhci-r8a7790"; reg = <0 0xee000000 0 0xc00>; - interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SSUSB>; power-domains = <&cpg_clocks>; phys = <&usb2 1>; @@ -1480,7 +1503,7 @@ device_type = "pci"; reg = <0 0xee090000 0 0xc00>, <0 0xee080000 0 0x1100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1491,9 +1514,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1515,7 +1538,7 @@ device_type = "pci"; reg = <0 0xee0b0000 0 0xc00>, <0 0xee0a0000 0 0x1100>; - interrupts = <0 112 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1526,9 +1549,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0a0000 0 0xee0a0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 112 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 112 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 112 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; }; pci2: pci@ee0d0000 { @@ -1538,7 +1561,7 @@ power-domains = <&cpg_clocks>; reg = <0 0xee0d0000 0 0xc00>, <0 0xee0c0000 0 0x1100>; - interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; status = "disabled"; bus-range = <2 2>; @@ -1547,9 +1570,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1580,12 +1603,12 @@ /* Map all possible DDR as inbound ranges */ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000 0x43000000 1 0x80000000 1 0x80000000 0 0x80000000>; - interrupts = <0 116 IRQ_TYPE_LEVEL_HIGH>, - <0 117 IRQ_TYPE_LEVEL_HIGH>, - <0 118 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp3_clks R8A7790_CLK_PCIEC>, <&pcie_bus_clk>; clock-names = "pcie", "pcie_bus"; power-domains = <&cpg_clocks>; @@ -1664,52 +1687,52 @@ rcar_sound,src { src0: src@0 { - interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; src1: src@1 { - interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x87>, <&audma1 0x9c>; dma-names = "rx", "tx"; }; src2: src@2 { - interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x89>, <&audma1 0x9e>; dma-names = "rx", "tx"; }; src3: src@3 { - interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8b>, <&audma1 0xa0>; dma-names = "rx", "tx"; }; src4: src@4 { - interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8d>, <&audma1 0xb0>; dma-names = "rx", "tx"; }; src5: src@5 { - interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8f>, <&audma1 0xb2>; dma-names = "rx", "tx"; }; src6: src@6 { - interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x91>, <&audma1 0xb4>; dma-names = "rx", "tx"; }; src7: src@7 { - interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x93>, <&audma1 0xb6>; dma-names = "rx", "tx"; }; src8: src@8 { - interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x95>, <&audma1 0xb8>; dma-names = "rx", "tx"; }; src9: src@9 { - interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x97>, <&audma1 0xba>; dma-names = "rx", "tx"; }; @@ -1717,52 +1740,52 @@ rcar_sound,ssi { ssi0: ssi@0 { - interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi1: ssi@1 { - interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi2: ssi@2 { - interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi3: ssi@3 { - interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi4: ssi@4 { - interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi5: ssi@5 { - interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi6: ssi@6 { - interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi7: ssi@7 { - interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi8: ssi@8 { - interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi9: ssi@9 { - interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dma-names = "rx", "tx", "rxu", "txu"; }; @@ -1772,8 +1795,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1781,7 +1804,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1789,8 +1812,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1798,7 +1821,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1806,8 +1829,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1815,7 +1838,7 @@ ipmmu_rt: mmu@ffc80000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; - interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 45256f3cc835..0ad71b81d3a2 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -320,6 +320,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + i2c2_pins: i2c2 { renesas,groups = "i2c2"; renesas,function = "i2c2"; @@ -340,6 +343,11 @@ renesas,function = "scif1"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -440,6 +448,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &sdhi0 { pinctrl-0 = <&sdhi0_pins>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts index 6713b1ea732b..ed1f6f884e2b 100644 --- a/arch/arm/boot/dts/r8a7791-porter.dts +++ b/arch/arm/boot/dts/r8a7791-porter.dts @@ -8,6 +8,17 @@ * kind, whether express or implied. */ +/* + * SSI-AK4642 + * + * SW3: 1: AK4642 + * 3: ADV7511 + * + * This command is required before playback/capture: + * + * amixer set "LINEOUT Mixer DACL" on + */ + /dts-v1/; #include "r8a7791.dtsi" #include @@ -78,6 +89,53 @@ states = <3300000 1 1800000 0>; }; + + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7511_out>; + }; + }; + }; + + x3_clk: x3-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <148500000>; + }; + + x16_clk: x16-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; + + x14_clk: x14-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <11289600>; + clock-output-names = "audio_clock"; + }; + + sound { + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&soundcodec>; + simple-audio-card,frame-master = <&soundcodec>; + + simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + soundcodec: simple-audio-card,codec { + sound-dai = <&ak4642>; + clocks = <&x14_clk>; + }; + }; }; &extal_clk { @@ -85,11 +143,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif0_pins: serial0 { renesas,groups = "scif0_data_d"; renesas,function = "scif0"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -139,6 +205,21 @@ renesas,groups = "can0_data"; renesas,function = "can0"; }; + + du_pins: du { + renesas,groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0"; + renesas,function = "du"; + }; + + ssi_pins: sound { + renesas,groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data"; + renesas,function = "ssi"; + }; + + audio_clk_pins: audio_clk { + renesas,groups = "audio_clk_a"; + renesas,function = "audio_clk"; + }; }; &scif0 { @@ -148,6 +229,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + ðer { pinctrl-0 = <ðer_pins &phy1_pins>; pinctrl-names = "default"; @@ -229,6 +315,12 @@ status = "okay"; clock-frequency = <400000>; + ak4642: codec@12 { + compatible = "asahi-kasei,ak4642"; + #sound-dai-cells = <0>; + reg = <0x12>; + }; + composite-in@20 { compatible = "adi,adv7180"; reg = <0x20>; @@ -241,6 +333,38 @@ }; }; }; + + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio3>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_rgb>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; }; &sata0 { @@ -304,3 +428,44 @@ status = "okay"; }; + +&du { + pinctrl-0 = <&du_pins>; + pinctrl-names = "default"; + status = "okay"; + + clocks = <&mstp7_clks R8A7791_CLK_DU0>, + <&mstp7_clks R8A7791_CLK_DU1>, + <&mstp7_clks R8A7791_CLK_LVDS0>, + <&x3_clk>, <&x16_clk>; + clock-names = "du.0", "du.1", "lvds.0", + "dclkin.0", "dclkin.1"; + + ports { + port@1 { + endpoint { + remote-endpoint = <&adv7511_in>; + }; + }; + }; +}; + +&rcar_sound { + pinctrl-0 = <&ssi_pins &audio_clk_pins>; + pinctrl-names = "default"; + status = "okay"; + + /* Single DAI */ + #sound-dai-cells = <0>; + + rcar_sound,dai { + dai0 { + playback = <&ssi0>; + capture = <&ssi1>; + }; + }; +}; + +&ssi1 { + shared-pin; +}; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 2a369ddcb6fd..14aa62539ff2 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -78,13 +78,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -97,7 +97,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 26>; @@ -110,7 +110,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -123,7 +123,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -136,7 +136,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -149,7 +149,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -162,7 +162,7 @@ gpio6: gpio@e6055400 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6055400 0 0x50>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 32>; @@ -175,7 +175,7 @@ gpio7: gpio@e6055800 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6055800 0 0x50>; - interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 224 26>; @@ -188,24 +188,24 @@ thermal@e61f0000 { compatible = "renesas,thermal-r8a7791", "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A7791_CLK_THERMAL>; power-domains = <&cpg_clocks>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-r8a7791", "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7791_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -218,14 +218,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a7791", "renesas,cmt-48-gen2"; 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>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7791_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -240,16 +240,16 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A7791_CLK_IRQC>; power-domains = <&cpg_clocks>; }; @@ -257,22 +257,22 @@ dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -288,22 +288,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -319,20 +319,20 @@ audma0: dma-controller@ec700000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xec700000 0 0x10000>; - interrupts = <0 346 IRQ_TYPE_LEVEL_HIGH - 0 320 IRQ_TYPE_LEVEL_HIGH - 0 321 IRQ_TYPE_LEVEL_HIGH - 0 322 IRQ_TYPE_LEVEL_HIGH - 0 323 IRQ_TYPE_LEVEL_HIGH - 0 324 IRQ_TYPE_LEVEL_HIGH - 0 325 IRQ_TYPE_LEVEL_HIGH - 0 326 IRQ_TYPE_LEVEL_HIGH - 0 327 IRQ_TYPE_LEVEL_HIGH - 0 328 IRQ_TYPE_LEVEL_HIGH - 0 329 IRQ_TYPE_LEVEL_HIGH - 0 330 IRQ_TYPE_LEVEL_HIGH - 0 331 IRQ_TYPE_LEVEL_HIGH - 0 332 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -348,20 +348,20 @@ audma1: dma-controller@ec720000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xec720000 0 0x10000>; - interrupts = <0 347 IRQ_TYPE_LEVEL_HIGH - 0 333 IRQ_TYPE_LEVEL_HIGH - 0 334 IRQ_TYPE_LEVEL_HIGH - 0 335 IRQ_TYPE_LEVEL_HIGH - 0 336 IRQ_TYPE_LEVEL_HIGH - 0 337 IRQ_TYPE_LEVEL_HIGH - 0 338 IRQ_TYPE_LEVEL_HIGH - 0 339 IRQ_TYPE_LEVEL_HIGH - 0 340 IRQ_TYPE_LEVEL_HIGH - 0 341 IRQ_TYPE_LEVEL_HIGH - 0 342 IRQ_TYPE_LEVEL_HIGH - 0 343 IRQ_TYPE_LEVEL_HIGH - 0 344 IRQ_TYPE_LEVEL_HIGH - 0 345 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -377,8 +377,8 @@ usb_dmac0: dma-controller@e65a0000 { compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65a0000 0 0x100>; - interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH - 0 109 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7791_CLK_USBDMAC0>; power-domains = <&cpg_clocks>; @@ -389,8 +389,8 @@ usb_dmac1: dma-controller@e65b0000 { compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65b0000 0 0x100>; - interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH - 0 110 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7791_CLK_USBDMAC1>; power-domains = <&cpg_clocks>; @@ -404,7 +404,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C0>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -416,7 +416,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6518000 0 0x40>; - interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C1>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -428,7 +428,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6530000 0 0x40>; - interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C2>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -440,7 +440,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6540000 0 0x40>; - interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C3>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -452,7 +452,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6520000 0 0x40>; - interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C4>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -465,7 +465,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6528000 0 0x40>; - interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C5>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <110>; @@ -478,7 +478,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x425>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_IICDVFS>; dmas = <&dmac0 0x77>, <&dmac0 0x78>; dma-names = "tx", "rx"; @@ -491,7 +491,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x425>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_IIC0>; dmas = <&dmac0 0x61>, <&dmac0 0x62>; dma-names = "tx", "rx"; @@ -504,7 +504,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x425>; - interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_IIC1>; dmas = <&dmac0 0x65>, <&dmac0 0x66>; dma-names = "tx", "rx"; @@ -520,7 +520,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,mmcif-r8a7791", "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_MMCIF0>; dmas = <&dmac0 0xd1>, <&dmac0 0xd2>; dma-names = "tx", "rx"; @@ -533,7 +533,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7791"; reg = <0 0xee100000 0 0x328>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SDHI0>; dmas = <&dmac1 0xcd>, <&dmac1 0xce>; dma-names = "tx", "rx"; @@ -544,7 +544,7 @@ sdhi1: sd@ee140000 { compatible = "renesas,sdhi-r8a7791"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SDHI1>; dmas = <&dmac1 0xc1>, <&dmac1 0xc2>; dma-names = "tx", "rx"; @@ -555,7 +555,7 @@ sdhi2: sd@ee160000 { compatible = "renesas,sdhi-r8a7791"; reg = <0 0xee160000 0 0x100>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SDHI2>; dmas = <&dmac1 0xd3>, <&dmac1 0xd4>; dma-names = "tx", "rx"; @@ -564,11 +564,12 @@ }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -576,11 +577,12 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -588,11 +590,12 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -600,11 +603,12 @@ }; scifa3: serial@e6c70000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; - interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -612,11 +616,12 @@ }; scifa4: serial@e6c78000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; - interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -624,11 +629,12 @@ }; scifa5: serial@e6c80000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -636,11 +642,12 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7791", "renesas,scifb"; + compatible = "renesas,scifb-r8a7791", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -648,11 +655,12 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7791", "renesas,scifb"; + compatible = "renesas,scifb-r8a7791", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -660,11 +668,12 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7791", "renesas,scifb"; + compatible = "renesas,scifb-r8a7791", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -672,11 +681,13 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -684,11 +695,13 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -696,11 +709,13 @@ }; scif2: serial@e6e58000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e58000 0 64>; - interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -708,11 +723,13 @@ }; scif3: serial@e6ea8000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ea8000 0 64>; - interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF3>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF3>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -720,11 +737,13 @@ }; scif4: serial@e6ee0000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee0000 0 64>; - interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF4>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF4>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -732,11 +751,13 @@ }; scif5: serial@e6ee8000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee8000 0 64>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF5>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF5>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -744,11 +765,13 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7791", "renesas,hscif"; + compatible = "renesas,hscif-r8a7791", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -756,11 +779,13 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7791", "renesas,hscif"; + compatible = "renesas,hscif-r8a7791", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -768,11 +793,13 @@ }; hscif2: serial@e62d0000 { - compatible = "renesas,hscif-r8a7791", "renesas,hscif"; + compatible = "renesas,hscif-r8a7791", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; - interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -782,7 +809,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7791"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -795,7 +822,7 @@ compatible = "renesas,etheravb-r8a7791", "renesas,etheravb-rcar-gen2"; reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>; - interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_ETHERAVB>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -806,7 +833,7 @@ sata0: sata@ee300000 { compatible = "renesas,sata-r8a7791"; reg = <0 0xee300000 0 0x2000>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_SATA0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -815,16 +842,16 @@ sata1: sata@ee500000 { compatible = "renesas,sata-r8a7791"; reg = <0 0xee500000 0 0x2000>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_SATA1>; power-domains = <&cpg_clocks>; status = "disabled"; }; hsusb: usb@e6590000 { - compatible = "renesas,usbhs-r8a7791"; + compatible = "renesas,usbhs-r8a7791", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSUSB>; dmas = <&usb_dmac0 0>, <&usb_dmac0 1>, <&usb_dmac1 0>, <&usb_dmac1 1>; @@ -859,7 +886,7 @@ vin0: video@e6ef0000 { compatible = "renesas,vin-r8a7791"; reg = <0 0xe6ef0000 0 0x1000>; - interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -868,7 +895,7 @@ vin1: video@e6ef1000 { compatible = "renesas,vin-r8a7791"; reg = <0 0xe6ef1000 0 0x1000>; - interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -877,7 +904,7 @@ vin2: video@e6ef2000 { compatible = "renesas,vin-r8a7791"; reg = <0 0xe6ef2000 0 0x1000>; - interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -886,7 +913,7 @@ vsp1@fe928000 { compatible = "renesas,vsp1"; reg = <0 0xfe928000 0 0x8000>; - interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_VSP1_S>; power-domains = <&cpg_clocks>; @@ -900,7 +927,7 @@ vsp1@fe930000 { compatible = "renesas,vsp1"; reg = <0 0xfe930000 0 0x8000>; - interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU0>; power-domains = <&cpg_clocks>; @@ -914,7 +941,7 @@ vsp1@fe938000 { compatible = "renesas,vsp1"; reg = <0 0xfe938000 0 0x8000>; - interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU1>; power-domains = <&cpg_clocks>; @@ -930,8 +957,8 @@ reg = <0 0xfeb00000 0 0x40000>, <0 0xfeb90000 0 0x1c>; reg-names = "du", "lvds.0"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp7_clks R8A7791_CLK_DU0>, <&mstp7_clks R8A7791_CLK_DU1>, <&mstp7_clks R8A7791_CLK_LVDS0>; @@ -958,7 +985,7 @@ can0: can@e6e80000 { compatible = "renesas,can-r8a7791"; reg = <0 0xe6e80000 0 0x1000>; - interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_RCAN0>, <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -969,7 +996,7 @@ can1: can@e6e88000 { compatible = "renesas,can-r8a7791"; reg = <0 0xe6e88000 0 0x1000>; - interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_RCAN1>, <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -980,7 +1007,7 @@ jpu: jpeg-codec@fe980000 { compatible = "renesas,jpu-r8a7791"; reg = <0 0xfe980000 0 0x10300>; - interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_JPU>; power-domains = <&cpg_clocks>; }; @@ -1031,6 +1058,15 @@ status = "disabled"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* External USB clock - can be overridden by the board */ usb_extal_clk: usb_extal_clk { compatible = "fixed-clock"; @@ -1432,7 +1468,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7791", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -1446,7 +1482,7 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-r8a7791"; reg = <0 0xe6e20000 0 0x0064>; - interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>; dmas = <&dmac0 0x51>, <&dmac0 0x52>; dma-names = "tx", "rx"; @@ -1459,7 +1495,7 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-r8a7791"; reg = <0 0xe6e10000 0 0x0064>; - interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_MSIOF1>; dmas = <&dmac0 0x55>, <&dmac0 0x56>; dma-names = "tx", "rx"; @@ -1472,7 +1508,7 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-r8a7791"; reg = <0 0xe6e00000 0 0x0064>; - interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_MSIOF2>; dmas = <&dmac0 0x41>, <&dmac0 0x42>; dma-names = "tx", "rx"; @@ -1485,7 +1521,7 @@ xhci: usb@ee000000 { compatible = "renesas,xhci-r8a7791"; reg = <0 0xee000000 0 0xc00>; - interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SSUSB>; power-domains = <&cpg_clocks>; phys = <&usb2 1>; @@ -1498,7 +1534,7 @@ device_type = "pci"; reg = <0 0xee090000 0 0xc00>, <0 0xee080000 0 0x1100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1509,9 +1545,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1533,7 +1569,7 @@ device_type = "pci"; reg = <0 0xee0d0000 0 0xc00>, <0 0xee0c0000 0 0x1100>; - interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1544,9 +1580,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1577,12 +1613,12 @@ /* Map all possible DDR as inbound ranges */ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000 0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>; - interrupts = <0 116 IRQ_TYPE_LEVEL_HIGH>, - <0 117 IRQ_TYPE_LEVEL_HIGH>, - <0 118 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp3_clks R8A7791_CLK_PCIEC>, <&pcie_bus_clk>; clock-names = "pcie", "pcie_bus"; power-domains = <&cpg_clocks>; @@ -1592,8 +1628,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1601,7 +1637,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1609,8 +1645,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1618,7 +1654,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1626,8 +1662,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1635,7 +1671,7 @@ ipmmu_rt: mmu@ffc80000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; - interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1643,8 +1679,8 @@ ipmmu_gp: mmu@e62a0000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; - interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>, - <0 261 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1721,52 +1757,52 @@ rcar_sound,src { src0: src@0 { - interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; src1: src@1 { - interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x87>, <&audma1 0x9c>; dma-names = "rx", "tx"; }; src2: src@2 { - interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x89>, <&audma1 0x9e>; dma-names = "rx", "tx"; }; src3: src@3 { - interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8b>, <&audma1 0xa0>; dma-names = "rx", "tx"; }; src4: src@4 { - interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8d>, <&audma1 0xb0>; dma-names = "rx", "tx"; }; src5: src@5 { - interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8f>, <&audma1 0xb2>; dma-names = "rx", "tx"; }; src6: src@6 { - interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x91>, <&audma1 0xb4>; dma-names = "rx", "tx"; }; src7: src@7 { - interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x93>, <&audma1 0xb6>; dma-names = "rx", "tx"; }; src8: src@8 { - interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x95>, <&audma1 0xb8>; dma-names = "rx", "tx"; }; src9: src@9 { - interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x97>, <&audma1 0xba>; dma-names = "rx", "tx"; }; @@ -1774,52 +1810,52 @@ rcar_sound,ssi { ssi0: ssi@0 { - interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi1: ssi@1 { - interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi2: ssi@2 { - interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi3: ssi@3 { - interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi4: ssi@4 { - interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi5: ssi@5 { - interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi6: ssi@6 { - interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi7: ssi@7 { - interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi8: ssi@8 { - interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi9: ssi@9 { - interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dma-names = "rx", "tx", "rxu", "txu"; }; diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index baa59fe84298..cfe142c2ba38 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -8,6 +8,34 @@ * kind, whether express or implied. */ +/* + * SSI-AK4643 + * + * SW1: 1: AK4643 + * 2: CN22 + * 3: ADV7511 + * + * This command is required when Playback/Capture + * + * amixer set "LINEOUT Mixer DACL" on + * amixer set "DVC Out" 100% + * amixer set "DVC In" 100% + * + * You can use Mute + * + * amixer set "DVC Out Mute" on + * amixer set "DVC In Mute" on + * + * You can use Volume Ramp + * + * amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps" + * amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps" + * amixer set "DVC Out Ramp" on + * aplay xxx.wav & + * amixer set "DVC Out" 80% // Volume Down + * amixer set "DVC Out" 100% // Volume Up + */ + /dts-v1/; #include "r8a7793.dtsi" #include @@ -31,6 +59,176 @@ device_type = "memory"; reg = <0 0x40000000 0 0x40000000>; }; + + gpio-keys { + compatible = "gpio-keys"; + + key-1 { + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-1"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-2 { + gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-2"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-3 { + gpios = <&gpio5 2 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-3"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-4 { + gpios = <&gpio5 3 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-4"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-a { + gpios = <&gpio7 0 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW30"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-b { + gpios = <&gpio7 1 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW31"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-c { + gpios = <&gpio7 2 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW32"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-d { + gpios = <&gpio7 3 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW33"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-e { + gpios = <&gpio7 4 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW34"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-f { + gpios = <&gpio7 5 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW35"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-g { + gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW36"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + }; + + leds { + compatible = "gpio-leds"; + led6 { + gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>; + label = "LED6"; + }; + led7 { + gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>; + label = "LED7"; + }; + led8 { + gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>; + label = "LED8"; + }; + }; + + audio_clock: clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <11289600>; + clock-output-names = "audio_clock"; + }; + + rsnd_ak4643: sound { + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&sndcodec>; + simple-audio-card,frame-master = <&sndcodec>; + + sndcpu: simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + sndcodec: simple-audio-card,codec { + sound-dai = <&ak4643>; + clocks = <&audio_clock>; + }; + }; + + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7511_out>; + }; + }; + }; + + x2_clk: x2-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; + + x13_clk: x13-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <148500000>; + }; +}; + +&du { + pinctrl-0 = <&du_pins>; + pinctrl-names = "default"; + status = "okay"; + + clocks = <&mstp7_clks R8A7793_CLK_DU0>, + <&mstp7_clks R8A7793_CLK_DU1>, + <&mstp7_clks R8A7793_CLK_LVDS0>, + <&x13_clk>, <&x2_clk>; + clock-names = "du.0", "du.1", "lvds.0", + "dclkin.0", "dclkin.1"; + + ports { + port@0 { + endpoint { + remote-endpoint = <&adv7511_in>; + }; + }; + port@1 { + lvds_connector: endpoint { + }; + }; + }; }; &extal_clk { @@ -38,6 +236,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + + i2c2_pins: i2c2 { + renesas,groups = "i2c2"; + renesas,function = "i2c2"; + }; + + du_pins: du { + renesas,groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0"; + renesas,function = "du"; + }; + scif0_pins: serial0 { renesas,groups = "scif0_data_d"; renesas,function = "scif0"; @@ -48,6 +259,11 @@ renesas,function = "scif1"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -62,6 +278,16 @@ renesas,groups = "qspi_ctrl", "qspi_data4"; renesas,function = "qspi"; }; + + sound_pins: sound { + renesas,groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data"; + renesas,function = "ssi"; + }; + + sound_clk_pins: sound_clk { + renesas,groups = "audio_clk_a"; + renesas,function = "audio_clk"; + }; }; ðer { @@ -98,6 +324,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &qspi { pinctrl-0 = <&qspi_pins>; pinctrl-names = "default"; @@ -136,3 +367,76 @@ }; }; }; + +&i2c2 { + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "default"; + + status = "okay"; + clock-frequency = <100000>; + + ak4643: codec@12 { + compatible = "asahi-kasei,ak4643"; + #sound-dai-cells = <0>; + reg = <0x12>; + }; + + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio3>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_rgb>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; + + eeprom@50 { + compatible = "renesas,r1ex24002", "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&rcar_sound { + pinctrl-0 = <&sound_pins &sound_clk_pins>; + pinctrl-names = "default"; + + /* Single DAI */ + #sound-dai-cells = <0>; + + status = "okay"; + + rcar_sound,dai { + dai0 { + playback = <&ssi0 &src2 &dvc0>; + capture = <&ssi1 &src3 &dvc1>; + }; + }; +}; + +&ssi1 { + shared-pin; +}; diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index aef9e69d6c26..45dba1c79a43 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -19,6 +19,15 @@ #size-cells = <2>; aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; spi0 = &qspi; }; @@ -54,13 +63,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -73,7 +82,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 26>; @@ -86,7 +95,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -99,7 +108,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -112,7 +121,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -125,7 +134,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -138,7 +147,7 @@ gpio6: gpio@e6055400 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6055400 0 0x50>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 32>; @@ -151,7 +160,7 @@ gpio7: gpio@e6055800 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6055800 0 0x50>; - interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 224 26>; @@ -164,24 +173,24 @@ thermal@e61f0000 { compatible = "renesas,thermal-r8a7793", "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A7793_CLK_THERMAL>; power-domains = <&cpg_clocks>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-r8a7793", "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7793_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -194,14 +203,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a7793", "renesas,cmt-48-gen2"; 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>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7793_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -216,44 +225,39 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A7793_CLK_IRQC>; power-domains = <&cpg_clocks>; }; - pfc: pfc@e6060000 { - compatible = "renesas,pfc-r8a7793"; - reg = <0 0xe6060000 0 0x250>; - }; - dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -269,22 +273,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -297,12 +301,190 @@ dma-channels = <15>; }; + audma0: dma-controller@ec700000 { + compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; + reg = <0 0xec700000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12"; + clocks = <&mstp5_clks R8A7793_CLK_AUDIO_DMAC0>; + clock-names = "fck"; + power-domains = <&cpg_clocks>; + #dma-cells = <1>; + dma-channels = <13>; + }; + + audma1: dma-controller@ec720000 { + compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; + reg = <0 0xec720000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12"; + clocks = <&mstp5_clks R8A7793_CLK_AUDIO_DMAC1>; + clock-names = "fck"; + power-domains = <&cpg_clocks>; + #dma-cells = <1>; + dma-channels = <13>; + }; + + /* 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-r8a7793"; + reg = <0 0xe6508000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C0>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c1: i2c@e6518000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6518000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C1>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c2: i2c@e6530000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6530000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C2>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c3: i2c@e6540000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6540000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C3>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c4: i2c@e6520000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6520000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C4>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c5: i2c@e6528000 { + /* doesn't need pinmux */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6528000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C5>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <110>; + status = "disabled"; + }; + + i2c6: i2c@e60b0000 { + /* doesn't need pinmux */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; + reg = <0 0xe60b0000 0 0x425>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_IICDVFS>; + dmas = <&dmac0 0x77>, <&dmac0 0x78>; + dma-names = "tx", "rx"; + power-domains = <&cpg_clocks>; + status = "disabled"; + }; + + i2c7: i2c@e6500000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; + reg = <0 0xe6500000 0 0x425>; + interrupts = ; + clocks = <&mstp3_clks R8A7793_CLK_IIC0>; + dmas = <&dmac0 0x61>, <&dmac0 0x62>; + dma-names = "tx", "rx"; + power-domains = <&cpg_clocks>; + status = "disabled"; + }; + + i2c8: i2c@e6510000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; + reg = <0 0xe6510000 0 0x425>; + interrupts = ; + clocks = <&mstp3_clks R8A7793_CLK_IIC1>; + dmas = <&dmac0 0x65>, <&dmac0 0x66>; + dma-names = "tx", "rx"; + power-domains = <&cpg_clocks>; + status = "disabled"; + }; + + pfc: pfc@e6060000 { + compatible = "renesas,pfc-r8a7793"; + reg = <0 0xe6060000 0 0x250>; + }; + scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -310,11 +492,12 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -322,11 +505,12 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -334,11 +518,12 @@ }; scifa3: serial@e6c70000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; - interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -346,11 +531,12 @@ }; scifa4: serial@e6c78000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; - interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -358,11 +544,12 @@ }; scifa5: serial@e6c80000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -370,11 +557,12 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7793", "renesas,scifb"; + compatible = "renesas,scifb-r8a7793", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -382,11 +570,12 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7793", "renesas,scifb"; + compatible = "renesas,scifb-r8a7793", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -394,11 +583,12 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7793", "renesas,scifb"; + compatible = "renesas,scifb-r8a7793", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -406,11 +596,13 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -418,11 +610,13 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -430,11 +624,13 @@ }; scif2: serial@e6e58000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e58000 0 64>; - interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -442,11 +638,13 @@ }; scif3: serial@e6ea8000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ea8000 0 64>; - interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF3>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF3>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -454,11 +652,13 @@ }; scif4: serial@e6ee0000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee0000 0 64>; - interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF4>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF4>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -466,11 +666,13 @@ }; scif5: serial@e6ee8000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee8000 0 64>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF5>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF5>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -478,11 +680,13 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7793", "renesas,hscif"; + compatible = "renesas,hscif-r8a7793", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -490,11 +694,13 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7793", "renesas,hscif"; + compatible = "renesas,hscif-r8a7793", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -502,11 +708,13 @@ }; hscif2: serial@e62d0000 { - compatible = "renesas,hscif-r8a7793", "renesas,hscif"; + compatible = "renesas,hscif-r8a7793", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; - interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -516,7 +724,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7793"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7793_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -528,7 +736,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7793", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7793_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -544,8 +752,8 @@ reg = <0 0xfeb00000 0 0x40000>, <0 0xfeb90000 0 0x1c>; reg-names = "du", "lvds.0"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp7_clks R8A7793_CLK_DU0>, <&mstp7_clks R8A7793_CLK_DU1>, <&mstp7_clks R8A7793_CLK_LVDS0>; @@ -583,6 +791,38 @@ clock-output-names = "extal"; }; + /* + * The external audio clocks are configured as 0 Hz fixed frequency clocks by + * default. Boards that provide audio clocks should override them. + */ + audio_clk_a: audio_clk_a { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "audio_clk_a"; + }; + audio_clk_b: audio_clk_b { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "audio_clk_b"; + }; + audio_clk_c: audio_clk_c { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "audio_clk_c"; + }; + + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: cpg_clocks@e6150000 { compatible = "renesas,r8a7793-cpg-clocks", @@ -671,6 +911,14 @@ clock-mult = <1>; clock-output-names = "p"; }; + m2_clk: m2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7793_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <8>; + clock-mult = <1>; + clock-output-names = "m2"; + }; rclk_clk: rclk_clk { compatible = "fixed-factor-clock"; clocks = <&cpg_clocks R8A7793_CLK_PLL1>; @@ -770,10 +1018,11 @@ mstp5_clks: mstp5_clks@e6150144 { compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>; - clocks = <&extal_clk>; + clocks = <&hp_clk>, <&hp_clk>, <&extal_clk>; #clock-cells = <1>; - clock-indices = ; - clock-output-names = "thermal"; + clock-indices = ; + clock-output-names = "audmac0", "audmac1", "thermal"; }; mstp7_clks: mstp7_clks@e615014c { compatible = "renesas,r8a7793-mstp-clocks", @@ -820,19 +1069,61 @@ reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>; clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, - <&cpg_clocks R8A7793_CLK_QSPI>; + <&cpg_clocks R8A7793_CLK_QSPI>, <&hp_clk>, + <&cp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>, + <&hp_clk>, <&hp_clk>; #clock-cells = <1>; clock-indices = < R8A7793_CLK_GPIO7 R8A7793_CLK_GPIO6 R8A7793_CLK_GPIO5 R8A7793_CLK_GPIO4 R8A7793_CLK_GPIO3 R8A7793_CLK_GPIO2 R8A7793_CLK_GPIO1 R8A7793_CLK_GPIO0 - R8A7793_CLK_QSPI_MOD + R8A7793_CLK_QSPI_MOD R8A7793_CLK_I2C5 + R8A7793_CLK_IICDVFS R8A7793_CLK_I2C4 + R8A7793_CLK_I2C3 R8A7793_CLK_I2C2 + R8A7793_CLK_I2C1 R8A7793_CLK_I2C0 >; clock-output-names = "gpio7", "gpio6", "gpio5", "gpio4", "gpio3", "gpio2", "gpio1", "gpio0", - "qspi_mod"; + "qspi_mod", "i2c5", "i2c6", "i2c4", + "i2c3", "i2c2", "i2c1", "i2c0"; + }; + mstp10_clks: mstp10_clks@e6150998 { + compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150998 0 4>, <0 0xe61509a8 0 4>; + clocks = <&p_clk>, + <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&p_clk>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>; + + #clock-cells = <1>; + clock-indices = < + R8A7793_CLK_SSI_ALL + R8A7793_CLK_SSI9 R8A7793_CLK_SSI8 R8A7793_CLK_SSI7 R8A7793_CLK_SSI6 R8A7793_CLK_SSI5 + R8A7793_CLK_SSI4 R8A7793_CLK_SSI3 R8A7793_CLK_SSI2 R8A7793_CLK_SSI1 R8A7793_CLK_SSI0 + R8A7793_CLK_SCU_ALL + R8A7793_CLK_SCU_DVC1 R8A7793_CLK_SCU_DVC0 + R8A7793_CLK_SCU_CTU1_MIX1 R8A7793_CLK_SCU_CTU0_MIX0 + R8A7793_CLK_SCU_SRC9 R8A7793_CLK_SCU_SRC8 R8A7793_CLK_SCU_SRC7 R8A7793_CLK_SCU_SRC6 R8A7793_CLK_SCU_SRC5 + R8A7793_CLK_SCU_SRC4 R8A7793_CLK_SCU_SRC3 R8A7793_CLK_SCU_SRC2 R8A7793_CLK_SCU_SRC1 R8A7793_CLK_SCU_SRC0 + >; + clock-output-names = + "ssi-all", + "ssi9", "ssi8", "ssi7", "ssi6", "ssi5", + "ssi4", "ssi3", "ssi2", "ssi1", "ssi0", + "scu-all", + "scu-dvc1", "scu-dvc0", + "scu-ctu1-mix1", "scu-ctu0-mix0", + "scu-src9", "scu-src8", "scu-src7", "scu-src6", "scu-src5", + "scu-src4", "scu-src3", "scu-src2", "scu-src1", "scu-src0"; }; mstp11_clks: mstp11_clks@e615099c { compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; @@ -849,8 +1140,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -858,7 +1149,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -866,8 +1157,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -875,7 +1166,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -883,8 +1174,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -892,7 +1183,7 @@ ipmmu_rt: mmu@ffc80000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; - interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -900,9 +1191,166 @@ ipmmu_gp: mmu@e62a0000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; - interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>, - <0 261 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; + + rcar_sound: sound@ec500000 { + /* + * #sound-dai-cells is required + * + * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>; + * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>; + */ + compatible = "renesas,rcar_sound-r8a7793", "renesas,rcar_sound-gen2"; + reg = <0 0xec500000 0 0x1000>, /* SCU */ + <0 0xec5a0000 0 0x100>, /* ADG */ + <0 0xec540000 0 0x1000>, /* SSIU */ + <0 0xec541000 0 0x280>, /* SSI */ + <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/ + reg-names = "scu", "adg", "ssiu", "ssi", "audmapp"; + + clocks = <&mstp10_clks R8A7793_CLK_SSI_ALL>, + <&mstp10_clks R8A7793_CLK_SSI9>, <&mstp10_clks R8A7793_CLK_SSI8>, + <&mstp10_clks R8A7793_CLK_SSI7>, <&mstp10_clks R8A7793_CLK_SSI6>, + <&mstp10_clks R8A7793_CLK_SSI5>, <&mstp10_clks R8A7793_CLK_SSI4>, + <&mstp10_clks R8A7793_CLK_SSI3>, <&mstp10_clks R8A7793_CLK_SSI2>, + <&mstp10_clks R8A7793_CLK_SSI1>, <&mstp10_clks R8A7793_CLK_SSI0>, + <&mstp10_clks R8A7793_CLK_SCU_SRC9>, <&mstp10_clks R8A7793_CLK_SCU_SRC8>, + <&mstp10_clks R8A7793_CLK_SCU_SRC7>, <&mstp10_clks R8A7793_CLK_SCU_SRC6>, + <&mstp10_clks R8A7793_CLK_SCU_SRC5>, <&mstp10_clks R8A7793_CLK_SCU_SRC4>, + <&mstp10_clks R8A7793_CLK_SCU_SRC3>, <&mstp10_clks R8A7793_CLK_SCU_SRC2>, + <&mstp10_clks R8A7793_CLK_SCU_SRC1>, <&mstp10_clks R8A7793_CLK_SCU_SRC0>, + <&mstp10_clks R8A7793_CLK_SCU_DVC0>, <&mstp10_clks R8A7793_CLK_SCU_DVC1>, + <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>, <&m2_clk>; + clock-names = "ssi-all", + "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5", + "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0", + "src.9", "src.8", "src.7", "src.6", "src.5", + "src.4", "src.3", "src.2", "src.1", "src.0", + "dvc.0", "dvc.1", + "clk_a", "clk_b", "clk_c", "clk_i"; + power-domains = <&cpg_clocks>; + + status = "disabled"; + + rcar_sound,dvc { + dvc0: dvc@0 { + dmas = <&audma0 0xbc>; + dma-names = "tx"; + }; + dvc1: dvc@1 { + dmas = <&audma0 0xbe>; + dma-names = "tx"; + }; + }; + + rcar_sound,src { + src0: src@0 { + interrupts = ; + dmas = <&audma0 0x85>, <&audma1 0x9a>; + dma-names = "rx", "tx"; + }; + src1: src@1 { + interrupts = ; + dmas = <&audma0 0x87>, <&audma1 0x9c>; + dma-names = "rx", "tx"; + }; + src2: src@2 { + interrupts = ; + dmas = <&audma0 0x89>, <&audma1 0x9e>; + dma-names = "rx", "tx"; + }; + src3: src@3 { + interrupts = ; + dmas = <&audma0 0x8b>, <&audma1 0xa0>; + dma-names = "rx", "tx"; + }; + src4: src@4 { + interrupts = ; + dmas = <&audma0 0x8d>, <&audma1 0xb0>; + dma-names = "rx", "tx"; + }; + src5: src@5 { + interrupts = ; + dmas = <&audma0 0x8f>, <&audma1 0xb2>; + dma-names = "rx", "tx"; + }; + src6: src@6 { + interrupts = ; + dmas = <&audma0 0x91>, <&audma1 0xb4>; + dma-names = "rx", "tx"; + }; + src7: src@7 { + interrupts = ; + dmas = <&audma0 0x93>, <&audma1 0xb6>; + dma-names = "rx", "tx"; + }; + src8: src@8 { + interrupts = ; + dmas = <&audma0 0x95>, <&audma1 0xb8>; + dma-names = "rx", "tx"; + }; + src9: src@9 { + interrupts = ; + dmas = <&audma0 0x97>, <&audma1 0xba>; + dma-names = "rx", "tx"; + }; + }; + + rcar_sound,ssi { + ssi0: ssi@0 { + interrupts = ; + dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi1: ssi@1 { + interrupts = ; + dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi2: ssi@2 { + interrupts = ; + dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi3: ssi@3 { + interrupts = ; + dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi4: ssi@4 { + interrupts = ; + dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi5: ssi@5 { + interrupts = ; + dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi6: ssi@6 { + interrupts = ; + dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi7: ssi@7 { + interrupts = ; + dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi8: ssi@8 { + interrupts = ; + dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi9: ssi@9 { + interrupts = ; + dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + }; + }; }; diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts index 2394e4883786..ca9bc4fff287 100644 --- a/arch/arm/boot/dts/r8a7794-alt.dts +++ b/arch/arm/boot/dts/r8a7794-alt.dts @@ -103,6 +103,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + du_pins: du { renesas,groups = "du1_rgb666", "du1_sync", "du1_disp", "du1_dotclkout0"; renesas,function = "du"; @@ -113,6 +116,11 @@ renesas,function = "scif2"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -138,6 +146,13 @@ status = "okay"; }; +&pfc { + qspi_pins: spi0 { + renesas,groups = "qspi_ctrl", "qspi_data4"; + renesas,function = "qspi"; + }; +}; + ðer { pinctrl-0 = <ðer_pins &phy1_pins>; pinctrl-names = "default"; @@ -197,3 +212,47 @@ status = "okay"; }; + +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + +&qspi { + pinctrl-0 = <&qspi_pins>; + pinctrl-names = "default"; + + status = "okay"; + + flash@0 { + compatible = "spansion,s25fl512s", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <30000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-cpol; + spi-cpha; + m25p,fast-read; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "loader"; + reg = <0x00000000 0x00040000>; + read-only; + }; + partition@40000 { + label = "system"; + reg = <0x00040000 0x00040000>; + read-only; + }; + partition@80000 { + label = "user"; + reg = <0x00080000 0x03f80000>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts index 5153e3af25d9..66f077a3ca41 100644 --- a/arch/arm/boot/dts/r8a7794-silk.dts +++ b/arch/arm/boot/dts/r8a7794-silk.dts @@ -64,6 +64,61 @@ states = <3300000 1 1800000 0>; }; + + vga-encoder { + compatible = "adi,adv7123"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7123_in: endpoint { + remote-endpoint = <&du_out_rgb1>; + }; + }; + port@1 { + reg = <1>; + adv7123_out: endpoint { + remote-endpoint = <&vga_in>; + }; + }; + }; + }; + + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7511_out>; + }; + }; + }; + + vga { + compatible = "vga-connector"; + + port { + vga_in: endpoint { + remote-endpoint = <&adv7123_out>; + }; + }; + }; + + x2_clk: x2-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <148500000>; + }; + + x3_clk: x3-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; }; &extal_clk { @@ -71,11 +126,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif2_pins: serial2 { renesas,groups = "scif2_data"; renesas,function = "scif2"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -129,6 +192,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + ðer { pinctrl-0 = <ðer_pins &phy1_pins>; pinctrl-names = "default"; @@ -164,6 +232,38 @@ }; }; }; + + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio5>; + interrupts = <23 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_rgb0>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; }; &mmcif0 { @@ -258,3 +358,25 @@ &usbphy { status = "okay"; }; + +&du { + status = "okay"; + + clocks = <&mstp7_clks R8A7794_CLK_DU0>, + <&mstp7_clks R8A7794_CLK_DU0>, + <&x2_clk>, <&x3_clk>; + clock-names = "du.0", "du.1", "dclkin.0", "dclkin.1"; + + ports { + port@0 { + endpoint { + remote-endpoint = <&adv7511_in>; + }; + }; + port@1 { + endpoint { + remote-endpoint = <&adv7123_in>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index 6c78f1fae90f..7d4c5597af5b 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -59,13 +59,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -78,7 +78,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 26>; @@ -91,7 +91,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -104,7 +104,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -117,7 +117,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -130,7 +130,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 28>; @@ -143,7 +143,7 @@ gpio6: gpio@e6055400 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6055400 0 0x50>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 26>; @@ -156,8 +156,8 @@ cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7794_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -170,14 +170,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-gen2"; 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>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7794_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -189,10 +189,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; irqc0: interrupt-controller@e61c0000 { @@ -200,16 +200,16 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A7794_CLK_IRQC>; power-domains = <&cpg_clocks>; }; @@ -222,22 +222,22 @@ dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -253,22 +253,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -282,11 +282,12 @@ }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -294,11 +295,12 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -306,11 +308,12 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -318,11 +321,12 @@ }; scifa3: serial@e6c70000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; - interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -330,11 +334,12 @@ }; scifa4: serial@e6c78000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; - interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -342,11 +347,12 @@ }; scifa5: serial@e6c80000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -354,11 +360,12 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7794", "renesas,scifb"; + compatible = "renesas,scifb-r8a7794", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -366,11 +373,12 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7794", "renesas,scifb"; + compatible = "renesas,scifb-r8a7794", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -378,11 +386,12 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7794", "renesas,scifb"; + compatible = "renesas,scifb-r8a7794", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -390,11 +399,13 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -402,11 +413,13 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -414,11 +427,13 @@ }; scif2: serial@e6e58000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e58000 0 64>; - interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -426,11 +441,13 @@ }; scif3: serial@e6ea8000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ea8000 0 64>; - interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF3>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF3>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -438,11 +455,13 @@ }; scif4: serial@e6ee0000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee0000 0 64>; - interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF4>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF4>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -450,11 +469,13 @@ }; scif5: serial@e6ee8000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee8000 0 64>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF5>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF5>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -462,11 +483,13 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7794", "renesas,hscif"; + compatible = "renesas,hscif-r8a7794", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -474,11 +497,13 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7794", "renesas,hscif"; + compatible = "renesas,hscif-r8a7794", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -486,11 +511,13 @@ }; hscif2: serial@e62d0000 { - compatible = "renesas,hscif-r8a7794", "renesas,hscif"; + compatible = "renesas,hscif-r8a7794", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; - interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -500,7 +527,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7794"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -513,7 +540,7 @@ i2c0: i2c@e6508000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C0>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -525,7 +552,7 @@ i2c1: i2c@e6518000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6518000 0 0x40>; - interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C1>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -537,7 +564,7 @@ i2c2: i2c@e6530000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6530000 0 0x40>; - interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C2>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -549,7 +576,7 @@ i2c3: i2c@e6540000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6540000 0 0x40>; - interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C3>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -561,7 +588,7 @@ i2c4: i2c@e6520000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6520000 0 0x40>; - interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C4>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -573,7 +600,7 @@ i2c5: i2c@e6528000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6528000 0 0x40>; - interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C5>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -585,7 +612,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,mmcif-r8a7794", "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_MMCIF0>; dmas = <&dmac0 0xd1>, <&dmac0 0xd2>; dma-names = "tx", "rx"; @@ -597,7 +624,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7794"; reg = <0 0xee100000 0 0x200>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_SDHI0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -606,7 +633,7 @@ sdhi1: sd@ee140000 { compatible = "renesas,sdhi-r8a7794"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_SDHI1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -615,7 +642,7 @@ sdhi2: sd@ee160000 { compatible = "renesas,sdhi-r8a7794"; reg = <0 0xee160000 0 0x100>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_SDHI2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -624,7 +651,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7794", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -638,7 +665,7 @@ vin0: video@e6ef0000 { compatible = "renesas,vin-r8a7794"; reg = <0 0xe6ef0000 0 0x1000>; - interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_VIN0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -647,7 +674,7 @@ vin1: video@e6ef1000 { compatible = "renesas,vin-r8a7794"; reg = <0 0xe6ef1000 0 0x1000>; - interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_VIN1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -658,7 +685,7 @@ device_type = "pci"; reg = <0 0xee090000 0 0xc00>, <0 0xee080000 0 0x1100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -669,9 +696,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -693,7 +720,7 @@ device_type = "pci"; reg = <0 0xee0d0000 0 0xc00>, <0 0xee0c0000 0 0x1100>; - interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -704,9 +731,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -724,9 +751,9 @@ }; hsusb: usb@e6590000 { - compatible = "renesas,usbhs-r8a7794"; + compatible = "renesas,usbhs-r8a7794", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSUSB>; power-domains = <&cpg_clocks>; renesas,buswait = <4>; @@ -759,8 +786,8 @@ compatible = "renesas,du-r8a7794"; reg = <0 0xfeb00000 0 0x40000>; reg-names = "du"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp7_clks R8A7794_CLK_DU0>, <&mstp7_clks R8A7794_CLK_DU0>; clock-names = "du.0", "du.1"; @@ -797,6 +824,15 @@ clock-output-names = "extal"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: cpg_clocks@e6150000 { compatible = "renesas,r8a7794-cpg-clocks", @@ -1111,8 +1147,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1120,7 +1156,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1128,8 +1164,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1137,7 +1173,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1145,8 +1181,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1154,8 +1190,8 @@ ipmmu_gp: mmu@e62a0000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; - interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>, - <0 261 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 992f9cadbc04..d5913fe128ee 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -46,6 +46,58 @@ model = "Rockchip RK3036 KylinBoard"; compatible = "rockchip,rk3036-kylin", "rockchip,rk3036"; + leds: gpio-leds { + compatible = "gpio-leds"; + + work { + gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>; + label = "kylin:red:led"; + pinctrl-names = "default"; + pinctrl-0 = <&led_ctl>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&bt_wake_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - SDIO_RESET_L_WL_RST + * - SDIO_RESET_L_BT_EN + */ + reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>, /* WL_REG_ON */ + <&gpio0 27 GPIO_ACTIVE_LOW>, /* WL_RST */ + <&gpio2 9 GPIO_ACTIVE_LOW>; /* BT_EN */ + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rt5616-codec"; + simple-audio-card,mclk-fs = <512>; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "MIC1", "Microphone Jack", + "MIC2", "Microphone Jack", + "Microphone Jack", "micbias1", + "Headphone Jack", "HPOL", + "Headphone Jack", "HPOR"; + + simple-audio-card,cpu { + sound-dai = <&i2s>; + }; + + simple-audio-card,codec { + sound-dai = <&rt5616>; + }; + }; + vcc_sys: vsys-regulator { compatible = "regulator-fixed"; regulator-name = "vcc_sys"; @@ -257,6 +309,19 @@ &i2c2 { status = "okay"; + + rt5616: rt5616@1b { + compatible = "rt5616"; + reg = <0x1b>; + clocks = <&cru SCLK_I2S_OUT>; + clock-names = "mclk"; + #sound-dai-cells = <0>; + }; +}; + +&i2s { + #sound-dai-cells = <0>; + status = "okay"; }; &sdio { @@ -264,13 +329,34 @@ broken-cd; bus-width = <4>; + cap-sd-highspeed; cap-sdio-irq; default-sample-phase = <90>; 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; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + 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>; +}; + +&uart0 { + status = "okay"; }; &uart2 { @@ -286,12 +372,30 @@ }; &pinctrl { + leds { + led_ctl: led-ctl { + rockchip,pins = <2 30 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pmic { pmic_int: pmic-int { rockchip,pins = <2 2 RK_FUNC_GPIO &pcfg_pull_default>; }; }; + sdio { + bt_wake_h: bt-wake-h { + rockchip,pins = <2 8 RK_FUNC_GPIO &pcfg_pull_default>; + }; + }; + + sdmmc { + sdmmc_pwr: sdmmc-pwr { + rockchip,pins = <2 28 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + sleep { global_pwroff: global-pwroff { rockchip,pins = <2 7 RK_FUNC_1 &pcfg_pull_none>; diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index b9567c1e0687..3864fa142df0 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -60,6 +60,7 @@ serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; + spi = &spi; }; memory { @@ -105,6 +106,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC2>; clock-names = "apb_pclk"; }; @@ -161,7 +163,7 @@ }; usb_otg: usb@10180000 { - compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", + compatible = "rockchip,rk3036-usb", "rockchip,rk3066-usb", "snps,dwc2"; reg = <0x10180000 0x40000>; interrupts = ; @@ -176,7 +178,7 @@ }; usb_host: usb@101c0000 { - compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", + compatible = "rockchip,rk3036-usb", "rockchip,rk3066-usb", "snps,dwc2"; reg = <0x101c0000 0x40000>; interrupts = ; @@ -211,7 +213,7 @@ }; emmc: dwmmc@1021c000 { - compatible = "rockchip,rk3288-dw-mshc"; + compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x1021c000 0x4000>; interrupts = ; broken-cd; @@ -241,8 +243,8 @@ interrupts = ; #address-cells = <1>; #size-cells = <0>; - clock-names = "i2s_hclk", "i2s_clk"; - clocks = <&cru HCLK_I2S>, <&cru SCLK_I2S>; + clock-names = "i2s_clk", "i2s_hclk"; + clocks = <&cru SCLK_I2S>, <&cru HCLK_I2S>; dmas = <&pdma 0>, <&pdma 1>; dma-names = "tx", "rx"; pinctrl-names = "default"; @@ -327,7 +329,7 @@ }; i2c1: i2c@20056000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x20056000 0x1000>; interrupts = ; #address-cells = <1>; @@ -340,7 +342,7 @@ }; i2c2: i2c@2005a000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x2005a000 0x1000>; interrupts = ; #address-cells = <1>; @@ -395,7 +397,7 @@ }; i2c0: i2c@20072000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x20072000 0x1000>; interrupts = ; #address-cells = <1>; @@ -407,6 +409,21 @@ status = "disabled"; }; + spi: spi@20074000 { + compatible = "rockchip,rockchip-spi"; + reg = <0x20074000 0x1000>; + interrupts = ; + clocks =<&cru PCLK_SPI>, <&cru SCLK_SPI>; + clock-names = "apb-pclk","spi_pclk"; + dmas = <&pdma 8>, <&pdma 9>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi_txd &spi_rxd &spi_clk &spi_cs0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + pinctrl: pinctrl { compatible = "rockchip,rk3036-pinctrl"; rockchip,grf = <&grf>; @@ -579,12 +596,12 @@ i2s { i2s_bus: i2s-bus { - rockchip,pins = <1 0 RK_FUNC_1 &pcfg_pull_none>, - <1 1 RK_FUNC_1 &pcfg_pull_none>, - <1 2 RK_FUNC_1 &pcfg_pull_none>, - <1 3 RK_FUNC_1 &pcfg_pull_none>, - <1 4 RK_FUNC_1 &pcfg_pull_none>, - <1 5 RK_FUNC_1 &pcfg_pull_none>; + rockchip,pins = <1 0 RK_FUNC_1 &pcfg_pull_default>, + <1 1 RK_FUNC_1 &pcfg_pull_default>, + <1 2 RK_FUNC_1 &pcfg_pull_default>, + <1 3 RK_FUNC_1 &pcfg_pull_default>, + <1 4 RK_FUNC_1 &pcfg_pull_default>, + <1 5 RK_FUNC_1 &pcfg_pull_default>; }; }; @@ -618,5 +635,29 @@ }; /* no rts / cts for uart2 */ }; + + spi { + spi_txd:spi-txd { + rockchip,pins = <1 29 RK_FUNC_3 &pcfg_pull_default>; + }; + + spi_rxd:spi-rxd { + rockchip,pins = <1 28 RK_FUNC_3 &pcfg_pull_default>; + }; + + spi_clk:spi-clk { + rockchip,pins = <2 0 RK_FUNC_2 &pcfg_pull_default>; + }; + + spi_cs0:spi-cs0 { + rockchip,pins = <1 30 RK_FUNC_3 &pcfg_pull_default>; + + }; + + spi_cs1:spi-cs1 { + rockchip,pins = <1 31 RK_FUNC_3 &pcfg_pull_default>; + + }; + }; }; }; diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts index 38c91a839795..6d2a5b3a84a8 100644 --- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts @@ -53,6 +53,18 @@ reg = <0x60000000 0x40000000>; }; + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm3 0 1000>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + voltage-table = <1000000 100>, + <1200000 42>; + status = "okay"; + }; + vcc_sd0: fixed-regulator { compatible = "regulator-fixed"; regulator-name = "sdmmc-supply"; @@ -74,7 +86,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; button@1 { @@ -82,7 +94,6 @@ linux,code = <104>; label = "GPIO Key Vol-"; linux,input-type = <1>; - gpio-key,wakeup = <0>; debounce-interval = <100>; }; /* VOL+ comes somehow thru the ADC */ @@ -203,6 +214,10 @@ disable-wp; }; +&pwm3 { + status = "okay"; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts index 7cdc308bfac5..a2b763e949b4 100644 --- a/arch/arm/boot/dts/rk3066a-marsboard.dts +++ b/arch/arm/boot/dts/rk3066a-marsboard.dts @@ -52,6 +52,18 @@ reg = <0x60000000 0x40000000>; }; + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm3 0 1000>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + voltage-table = <1000000 100>, + <1200000 42>; + status = "okay"; + }; + vcc_sd0: sdmmc-regulator { compatible = "regulator-fixed"; regulator-name = "sdmmc-supply"; @@ -194,6 +206,10 @@ }; }; +&pwm3 { + status = "okay"; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts index 341c1f87936a..05533005a809 100644 --- a/arch/arm/boot/dts/rk3066a-rayeager.dts +++ b/arch/arm/boot/dts/rk3066a-rayeager.dts @@ -65,7 +65,7 @@ #size-cells = <0>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; @@ -74,6 +74,18 @@ }; }; + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm3 0 1000>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + voltage-table = <1000000 100>, + <1200000 42>; + status = "okay"; + }; + vsys: vsys-regulator { compatible = "regulator-fixed"; regulator-name = "vsys"; @@ -431,6 +443,10 @@ status = "okay"; }; +&pwm3 { + status = "okay"; +}; + &saradc { vref-supply = <&vcc_25>; status = "okay"; diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index 58bac5053858..cb0a552e0b18 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -61,11 +61,13 @@ reg = <0x0>; operating-points = < /* kHz uV */ - 1008000 1075000 - 816000 1025000 - 600000 1025000 - 504000 1000000 - 312000 975000 + 1416000 1300000 + 1200000 1175000 + 1008000 1125000 + 816000 1125000 + 600000 1100000 + 504000 1100000 + 312000 1075000 >; clock-latency = <40000>; clocks = <&cru ARMCLK>; @@ -188,6 +190,16 @@ clock-names = "timer", "pclk"; }; + tsadc: tsadc@20060000 { + compatible = "rockchip,rk3066-tsadc"; + reg = <0x20060000 0x100>; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "saradc", "apb_pclk"; + interrupts = ; + #io-channel-cells = <1>; + status = "disabled"; + }; + usbphy: phy { compatible = "rockchip,rk3066a-usb-phy", "rockchip,rk3288-usb-phy"; rockchip,grf = <&grf>; @@ -200,6 +212,7 @@ reg = <0x17c>; clocks = <&cru SCLK_OTGPHY0>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy1: usb-phy1 { @@ -207,6 +220,7 @@ reg = <0x188>; clocks = <&cru SCLK_OTGPHY1>; clock-names = "phyclk"; + #clock-cells = <0>; }; }; diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts index 66fa87d1e2c2..0b6924c97b6b 100644 --- a/arch/arm/boot/dts/rk3188-radxarock.dts +++ b/arch/arm/boot/dts/rk3188-radxarock.dts @@ -63,7 +63,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 348d46b7ada5..9271833958f9 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -171,6 +171,7 @@ reg = <0x10c>; clocks = <&cru SCLK_OTGPHY0>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy1: usb-phy1 { @@ -178,6 +179,7 @@ reg = <0x11c>; clocks = <&cru SCLK_OTGPHY1>; clock-names = "phyclk"; + #clock-cells = <0>; }; }; diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi index 4faabdb65868..78d47f7d2938 100644 --- a/arch/arm/boot/dts/rk3288-evb.dtsi +++ b/arch/arm/boot/dts/rk3288-evb.dtsi @@ -110,7 +110,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi index 4e3fd9aefe34..98c586a43c73 100644 --- a/arch/arm/boot/dts/rk3288-firefly.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly.dtsi @@ -91,7 +91,7 @@ #size-cells = <0>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; @@ -408,6 +408,11 @@ output-low; }; + pcfg_pull_up_drv_12ma: pcfg-pull-up-drv-12ma { + bias-pull-up; + drive-strength = <12>; + }; + act8846 { pwr_hold: pwr-hold { rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_output_high>; @@ -457,6 +462,25 @@ }; sdmmc { + /* + * Default drive strength isn't enough to achieve even + * high-speed mode on firefly board so bump up to 12ma. + */ + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 17 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 18 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 19 RK_FUNC_1 &pcfg_pull_up_drv_12ma>; + }; + + sdmmc_clk: sdmmc-clk { + rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none_12ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_12ma>; + }; + sdmmc_pwr: sdmmc-pwr { rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; }; diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts index 65c475642d5a..2ff9689d2e1b 100644 --- a/arch/arm/boot/dts/rk3288-popmetal.dts +++ b/arch/arm/boot/dts/rk3288-popmetal.dts @@ -74,7 +74,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts index 17f13c73fe5e..510a1d0d7abb 100644 --- a/arch/arm/boot/dts/rk3288-r89.dts +++ b/arch/arm/boot/dts/rk3288-r89.dts @@ -73,7 +73,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi index 1ece66f3e162..e1ee9f949035 100644 --- a/arch/arm/boot/dts/rk3288-rock2-som.dtsi +++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi @@ -61,6 +61,31 @@ clock-output-names = "ext_gmac"; }; + io_domains: io-domains { + compatible = "rockchip,rk3288-io-voltage-domain"; + rockchip,grf = <&grf>; + + audio-supply = <&vcc_io>; + bb-supply = <&vcc_io>; + dvp-supply = <&vcc_18>; + flash0-supply = <&vcc_flash>; + flash1-supply = <&vccio_pmu>; + gpio30-supply = <&vccio_pmu>; + gpio1830 = <&vcc_io>; + lcdc-supply = <&vcc_io>; + sdcard-supply = <&vccio_sd>; + wifi-supply = <&vcc_18>; + }; + + vcc_flash: flash-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + startup-delay-us = <150>; + vin-supply = <&vcc_io>; + }; + vcc_sys: vsys-regulator { compatible = "regulator-fixed"; regulator-name = "vcc_sys"; @@ -85,6 +110,7 @@ pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc_flash>; status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts index c5453a0b07fc..dd3ad2e93a6d 100644 --- a/arch/arm/boot/dts/rk3288-rock2-square.dts +++ b/arch/arm/boot/dts/rk3288-rock2-square.dts @@ -49,6 +49,22 @@ stdout-path = "serial2:115200n8"; }; + gpio-leds { + compatible = "gpio-leds"; + + heartbeat { + gpios = <&gpio7 15 GPIO_ACTIVE_LOW>; + label = "rock2:green:state1"; + linux,default-trigger = "heartbeat"; + }; + + mmc { + gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + label = "rock2:blue:state2"; + linux,default-trigger = "mmc0"; + }; + }; + ir: ir-receiver { compatible = "gpio-ir-receiver"; gpios = <&gpio8 1 GPIO_ACTIVE_LOW>; @@ -70,6 +86,15 @@ #sound-dai-cells = <0>; }; + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&hym8563>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable>; + reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>; + }; + vcc_usb_host: vcc-host-regulator { compatible = "regulator-fixed"; enable-active-high; @@ -95,6 +120,21 @@ }; }; +&sdio0 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + 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>; + vqmmc-supply = <&vcc_18>; + status = "okay"; +}; + &sdmmc { bus-width = <4>; cap-mmc-highspeed; @@ -119,7 +159,7 @@ }; &i2c0 { - hym8563@51 { + hym8563: hym8563@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; @@ -161,6 +201,12 @@ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; }; }; + + sdio { + wifi_enable: wifi-enable { + rockchip,pins = <4 28 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; }; &spdif { diff --git a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi index 136d650dd05f..610769d99522 100644 --- a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi @@ -108,7 +108,7 @@ lid { label = "Lid"; gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; - gpio-key,wakeup; + wakeup-source; linux,code = <0>; /* SW_LID */ linux,input-type = <5>; /* EV_SW */ debounce-interval = <1>; diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi index 9fce91ffff6f..412809c60d01 100644 --- a/arch/arm/boot/dts/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi @@ -64,7 +64,7 @@ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; linux,code = ; debounce-interval = <100>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -340,11 +340,6 @@ i2c-scl-rising-time-ns = <1000>; }; -&power { - assigned-clocks = <&cru SCLK_EDP_24M>; - assigned-clock-parents = <&xin24m>; -}; - &pwm1 { status = "okay"; }; @@ -421,7 +416,7 @@ status = "okay"; assigned-clocks = <&cru SCLK_USBPHY480M_SRC>; - assigned-clock-parents = <&cru SCLK_OTGPHY0>; + assigned-clock-parents = <&usbphy0>; dr_mode = "host"; }; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 8ac49f3efc17..0934b6abcaab 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -145,6 +145,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC2>; clock-names = "apb_pclk"; }; @@ -155,6 +156,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC1>; clock-names = "apb_pclk"; status = "disabled"; @@ -166,6 +168,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC1>; clock-names = "apb_pclk"; }; @@ -630,6 +633,9 @@ #address-cells = <1>; #size-cells = <0>; + assigned-clocks = <&cru SCLK_EDP_24M>; + assigned-clock-parents = <&xin24m>; + /* * Note: Although SCLK_* are the working clocks * of device without including on the NOC, needed for @@ -815,6 +821,10 @@ reg = <0>; remote-endpoint = <&hdmi_in_vopb>; }; + vopb_out_mipi: endpoint@2 { + reg = <2>; + remote-endpoint = <&mipi_in_vopb>; + }; }; }; @@ -848,6 +858,10 @@ reg = <0>; remote-endpoint = <&hdmi_in_vopl>; }; + vopl_out_mipi: endpoint@2 { + reg = <2>; + remote-endpoint = <&mipi_in_vopl>; + }; }; }; @@ -861,6 +875,37 @@ status = "disabled"; }; + mipi_dsi: mipi@ff960000 { + compatible = "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi"; + reg = <0xff960000 0x4000>; + interrupts = ; + clocks = <&cru SCLK_MIPIDSI_24M>, <&cru PCLK_MIPI_DSI0>; + clock-names = "ref", "pclk"; + rockchip,grf = <&grf>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + 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>; + }; + }; + }; + }; + hdmi: hdmi@ff980000 { compatible = "rockchip,rk3288-dw-hdmi"; reg = <0xff980000 0x20000>; @@ -926,6 +971,7 @@ reg = <0x320>; clocks = <&cru SCLK_OTGPHY0>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy1: usb-phy1 { @@ -933,6 +979,7 @@ reg = <0x334>; clocks = <&cru SCLK_OTGPHY1>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy2: usb-phy2 { @@ -940,6 +987,7 @@ reg = <0x348>; clocks = <&cru SCLK_OTGPHY2>; clock-names = "phyclk"; + #clock-cells = <0>; }; }; diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi index 99eeea70223b..f1581f9d050f 100644 --- a/arch/arm/boot/dts/rk3xxx.dtsi +++ b/arch/arm/boot/dts/rk3xxx.dtsi @@ -78,6 +78,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMA1>; clock-names = "apb_pclk"; }; @@ -88,6 +89,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMA1>; clock-names = "apb_pclk"; status = "disabled"; @@ -99,6 +101,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMA2>; clock-names = "apb_pclk"; }; diff --git a/arch/arm/boot/dts/s5pv210-aquila.dts b/arch/arm/boot/dts/s5pv210-aquila.dts index aa64faa72970..da24ab570b0e 100644 --- a/arch/arm/boot/dts/s5pv210-aquila.dts +++ b/arch/arm/boot/dts/s5pv210-aquila.dts @@ -257,7 +257,7 @@ linux,code = ; label = "power"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; }; @@ -268,7 +268,7 @@ &keypad { linux,input-no-autorepeat; - linux,input-wakeup; + wakeup-source; samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/s5pv210-goni.dts b/arch/arm/boot/dts/s5pv210-goni.dts index 3b76eeeb8410..0a33d402138e 100644 --- a/arch/arm/boot/dts/s5pv210-goni.dts +++ b/arch/arm/boot/dts/s5pv210-goni.dts @@ -239,7 +239,7 @@ linux,code = ; label = "power"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; }; @@ -250,7 +250,7 @@ &keypad { linux,input-no-autorepeat; - linux,input-wakeup; + wakeup-source; samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/s5pv210-smdkv210.dts b/arch/arm/boot/dts/s5pv210-smdkv210.dts index da7d210df670..54fcc3fc82e2 100644 --- a/arch/arm/boot/dts/s5pv210-smdkv210.dts +++ b/arch/arm/boot/dts/s5pv210-smdkv210.dts @@ -59,7 +59,7 @@ &keypad { linux,input-no-autorepeat; - linux,input-wakeup; + wakeup-source; samsung,keypad-num-rows = <8>; samsung,keypad-num-columns = <8>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index b8032bca4621..db1151c18466 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -1342,7 +1342,7 @@ dbgu: serial@fc069000 { compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; reg = <0xfc069000 0x200>; - interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>; + interrupts = <45 IRQ_TYPE_LEVEL_HIGH 7>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_dbgu>; clocks = <&dbgu_clk>; diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index 3a6056f9f0d2..bf825ca4f6f7 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -58,7 +58,7 @@ L2: cache-controller { compatible = "arm,pl310-cache"; reg = <0xf0100000 0x1000>; - interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; power-domains = <&pd_a3sm>; arm,data-latency = <3 3 3>; arm,tag-latency = <2 2 2>; @@ -70,8 +70,8 @@ sbsc2: memory-controller@fb400000 { compatible = "renesas,sbsc-sh73a0"; reg = <0xfb400000 0x400>; - interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-names = "sec", "temp"; power-domains = <&pd_a4bc1>; }; @@ -79,22 +79,22 @@ sbsc1: memory-controller@fe400000 { compatible = "renesas,sbsc-sh73a0"; reg = <0xfe400000 0x400>; - interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>, - <0 36 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-names = "sec", "temp"; power-domains = <&pd_a4bc0>; }; pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>, - <0 56 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; }; cmt1: timer@e6138000 { compatible = "renesas,cmt-48-sh73a0", "renesas,cmt-48"; reg = <0xe6138000 0x200>; - interrupts = <0 65 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; @@ -113,14 +113,14 @@ <0xe6900020 1>, <0xe6900040 1>, <0xe6900060 1>; - interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH - 0 2 IRQ_TYPE_LEVEL_HIGH - 0 3 IRQ_TYPE_LEVEL_HIGH - 0 4 IRQ_TYPE_LEVEL_HIGH - 0 5 IRQ_TYPE_LEVEL_HIGH - 0 6 IRQ_TYPE_LEVEL_HIGH - 0 7 IRQ_TYPE_LEVEL_HIGH - 0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -135,14 +135,14 @@ <0xe6900024 1>, <0xe6900044 1>, <0xe6900064 1>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH - 0 10 IRQ_TYPE_LEVEL_HIGH - 0 11 IRQ_TYPE_LEVEL_HIGH - 0 12 IRQ_TYPE_LEVEL_HIGH - 0 13 IRQ_TYPE_LEVEL_HIGH - 0 14 IRQ_TYPE_LEVEL_HIGH - 0 15 IRQ_TYPE_LEVEL_HIGH - 0 16 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -157,14 +157,14 @@ <0xe6900028 1>, <0xe6900048 1>, <0xe6900068 1>; - interrupts = <0 17 IRQ_TYPE_LEVEL_HIGH - 0 18 IRQ_TYPE_LEVEL_HIGH - 0 19 IRQ_TYPE_LEVEL_HIGH - 0 20 IRQ_TYPE_LEVEL_HIGH - 0 21 IRQ_TYPE_LEVEL_HIGH - 0 22 IRQ_TYPE_LEVEL_HIGH - 0 23 IRQ_TYPE_LEVEL_HIGH - 0 24 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -179,14 +179,14 @@ <0xe690002c 1>, <0xe690004c 1>, <0xe690006c 1>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH - 0 26 IRQ_TYPE_LEVEL_HIGH - 0 27 IRQ_TYPE_LEVEL_HIGH - 0 28 IRQ_TYPE_LEVEL_HIGH - 0 29 IRQ_TYPE_LEVEL_HIGH - 0 30 IRQ_TYPE_LEVEL_HIGH - 0 31 IRQ_TYPE_LEVEL_HIGH - 0 32 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -197,10 +197,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6820000 0x425>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH - 0 168 IRQ_TYPE_LEVEL_HIGH - 0 169 IRQ_TYPE_LEVEL_HIGH - 0 170 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks SH73A0_CLK_IIC0>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -211,10 +211,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6822000 0x425>; - interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH - 0 52 IRQ_TYPE_LEVEL_HIGH - 0 53 IRQ_TYPE_LEVEL_HIGH - 0 54 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_IIC1>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -225,10 +225,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6824000 0x425>; - interrupts = <0 171 IRQ_TYPE_LEVEL_HIGH - 0 172 IRQ_TYPE_LEVEL_HIGH - 0 173 IRQ_TYPE_LEVEL_HIGH - 0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks SH73A0_CLK_IIC2>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -239,10 +239,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6826000 0x425>; - interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH - 0 184 IRQ_TYPE_LEVEL_HIGH - 0 185 IRQ_TYPE_LEVEL_HIGH - 0 186 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks SH73A0_CLK_IIC3>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -253,10 +253,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6828000 0x425>; - interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH - 0 188 IRQ_TYPE_LEVEL_HIGH - 0 189 IRQ_TYPE_LEVEL_HIGH - 0 190 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks SH73A0_CLK_IIC4>; power-domains = <&pd_c5>; status = "disabled"; @@ -265,8 +265,8 @@ mmcif: mmc@e6bd0000 { compatible = "renesas,sh-mmcif"; reg = <0xe6bd0000 0x100>; - interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH - 0 141 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_MMCIF0>; power-domains = <&pd_a3sp>; reg-io-width = <4>; @@ -276,7 +276,7 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6e20000 0x0064>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks SH73A0_CLK_MSIOF0>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -287,7 +287,7 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6e10000 0x0064>; - interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_MSIOF1>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -298,7 +298,7 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6e00000 0x0064>; - interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_MSIOF2>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -309,7 +309,7 @@ msiof3: spi@e6c90000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6c90000 0x0064>; - interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_MSIOF3>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -320,9 +320,9 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-sh73a0"; reg = <0xee100000 0x100>; - interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH - 0 84 IRQ_TYPE_LEVEL_HIGH - 0 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SDHI0>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -333,8 +333,8 @@ sdhi1: sd@ee120000 { compatible = "renesas,sdhi-sh73a0"; reg = <0xee120000 0x100>; - interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH - 0 89 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SDHI1>; power-domains = <&pd_a3sp>; toshiba,mmc-wrprotect-disable; @@ -345,8 +345,8 @@ sdhi2: sd@ee140000 { compatible = "renesas,sdhi-sh73a0"; reg = <0xee140000 0x100>; - interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH - 0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SDHI2>; power-domains = <&pd_a3sp>; toshiba,mmc-wrprotect-disable; @@ -357,9 +357,9 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c40000 0x100>; - interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -367,9 +367,9 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c50000 0x100>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -377,9 +377,9 @@ scifa2: serial@e6c60000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c60000 0x100>; - interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -387,9 +387,9 @@ scifa3: serial@e6c70000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c70000 0x100>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -397,9 +397,9 @@ scifa4: serial@e6c80000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c80000 0x100>; - interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -407,9 +407,9 @@ scifa5: serial@e6cb0000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cb0000 0x100>; - interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -417,9 +417,9 @@ scifa6: serial@e6cc0000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cc0000 0x100>; - interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SCIFA6>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -427,9 +427,9 @@ scifa7: serial@e6cd0000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cd0000 0x100>; - interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA7>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -437,9 +437,9 @@ scifb: serial@e6c30000 { compatible = "renesas,scifb-sh73a0", "renesas,scifb"; reg = <0xe6c30000 0x100>; - interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFB>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -579,7 +579,7 @@ #sound-dai-cells = <1>; compatible = "renesas,fsi2-sh73a0", "renesas,sh_fsi2"; reg = <0xec230000 0x400>; - interrupts = <0 146 0x4>; + interrupts = ; power-domains = <&pd_a4mp>; status = "disabled"; }; @@ -591,7 +591,7 @@ #size-cells = <1>; ranges = <0 0 0x20000000>; reg = <0xfec10000 0x400>; - interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&zb_clk>; power-domains = <&pd_a4s>; }; diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi index d0c743853318..27a333eb8987 100644 --- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi @@ -127,22 +127,14 @@ }; mmcsd_default_mode: mmcsd_default { mmcsd_default_cfg1 { - /* MCCLK */ - pins = "GPIO8_B10"; - ste,output = <0>; - }; - mmcsd_default_cfg2 { - /* MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2 */ - pins = "GPIO10_C11", "GPIO15_A12", - "GPIO16_C13", "GPIO23_D15"; - ste,output = <1>; - }; - mmcsd_default_cfg3 { - /* MCCMD, MCDAT3-0, MCMSFBCLK */ - pins = "GPIO9_A10", "GPIO11_B11", - "GPIO12_A11", "GPIO13_C12", - "GPIO14_B12", "GPIO24_C15"; - ste,input = <1>; + /* + * MCCLK, MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2 + * MCCMD, MCDAT3-0, MCMSFBCLK + */ + pins = "GPIO8_B10", "GPIO9_A10", "GPIO10_C11", "GPIO11_B11", + "GPIO12_A11", "GPIO13_C12", "GPIO14_B12", "GPIO15_A12", + "GPIO16_C13", "GPIO23_D15", "GPIO24_C15"; + ste,output = <2>; }; }; }; @@ -802,10 +794,21 @@ clock-names = "mclk", "apb_pclk"; interrupt-parent = <&vica>; interrupts = <22>; - max-frequency = <48000000>; + max-frequency = <400000>; bus-width = <4>; cap-mmc-highspeed; cap-sd-highspeed; + full-pwr-cycle; + /* + * The STw4811 circuit used with the Nomadik strictly + * requires that all of these signal direction pins be + * routed and used for its 4-bit levelshifter. + */ + st,sig-dir-dat0; + st,sig-dir-dat2; + st,sig-dir-dat31; + st,sig-dir-cmd; + st,sig-pin-fbclk; pinctrl-names = "default"; pinctrl-0 = <&mmcsd_default_mux>, <&mmcsd_default_mode>; vmmc-supply = <&vmmc_regulator>; diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts index 53660894ea95..023b03efa5ff 100644 --- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts @@ -45,6 +45,7 @@ #include "sunxi-common-regulators.dtsi" #include #include +#include / { model = "Chuwi V7 CW0825"; @@ -88,6 +89,15 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; status = "okay"; + + ft5306de4: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + interrupt-parent = <&pio>; + interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <1024>; + touchscreen-size-y = <768>; + }; }; &lradc { diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts index 77c31dab86b1..04b0d2d1ae6c 100644 --- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts +++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts @@ -48,6 +48,7 @@ #include #include +#include / { model = "INet-97F Rev 02"; @@ -93,6 +94,15 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; status = "okay"; + + ft5406ee8: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + interrupt-parent = <&pio>; + interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + }; }; &lradc { diff --git a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts index ca49b0d0ce1e..bba4f9cf9bf5 100644 --- a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts +++ b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts @@ -253,6 +253,15 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; status = "okay"; + + ft5406ee8: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + interrupt-parent = <&pio>; + interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + }; }; &lradc { diff --git a/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts b/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts index 985e15503378..4e798f014c99 100644 --- a/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts +++ b/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts @@ -1,5 +1,6 @@ /* * Copyright 2015 Josef Gajdusek + * Copyright 2015 - Marcus Cooper * * 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 @@ -42,22 +43,11 @@ /dts-v1/; #include "sun4i-a10.dtsi" -#include "sunxi-common-regulators.dtsi" - -#include -#include +#include "sunxi-itead-core-common.dtsi" / { model = "Iteaduino Plus A10"; compatible = "itead,iteaduino-plus-a10", "allwinner,sun4i-a10"; - - aliases { - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; }; &ahci { @@ -65,18 +55,6 @@ status = "okay"; }; -&cpu0 { - cpu-supply = <®_dcdc2>; -}; - -&ehci0 { - status = "okay"; -}; - -&ehci1 { - status = "okay"; -}; - &emac { pinctrl-names = "default"; pinctrl-0 = <&emac_pins_a>; @@ -89,12 +67,7 @@ }; &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; - axp209: pmic@34 { - reg = <0x34>; interrupts = <0>; }; }; @@ -135,68 +108,13 @@ status = "okay"; }; -&ohci0 { - status = "okay"; -}; - -&ohci1 { - status = "okay"; -}; - ®_ahci_5v { status = "okay"; }; -#include "axp209.dtsi" - -®_dcdc2 { - regulator-always-on; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1450000>; - regulator-name = "vdd-cpu"; -}; - -®_dcdc3 { - regulator-always-on; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1400000>; - regulator-name = "vdd-int-dll"; -}; - -®_ldo1 { - regulator-name = "vdd-rtc"; -}; - -®_ldo2 { - regulator-always-on; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-name = "avcc"; -}; - -®_usb1_vbus { - status = "okay"; -}; - -®_usb2_vbus { - status = "okay"; -}; - &spi0 { pinctrl-names = "default"; pinctrl-0 = <&spi0_pins_a>, <&spi0_cs0_pins_a>; status = "okay"; }; - -&uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; - status = "okay"; -}; - -&usbphy { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; - status = "okay"; -}; diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts index 530ab28e9ca2..f6898c6b84d4 100644 --- a/arch/arm/boot/dts/sun5i-r8-chip.dts +++ b/arch/arm/boot/dts/sun5i-r8-chip.dts @@ -70,6 +70,10 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + &ehci0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index b6ad7850fac6..7a198dcd4ae8 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -65,7 +65,7 @@ compatible = "allwinner,simple-framebuffer", "simple-framebuffer"; allwinner,pipeline = "de_be0-lcd0-hdmi"; - clocks = <&pll6 0>; + clocks = <&pll6>; status = "disabled"; }; @@ -73,7 +73,7 @@ compatible = "allwinner,simple-framebuffer", "simple-framebuffer"; allwinner,pipeline = "de_be0-lcd0"; - clocks = <&pll6 0>; + clocks = <&pll6>; status = "disabled"; }; }; @@ -201,11 +201,11 @@ }; pll6: clk@01c20028 { - #clock-cells = <1>; + #clock-cells = <0>; compatible = "allwinner,sun6i-a31-pll6-clk"; reg = <0x01c20028 0x4>; clocks = <&osc24M>; - clock-output-names = "pll6", "pll6x2"; + clock-output-names = "pll6"; }; cpu: cpu@01c20050 { @@ -235,7 +235,7 @@ #clock-cells = <0>; compatible = "allwinner,sun6i-a31-ahb1-clk"; reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>; + clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6>; clock-output-names = "ahb1"; /* @@ -244,7 +244,7 @@ * controller requires AHB1 clocked from PLL6. */ assigned-clocks = <&ahb1>; - assigned-clock-parents = <&pll6 0>; + assigned-clock-parents = <&pll6>; }; ahb1_gates: clk@01c20060 { @@ -307,7 +307,7 @@ #clock-cells = <0>; compatible = "allwinner,sun4i-a10-apb1-clk"; reg = <0x01c20058 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>; + clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; clock-output-names = "apb2"; }; @@ -331,7 +331,7 @@ #clock-cells = <1>; compatible = "allwinner,sun4i-a10-mmc-clk"; reg = <0x01c20088 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "mmc0", "mmc0_output", "mmc0_sample"; @@ -341,7 +341,7 @@ #clock-cells = <1>; compatible = "allwinner,sun4i-a10-mmc-clk"; reg = <0x01c2008c 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "mmc1", "mmc1_output", "mmc1_sample"; @@ -351,7 +351,7 @@ #clock-cells = <1>; compatible = "allwinner,sun4i-a10-mmc-clk"; reg = <0x01c20090 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "mmc2", "mmc2_output", "mmc2_sample"; @@ -361,7 +361,7 @@ #clock-cells = <1>; compatible = "allwinner,sun4i-a10-mmc-clk"; reg = <0x01c20094 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "mmc3", "mmc3_output", "mmc3_sample"; @@ -371,7 +371,7 @@ #clock-cells = <0>; compatible = "allwinner,sun4i-a10-mod0-clk"; reg = <0x01c2009c 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "ss"; }; @@ -379,7 +379,7 @@ #clock-cells = <0>; compatible = "allwinner,sun4i-a10-mod0-clk"; reg = <0x01c200a0 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "spi0"; }; @@ -387,7 +387,7 @@ #clock-cells = <0>; compatible = "allwinner,sun4i-a10-mod0-clk"; reg = <0x01c200a4 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "spi1"; }; @@ -395,7 +395,7 @@ #clock-cells = <0>; compatible = "allwinner,sun4i-a10-mod0-clk"; reg = <0x01c200a8 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "spi2"; }; @@ -403,7 +403,7 @@ #clock-cells = <0>; compatible = "allwinner,sun4i-a10-mod0-clk"; reg = <0x01c200ac 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "spi3"; }; @@ -709,6 +709,16 @@ allwinner,pull = ; }; + mmc3_8bit_emmc_pins: mmc3@1 { + allwinner,pins = "PC6", "PC7", "PC8", "PC9", + "PC10", "PC11", "PC12", + "PC13", "PC14", "PC15", + "PC24"; + allwinner,function = "mmc3"; + allwinner,drive = ; + allwinner,pull = ; + }; + gmac_pins_mii_a: gmac_mii@0 { allwinner,pins = "PA0", "PA1", "PA2", "PA3", "PA8", "PA9", "PA11", @@ -1042,8 +1052,8 @@ ar100: ar100_clk { compatible = "allwinner,sun6i-a31-ar100-clk"; #clock-cells = <0>; - clocks = <&osc32k>, <&osc24M>, <&pll6 0>, - <&pll6 0>; + clocks = <&osc32k>, <&osc24M>, <&pll6>, + <&pll6>; clock-output-names = "ar100"; }; diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi index ea69fb8ad4d8..4ec0c8679b2e 100644 --- a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi +++ b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi @@ -61,12 +61,14 @@ }; /* eMMC on core board */ -&mmc2 { +&mmc3 { pinctrl-names = "default"; - pinctrl-0 = <&mmc2_8bit_emmc_pins>; + pinctrl-0 = <&mmc3_8bit_emmc_pins>; vmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_dcdc1>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; diff --git a/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts b/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts new file mode 100644 index 000000000000..661c21d9bdbd --- /dev/null +++ b/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts @@ -0,0 +1,125 @@ +/* + * Copyright 2015 - Marcus Cooper + * + * 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 "sun7i-a20.dtsi" +#include "sunxi-itead-core-common.dtsi" + +/ { + model = "Itead Ibox A20"; + compatible = "itead,itead-ibox-a20", "allwinner,sun7i-a20"; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_itead_core>; + + green { + label = "itead_core:green:usr"; + gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + blue { + label = "itead_core:blue:usr"; + gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; +}; + +&ahci { + target-supply = <®_ahci_5v>; + status = "okay"; +}; + +&codec { + status = "okay"; +}; + +&gmac { + pinctrl-names = "default"; + pinctrl-0 = <&gmac_pins_mii_a>; + phy = <&phy1>; + phy-mode = "mii"; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + +&i2c0 { + axp209: pmic@34 { + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&ir0 { + pinctrl-names = "default"; + pinctrl-0 = <&ir0_rx_pins_a>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ + cd-inverted; + status = "okay"; +}; + +&pio { + led_pins_itead_core: led_pins@0 { + allwinner,pins = "PH20","PH21"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +®_ahci_5v { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi index 6f88fb0ddbc7..783b4b8b7c18 100644 --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi @@ -60,7 +60,7 @@ compatible = "allwinner,simple-framebuffer", "simple-framebuffer"; allwinner,pipeline = "de_be0-lcd0"; - clocks = <&pll6 0>; + clocks = <&pll6>; status = "disabled"; }; }; @@ -129,11 +129,20 @@ }; pll6: clk@01c20028 { - #clock-cells = <1>; + #clock-cells = <0>; compatible = "allwinner,sun6i-a31-pll6-clk"; reg = <0x01c20028 0x4>; clocks = <&osc24M>; - clock-output-names = "pll6", "pll6x2"; + clock-output-names = "pll6"; + }; + + pll6x2: pll6x2_clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + clock-div = <1>; + clock-mult = <2>; + clocks = <&pll6>; + clock-output-names = "pll6-2x"; }; cpu: cpu_clk@01c20050 { @@ -163,7 +172,7 @@ #clock-cells = <0>; compatible = "allwinner,sun6i-a31-ahb1-clk"; reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>; + clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6>; clock-output-names = "ahb1"; }; @@ -190,7 +199,7 @@ #clock-cells = <0>; compatible = "allwinner,sun4i-a10-apb1-clk"; reg = <0x01c20058 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>; + clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; clock-output-names = "apb2"; }; @@ -213,7 +222,7 @@ #clock-cells = <1>; compatible = "allwinner,sun4i-a10-mmc-clk"; reg = <0x01c20088 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "mmc0", "mmc0_output", "mmc0_sample"; @@ -223,7 +232,7 @@ #clock-cells = <1>; compatible = "allwinner,sun4i-a10-mmc-clk"; reg = <0x01c2008c 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "mmc1", "mmc1_output", "mmc1_sample"; @@ -233,7 +242,7 @@ #clock-cells = <1>; compatible = "allwinner,sun4i-a10-mmc-clk"; reg = <0x01c20090 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "mmc2", "mmc2_output", "mmc2_sample"; @@ -381,7 +390,7 @@ allwinner,pins = "PC5", "PC6", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", - "PC15"; + "PC15", "PC16"; allwinner,function = "mmc2"; allwinner,drive = ; allwinner,pull = ; diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 92e6616979ea..5e589c1ddda9 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -79,7 +79,7 @@ #clock-cells = <0>; compatible = "allwinner,sun8i-a23-mbus-clk"; reg = <0x01c2015c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5>; + clocks = <&osc24M>, <&pll6x2>, <&pll5>; clock-output-names = "mbus"; }; }; diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts index 13ce68f06dd6..bd2a3beb4629 100644 --- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts +++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts @@ -109,10 +109,13 @@ vmmc-supply = <®_vcc3v0>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; &mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = ; /* eMMC is missing pull-ups */ allwinner,pull = ; }; diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi index 001d8402ca18..f3eb618bcfa7 100644 --- a/arch/arm/boot/dts/sun8i-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a33.dtsi @@ -103,7 +103,7 @@ #clock-cells = <0>; compatible = "allwinner,sun4i-a10-mod0-clk"; reg = <0x01c2009c 0x4>; - clocks = <&osc24M>, <&pll6 0>; + clocks = <&osc24M>, <&pll6>; clock-output-names = "ss"; }; @@ -111,7 +111,7 @@ #clock-cells = <0>; compatible = "allwinner,sun8i-a23-mbus-clk"; reg = <0x01c2015c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5>, <&pll11>; + clocks = <&osc24M>, <&pll6x2>, <&pll5>, <&pll11>; clock-output-names = "mbus"; }; }; diff --git a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts new file mode 100644 index 000000000000..342e1d33fa1c --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Vishnu Patekar + * Vishnu Patekar + * + * 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" + +/ { + model = "Allwinner A83T H8Homlet Proto Dev Board v2.0"; + compatible = "allwinner,h8homlet-v2", "allwinner,sun8i-a83t"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_b>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts new file mode 100644 index 000000000000..88b1e0970b8d --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts @@ -0,0 +1,65 @@ +/* + * Copyright 2015 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" + +/ { + model = "Cubietech Cubietruck Plus"; + compatible = "cubietech,cubietruck-plus", "allwinner,sun8i-a83t"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_b>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi new file mode 100644 index 000000000000..d3473f81b12f --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -0,0 +1,228 @@ +/* + * Copyright 2015 Vishnu Patekar + * + * Vishnu Patekar + * + * 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 "skeleton.dtsi" + +#include + +#include + +/ { + interrupt-parent = <&gic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0>; + }; + + cpu@1 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <1>; + }; + + cpu@2 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <2>; + }; + + cpu@3 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <3>; + }; + + cpu@100 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x100>; + }; + + cpu@101 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x101>; + }; + + cpu@102 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x102>; + }; + + cpu@103 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x103>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = , + , + , + ; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* TODO: PRCM block has a mux for this. */ + osc24M: osc24M_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "osc24M"; + }; + + /* + * This is called "internal OSC" in some places. + * It is an internal RC-based oscillator. + * TODO: Its controls are in the PRCM block. + */ + osc16M: osc16M_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <16000000>; + clock-output-names = "osc16M"; + }; + + osc16Md512: osc16Md512_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <512>; + clock-mult = <1>; + clocks = <&osc16M>; + clock-output-names = "osc16M-d512"; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pio: pinctrl@01c20800 { + compatible = "allwinner,sun8i-a83t-pinctrl"; + interrupts = , + , + ; + reg = <0x01c20800 0x400>; + clocks = <&osc24M>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <3>; + #gpio-cells = <3>; + + mmc0_pins_a: mmc0@0 { + allwinner,pins = "PF0", "PF1", "PF2", + "PF3", "PF4", "PF5"; + allwinner,function = "mmc0"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart0_pins_a: uart0@0 { + allwinner,pins = "PF2", "PF4"; + allwinner,function = "uart0"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart0_pins_b: uart0@1 { + allwinner,pins = "PB9", "PB10"; + allwinner,function = "uart0"; + allwinner,drive = ; + allwinner,pull = ; + }; + }; + + timer@01c20c00 { + compatible = "allwinner,sun4i-a10-timer"; + reg = <0x01c20c00 0xa0>; + interrupts = , + ; + clocks = <&osc24M>; + }; + + watchdog@01c20ca0 { + compatible = "allwinner,sun6i-a31-wdt"; + reg = <0x01c20ca0 0x20>; + interrupts = ; + clocks = <&osc24M>; + }; + + uart0: serial@01c28000 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&osc24M>; + status = "disabled"; + }; + + gic: interrupt-controller@01c81000 { + compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; + reg = <0x01c81000 0x1000>, + <0x01c82000 0x1000>, + <0x01c84000 0x2000>, + <0x01c86000 0x2000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupts = ; + }; + }; +}; diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi index 1524130e43c9..6f6b4e469ac9 100644 --- a/arch/arm/boot/dts/sun8i-h3.dtsi +++ b/arch/arm/boot/dts/sun8i-h3.dtsi @@ -121,11 +121,11 @@ }; pll6: clk@01c20028 { - #clock-cells = <1>; + #clock-cells = <0>; compatible = "allwinner,sun6i-a31-pll6-clk"; reg = <0x01c20028 0x4>; clocks = <&osc24M>; - clock-output-names = "pll6", "pll6x2"; + clock-output-names = "pll6"; }; pll6d2: pll6d2_clk { @@ -133,15 +133,24 @@ compatible = "fixed-factor-clock"; clock-div = <2>; clock-mult = <1>; - clocks = <&pll6 0>; - clock-output-names = "pll6d2"; + clocks = <&pll6>; + clock-output-names = "pll6-d2"; }; - /* dummy clock until pll6 can be reused */ - pll8: pll8_clk { + pll6x2: pll6x2_clk { #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <1>; + compatible = "fixed-factor-clock"; + clock-div = <1>; + clock-mult = <2>; + clocks = <&pll6>; + clock-output-names = "pll6-2x"; + }; + + pll8: clk@01c20044 { + #clock-cells = <0>; + compatible = "allwinner,sun6i-a31-pll6-clk"; + reg = <0x01c20044 0x4>; + clocks = <&osc24M>; clock-output-names = "pll8"; }; @@ -165,7 +174,7 @@ #clock-cells = <0>; compatible = "allwinner,sun6i-a31-ahb1-clk"; reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>; + clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6>; clock-output-names = "ahb1"; }; @@ -189,7 +198,7 @@ #clock-cells = <0>; compatible = "allwinner,sun4i-a10-apb1-clk"; reg = <0x01c20058 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>; + clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; clock-output-names = "apb2"; }; @@ -243,7 +252,7 @@ #clock-cells = <1>; compatible = "allwinner,sun4i-a10-mmc-clk"; reg = <0x01c20088 0x4>; - clocks = <&osc24M>, <&pll6 0>, <&pll8>; + clocks = <&osc24M>, <&pll6>, <&pll8>; clock-output-names = "mmc0", "mmc0_output", "mmc0_sample"; @@ -253,7 +262,7 @@ #clock-cells = <1>; compatible = "allwinner,sun4i-a10-mmc-clk"; reg = <0x01c2008c 0x4>; - clocks = <&osc24M>, <&pll6 0>, <&pll8>; + clocks = <&osc24M>, <&pll6>, <&pll8>; clock-output-names = "mmc1", "mmc1_output", "mmc1_sample"; @@ -263,7 +272,7 @@ #clock-cells = <1>; compatible = "allwinner,sun4i-a10-mmc-clk"; reg = <0x01c20090 0x4>; - clocks = <&osc24M>, <&pll6 0>, <&pll8>; + clocks = <&osc24M>, <&pll6>, <&pll8>; clock-output-names = "mmc2", "mmc2_output", "mmc2_sample"; @@ -273,7 +282,7 @@ #clock-cells = <0>; compatible = "allwinner,sun8i-a23-mbus-clk"; reg = <0x01c2015c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5>; + clocks = <&osc24M>, <&pll6x2>, <&pll5>; clock-output-names = "mbus"; }; }; diff --git a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts index 382bd9fc5647..eb2ccd0a3bd5 100644 --- a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts +++ b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts @@ -111,9 +111,15 @@ vmmc-supply = <®_vcc3v0>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; +&mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = ; +}; + &r_ir { status = "okay"; }; diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts index c0060e4f7379..d7a20d92b114 100644 --- a/arch/arm/boot/dts/sun9i-a80-optimus.dts +++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts @@ -109,17 +109,6 @@ status = "okay"; }; -&i2c3 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c3_pins_a>; - status = "okay"; -}; - -&i2c3_pins_a { - /* Enable internal pull-up */ - allwinner,pull = ; -}; - &ohci0 { status = "okay"; }; @@ -174,9 +163,15 @@ vmmc-supply = <®_vcc3v0>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; +&mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = ; +}; + ®_usb1_vbus { pinctrl-0 = <&usb1_vbus_pin_optimus>; gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ @@ -206,17 +201,6 @@ status = "okay"; }; -&uart4 { - pinctrl-names = "default"; - pinctrl-0 = <&uart4_pins_a>; - status = "okay"; -}; - -&uart4_pins_a { - /* Enable internal pull-up */ - allwinner,pull = ; -}; - &usbphy1 { phy-supply = <®_usb1_vbus>; status = "okay"; diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi index e838f206f2a0..f68b3242b33a 100644 --- a/arch/arm/boot/dts/sun9i-a80.dtsi +++ b/arch/arm/boot/dts/sun9i-a80.dtsi @@ -543,7 +543,7 @@ }; mmc0: mmc@01c0f000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c0f000 0x1000>; clocks = <&mmc_config_clk 0>, <&mmc0_clk 0>, <&mmc0_clk 1>, <&mmc0_clk 2>; @@ -557,7 +557,7 @@ }; mmc1: mmc@01c10000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c10000 0x1000>; clocks = <&mmc_config_clk 1>, <&mmc1_clk 0>, <&mmc1_clk 1>, <&mmc1_clk 2>; @@ -571,7 +571,7 @@ }; mmc2: mmc@01c11000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c11000 0x1000>; clocks = <&mmc_config_clk 2>, <&mmc2_clk 0>, <&mmc2_clk 1>, <&mmc2_clk 2>; @@ -585,7 +585,7 @@ }; mmc3: mmc@01c12000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c12000 0x1000>; clocks = <&mmc_config_clk 3>, <&mmc3_clk 0>, <&mmc3_clk 1>, <&mmc3_clk 2>; @@ -704,7 +704,8 @@ mmc2_8bit_pins: mmc2_8bit { allwinner,pins = "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", - "PC13", "PC14", "PC15"; + "PC13", "PC14", "PC15", + "PC16"; allwinner,function = "mmc2"; allwinner,drive = ; allwinner,pull = ; diff --git a/arch/arm/boot/dts/sunxi-itead-core-common.dtsi b/arch/arm/boot/dts/sunxi-itead-core-common.dtsi new file mode 100644 index 000000000000..2565d5137a17 --- /dev/null +++ b/arch/arm/boot/dts/sunxi-itead-core-common.dtsi @@ -0,0 +1,136 @@ +/* + * Copyright 2015 - Marcus Cooper + * + * 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 "sunxi-common-regulators.dtsi" + +/ { + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + + axp209: pmic@34 { + reg = <0x34>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +#include "axp209.dtsi" + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-int-dll"; +}; + +®_ldo1 { + regulator-name = "vdd-rtc"; +}; + +®_ldo2 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + +®_usb1_vbus { + status = "okay"; +}; + +®_usb2_vbus { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_usb1_vbus>; + usb2_vbus-supply = <®_usb2_vbus>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index d845bd1448b5..5017ed8ad5c4 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi @@ -256,7 +256,7 @@ * driver and APB DMA based serial driver for higher baudrate * and performace. To enable the 8250 based driver, the compatible * is "nvidia,tegra114-uart", "nvidia,tegra20-uart" and to enable - * the APB DMA based serial driver, the comptible is + * the APB DMA based serial driver, the compatible is * "nvidia,tegra114-hsuart", "nvidia,tegra30-hsuart". */ uarta: serial@70006000 { diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts index 66b4451eb2ca..4ee2e63e11d0 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts +++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts @@ -12,7 +12,11 @@ aliases { rtc0 = "/i2c@0,7000d000/pmic@40"; rtc1 = "/rtc@0,7000e000"; + + /* This order keeps the mapping DB9 connector <-> ttyS0 */ serial0 = &uartd; + serial1 = &uarta; + serial2 = &uartb; }; memory { @@ -1367,6 +1371,28 @@ }; }; + /* + * First high speed UART, exposed on the expansion connector J3A2 + * Pin 41: BR_UART1_TXD + * Pin 44: BR_UART1_RXD + */ + serial@0,70006000 { + compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; + status = "okay"; + }; + + /* + * Second high speed UART, exposed on the expansion connector J3A2 + * Pin 65: UART2_RXD + * Pin 68: UART2_TXD + * Pin 71: UART2_CTS_L + * Pin 74: UART2_RTS_L + */ + serial@0,70006040 { + compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; + status = "okay"; + }; + /* DB9 serial port */ serial@0,70006300 { status = "okay"; diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 68669f791c8b..995289b59e11 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -322,7 +322,7 @@ * driver and APB DMA based serial driver for higher baudrate * and performace. To enable the 8250 based driver, the compatible * is "nvidia,tegra124-uart", "nvidia,tegra20-uart" and to enable - * the APB DMA based serial driver, the comptible is + * the APB DMA based serial driver, the compatible is * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart". */ uarta: serial@0,70006000 { diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 33173e1bace9..8fb61b93c226 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -309,7 +309,7 @@ * driver and APB DMA based serial driver for higher baudrate * and performace. To enable the 8250 based driver, the compatible * is "nvidia,tegra20-uart" and to enable the APB DMA based serial - * driver, the comptible is "nvidia,tegra20-hsuart". + * driver, the compatible is "nvidia,tegra20-hsuart". */ uarta: serial@70006000 { compatible = "nvidia,tegra20-uart"; diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 313e260529a3..c6edc8cea34e 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -371,7 +371,7 @@ * driver and APB DMA based serial driver for higher baudrate * and performace. To enable the 8250 based driver, the compatible * is "nvidia,tegra30-uart", "nvidia,tegra20-uart" and to enable - * the APB DMA based serial driver, the comptible is + * the APB DMA based serial driver, the compatible is * "nvidia,tegra30-hsuart", "nvidia,tegra20-hsuart". */ uarta: serial@70006000 { diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index 6e556be42ccd..c4312c4a3767 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -10,7 +10,10 @@ / { bl: backlight { compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_bl_on>; pwms = <&pwm0 0 5000000 0>; + enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; status = "disabled"; }; }; @@ -195,6 +198,12 @@ >; }; + pinctrl_gpio_bl_on: gpio_bl_on { + fsl,pins = < + VF610_PAD_PTC0__GPIO_45 0x22ef + >; + }; + pinctrl_i2c0: i2c0grp { fsl,pins = < VF610_PAD_PTB14__I2C0_SCL 0x37ff diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi index a9ceb5bac40e..a5f07e3664da 100644 --- a/arch/arm/boot/dts/vfxxx.dtsi +++ b/arch/arm/boot/dts/vfxxx.dtsi @@ -16,6 +16,8 @@ aliases { can0 = &can0; can1 = &can1; + ethernet0 = &fec0; + ethernet1 = &fec1; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -174,6 +176,34 @@ status = "disabled"; }; + sai0: sai@4002f000 { + compatible = "fsl,vf610-sai"; + reg = <0x4002f000 0x1000>; + interrupts = <84 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_SAI0>, + <&clks VF610_CLK_SAI0_DIV>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "tx", "rx"; + dmas = <&edma0 0 17>, + <&edma0 0 16>; + status = "disabled"; + }; + + sai1: sai@40030000 { + compatible = "fsl,vf610-sai"; + reg = <0x40030000 0x1000>; + interrupts = <85 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_SAI1>, + <&clks VF610_CLK_SAI1_DIV>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "tx", "rx"; + dmas = <&edma0 0 19>, + <&edma0 0 18>; + status = "disabled"; + }; + sai2: sai@40031000 { compatible = "fsl,vf610-sai"; reg = <0x40031000 0x1000>; @@ -188,6 +218,20 @@ status = "disabled"; }; + sai3: sai@40032000 { + compatible = "fsl,vf610-sai"; + reg = <0x40032000 0x1000>; + interrupts = <87 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_SAI3>, + <&clks VF610_CLK_SAI3_DIV>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "tx", "rx"; + dmas = <&edma0 1 9>, + <&edma0 1 8>; + status = "disabled"; + }; + pit: pit@40037000 { compatible = "fsl,vf610-pit"; reg = <0x40037000 0x1000>; diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c index 2dc6da70ae59..d3c0e69df259 100644 --- a/arch/arm/common/icst.c +++ b/arch/arm/common/icst.c @@ -16,7 +16,7 @@ */ #include #include - +#include #include /* @@ -29,7 +29,11 @@ EXPORT_SYMBOL(icst525_s2div); unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco) { - return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); + u64 dividend = p->ref * 2 * (u64)(vco.v + 8); + u32 divisor = (vco.r + 2) * p->s2div[vco.s]; + + do_div(dividend, divisor); + return (unsigned long)dividend; } EXPORT_SYMBOL(icst_hz); diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 24dcd2bb1215..6ffd7e76f3ce 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -26,12 +26,14 @@ CONFIG_ARM_APPENDED_DTB=y CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M" CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT_DETAILS=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPUFREQ_DT=y CONFIG_CPU_IDLE=y CONFIG_ARM_EXYNOS_CPUIDLE=y CONFIG_VFP=y CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -193,7 +195,6 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_MAX8997=y CONFIG_RTC_DRV_MAX77686=y -CONFIG_RTC_DRV_MAX77802=y CONFIG_RTC_DRV_S5M=y CONFIG_RTC_DRV_S3C=y CONFIG_DMADEVICES=y @@ -238,7 +239,12 @@ CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_USER=y -CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_DEV_S5P=y +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM_NEON=m +CONFIG_CRYPTO_SHA256_ARM=m +CONFIG_CRYPTO_SHA512_ARM=m +CONFIG_CRYPTO_AES_ARM_BS=m CONFIG_CRC_CCITT=y CONFIG_FONTS=y CONFIG_FONT_7x14=y diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 2d5253dcc226..25a6066493e4 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -47,6 +47,7 @@ CONFIG_PCI=y CONFIG_PCI_MSI=y CONFIG_PCI_IMX6=y CONFIG_SMP=y +CONFIG_ARM_PSCI=y CONFIG_PREEMPT_VOLUNTARY=y CONFIG_AEABI=y CONFIG_HIGHMEM=y @@ -320,6 +321,8 @@ CONFIG_IIO=y CONFIG_VF610_ADC=y CONFIG_PWM=y CONFIG_PWM_IMX=y +CONFIG_NVMEM=y +CONFIG_NVMEM_IMX_OCOTP=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 314f6be2dca2..e28c660c35e9 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -426,6 +426,7 @@ CONFIG_SUNXI_WATCHDOG=y CONFIG_IMX2_WDT=y CONFIG_TEGRA_WATCHDOG=m CONFIG_MESON_WATCHDOG=y +CONFIG_DW_WATCHDOG=y CONFIG_DIGICOLOR_WATCHDOG=y CONFIG_MFD_AS3711=y CONFIG_MFD_AS3722=y @@ -577,6 +578,7 @@ CONFIG_SND_SOC_WM8978=m CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_MVEBU=y +CONFIG_USB_XHCI_RCAR=m CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MSM=m CONFIG_USB_EHCI_EXYNOS=y @@ -664,7 +666,6 @@ CONFIG_RTC_DRV_MAX8907=y CONFIG_RTC_DRV_MAX8997=m CONFIG_RTC_DRV_MAX77686=y CONFIG_RTC_DRV_RK808=m -CONFIG_RTC_DRV_MAX77802=m CONFIG_RTC_DRV_RS5C372=m CONFIG_RTC_DRV_PALMAS=y CONFIG_RTC_DRV_ST_LPC=y diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig index af29780accdc..9317e5a5b730 100644 --- a/arch/arm/configs/mvebu_v5_defconfig +++ b/arch/arm/configs/mvebu_v5_defconfig @@ -137,6 +137,7 @@ CONFIG_SND=y CONFIG_SND_SOC=y CONFIG_SND_KIRKWOOD_SOC=y CONFIG_SND_SOC_ALC5623=y +CONFIG_SND_SOC_CS42L51_I2C=y CONFIG_SND_SIMPLE_CARD=y CONFIG_HID_DRAGONRISE=y CONFIG_HID_GYRATION=y diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig index c6729bf0a8dd..cf363abd974e 100644 --- a/arch/arm/configs/mvebu_v7_defconfig +++ b/arch/arm/configs/mvebu_v7_defconfig @@ -109,6 +109,7 @@ CONFIG_USB_XHCI_MVEBU=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_STORAGE=y +CONFIG_NOP_USB_XCEIV=y CONFIG_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index b47e7c6628c9..1b2d9b377976 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -141,6 +141,8 @@ CONFIG_IIO=y CONFIG_IIO_SYSFS_TRIGGER=y CONFIG_PWM=y CONFIG_PWM_MXS=y +CONFIG_NVMEM=y +CONFIG_NVMEM_MXS_OCOTP=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT3_FS=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index c5e1943e5427..a7151744b85c 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -50,6 +50,7 @@ CONFIG_SOC_AM33XX=y CONFIG_SOC_AM43XX=y CONFIG_SOC_DRA7XX=y CONFIG_ARM_THUMBEE=y +CONFIG_ARM_KERNMEM_PERMS=y CONFIG_ARM_ERRATA_411920=y CONFIG_ARM_ERRATA_430973=y CONFIG_SMP=y @@ -177,6 +178,7 @@ CONFIG_TI_CPTS=y CONFIG_AT803X_PHY=y CONFIG_SMSC_PHY=y CONFIG_USB_USBNET=m +CONFIG_USB_NET_SMSC75XX=m CONFIG_USB_NET_SMSC95XX=m CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y @@ -354,6 +356,11 @@ CONFIG_USB_MUSB_DSPS=m CONFIG_USB_INVENTRA_DMA=y CONFIG_USB_TI_CPPI41_DMA=y CONFIG_USB_DWC3=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_PL2303=m CONFIG_USB_TEST=m CONFIG_AM335X_PHY_USB=y CONFIG_USB_GADGET=m @@ -387,6 +394,7 @@ CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=m CONFIG_LEDS_GPIO=m CONFIG_LEDS_PWM=m +CONFIG_LEDS_PCA963X=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_ONESHOT=m @@ -449,6 +457,8 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_SPLIT=y +CONFIG_DEBUG_INFO_DWARF4=y CONFIG_MAGIC_SYSRQ=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 969738324a5d..b7b714c3958c 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -20,7 +20,6 @@ CONFIG_ARCH_R8A7791=y CONFIG_ARCH_R8A7793=y CONFIG_ARCH_R8A7794=y CONFIG_ARCH_SH73A0=y -CONFIG_CPU_BPREDICT_DISABLE=y CONFIG_PL310_ERRATA_588369=y CONFIG_ARM_ERRATA_754322=y CONFIG_PCI=y @@ -163,6 +162,8 @@ CONFIG_SND_SOC_RSRC_CARD=y CONFIG_SND_SOC_AK4642=y CONFIG_SND_SOC_WM8978=y CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_RCAR=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_R8A66597_HCD=y diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h index e1f07764b0d6..7d919a9b32e5 100644 --- a/arch/arm/include/asm/div64.h +++ b/arch/arm/include/asm/div64.h @@ -74,7 +74,7 @@ static inline uint32_t __div64_32(uint64_t *n, uint32_t base) static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias) { unsigned long long res; - unsigned int tmp = 0; + register unsigned int tmp asm("ip") = 0; if (!bias) { asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" @@ -90,12 +90,12 @@ static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias) : "r" (m), "r" (n) : "cc"); } else { - asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" - "cmn %Q0, %Q1\n\t" - "adcs %R0, %R0, %R1\n\t" - "adc %Q0, %3, #0" - : "=&r" (res) - : "r" (m), "r" (n), "r" (tmp) + asm ( "umull %Q0, %R0, %Q2, %Q3\n\t" + "cmn %Q0, %Q2\n\t" + "adcs %R0, %R0, %R2\n\t" + "adc %Q0, %1, #0" + : "=&r" (res), "+&r" (tmp) + : "r" (m), "r" (n) : "cc"); } diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 194c91b610ff..c35c349da069 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h @@ -79,6 +79,8 @@ #define rr_lo_hi(a1, a2) a1, a2 #endif +#define kvm_ksym_ref(kva) (kva) + #ifndef __ASSEMBLY__ struct kvm; struct kvm_vcpu; diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index c79b57bf71c4..49bf6b1e2177 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -273,14 +273,14 @@ static inline void *phys_to_virt(phys_addr_t x) #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) #define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT) -extern phys_addr_t (*arch_virt_to_idmap)(unsigned long x); +extern unsigned long (*arch_virt_to_idmap)(unsigned long x); /* * These are for systems that have a hardware interconnect supported alias of * physical memory for idmap purposes. Most cases should leave these - * untouched. + * untouched. Note: this can only return addresses less than 4GiB. */ -static inline phys_addr_t __virt_to_idmap(unsigned long x) +static inline unsigned long __virt_to_idmap(unsigned long x) { if (IS_ENABLED(CONFIG_MMU) && arch_virt_to_idmap) return arch_virt_to_idmap(x); diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index a5635444ca41..d7de19a77d51 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -3,8 +3,6 @@ #ifdef __KERNEL__ #include -#include - #include /* for pci_sys_data */ extern unsigned long pcibios_min_io; @@ -41,5 +39,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) } #endif /* __KERNEL__ */ - #endif diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S index 619d8cc1ac12..92c44760d656 100644 --- a/arch/arm/include/debug/imx.S +++ b/arch/arm/include/debug/imx.S @@ -11,6 +11,7 @@ * */ +#include #include "imx-uart.h" /* @@ -34,6 +35,7 @@ .endm .macro senduart,rd,rx + ARM_BE8(rev \rd, \rd) str \rd, [\rx, #0x40] @ TXDATA .endm @@ -42,6 +44,7 @@ .macro busyuart,rd,rx 1002: ldr \rd, [\rx, #0x98] @ SR2 + ARM_BE8(rev \rd, \rd) tst \rd, #1 << 3 @ TXDC beq 1002b @ wait until transmit done .endm diff --git a/arch/arm/include/debug/palmchip.S b/arch/arm/include/debug/palmchip.S new file mode 100644 index 000000000000..6824b2d1c38e --- /dev/null +++ b/arch/arm/include/debug/palmchip.S @@ -0,0 +1,11 @@ +#include + +#undef UART_TX +#undef UART_LSR +#undef UART_MSR + +#define UART_TX 1 +#define UART_LSR 7 +#define UART_MSR 8 + +#include diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h index ede692ffa32e..5dd2528e9e45 100644 --- a/arch/arm/include/uapi/asm/unistd.h +++ b/arch/arm/include/uapi/asm/unistd.h @@ -417,6 +417,7 @@ #define __NR_userfaultfd (__NR_SYSCALL_BASE+388) #define __NR_membarrier (__NR_SYSCALL_BASE+389) #define __NR_mlock2 (__NR_SYSCALL_BASE+390) +#define __NR_copy_file_range (__NR_SYSCALL_BASE+391) /* * The following SWIs are ARM private. diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index ac368bb068d1..dfc7cd6851ad 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -400,6 +400,7 @@ CALL(sys_userfaultfd) CALL(sys_membarrier) CALL(sys_mlock2) + CALL(sys_copy_file_range) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 3ce377f7251f..788e40c1254f 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -1064,7 +1064,6 @@ ENDPROC(vector_\name) .endm .section .stubs, "ax", %progbits -__stubs_start: @ This must be the first word .word vector_swi @@ -1206,10 +1205,10 @@ vector_addrexcptn: .equ vector_fiq_offset, vector_fiq .section .vectors, "ax", %progbits -__vectors_start: +.L__vectors_start: W(b) vector_rst W(b) vector_und - W(ldr) pc, __vectors_start + 0x1000 + W(ldr) pc, .L__vectors_start + 0x1000 W(b) vector_pabt W(b) vector_dabt W(b) vector_addrexcptn diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c index a71501ff6f18..b09561a6d06a 100644 --- a/arch/arm/kernel/hibernate.c +++ b/arch/arm/kernel/hibernate.c @@ -62,7 +62,7 @@ static int notrace arch_save_image(unsigned long unused) ret = swsusp_save(); if (ret == 0) - _soft_restart(virt_to_phys(cpu_resume), false); + _soft_restart(virt_to_idmap(cpu_resume), false); return ret; } @@ -87,7 +87,7 @@ static void notrace arch_restore_image(void *unused) for (pbe = restore_pblist; pbe; pbe = pbe->next) copy_page(pbe->orig_address, pbe->address); - _soft_restart(virt_to_phys(cpu_resume), false); + _soft_restart(virt_to_idmap(cpu_resume), false); } static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata; diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 1d45320ee125..ece04a457486 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -95,7 +95,7 @@ void __init init_IRQ(void) outer_cache.write_sec = machine_desc->l2c_write_sec; ret = l2x0_of_init(machine_desc->l2c_aux_val, machine_desc->l2c_aux_mask); - if (ret) + if (ret && ret != -ENODEV) pr_err("L2C: failed to init: %d\n", ret); } diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 8bf3b7c09888..59fd0e24c56b 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -143,10 +143,8 @@ void (*kexec_reinit)(void); void machine_kexec(struct kimage *image) { - unsigned long page_list; - unsigned long reboot_code_buffer_phys; - unsigned long reboot_entry = (unsigned long)relocate_new_kernel; - unsigned long reboot_entry_phys; + unsigned long page_list, reboot_entry_phys; + void (*reboot_entry)(void); void *reboot_code_buffer; /* @@ -159,9 +157,6 @@ void machine_kexec(struct kimage *image) page_list = image->head & PAGE_MASK; - /* we need both effective and real address here */ - reboot_code_buffer_phys = - page_to_pfn(image->control_code_page) << PAGE_SHIFT; reboot_code_buffer = page_address(image->control_code_page); /* Prepare parameters for reboot_code_buffer*/ @@ -174,10 +169,11 @@ void machine_kexec(struct kimage *image) /* copy our kernel relocation code to the control code page */ reboot_entry = fncpy(reboot_code_buffer, - reboot_entry, + &relocate_new_kernel, relocate_new_kernel_size); - reboot_entry_phys = (unsigned long)reboot_entry + - (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); + + /* get the identity mapping physical address for the reboot code */ + reboot_entry_phys = virt_to_idmap(reboot_entry); pr_info("Bye!\n"); diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c index 38269358fd25..71a2ff9ec490 100644 --- a/arch/arm/kernel/reboot.c +++ b/arch/arm/kernel/reboot.c @@ -50,7 +50,7 @@ static void __soft_restart(void *addr) flush_cache_all(); /* Switch to the identity mapping. */ - phys_reset = (phys_reset_t)(unsigned long)virt_to_idmap(cpu_reset); + phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset); phys_reset((unsigned long)addr); /* Should never get here. */ diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 7d0cba6f1cc5..139791ed473d 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -176,13 +176,13 @@ static struct resource mem_res[] = { .name = "Kernel code", .start = 0, .end = 0, - .flags = IORESOURCE_MEM + .flags = IORESOURCE_SYSTEM_RAM }, { .name = "Kernel data", .start = 0, .end = 0, - .flags = IORESOURCE_MEM + .flags = IORESOURCE_SYSTEM_RAM } }; @@ -851,7 +851,7 @@ static void __init request_standard_resources(const struct machine_desc *mdesc) res->name = "System RAM"; res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 08b7847bf912..ec279d161b32 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -40,7 +40,7 @@ * to run the rebalance_domains for all idle cores and the cpu_capacity can be * updated during this sequence. */ -static DEFINE_PER_CPU(unsigned long, cpu_scale); +static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE; unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu) { @@ -306,8 +306,6 @@ void __init init_cpu_topology(void) cpu_topo->socket_id = -1; cpumask_clear(&cpu_topo->core_sibling); cpumask_clear(&cpu_topo->thread_sibling); - - set_capacity_scale(cpu, SCHED_CAPACITY_SCALE); } smp_wmb(); diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S new file mode 100644 index 000000000000..6f59ef290289 --- /dev/null +++ b/arch/arm/kernel/vmlinux-xip.lds.S @@ -0,0 +1,322 @@ +/* ld script to make ARM Linux kernel + * taken from the i386 version by Russell King + * Written by Martin Mares + */ + +#include +#include +#include +#include +#include +#ifdef CONFIG_DEBUG_RODATA +#include +#endif + +#define PROC_INFO \ + . = ALIGN(4); \ + VMLINUX_SYMBOL(__proc_info_begin) = .; \ + *(.proc.info.init) \ + VMLINUX_SYMBOL(__proc_info_end) = .; + +#define IDMAP_TEXT \ + ALIGN_FUNCTION(); \ + VMLINUX_SYMBOL(__idmap_text_start) = .; \ + *(.idmap.text) \ + VMLINUX_SYMBOL(__idmap_text_end) = .; \ + . = ALIGN(PAGE_SIZE); \ + VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ + *(.hyp.idmap.text) \ + VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; + +#ifdef CONFIG_HOTPLUG_CPU +#define ARM_CPU_DISCARD(x) +#define ARM_CPU_KEEP(x) x +#else +#define ARM_CPU_DISCARD(x) x +#define ARM_CPU_KEEP(x) +#endif + +#if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \ + defined(CONFIG_GENERIC_BUG) +#define ARM_EXIT_KEEP(x) x +#define ARM_EXIT_DISCARD(x) +#else +#define ARM_EXIT_KEEP(x) +#define ARM_EXIT_DISCARD(x) x +#endif + +OUTPUT_ARCH(arm) +ENTRY(stext) + +#ifndef __ARMEB__ +jiffies = jiffies_64; +#else +jiffies = jiffies_64 + 4; +#endif + +SECTIONS +{ + /* + * XXX: The linker does not define how output sections are + * assigned to input sections when there are multiple statements + * matching the same input section name. There is no documented + * order of matching. + * + * unwind exit sections must be discarded before the rest of the + * unwind sections get included. + */ + /DISCARD/ : { + *(.ARM.exidx.exit.text) + *(.ARM.extab.exit.text) + ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text)) + ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text)) + ARM_EXIT_DISCARD(EXIT_TEXT) + ARM_EXIT_DISCARD(EXIT_DATA) + EXIT_CALL +#ifndef CONFIG_MMU + *(.text.fixup) + *(__ex_table) +#endif +#ifndef CONFIG_SMP_ON_UP + *(.alt.smp.init) +#endif + *(.discard) + *(.discard.*) + } + + . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); + + .head.text : { + _text = .; + HEAD_TEXT + } + +#ifdef CONFIG_DEBUG_RODATA + . = ALIGN(1< */ +#ifdef CONFIG_XIP_KERNEL +#include "vmlinux-xip.lds.S" +#else + #include #include #include #include #include -#ifdef CONFIG_ARM_KERNMEM_PERMS +#ifdef CONFIG_DEBUG_RODATA #include #endif @@ -84,17 +88,13 @@ SECTIONS *(.discard.*) } -#ifdef CONFIG_XIP_KERNEL - . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); -#else . = PAGE_OFFSET + TEXT_OFFSET; -#endif .head.text : { _text = .; HEAD_TEXT } -#ifdef CONFIG_ARM_KERNMEM_PERMS +#ifdef CONFIG_DEBUG_RODATA . = ALIGN(1< #include #include +#include #include #include @@ -31,17 +32,9 @@ #include "common.h" #include "mfc.h" -#include "regs-pmu.h" - -void __iomem *pmu_base_addr; static struct map_desc exynos4_iodesc[] __initdata = { { - .virtual = (unsigned long)S5P_VA_SROMC, - .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC), - .length = SZ_4K, - .type = MT_DEVICE, - }, { .virtual = (unsigned long)S5P_VA_CMU, .pfn = __phys_to_pfn(EXYNOS4_PA_CMU), .length = SZ_128K, @@ -64,20 +57,6 @@ static struct map_desc exynos4_iodesc[] __initdata = { }, }; -static struct map_desc exynos5_iodesc[] __initdata = { - { - .virtual = (unsigned long)S5P_VA_SROMC, - .pfn = __phys_to_pfn(EXYNOS5_PA_SROMC), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_CMU, - .pfn = __phys_to_pfn(EXYNOS5_PA_CMU), - .length = 144 * SZ_1K, - .type = MT_DEVICE, - }, -}; - static struct platform_device exynos_cpuidle = { .name = "exynos_cpuidle", #ifdef CONFIG_ARM_EXYNOS_CPUIDLE @@ -149,9 +128,6 @@ static void __init exynos_map_io(void) { if (soc_is_exynos4()) iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc)); - - if (soc_is_exynos5()) - iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc)); } static void __init exynos_init_io(void) @@ -230,6 +206,10 @@ static const struct of_device_id exynos_cpufreq_matches[] = { { .compatible = "samsung,exynos4212", .data = "cpufreq-dt" }, { .compatible = "samsung,exynos4412", .data = "cpufreq-dt" }, { .compatible = "samsung,exynos5250", .data = "cpufreq-dt" }, +#ifndef CONFIG_BL_SWITCHER + { .compatible = "samsung,exynos5420", .data = "cpufreq-dt" }, + { .compatible = "samsung,exynos5800", .data = "cpufreq-dt" }, +#endif { /* sentinel */ } }; diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index de3ae59e1cfb..351e839fcb04 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -25,7 +25,6 @@ #define EXYNOS_PA_CHIPID 0x10000000 #define EXYNOS4_PA_CMU 0x10030000 -#define EXYNOS5_PA_CMU 0x10010000 #define EXYNOS4_PA_DMC0 0x10400000 #define EXYNOS4_PA_DMC1 0x10410000 @@ -33,11 +32,4 @@ #define EXYNOS4_PA_COREPERI 0x10500000 #define EXYNOS4_PA_L2CC 0x10502000 -#define EXYNOS4_PA_SROMC 0x12570000 -#define EXYNOS5_PA_SROMC 0x12250000 - -/* Compatibility UART */ - -#define EXYNOS5440_PA_UART0 0x000B0000 - #endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c index 56978199c479..f086bf615b29 100644 --- a/arch/arm/mach-exynos/mcpm-exynos.c +++ b/arch/arm/mach-exynos/mcpm-exynos.c @@ -16,13 +16,13 @@ #include #include #include +#include #include #include #include #include -#include "regs-pmu.h" #include "common.h" #define EXYNOS5420_CPUS_PER_CLUSTER 4 diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 5bd9559786ba..da46c639f621 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -30,7 +31,6 @@ #include #include "common.h" -#include "regs-pmu.h" extern void exynos4_secondary_startup(void); diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index 9c1506b499bc..b9b9186f8781 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include @@ -29,8 +31,6 @@ #include #include "common.h" -#include "exynos-pmu.h" -#include "regs-pmu.h" static inline void __iomem *exynos_boot_vector_addr(void) { diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c deleted file mode 100644 index dbf9fe98d479..000000000000 --- a/arch/arm/mach-exynos/pmu.c +++ /dev/null @@ -1,967 +0,0 @@ -/* - * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * EXYNOS - CPU PMU(Power Management Unit) support - * - * 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 "exynos-pmu.h" -#include "regs-pmu.h" - -#define PMU_TABLE_END (-1U) - -struct exynos_pmu_conf { - unsigned int offset; - u8 val[NUM_SYS_POWERDOWN]; -}; - -struct exynos_pmu_data { - const struct exynos_pmu_conf *pmu_config; - const struct exynos_pmu_conf *pmu_config_extra; - - void (*pmu_init)(void); - void (*powerdown_conf)(enum sys_powerdown); - void (*powerdown_conf_extra)(enum sys_powerdown); -}; - -struct exynos_pmu_context { - struct device *dev; - const struct exynos_pmu_data *pmu_data; -}; - -static void __iomem *pmu_base_addr; -static struct exynos_pmu_context *pmu_context; - -static inline void pmu_raw_writel(u32 val, u32 offset) -{ - writel_relaxed(val, pmu_base_addr + offset); -} - -static inline u32 pmu_raw_readl(u32 offset) -{ - return readl_relaxed(pmu_base_addr + offset); -} - -static struct exynos_pmu_conf exynos3250_pmu_config[] = { - /* { .offset = offset, .val = { AFTR, W-AFTR, SLEEP } */ - { EXYNOS3_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS3_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS3_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x3} }, - { EXYNOS3_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_LPDDR_PHY_DLL_LOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_CMU_ACLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_SCLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_UPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_EPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS3_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, - { EXYNOS3_TOP_BUS_COREBLK_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS3_TOP_RETENTION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_TOP_PWR_COREBLK_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, - { EXYNOS3_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_LOGIC_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_OSCCLK_GATE_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS3_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_EXT_REGULATOR_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_GPIO_MODE_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_TOP_ASB_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_TOP_ASB_ISOLATION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_CAM_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_LCD0_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_MAUDIO_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { PMU_TABLE_END,}, -}; - -static const struct exynos_pmu_conf exynos4210_pmu_config[] = { - /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ - { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, - { S5P_ARM_CORE1_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_DIS_IRQ_CORE1, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_CENTRAL1, { 0x0, 0x0, 0x0 } }, - { S5P_ARM_COMMON_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_L2_0_LOWPWR, { 0x2, 0x2, 0x3 } }, - { S5P_L2_1_LOWPWR, { 0x2, 0x2, 0x3 } }, - { S5P_CMU_ACLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_SCLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_APLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_MPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_VPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_EPLL_SYSCLK_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_GPSALIVE_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_CAM_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_TV_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_MFC_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_G3D_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_LCD0_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_LCD1_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_GPS_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_CAM_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_TV_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_MFC_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_G3D_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_LCD0_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_LCD1_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_GPS_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_TOP_BUS_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_TOP_RETENTION_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_TOP_PWR_LOWPWR, { 0x3, 0x0, 0x3 } }, - { S5P_LOGIC_RESET_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_ONENAND_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_MODIMIF_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_G2D_ACP_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_USBOTG_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_HSMMC_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_CSSYS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_SECSS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_PCIE_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_SATA_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_DRAM_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_PAD_RETENTION_GPIO_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_UART_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MMCA_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MMCB_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_EBIA_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_EBIB_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_ISOLATION_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_ALV_SEL_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_XUSBXTI_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_XXTI_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_EXT_REGULATOR_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_GPIO_MODE_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_GPIO_MODE_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CAM_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_TV_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_MFC_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_G3D_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_LCD0_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_LCD1_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_MAUDIO_LOWPWR, { 0x7, 0x7, 0x0 } }, - { S5P_GPS_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_GPS_ALIVE_LOWPWR, { 0x7, 0x0, 0x0 } }, - { PMU_TABLE_END,}, -}; - -static const struct exynos_pmu_conf exynos4x12_pmu_config[] = { - { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, - { S5P_ARM_CORE1_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_DIS_IRQ_CORE1, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_CENTRAL1, { 0x0, 0x0, 0x0 } }, - { S5P_ISP_ARM_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR, { 0x0, 0x0, 0x0 } }, - { S5P_ARM_COMMON_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_L2_0_LOWPWR, { 0x0, 0x0, 0x3 } }, - /* XXX_OPTION register should be set other field */ - { S5P_ARM_L2_0_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_L2_1_LOWPWR, { 0x0, 0x0, 0x3 } }, - { S5P_ARM_L2_1_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_CMU_ACLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_SCLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_DRAM_FREQ_DOWN_LOWPWR, { 0x1, 0x1, 0x1 } }, - { S5P_DDRPHY_DLLOFF_LOWPWR, { 0x1, 0x1, 0x1 } }, - { S5P_LPDDR_PHY_DLL_LOCK_LOWPWR, { 0x1, 0x1, 0x1 } }, - { S5P_CMU_ACLKSTOP_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_SCLKSTOP_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_COREBLK_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_APLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_MPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_VPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_EPLL_SYSCLK_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_MPLLUSER_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_GPSALIVE_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_CAM_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_TV_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_MFC_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_G3D_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_LCD0_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_ISP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_GPS_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_CAM_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_TV_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_MFC_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_G3D_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_LCD0_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_ISP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_GPS_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_TOP_BUS_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_TOP_RETENTION_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_TOP_PWR_LOWPWR, { 0x3, 0x0, 0x3 } }, - { S5P_TOP_BUS_COREBLK_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_TOP_RETENTION_COREBLK_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_TOP_PWR_COREBLK_LOWPWR, { 0x3, 0x0, 0x3 } }, - { S5P_LOGIC_RESET_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_OSCCLK_GATE_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_LOGIC_RESET_COREBLK_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_OSCCLK_GATE_COREBLK_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_ONENAND_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_ONENAND_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_HSI_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_HSI_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_G2D_ACP_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_G2D_ACP_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_USBOTG_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_USBOTG_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_HSMMC_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_HSMMC_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_CSSYS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_CSSYS_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_SECSS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_SECSS_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_ROTATOR_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_ROTATOR_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_PAD_RETENTION_DRAM_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_PAD_RETENTION_GPIO_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_UART_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MMCA_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MMCB_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_EBIA_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_EBIB_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_GPIO_COREBLK_LOWPWR,{ 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_ISOLATION_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_ISOLATION_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_ALV_SEL_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_XUSBXTI_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_XXTI_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_EXT_REGULATOR_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_GPIO_MODE_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_GPIO_MODE_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_GPIO_MODE_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_TOP_ASB_RESET_LOWPWR, { 0x1, 0x1, 0x1 } }, - { S5P_TOP_ASB_ISOLATION_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_CAM_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_TV_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_MFC_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_G3D_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_LCD0_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_ISP_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_MAUDIO_LOWPWR, { 0x7, 0x7, 0x0 } }, - { S5P_GPS_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_GPS_ALIVE_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_CMU_SYSCLK_ISP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_SYSCLK_GPS_LOWPWR, { 0x1, 0x0, 0x0 } }, - { PMU_TABLE_END,}, -}; - -static const struct exynos_pmu_conf exynos4412_pmu_config[] = { - { S5P_ARM_CORE2_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_DIS_IRQ_CORE2, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_CENTRAL2, { 0x0, 0x0, 0x0 } }, - { S5P_ARM_CORE3_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_DIS_IRQ_CORE3, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_CENTRAL3, { 0x0, 0x0, 0x0 } }, - { PMU_TABLE_END,}, -}; - -static const struct exynos_pmu_conf exynos5250_pmu_config[] = { - /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ - { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_FSYS_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, - { EXYNOS5_ARM_L2_OPTION, { 0x10, 0x10, 0x0 } }, - { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, - { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, - { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_USBOTG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_G2D_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_USBDRD_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_SDMMC_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_CSSYS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_SECSS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_ROTATOR_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_JPEG_MEM_OPTION, { 0x10, 0x10, 0x0} }, - { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { PMU_TABLE_END,}, -}; - -static struct exynos_pmu_conf exynos5420_pmu_config[] = { - /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ - { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_ARM_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_ARM_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x0} }, - { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, - { EXYNOS5420_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, - { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} }, - { EXYNOS5420_G2D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_MSC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_FSYS_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_FSYS2_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_PSGEN_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_PERIC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_WCORE_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { PMU_TABLE_END,}, -}; - -static unsigned int const exynos3250_list_feed[] = { - EXYNOS3_ARM_CORE_OPTION(0), - EXYNOS3_ARM_CORE_OPTION(1), - EXYNOS3_ARM_CORE_OPTION(2), - EXYNOS3_ARM_CORE_OPTION(3), - EXYNOS3_ARM_COMMON_OPTION, - EXYNOS3_TOP_PWR_OPTION, - EXYNOS3_CORE_TOP_PWR_OPTION, - S5P_CAM_OPTION, - S5P_MFC_OPTION, - S5P_G3D_OPTION, - S5P_LCD0_OPTION, - S5P_ISP_OPTION, -}; - -static void exynos3250_powerdown_conf_extra(enum sys_powerdown mode) -{ - unsigned int i; - unsigned int tmp; - - /* Enable only SC_FEEDBACK */ - for (i = 0; i < ARRAY_SIZE(exynos3250_list_feed); i++) { - tmp = pmu_raw_readl(exynos3250_list_feed[i]); - tmp &= ~(EXYNOS3_OPTION_USE_SC_COUNTER); - tmp |= EXYNOS3_OPTION_USE_SC_FEEDBACK; - pmu_raw_writel(tmp, exynos3250_list_feed[i]); - } - - if (mode != SYS_SLEEP) - return; - - pmu_raw_writel(XUSBXTI_DURATION, EXYNOS3_XUSBXTI_DURATION); - pmu_raw_writel(XXTI_DURATION, EXYNOS3_XXTI_DURATION); - pmu_raw_writel(EXT_REGULATOR_DURATION, EXYNOS3_EXT_REGULATOR_DURATION); - pmu_raw_writel(EXT_REGULATOR_COREBLK_DURATION, - EXYNOS3_EXT_REGULATOR_COREBLK_DURATION); -} - -static unsigned int const exynos5_list_both_cnt_feed[] = { - EXYNOS5_ARM_CORE0_OPTION, - EXYNOS5_ARM_CORE1_OPTION, - EXYNOS5_ARM_COMMON_OPTION, - EXYNOS5_GSCL_OPTION, - EXYNOS5_ISP_OPTION, - EXYNOS5_MFC_OPTION, - EXYNOS5_G3D_OPTION, - EXYNOS5_DISP1_OPTION, - EXYNOS5_MAU_OPTION, - EXYNOS5_TOP_PWR_OPTION, - EXYNOS5_TOP_PWR_SYSMEM_OPTION, -}; - -static unsigned int const exynos5_list_disable_wfi_wfe[] = { - EXYNOS5_ARM_CORE1_OPTION, - EXYNOS5_FSYS_ARM_OPTION, - EXYNOS5_ISP_ARM_OPTION, -}; - -static unsigned int const exynos5420_list_disable_pmu_reg[] = { - EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, - EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, - EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, - EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, - EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, - EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, - EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, - EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, - EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, -}; - -static void exynos5420_powerdown_conf(enum sys_powerdown mode) -{ - u32 this_cluster; - - this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); - - /* - * set the cluster id to IROM register to ensure that we wake - * up with the current cluster. - */ - pmu_raw_writel(this_cluster, EXYNOS_IROM_DATA2); -} - - -static void exynos5_powerdown_conf(enum sys_powerdown mode) -{ - unsigned int i; - unsigned int tmp; - - /* - * Enable both SC_FEEDBACK and SC_COUNTER - */ - for (i = 0; i < ARRAY_SIZE(exynos5_list_both_cnt_feed); i++) { - tmp = pmu_raw_readl(exynos5_list_both_cnt_feed[i]); - tmp |= (EXYNOS5_USE_SC_FEEDBACK | - EXYNOS5_USE_SC_COUNTER); - pmu_raw_writel(tmp, exynos5_list_both_cnt_feed[i]); - } - - /* - * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable - */ - tmp = pmu_raw_readl(EXYNOS5_ARM_COMMON_OPTION); - tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - pmu_raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION); - - /* - * Disable WFI/WFE on XXX_OPTION - */ - for (i = 0; i < ARRAY_SIZE(exynos5_list_disable_wfi_wfe); i++) { - tmp = pmu_raw_readl(exynos5_list_disable_wfi_wfe[i]); - tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE | - EXYNOS5_OPTION_USE_STANDBYWFI); - pmu_raw_writel(tmp, exynos5_list_disable_wfi_wfe[i]); - } -} - -void exynos_sys_powerdown_conf(enum sys_powerdown mode) -{ - unsigned int i; - const struct exynos_pmu_data *pmu_data; - - if (!pmu_context) - return; - - pmu_data = pmu_context->pmu_data; - - if (pmu_data->powerdown_conf) - pmu_data->powerdown_conf(mode); - - if (pmu_data->pmu_config) { - for (i = 0; (pmu_data->pmu_config[i].offset != PMU_TABLE_END); i++) - pmu_raw_writel(pmu_data->pmu_config[i].val[mode], - pmu_data->pmu_config[i].offset); - } - - if (pmu_data->powerdown_conf_extra) - pmu_data->powerdown_conf_extra(mode); - - if (pmu_data->pmu_config_extra) { - for (i = 0; pmu_data->pmu_config_extra[i].offset != PMU_TABLE_END; i++) - pmu_raw_writel(pmu_data->pmu_config_extra[i].val[mode], - pmu_data->pmu_config_extra[i].offset); - } -} - -static void exynos3250_pmu_init(void) -{ - unsigned int value; - - /* - * To prevent from issuing new bus request form L2 memory system - * If core status is power down, should be set '1' to L2 power down - */ - value = pmu_raw_readl(EXYNOS3_ARM_COMMON_OPTION); - value |= EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - pmu_raw_writel(value, EXYNOS3_ARM_COMMON_OPTION); - - /* Enable USE_STANDBY_WFI for all CORE */ - pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); - - /* - * Set PSHOLD port for output high - */ - value = pmu_raw_readl(S5P_PS_HOLD_CONTROL); - value |= S5P_PS_HOLD_OUTPUT_HIGH; - pmu_raw_writel(value, S5P_PS_HOLD_CONTROL); - - /* - * Enable signal for PSHOLD port - */ - value = pmu_raw_readl(S5P_PS_HOLD_CONTROL); - value |= S5P_PS_HOLD_EN; - pmu_raw_writel(value, S5P_PS_HOLD_CONTROL); -} - -static void exynos5250_pmu_init(void) -{ - unsigned int value; - /* - * When SYS_WDTRESET is set, watchdog timer reset request - * is ignored by power management unit. - */ - value = pmu_raw_readl(EXYNOS5_AUTO_WDTRESET_DISABLE); - value &= ~EXYNOS5_SYS_WDTRESET; - pmu_raw_writel(value, EXYNOS5_AUTO_WDTRESET_DISABLE); - - value = pmu_raw_readl(EXYNOS5_MASK_WDTRESET_REQUEST); - value &= ~EXYNOS5_SYS_WDTRESET; - pmu_raw_writel(value, EXYNOS5_MASK_WDTRESET_REQUEST); -} - -static void exynos5420_pmu_init(void) -{ - unsigned int value; - int i; - - /* - * Set the CMU_RESET, CMU_SYSCLK and CMU_CLKSTOP registers - * for local power blocks to Low initially as per Table 8-4: - * "System-Level Power-Down Configuration Registers". - */ - for (i = 0; i < ARRAY_SIZE(exynos5420_list_disable_pmu_reg); i++) - pmu_raw_writel(0, exynos5420_list_disable_pmu_reg[i]); - - /* Enable USE_STANDBY_WFI for all CORE */ - pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); - - value = pmu_raw_readl(EXYNOS_L2_OPTION(0)); - value &= ~EXYNOS5_USE_RETENTION; - pmu_raw_writel(value, EXYNOS_L2_OPTION(0)); - - value = pmu_raw_readl(EXYNOS_L2_OPTION(1)); - value &= ~EXYNOS5_USE_RETENTION; - pmu_raw_writel(value, EXYNOS_L2_OPTION(1)); - - /* - * If L2_COMMON is turned off, clocks related to ATB async - * bridge are gated. Thus, when ISP power is gated, LPI - * may get stuck. - */ - value = pmu_raw_readl(EXYNOS5420_LPI_MASK); - value |= EXYNOS5420_ATB_ISP_ARM; - pmu_raw_writel(value, EXYNOS5420_LPI_MASK); - - value = pmu_raw_readl(EXYNOS5420_LPI_MASK1); - value |= EXYNOS5420_ATB_KFC; - pmu_raw_writel(value, EXYNOS5420_LPI_MASK1); - - /* Prevent issue of new bus request from L2 memory */ - value = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION); - value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - pmu_raw_writel(value, EXYNOS5420_ARM_COMMON_OPTION); - - value = pmu_raw_readl(EXYNOS5420_KFC_COMMON_OPTION); - value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - pmu_raw_writel(value, EXYNOS5420_KFC_COMMON_OPTION); - - /* This setting is to reduce suspend/resume time */ - pmu_raw_writel(DUR_WAIT_RESET, EXYNOS5420_LOGIC_RESET_DURATION3); - - /* Serialized CPU wakeup of Eagle */ - pmu_raw_writel(SPREAD_ENABLE, EXYNOS5420_ARM_INTR_SPREAD_ENABLE); - - pmu_raw_writel(SPREAD_USE_STANDWFI, - EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI); - - pmu_raw_writel(0x1, EXYNOS5420_UP_SCHEDULER); - pr_info("EXYNOS5420 PMU initialized\n"); -} - -static const struct exynos_pmu_data exynos3250_pmu_data = { - .pmu_config = exynos3250_pmu_config, - .pmu_init = exynos3250_pmu_init, - .powerdown_conf_extra = exynos3250_powerdown_conf_extra, -}; - -static const struct exynos_pmu_data exynos4210_pmu_data = { - .pmu_config = exynos4210_pmu_config, -}; - -static const struct exynos_pmu_data exynos4212_pmu_data = { - .pmu_config = exynos4x12_pmu_config, -}; - -static const struct exynos_pmu_data exynos4412_pmu_data = { - .pmu_config = exynos4x12_pmu_config, - .pmu_config_extra = exynos4412_pmu_config, -}; - -static const struct exynos_pmu_data exynos5250_pmu_data = { - .pmu_config = exynos5250_pmu_config, - .pmu_init = exynos5250_pmu_init, - .powerdown_conf = exynos5_powerdown_conf, -}; - -static const struct exynos_pmu_data exynos5420_pmu_data = { - .pmu_config = exynos5420_pmu_config, - .pmu_init = exynos5420_pmu_init, - .powerdown_conf = exynos5420_powerdown_conf, -}; - -/* - * PMU platform driver and devicetree bindings. - */ -static const struct of_device_id exynos_pmu_of_device_ids[] = { - { - .compatible = "samsung,exynos3250-pmu", - .data = &exynos3250_pmu_data, - }, { - .compatible = "samsung,exynos4210-pmu", - .data = &exynos4210_pmu_data, - }, { - .compatible = "samsung,exynos4212-pmu", - .data = &exynos4212_pmu_data, - }, { - .compatible = "samsung,exynos4412-pmu", - .data = &exynos4412_pmu_data, - }, { - .compatible = "samsung,exynos5250-pmu", - .data = &exynos5250_pmu_data, - }, { - .compatible = "samsung,exynos5420-pmu", - .data = &exynos5420_pmu_data, - }, - { /*sentinel*/ }, -}; - -static int exynos_pmu_probe(struct platform_device *pdev) -{ - const struct of_device_id *match; - struct device *dev = &pdev->dev; - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pmu_base_addr = devm_ioremap_resource(dev, res); - if (IS_ERR(pmu_base_addr)) - return PTR_ERR(pmu_base_addr); - - pmu_context = devm_kzalloc(&pdev->dev, - sizeof(struct exynos_pmu_context), - GFP_KERNEL); - if (!pmu_context) { - dev_err(dev, "Cannot allocate memory.\n"); - return -ENOMEM; - } - pmu_context->dev = dev; - - match = of_match_node(exynos_pmu_of_device_ids, dev->of_node); - - pmu_context->pmu_data = match->data; - - if (pmu_context->pmu_data->pmu_init) - pmu_context->pmu_data->pmu_init(); - - platform_set_drvdata(pdev, pmu_context); - - dev_dbg(dev, "Exynos PMU Driver probe done\n"); - return 0; -} - -static struct platform_driver exynos_pmu_driver = { - .driver = { - .name = "exynos-pmu", - .of_match_table = exynos_pmu_of_device_ids, - }, - .probe = exynos_pmu_probe, -}; - -static int __init exynos_pmu_init(void) -{ - return platform_driver_register(&exynos_pmu_driver); - -} -postcore_initcall(exynos_pmu_init); diff --git a/arch/arm/mach-exynos/regs-srom.h b/arch/arm/mach-exynos/regs-srom.h deleted file mode 100644 index 5c4d4427db7b..000000000000 --- a/arch/arm/mach-exynos/regs-srom.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * S5P SROMC register definitions - * - * 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 __PLAT_SAMSUNG_REGS_SROM_H -#define __PLAT_SAMSUNG_REGS_SROM_H __FILE__ - -#include - -#define S5P_SROMREG(x) (S5P_VA_SROMC + (x)) - -#define S5P_SROM_BW S5P_SROMREG(0x0) -#define S5P_SROM_BC0 S5P_SROMREG(0x4) -#define S5P_SROM_BC1 S5P_SROMREG(0x8) -#define S5P_SROM_BC2 S5P_SROMREG(0xc) -#define S5P_SROM_BC3 S5P_SROMREG(0x10) -#define S5P_SROM_BC4 S5P_SROMREG(0x14) -#define S5P_SROM_BC5 S5P_SROMREG(0x18) - -/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */ - -#define S5P_SROM_BW__DATAWIDTH__SHIFT 0 -#define S5P_SROM_BW__ADDRMODE__SHIFT 1 -#define S5P_SROM_BW__WAITENABLE__SHIFT 2 -#define S5P_SROM_BW__BYTEENABLE__SHIFT 3 - -#define S5P_SROM_BW__CS_MASK 0xf - -#define S5P_SROM_BW__NCS0__SHIFT 0 -#define S5P_SROM_BW__NCS1__SHIFT 4 -#define S5P_SROM_BW__NCS2__SHIFT 8 -#define S5P_SROM_BW__NCS3__SHIFT 12 -#define S5P_SROM_BW__NCS4__SHIFT 16 -#define S5P_SROM_BW__NCS5__SHIFT 20 - -/* applies to same to BCS0 - BCS3 */ - -#define S5P_SROM_BCX__PMC__SHIFT 0 -#define S5P_SROM_BCX__TACP__SHIFT 4 -#define S5P_SROM_BCX__TCAH__SHIFT 8 -#define S5P_SROM_BCX__TCOH__SHIFT 12 -#define S5P_SROM_BCX__TACC__SHIFT 16 -#define S5P_SROM_BCX__TCOS__SHIFT 24 -#define S5P_SROM_BCX__TACS__SHIFT 28 - -#endif /* __PLAT_SAMSUNG_REGS_SROM_H */ diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index c169cc3049aa..f21690937b7d 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -32,12 +34,11 @@ #include #include +#include + #include #include "common.h" -#include "exynos-pmu.h" -#include "regs-pmu.h" -#include "regs-srom.h" #define REG_TABLE_END (-1U) @@ -53,15 +54,6 @@ struct exynos_wkup_irq { u32 mask; }; -static struct sleep_save exynos_core_save[] = { - /* SROM side */ - SAVE_ITEM(S5P_SROM_BW), - SAVE_ITEM(S5P_SROM_BC0), - SAVE_ITEM(S5P_SROM_BC1), - SAVE_ITEM(S5P_SROM_BC2), - SAVE_ITEM(S5P_SROM_BC3), -}; - struct exynos_pm_data { const struct exynos_wkup_irq *wkup_irq; unsigned int wake_disable_mask; @@ -343,8 +335,6 @@ static void exynos_pm_prepare(void) /* Set wake-up mask registers */ exynos_pm_set_wakeup_mask(); - s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); - exynos_pm_enter_sleep_mode(); /* ensure at least INFORM0 has the resume address */ @@ -375,8 +365,6 @@ static void exynos5420_pm_prepare(void) /* Set wake-up mask registers */ exynos_pm_set_wakeup_mask(); - s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); - exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3); /* * The cpu state needs to be saved and restored so that the @@ -467,8 +455,6 @@ static void exynos_pm_resume(void) /* For release retention */ exynos_pm_release_retention(); - s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); - if (cpuid == ARM_CPU_PART_CORTEX_A9) scu_enable(S5P_VA_SCU); @@ -535,8 +521,6 @@ static void exynos5420_pm_resume(void) pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3); - s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); - early_wakeup: tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1); diff --git a/arch/arm/mach-imx/3ds_debugboard.c b/arch/arm/mach-imx/3ds_debugboard.c index 16496a071ecb..cda330c93d61 100644 --- a/arch/arm/mach-imx/3ds_debugboard.c +++ b/arch/arm/mach-imx/3ds_debugboard.c @@ -94,8 +94,8 @@ static void mxc_expio_irq_handler(struct irq_desc *desc) /* irq = gpio irq number */ desc->irq_data.chip->irq_mask(&desc->irq_data); - imr_val = __raw_readw(brd_io + INTR_MASK_REG); - int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; + imr_val = imx_readw(brd_io + INTR_MASK_REG); + int_valid = imx_readw(brd_io + INTR_STATUS_REG) & ~imr_val; expio_irq = 0; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { @@ -117,17 +117,17 @@ static void expio_mask_irq(struct irq_data *d) u16 reg; u32 expio = d->hwirq; - reg = __raw_readw(brd_io + INTR_MASK_REG); + reg = imx_readw(brd_io + INTR_MASK_REG); reg |= (1 << expio); - __raw_writew(reg, brd_io + INTR_MASK_REG); + imx_writew(reg, brd_io + INTR_MASK_REG); } static void expio_ack_irq(struct irq_data *d) { u32 expio = d->hwirq; - __raw_writew(1 << expio, brd_io + INTR_RESET_REG); - __raw_writew(0, brd_io + INTR_RESET_REG); + imx_writew(1 << expio, brd_io + INTR_RESET_REG); + imx_writew(0, brd_io + INTR_RESET_REG); expio_mask_irq(d); } @@ -136,9 +136,9 @@ static void expio_unmask_irq(struct irq_data *d) u16 reg; u32 expio = d->hwirq; - reg = __raw_readw(brd_io + INTR_MASK_REG); + reg = imx_readw(brd_io + INTR_MASK_REG); reg &= ~(1 << expio); - __raw_writew(reg, brd_io + INTR_MASK_REG); + imx_writew(reg, brd_io + INTR_MASK_REG); } static struct irq_chip expio_irq_chip = { @@ -162,9 +162,9 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio) if (brd_io == NULL) return -ENOMEM; - if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || - (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || - (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { + if ((imx_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || + (imx_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || + (imx_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { pr_info("3-Stack Debug board not detected\n"); iounmap(brd_io); brd_io = NULL; @@ -181,10 +181,10 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio) gpio_direction_input(intr_gpio); /* disable the interrupt and clear the status */ - __raw_writew(0, brd_io + INTR_MASK_REG); - __raw_writew(0xFFFF, brd_io + INTR_RESET_REG); - __raw_writew(0, brd_io + INTR_RESET_REG); - __raw_writew(0x1F, brd_io + INTR_MASK_REG); + imx_writew(0, brd_io + INTR_MASK_REG); + imx_writew(0xFFFF, brd_io + INTR_RESET_REG); + imx_writew(0, brd_io + INTR_RESET_REG); + imx_writew(0x1F, brd_io + INTR_MASK_REG); irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); WARN_ON(irq_base < 0); diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 15df34fbdf44..ecc374060c27 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -2,6 +2,7 @@ menuconfig ARCH_MXC bool "Freescale i.MX family" depends on ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M select ARCH_REQUIRE_GPIOLIB + select ARCH_SUPPORTS_BIG_ENDIAN select ARM_CPU_SUSPEND if PM select CLKSRC_IMX_GPT select GENERIC_IRQ_CHIP @@ -561,6 +562,7 @@ config SOC_IMX7D bool "i.MX7 Dual support" select PINCTRL_IMX7D select ARM_GIC + select HAVE_ARM_ARCH_TIMER select HAVE_IMX_ANATOP select HAVE_IMX_MMDC select HAVE_IMX_SRC diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 231bb250c571..bd3555ee88c8 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -151,7 +151,14 @@ void __init imx_init_revision_from_anatop(void) revision = IMX_CHIP_REVISION_1_5; break; default: - revision = IMX_CHIP_REVISION_UNKNOWN; + /* + * Fail back to return raw register value instead of 0xff. + * It will be easy to know version information in SOC if it + * can't be recognized by known version. And some chip's (i.MX7D) + * digprog value match linux version format, so it needn't map + * again and we can use register value directly. + */ + revision = digprog & 0xff; } mxc_set_cpu_type(digprog >> 16 & 0xff); diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index 1a8932335b21..7fa176e792bd 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -66,12 +66,12 @@ static int avic_set_irq_fiq(unsigned int irq, unsigned int type) return -EINVAL; if (irq < AVIC_NUM_IRQS / 2) { - irqt = __raw_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq); - __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL); + irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq); + imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL); } else { irq -= AVIC_NUM_IRQS / 2; - irqt = __raw_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq); - __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH); + irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq); + imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH); } return 0; @@ -94,8 +94,8 @@ static void avic_irq_suspend(struct irq_data *d) struct irq_chip_type *ct = gc->chip_types; int idx = d->hwirq >> 5; - avic_saved_mask_reg[idx] = __raw_readl(avic_base + ct->regs.mask); - __raw_writel(gc->wake_active, avic_base + ct->regs.mask); + avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask); + imx_writel(gc->wake_active, avic_base + ct->regs.mask); } static void avic_irq_resume(struct irq_data *d) @@ -104,7 +104,7 @@ static void avic_irq_resume(struct irq_data *d) struct irq_chip_type *ct = gc->chip_types; int idx = d->hwirq >> 5; - __raw_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); + imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); } #else @@ -140,7 +140,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs) u32 nivector; do { - nivector = __raw_readl(avic_base + AVIC_NIVECSR) >> 16; + nivector = imx_readl(avic_base + AVIC_NIVECSR) >> 16; if (nivector == 0xffff) break; @@ -164,16 +164,16 @@ void __init mxc_init_irq(void __iomem *irqbase) /* put the AVIC into the reset value with * all interrupts disabled */ - __raw_writel(0, avic_base + AVIC_INTCNTL); - __raw_writel(0x1f, avic_base + AVIC_NIMASK); + imx_writel(0, avic_base + AVIC_INTCNTL); + imx_writel(0x1f, avic_base + AVIC_NIMASK); /* disable all interrupts */ - __raw_writel(0, avic_base + AVIC_INTENABLEH); - __raw_writel(0, avic_base + AVIC_INTENABLEL); + imx_writel(0, avic_base + AVIC_INTENABLEH); + imx_writel(0, avic_base + AVIC_INTENABLEL); /* all IRQ no FIQ */ - __raw_writel(0, avic_base + AVIC_INTTYPEH); - __raw_writel(0, avic_base + AVIC_INTTYPEL); + imx_writel(0, avic_base + AVIC_INTTYPEH); + imx_writel(0, avic_base + AVIC_INTTYPEL); irq_base = irq_alloc_descs(-1, 0, AVIC_NUM_IRQS, numa_node_id()); WARN_ON(irq_base < 0); @@ -188,7 +188,7 @@ void __init mxc_init_irq(void __iomem *irqbase) /* Set default priority value (0) for all IRQ's */ for (i = 0; i < 8; i++) - __raw_writel(0, avic_base + AVIC_NIPRIORITY(i)); + imx_writel(0, avic_base + AVIC_NIPRIORITY(i)); set_handle_irq(avic_handle_irq); diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c index fe8d36f7e30e..8d2ae4091465 100644 --- a/arch/arm/mach-imx/cpu-imx27.c +++ b/arch/arm/mach-imx/cpu-imx27.c @@ -39,8 +39,7 @@ static int mx27_read_cpu_rev(void) * the silicon revision very early we read it here to * avoid any further hooks */ - val = __raw_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR - + SYS_CHIP_ID)); + val = imx_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR + SYS_CHIP_ID)); mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF); diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c index fde1860a2521..3daf1959a2f0 100644 --- a/arch/arm/mach-imx/cpu-imx31.c +++ b/arch/arm/mach-imx/cpu-imx31.c @@ -39,7 +39,7 @@ static int mx31_read_cpu_rev(void) u32 i, srev; /* read SREV register from IIM module */ - srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); + srev = imx_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); srev &= 0xff; for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c index ec3aaa098c17..8a54234df23b 100644 --- a/arch/arm/mach-imx/cpu-imx35.c +++ b/arch/arm/mach-imx/cpu-imx35.c @@ -20,7 +20,7 @@ static int mx35_read_cpu_rev(void) { u32 rev; - rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); + rev = imx_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); switch (rev) { case 0x00: return IMX_CHIP_REVISION_1_0; diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 5b0f752d5507..6a96b7cf468f 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -45,20 +45,20 @@ void __init imx_set_aips(void __iomem *base) * Set all MPROTx to be non-bufferable, trusted for R/W, * not forced to user-mode. */ - __raw_writel(0x77777777, base + 0x0); - __raw_writel(0x77777777, base + 0x4); + imx_writel(0x77777777, base + 0x0); + imx_writel(0x77777777, base + 0x4); /* * Set all OPACRx to be non-bufferable, to not require * supervisor privilege level for access, allow for * write access and untrusted master access. */ - __raw_writel(0x0, base + 0x40); - __raw_writel(0x0, base + 0x44); - __raw_writel(0x0, base + 0x48); - __raw_writel(0x0, base + 0x4C); - reg = __raw_readl(base + 0x50) & 0x00FFFFFF; - __raw_writel(reg, base + 0x50); + imx_writel(0x0, base + 0x40); + imx_writel(0x0, base + 0x44); + imx_writel(0x0, base + 0x48); + imx_writel(0x0, base + 0x4C); + reg = imx_readl(base + 0x50) & 0x00FFFFFF; + imx_writel(reg, base + 0x50); } void __init imx_aips_allow_unprivileged_access( diff --git a/arch/arm/mach-imx/epit.c b/arch/arm/mach-imx/epit.c index 08ce20771bb3..fb9a73a57d00 100644 --- a/arch/arm/mach-imx/epit.c +++ b/arch/arm/mach-imx/epit.c @@ -64,23 +64,23 @@ static inline void epit_irq_disable(void) { u32 val; - val = __raw_readl(timer_base + EPITCR); + val = imx_readl(timer_base + EPITCR); val &= ~EPITCR_OCIEN; - __raw_writel(val, timer_base + EPITCR); + imx_writel(val, timer_base + EPITCR); } static inline void epit_irq_enable(void) { u32 val; - val = __raw_readl(timer_base + EPITCR); + val = imx_readl(timer_base + EPITCR); val |= EPITCR_OCIEN; - __raw_writel(val, timer_base + EPITCR); + imx_writel(val, timer_base + EPITCR); } static void epit_irq_acknowledge(void) { - __raw_writel(EPITSR_OCIF, timer_base + EPITSR); + imx_writel(EPITSR_OCIF, timer_base + EPITSR); } static int __init epit_clocksource_init(struct clk *timer_clk) @@ -98,9 +98,9 @@ static int epit_set_next_event(unsigned long evt, { unsigned long tcmp; - tcmp = __raw_readl(timer_base + EPITCNR); + tcmp = imx_readl(timer_base + EPITCNR); - __raw_writel(tcmp - evt, timer_base + EPITCMPR); + imx_writel(tcmp - evt, timer_base + EPITCMPR); return 0; } @@ -213,11 +213,11 @@ void __init epit_timer_init(void __iomem *base, int irq) /* * Initialise to a known state (all timers off, and timing reset) */ - __raw_writel(0x0, timer_base + EPITCR); + imx_writel(0x0, timer_base + EPITCR); - __raw_writel(0xffffffff, timer_base + EPITLR); - __raw_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN, - timer_base + EPITCR); + imx_writel(0xffffffff, timer_base + EPITLR); + imx_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN, + timer_base + EPITCR); /* init and register the timer to the framework */ epit_clocksource_init(timer_clk); diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S index b5e976816b63..6c28d28b3c64 100644 --- a/arch/arm/mach-imx/headsmp.S +++ b/arch/arm/mach-imx/headsmp.S @@ -12,6 +12,7 @@ #include #include +#include diag_reg_offset: .word g_diag_reg - . @@ -25,6 +26,7 @@ diag_reg_offset: .endm ENTRY(v7_secondary_startup) +ARM_BE8(setend be) @ go BE8 if entered LE set_diag_reg b secondary_startup ENDPROC(v7_secondary_startup) diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c index 0b5ba4bf572a..3982e91b2f3e 100644 --- a/arch/arm/mach-imx/iomux-imx31.c +++ b/arch/arm/mach-imx/iomux-imx31.c @@ -57,10 +57,10 @@ void mxc_iomux_mode(unsigned int pin_mode) spin_lock(&gpio_mux_lock); - l = __raw_readl(reg); + l = imx_readl(reg); l &= ~(0xff << (field * 8)); l |= mode << (field * 8); - __raw_writel(l, reg); + imx_writel(l, reg); spin_unlock(&gpio_mux_lock); } @@ -82,10 +82,10 @@ void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) spin_lock(&gpio_mux_lock); - l = __raw_readl(reg); + l = imx_readl(reg); l &= ~(0x1ff << (field * 10)); l |= config << (field * 10); - __raw_writel(l, reg); + imx_writel(l, reg); spin_unlock(&gpio_mux_lock); } @@ -163,12 +163,12 @@ void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) u32 l; spin_lock(&gpio_mux_lock); - l = __raw_readl(IOMUXGPR); + l = imx_readl(IOMUXGPR); if (en) l |= gp; else l &= ~gp; - __raw_writel(l, IOMUXGPR); + imx_writel(l, IOMUXGPR); spin_unlock(&gpio_mux_lock); } diff --git a/arch/arm/mach-imx/iomux-v1.c b/arch/arm/mach-imx/iomux-v1.c index ecd543664644..7aa90c863ad9 100644 --- a/arch/arm/mach-imx/iomux-v1.c +++ b/arch/arm/mach-imx/iomux-v1.c @@ -38,12 +38,12 @@ static unsigned imx_iomuxv1_numports; static inline unsigned long imx_iomuxv1_readl(unsigned offset) { - return __raw_readl(imx_iomuxv1_baseaddr + offset); + return imx_readl(imx_iomuxv1_baseaddr + offset); } static inline void imx_iomuxv1_writel(unsigned long val, unsigned offset) { - __raw_writel(val, imx_iomuxv1_baseaddr + offset); + imx_writel(val, imx_iomuxv1_baseaddr + offset); } static inline void imx_iomuxv1_rmwl(unsigned offset, diff --git a/arch/arm/mach-imx/iomux-v3.c b/arch/arm/mach-imx/iomux-v3.c index a53b2e64f98d..ca59d5f2ec92 100644 --- a/arch/arm/mach-imx/iomux-v3.c +++ b/arch/arm/mach-imx/iomux-v3.c @@ -45,13 +45,13 @@ int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad) u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT; if (mux_ctrl_ofs) - __raw_writel(mux_mode, base + mux_ctrl_ofs); + imx_writel(mux_mode, base + mux_ctrl_ofs); if (sel_input_ofs) - __raw_writel(sel_input, base + sel_input_ofs); + imx_writel(sel_input, base + sel_input_ofs); if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs) - __raw_writel(pad_ctrl, base + pad_ctrl_ofs); + imx_writel(pad_ctrl, base + pad_ctrl_ofs); return 0; } diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index f2060523ba48..eaee47a2fcc0 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -525,8 +525,8 @@ static void __init armadillo5x0_init(void) imx31_add_mxc_nand(&armadillo5x0_nand_board_info); /* set NAND page size to 2k if not configured via boot mode pins */ - __raw_writel(__raw_readl(mx3_ccm_base + MXC_CCM_RCSR) | - (1 << 30), mx3_ccm_base + MXC_CCM_RCSR); + imx_writel(imx_readl(mx3_ccm_base + MXC_CCM_RCSR) | (1 << 30), + mx3_ccm_base + MXC_CCM_RCSR); /* RTC */ /* Get RTC IRQ and register the chip */ diff --git a/arch/arm/mach-imx/mach-imx51.c b/arch/arm/mach-imx/mach-imx51.c index b015129e4045..6883fbaf9484 100644 --- a/arch/arm/mach-imx/mach-imx51.c +++ b/arch/arm/mach-imx/mach-imx51.c @@ -40,11 +40,10 @@ static void __init imx51_ipu_mipi_setup(void) WARN_ON(!hsc_addr); /* setup MIPI module to legacy mode */ - __raw_writel(0xf00, hsc_addr); + imx_writel(0xf00, hsc_addr); /* CSI mode: reserved; DI control mode: legacy (from Freescale BSP) */ - __raw_writel(__raw_readl(hsc_addr + 0x800) | 0x30ff, - hsc_addr + 0x800); + imx_writel(imx_readl(hsc_addr + 0x800) | 0x30ff, hsc_addr + 0x800); iounmap(hsc_addr); } diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c index eb1c3477c48a..267fad23b225 100644 --- a/arch/arm/mach-imx/mach-mx27ads.c +++ b/arch/arm/mach-imx/mach-mx27ads.c @@ -202,9 +202,9 @@ static struct i2c_board_info mx27ads_i2c_devices[] = { static void vgpio_set(struct gpio_chip *chip, unsigned offset, int value) { if (value) - __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); + imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); else - __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); + imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); } static int vgpio_dir_out(struct gpio_chip *chip, unsigned offset, int value) @@ -364,7 +364,7 @@ static void __init mx27ads_timer_init(void) { unsigned long fref = 26000000; - if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) + if ((imx_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) fref = 27000000; mx27_clocks_init(fref); diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index 2b147e4bf9c9..4f2c56d44ba1 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -160,8 +160,8 @@ static void mx31ads_expio_irq_handler(struct irq_desc *desc) u32 int_valid; u32 expio_irq; - imr_val = __raw_readw(PBC_INTMASK_SET_REG); - int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val; + imr_val = imx_readw(PBC_INTMASK_SET_REG); + int_valid = imx_readw(PBC_INTSTATUS_REG) & imr_val; expio_irq = 0; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { @@ -180,8 +180,8 @@ static void expio_mask_irq(struct irq_data *d) { u32 expio = d->hwirq; /* mask the interrupt */ - __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG); - __raw_readw(PBC_INTMASK_CLEAR_REG); + imx_writew(1 << expio, PBC_INTMASK_CLEAR_REG); + imx_readw(PBC_INTMASK_CLEAR_REG); } /* @@ -192,7 +192,7 @@ static void expio_ack_irq(struct irq_data *d) { u32 expio = d->hwirq; /* clear the interrupt status */ - __raw_writew(1 << expio, PBC_INTSTATUS_REG); + imx_writew(1 << expio, PBC_INTSTATUS_REG); } /* @@ -203,7 +203,7 @@ static void expio_unmask_irq(struct irq_data *d) { u32 expio = d->hwirq; /* unmask the interrupt */ - __raw_writew(1 << expio, PBC_INTMASK_SET_REG); + imx_writew(1 << expio, PBC_INTMASK_SET_REG); } static struct irq_chip expio_irq_chip = { @@ -226,8 +226,8 @@ static void __init mx31ads_init_expio(void) mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio"); /* disable the interrupt and clear the status */ - __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); - __raw_writew(0xFFFF, PBC_INTSTATUS_REG); + imx_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); + imx_writew(0xFFFF, PBC_INTSTATUS_REG); irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); WARN_ON(irq_base < 0); diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index bb6f8a52a6b8..4f2d99888afd 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -509,7 +509,7 @@ static void mx31moboard_poweroff(void) mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST); - __raw_writew(1 << 6 | 1 << 2, MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); + imx_writew(1 << 6 | 1 << 2, MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); } static int mx31moboard_baseboard; diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index 5c2764604727..34df64f133ed 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c @@ -190,9 +190,9 @@ static struct platform_device qong_nand_device = { static void __init qong_init_nand_mtd(void) { /* init CS */ - __raw_writel(0x00004f00, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(3))); - __raw_writel(0x20013b31, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(3))); - __raw_writel(0x00020800, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(3))); + imx_writel(0x00004f00, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(3))); + imx_writel(0x20013b31, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(3))); + imx_writel(0x00020800, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(3))); mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true); diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index a5b1af6d7441..d32704256781 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -193,4 +193,9 @@ extern struct cpu_op *(*get_cpu_op)(int *op); #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35()) #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27()) +#define imx_readl readl_relaxed +#define imx_readw readw_relaxed +#define imx_writel writel_relaxed +#define imx_writew writew_relaxed + #endif /* __ASM_ARCH_MXC_H__ */ diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c index 56d02d064fbf..43096c8990d4 100644 --- a/arch/arm/mach-imx/pm-imx27.c +++ b/arch/arm/mach-imx/pm-imx27.c @@ -19,9 +19,9 @@ static int mx27_suspend_enter(suspend_state_t state) switch (state) { case PM_SUSPEND_MEM: /* Clear MPEN and SPEN to disable MPLL/SPLL */ - cscr = __raw_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); + cscr = imx_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); cscr &= 0xFFFFFFFC; - __raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); + imx_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); /* Executes WFI */ cpu_do_idle(); break; diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c index 6a07006ff0f4..94c0898751d8 100644 --- a/arch/arm/mach-imx/pm-imx3.c +++ b/arch/arm/mach-imx/pm-imx3.c @@ -22,14 +22,14 @@ */ void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode) { - int reg = __raw_readl(mx3_ccm_base + MXC_CCM_CCMR); + int reg = imx_readl(mx3_ccm_base + MXC_CCM_CCMR); reg &= ~MXC_CCM_CCMR_LPM_MASK; switch (mode) { case MX3_WAIT: if (cpu_is_mx35()) reg |= MXC_CCM_CCMR_LPM_WAIT_MX35; - __raw_writel(reg, mx3_ccm_base + MXC_CCM_CCMR); + imx_writel(reg, mx3_ccm_base + MXC_CCM_CCMR); break; default: pr_err("Unknown cpu power mode: %d\n", mode); diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index 532d4b08276d..868781fd460c 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -153,15 +153,15 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) int stop_mode = 0; /* always allow platform to issue a deep sleep mode request */ - plat_lpc = __raw_readl(cortex_base + MXC_CORTEXA8_PLAT_LPC) & + plat_lpc = imx_readl(cortex_base + MXC_CORTEXA8_PLAT_LPC) & ~(MXC_CORTEXA8_PLAT_LPC_DSM); - ccm_clpcr = __raw_readl(ccm_base + MXC_CCM_CLPCR) & + ccm_clpcr = imx_readl(ccm_base + MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK); - arm_srpgcr = __raw_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) & + arm_srpgcr = imx_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR); - empgc0 = __raw_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) & + empgc0 = imx_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR); - empgc1 = __raw_readl(gpc_base + MXC_SRPG_EMPGC1_SRPGCR) & + empgc1 = imx_readl(gpc_base + MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR); switch (mode) { @@ -196,17 +196,17 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) return; } - __raw_writel(plat_lpc, cortex_base + MXC_CORTEXA8_PLAT_LPC); - __raw_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR); - __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR); - __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR); + imx_writel(plat_lpc, cortex_base + MXC_CORTEXA8_PLAT_LPC); + imx_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR); + imx_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR); + imx_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR); if (stop_mode) { empgc0 |= MXC_SRPGCR_PCR; empgc1 |= MXC_SRPGCR_PCR; - __raw_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); - __raw_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); + imx_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); + imx_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); } } @@ -228,8 +228,8 @@ static int mx5_suspend_enter(suspend_state_t state) flush_cache_all(); /*clear the EMPGC0/1 bits */ - __raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); - __raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); + imx_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); + imx_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); if (imx5_suspend_in_ocram_fn) imx5_suspend_in_ocram_fn(suspend_ocram_base); diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 4470376af5f8..58924b3844df 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -561,13 +561,13 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) goto put_node; pl310_cache_map_failed: - iounmap(&pm_info->gpc_base.vbase); + iounmap(pm_info->gpc_base.vbase); gpc_map_failed: - iounmap(&pm_info->iomuxc_base.vbase); + iounmap(pm_info->iomuxc_base.vbase); iomuxc_map_failed: - iounmap(&pm_info->src_base.vbase); + iounmap(pm_info->src_base.vbase); src_map_failed: - iounmap(&pm_info->mmdc_base.vbase); + iounmap(pm_info->mmdc_base.vbase); put_node: of_node_put(node); diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c index 51c35013b673..93d4a9a39353 100644 --- a/arch/arm/mach-imx/system.c +++ b/arch/arm/mach-imx/system.c @@ -54,7 +54,7 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) wcr_enable = (1 << 2); /* Assert SRS signal */ - __raw_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); /* * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be * written twice), we add another two writes to ensure there must be at @@ -62,8 +62,8 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) * the target check here, since the writes shouldn't be a huge burden * for other platforms. */ - __raw_writew(wcr_enable, wdog_base); - __raw_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); /* wait for reset to assert... */ mdelay(500); diff --git a/arch/arm/mach-imx/tzic.c b/arch/arm/mach-imx/tzic.c index 4de65eeda1eb..ae23d50f7861 100644 --- a/arch/arm/mach-imx/tzic.c +++ b/arch/arm/mach-imx/tzic.c @@ -65,10 +65,10 @@ static int tzic_set_irq_fiq(unsigned int irq, unsigned int type) return -EINVAL; mask = 1U << (irq & 0x1F); - value = __raw_readl(tzic_base + TZIC_INTSEC0(index)) | mask; + value = imx_readl(tzic_base + TZIC_INTSEC0(index)) | mask; if (type) value &= ~mask; - __raw_writel(value, tzic_base + TZIC_INTSEC0(index)); + imx_writel(value, tzic_base + TZIC_INTSEC0(index)); return 0; } @@ -82,15 +82,15 @@ static void tzic_irq_suspend(struct irq_data *d) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); int idx = d->hwirq >> 5; - __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); + imx_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); } static void tzic_irq_resume(struct irq_data *d) { int idx = d->hwirq >> 5; - __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)), - tzic_base + TZIC_WAKEUP0(idx)); + imx_writel(imx_readl(tzic_base + TZIC_ENSET0(idx)), + tzic_base + TZIC_WAKEUP0(idx)); } #else @@ -135,8 +135,8 @@ static void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs) handled = 0; for (i = 0; i < 4; i++) { - stat = __raw_readl(tzic_base + TZIC_HIPND(i)) & - __raw_readl(tzic_base + TZIC_INTSEC0(i)); + stat = imx_readl(tzic_base + TZIC_HIPND(i)) & + imx_readl(tzic_base + TZIC_INTSEC0(i)); while (stat) { handled = 1; @@ -166,18 +166,18 @@ void __init tzic_init_irq(void) /* put the TZIC into the reset value with * all interrupts disabled */ - i = __raw_readl(tzic_base + TZIC_INTCNTL); + i = imx_readl(tzic_base + TZIC_INTCNTL); - __raw_writel(0x80010001, tzic_base + TZIC_INTCNTL); - __raw_writel(0x1f, tzic_base + TZIC_PRIOMASK); - __raw_writel(0x02, tzic_base + TZIC_SYNCCTRL); + imx_writel(0x80010001, tzic_base + TZIC_INTCNTL); + imx_writel(0x1f, tzic_base + TZIC_PRIOMASK); + imx_writel(0x02, tzic_base + TZIC_SYNCCTRL); for (i = 0; i < 4; i++) - __raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i)); + imx_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i)); /* disable all interrupts */ for (i = 0; i < 4; i++) - __raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i)); + imx_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i)); /* all IRQ no FIQ Warning :: No selection */ @@ -214,13 +214,13 @@ int tzic_enable_wake(void) { unsigned int i; - __raw_writel(1, tzic_base + TZIC_DSMINT); - if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0)) + imx_writel(1, tzic_base + TZIC_DSMINT); + if (unlikely(imx_readl(tzic_base + TZIC_DSMINT) == 0)) return -EAGAIN; for (i = 0; i < 4; i++) - __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(i)), - tzic_base + TZIC_WAKEUP0(i)); + imx_writel(imx_readl(tzic_base + TZIC_ENSET0(i)), + tzic_base + TZIC_WAKEUP0(i)); return 0; } diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig index b01bdc9baf89..b2a85ba13f08 100644 --- a/arch/arm/mach-integrator/Kconfig +++ b/arch/arm/mach-integrator/Kconfig @@ -2,22 +2,16 @@ menuconfig ARCH_INTEGRATOR bool "ARM Ltd. Integrator family" depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6 select ARM_AMBA - select ARM_PATCH_PHYS_VIRT if MMU - select AUTO_ZRELADDR - select COMMON_CLK select COMMON_CLK_VERSATILE - select GENERIC_CLOCKEVENTS select HAVE_TCM select ICST select MFD_SYSCON - select MULTI_IRQ_HANDLER select PLAT_VERSATILE select POWER_RESET select POWER_RESET_VERSATILE select POWER_SUPPLY select SOC_INTEGRATOR_CM select SPARSE_IRQ - select USE_OF select VERSATILE_FPGA_IRQ help Support for ARM's Integrator platform. diff --git a/arch/arm/mach-integrator/Makefile.boot b/arch/arm/mach-integrator/Makefile.boot deleted file mode 100644 index ff0a4b5b0a82..000000000000 --- a/arch/arm/mach-integrator/Makefile.boot +++ /dev/null @@ -1,4 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 - diff --git a/arch/arm/mach-keystone/Makefile.boot b/arch/arm/mach-keystone/Makefile.boot deleted file mode 100644 index f3835c43af61..000000000000 --- a/arch/arm/mach-keystone/Makefile.boot +++ /dev/null @@ -1 +0,0 @@ -zreladdr-y := 0x80008000 diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c index c279293f084c..e6b9cb1e6709 100644 --- a/arch/arm/mach-keystone/keystone.c +++ b/arch/arm/mach-keystone/keystone.c @@ -63,7 +63,7 @@ static void __init keystone_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -static phys_addr_t keystone_virt_to_idmap(unsigned long x) +static unsigned long keystone_virt_to_idmap(unsigned long x) { return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START; } @@ -100,6 +100,7 @@ static const char *const keystone_match[] __initconst = { "ti,k2hk", "ti,k2e", "ti,k2l", + "ti,k2g", "ti,keystone", NULL, }; diff --git a/arch/arm/mach-mmp/Makefile.boot b/arch/arm/mach-mmp/Makefile.boot deleted file mode 100644 index 5edf03e2beed..000000000000 --- a/arch/arm/mach-mmp/Makefile.boot +++ /dev/null @@ -1 +0,0 @@ - zreladdr-y += 0x00008000 diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig index a32575fa3fba..c32f85559c65 100644 --- a/arch/arm/mach-mv78xx0/Kconfig +++ b/arch/arm/mach-mv78xx0/Kconfig @@ -1,5 +1,6 @@ menuconfig ARCH_MV78XX0 - bool "Marvell MV78xx0" if ARCH_MULTI_V5 + bool "Marvell MV78xx0" + depends on ARCH_MULTI_V5 select ARCH_REQUIRE_GPIOLIB select CPU_FEROCEON select MVEBU_MBUS diff --git a/arch/arm/mach-mv78xx0/Makefile.boot b/arch/arm/mach-mv78xx0/Makefile.boot deleted file mode 100644 index 760a0efe7580..000000000000 --- a/arch/arm/mach-mv78xx0/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index f9597b701028..46c742d3bd41 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c @@ -140,6 +140,7 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) panic("Cannot find 'marvell,bootrom' compatible node"); err = of_address_to_resource(node, 0, &res); + of_node_put(node); if (err < 0) panic("Cannot get 'bootrom' node address"); diff --git a/arch/arm/mach-netx/Kconfig b/arch/arm/mach-netx/Kconfig index 3d90ef19be2b..2da8e5dfcf24 100644 --- a/arch/arm/mach-netx/Kconfig +++ b/arch/arm/mach-netx/Kconfig @@ -3,20 +3,17 @@ menu "NetX Implementations" config MACH_NXDKN bool "Enable Hilscher nxdkn Eval Board support" - depends on ARCH_NETX help Board support for the Hilscher NetX Eval Board config MACH_NXDB500 bool "Enable Hilscher nxdb500 Eval Board support" - depends on ARCH_NETX select ARM_AMBA help Board support for the Hilscher nxdb500 Eval Board config MACH_NXEB500HMI bool "Enable Hilscher nxeb500hmi Eval Board support" - depends on ARCH_NETX select ARM_AMBA help Board support for the Hilscher nxeb500hmi Eval Board diff --git a/arch/arm/mach-nspire/Makefile.boot b/arch/arm/mach-nspire/Makefile.boot deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot deleted file mode 100644 index b03e562acc60..000000000000 --- a/arch/arm/mach-omap2/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x80008000 -params_phys-y := 0x80000100 -initrd_phys-y := 0x80800000 diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 9cda974a3009..d7f1d69daf6d 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -66,32 +65,6 @@ static int __init omap3_l3_init(void) } omap_postcore_initcall(omap3_l3_init); -#if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) -static inline void __init omap_init_mbox(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - struct omap_mbox_pdata *pdata; - - oh = omap_hwmod_lookup("mailbox"); - if (!oh) { - pr_err("%s: unable to find hwmod\n", __func__); - return; - } - if (!oh->dev_attr) { - pr_err("%s: hwmod doesn't have valid attrs\n", __func__); - return; - } - - pdata = (struct omap_mbox_pdata *)oh->dev_attr; - pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata)); - WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", - __func__, PTR_ERR(pdev)); -} -#else -static inline void omap_init_mbox(void) { } -#endif /* CONFIG_OMAP2PLUS_MBOX */ - static inline void omap_init_sti(void) {} #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) @@ -229,7 +202,6 @@ static int __init omap2_init_devices(void) * please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ - omap_init_mbox(); omap_init_mcspi(); omap_init_sham(); omap_init_aes(); diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index e781e4fae13a..a935d28443da 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "common.h" #include "common-board-devices.h" @@ -449,6 +451,24 @@ void omap_auxdata_legacy_init(struct device *dev) dev->platform_data = &twl_gpio_auxdata; } +/* Dual mode timer PWM callbacks platdata */ +#if IS_ENABLED(CONFIG_OMAP_DM_TIMER) +struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = { + .request_by_node = omap_dm_timer_request_by_node, + .free = omap_dm_timer_free, + .enable = omap_dm_timer_enable, + .disable = omap_dm_timer_disable, + .get_fclk = omap_dm_timer_get_fclk, + .start = omap_dm_timer_start, + .stop = omap_dm_timer_stop, + .set_load = omap_dm_timer_set_load, + .set_match = omap_dm_timer_set_match, + .set_pwm = omap_dm_timer_set_pwm, + .set_prescaler = omap_dm_timer_set_prescaler, + .write_counter = omap_dm_timer_write_counter, +}; +#endif + /* * Few boards still need auxdata populated before we populate * the dev entries in of_platform_populate(). @@ -502,6 +522,9 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("ti,am4372-wkup-m3", 0x44d00000, "44d00000.wkup_m3", &wkup_m3_data), #endif +#if IS_ENABLED(CONFIG_OMAP_DM_TIMER) + OF_DEV_AUXDATA("ti,omap-dmtimer-pwm", 0, NULL, &pwm_dmtimer_pdata), +#endif #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu", &omap4_iommu_pdata), diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index eafd120b53f1..1b9f0520dea9 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -86,13 +86,18 @@ ENTRY(enable_omap3630_toggle_l2_on_restore) stmfd sp!, {lr} @ save registers on stack /* Setup so that we will disable and enable l2 */ mov r1, #0x1 - adrl r2, l2dis_3630 @ may be too distant for plain adr - str r1, [r2] + adrl r3, l2dis_3630_offset @ may be too distant for plain adr + ldr r2, [r3] @ value for offset + str r1, [r2, r3] @ write to l2dis_3630 ldmfd sp!, {pc} @ restore regs and return ENDPROC(enable_omap3630_toggle_l2_on_restore) - .text -/* Function to call rom code to save secure ram context */ +/* + * Function to call rom code to save secure ram context. This gets + * relocated to SRAM, so it can be all in .data section. Otherwise + * we need to initialize api_params separately. + */ + .data .align 3 ENTRY(save_secure_ram_context) stmfd sp!, {r4 - r11, lr} @ save registers on stack @@ -126,6 +131,8 @@ ENDPROC(save_secure_ram_context) ENTRY(save_secure_ram_context_sz) .word . - save_secure_ram_context + .text + /* * ====================== * == Idle entry point == @@ -289,12 +296,6 @@ wait_sdrc_ready: bic r5, r5, #0x40 str r5, [r4] -/* - * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a - * base instead. - * Be careful not to clobber r7 when maintaing this code. - */ - is_dll_in_lock_mode: /* Is dll in lock mode? */ ldr r4, sdrc_dlla_ctrl @@ -302,11 +303,7 @@ is_dll_in_lock_mode: tst r5, #0x4 bne exit_nonoff_modes @ Return if locked /* wait till dll locks */ - adr r7, kick_counter wait_dll_lock_timed: - ldr r4, wait_dll_lock_counter - add r4, r4, #1 - str r4, [r7, #wait_dll_lock_counter - kick_counter] ldr r4, sdrc_dlla_status /* Wait 20uS for lock */ mov r6, #8 @@ -330,9 +327,6 @@ kick_dll: orr r6, r6, #(1<<3) @ enable dll str r6, [r4] dsb - ldr r4, kick_counter - add r4, r4, #1 - str r4, [r7] @ kick_counter b wait_dll_lock_timed exit_nonoff_modes: @@ -360,15 +354,6 @@ sdrc_dlla_status: .word SDRC_DLLA_STATUS_V sdrc_dlla_ctrl: .word SDRC_DLLA_CTRL_V - /* - * When exporting to userspace while the counters are in SRAM, - * these 2 words need to be at the end to facilitate retrival! - */ -kick_counter: - .word 0 -wait_dll_lock_counter: - .word 0 - ENTRY(omap3_do_wfi_sz) .word . - omap3_do_wfi @@ -437,7 +422,9 @@ ENTRY(omap3_restore) cmp r2, #0x0 @ Check if target power state was OFF or RET bne logic_l1_restore - ldr r0, l2dis_3630 + adr r1, l2dis_3630_offset @ address for offset + ldr r0, [r1] @ value for offset + ldr r0, [r1, r0] @ value at l2dis_3630 cmp r0, #0x1 @ should we disable L2 on 3630? bne skipl2dis mrc p15, 0, r0, c1, c0, 1 @@ -449,12 +436,14 @@ skipl2dis: and r1, #0x700 cmp r1, #0x300 beq l2_inv_gp + adr r0, l2_inv_api_params_offset + ldr r3, [r0] + add r3, r3, r0 @ r3 points to dummy parameters mov r0, #40 @ set service ID for PPA mov r12, r0 @ copy secure Service ID in r12 mov r1, #0 @ set task id for ROM code in r1 mov r2, #4 @ set some flags in r2, r6 mov r6, #0xff - adr r3, l2_inv_api_params @ r3 points to dummy parameters dsb @ data write barrier dmb @ data memory barrier smc #1 @ call SMI monitor (smi #1) @@ -488,8 +477,8 @@ skipl2dis: b logic_l1_restore .align -l2_inv_api_params: - .word 0x1, 0x00 +l2_inv_api_params_offset: + .long l2_inv_api_params - . l2_inv_gp: /* Execute smi to invalidate L2 cache */ mov r12, #0x1 @ set up to invalidate L2 @@ -506,7 +495,9 @@ l2_inv_gp: mov r12, #0x2 smc #0 @ Call SMI monitor (smieq) logic_l1_restore: - ldr r1, l2dis_3630 + adr r0, l2dis_3630_offset @ adress for offset + ldr r1, [r0] @ value for offset + ldr r1, [r0, r1] @ value at l2dis_3630 cmp r1, #0x1 @ Test if L2 re-enable needed on 3630 bne skipl2reen mrc p15, 0, r1, c1, c0, 1 @@ -535,9 +526,17 @@ control_stat: .word CONTROL_STAT control_mem_rta: .word CONTROL_MEM_RTA_CTRL +l2dis_3630_offset: + .long l2dis_3630 - . + + .data l2dis_3630: .word 0 + .data +l2_inv_api_params: + .word 0x1, 0x00 + /* * Internal functions */ diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index 9b09d85d811a..c7a3b4aab4b5 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -29,12 +29,6 @@ dsb .endm -ppa_zero_params: - .word 0x0 - -ppa_por_params: - .word 1, 0 - #ifdef CONFIG_ARCH_OMAP4 /* @@ -266,7 +260,9 @@ ENTRY(omap4_cpu_resume) beq skip_ns_smp_enable ppa_actrl_retry: mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX - adr r3, ppa_zero_params @ Pointer to parameters + adr r1, ppa_zero_params_offset + ldr r3, [r1] + add r3, r3, r1 @ Pointer to ppa_zero_params mov r1, #0x0 @ Process ID mov r2, #0x4 @ Flag mov r6, #0xff @@ -303,7 +299,9 @@ skip_ns_smp_enable: ldr r0, =OMAP4_PPA_L2_POR_INDEX ldr r1, =OMAP44XX_SAR_RAM_BASE ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET] - adr r3, ppa_por_params + adr r1, ppa_por_params_offset + ldr r3, [r1] + add r3, r3, r1 @ Pointer to ppa_por_params str r4, [r3, #0x04] mov r1, #0x0 @ Process ID mov r2, #0x4 @ Flag @@ -328,6 +326,8 @@ skip_l2en: #endif b cpu_resume @ Jump to generic resume +ppa_por_params_offset: + .long ppa_por_params - . ENDPROC(omap4_cpu_resume) #endif /* CONFIG_ARCH_OMAP4 */ @@ -380,4 +380,13 @@ ENTRY(omap_do_wfi) nop ldmfd sp!, {pc} +ppa_zero_params_offset: + .long ppa_zero_params - . ENDPROC(omap_do_wfi) + + .data +ppa_zero_params: + .word 0 + +ppa_por_params: + .word 1, 0 diff --git a/arch/arm/mach-orion5x/Makefile.boot b/arch/arm/mach-orion5x/Makefile.boot deleted file mode 100644 index 760a0efe7580..000000000000 --- a/arch/arm/mach-orion5x/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-prima2/Makefile.boot b/arch/arm/mach-prima2/Makefile.boot deleted file mode 100644 index c77a4883a4ee..000000000000 --- a/arch/arm/mach-prima2/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ -zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig index 73494500b51c..e165ae4600f5 100644 --- a/arch/arm/mach-qcom/Kconfig +++ b/arch/arm/mach-qcom/Kconfig @@ -11,16 +11,17 @@ menuconfig ARCH_QCOM if ARCH_QCOM -config ARCH_MSM8X60 - bool "Enable support for MSM8X60" +config ARCH_QCOM_A_FAMILY + bool "Support a-family chipsets (msm8660, msm8960, apq8064)" + default y select CLKSRC_QCOM + help + Select this option if you want to support a-family platforms. -config ARCH_MSM8960 - bool "Enable support for MSM8960" - select CLKSRC_QCOM + A-family includes all Snapdragon S1/S2/S3/S4 chips before 2013, + up to the MSM8x60 and APQ8064 SoCs. -config ARCH_MSM8974 - bool "Enable support for MSM8974" - select HAVE_ARM_ARCH_TIMER + B-family includes all Snapdragon 2xx/4xx/6xx/8xx models starting + in 2013 with the MSM8x74 SoC. endif diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index def40a0dd60c..70ab4a25a5f8 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig @@ -1,5 +1,6 @@ menuconfig ARCH_REALVIEW - bool "ARM Ltd. RealView family" if ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7 + bool "ARM Ltd. RealView family" + depends on ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7 select ARM_AMBA select ARM_TIMER_SP804 select COMMON_CLK_VERSATILE diff --git a/arch/arm/mach-realview/Makefile.boot b/arch/arm/mach-realview/Makefile.boot deleted file mode 100644 index d2c3d788f688..000000000000 --- a/arch/arm/mach-realview/Makefile.boot +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(CONFIG_REALVIEW_HIGH_PHYS_OFFSET),y) - zreladdr-y += 0x70008000 -params_phys-y := 0x70000100 -initrd_phys-y := 0x70800000 -else - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 -endif diff --git a/arch/arm/mach-realview/platsmp-dt.c b/arch/arm/mach-realview/platsmp-dt.c index 65585392655b..6964e8876061 100644 --- a/arch/arm/mach-realview/platsmp-dt.c +++ b/arch/arm/mach-realview/platsmp-dt.c @@ -80,7 +80,7 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus) virt_to_phys(versatile_secondary_startup)); } -struct smp_operations realview_dt_smp_ops __initdata = { +static const struct smp_operations realview_dt_smp_ops __initconst = { .smp_prepare_cpus = realview_smp_prepare_cpus, .smp_secondary_init = versatile_secondary_init, .smp_boot_secondary = versatile_boot_secondary, diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 7c0c420c3016..e5c1888fc67b 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -3,7 +3,8 @@ # # Licensed under GPLv2 menuconfig ARCH_S3C64XX - bool "Samsung S3C64XX" if ARCH_MULTI_V6 + bool "Samsung S3C64XX" + depends on ARCH_MULTI_V6 select ARCH_REQUIRE_GPIOLIB select ARM_AMBA select ARM_VIC diff --git a/arch/arm/mach-s3c64xx/Makefile.boot b/arch/arm/mach-s3c64xx/Makefile.boot deleted file mode 100644 index c642333af3ed..000000000000 --- a/arch/arm/mach-s3c64xx/Makefile.boot +++ /dev/null @@ -1,2 +0,0 @@ - zreladdr-y += 0x50008000 -params_phys-y := 0x50000100 diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index 9cb11215ceba..225c12bb3de9 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h @@ -12,7 +12,8 @@ extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg); extern bool shmobile_smp_cpu_can_disable(unsigned int cpu); extern void shmobile_boot_scu(void); -extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); +extern void shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys, + unsigned int max_cpus); extern void shmobile_smp_scu_cpu_die(unsigned int cpu); extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); extern struct platform_suspend_ops shmobile_suspend_ops; @@ -31,8 +32,6 @@ int shmobile_cpufreq_init(void); static inline int shmobile_cpufreq_init(void) { return 0; } #endif -extern void __iomem *shmobile_scu_base; - static inline void __init shmobile_init_late(void) { shmobile_suspend_init(); diff --git a/arch/arm/mach-shmobile/cpufreq.c b/arch/arm/mach-shmobile/cpufreq.c index 57fbff024dcd..634d701c56a7 100644 --- a/arch/arm/mach-shmobile/cpufreq.c +++ b/arch/arm/mach-shmobile/cpufreq.c @@ -10,6 +10,8 @@ #include +#include "common.h" + int __init shmobile_cpufreq_init(void) { platform_device_register_simple("cpufreq-dt", -1, NULL, 0); diff --git a/arch/arm/mach-shmobile/emev2.h b/arch/arm/mach-shmobile/emev2.h new file mode 100644 index 000000000000..916d25f6780e --- /dev/null +++ b/arch/arm/mach-shmobile/emev2.h @@ -0,0 +1,6 @@ +#ifndef __ASM_EMEV2_H__ +#define __ASM_EMEV2_H__ + +extern const struct smp_operations emev2_smp_ops; + +#endif /* __ASM_EMEV2_H__ */ diff --git a/arch/arm/mach-shmobile/headsmp-scu.S b/arch/arm/mach-shmobile/headsmp-scu.S index fa5248c52399..936d7011c314 100644 --- a/arch/arm/mach-shmobile/headsmp-scu.S +++ b/arch/arm/mach-shmobile/headsmp-scu.S @@ -27,7 +27,7 @@ */ ENTRY(shmobile_boot_scu) @ r0 = SCU base address - mrc p15, 0, r1, c0, c0, 5 @ read MIPDR + mrc p15, 0, r1, c0, c0, 5 @ read MPIDR and r1, r1, #3 @ mask out cpu ID lsl r1, r1, #3 @ we will shift by cpu_id * 8 bits ldr r2, [r0, #8] @ SCU Power Status Register @@ -38,9 +38,3 @@ ENTRY(shmobile_boot_scu) b secondary_startup ENDPROC(shmobile_boot_scu) - - .text - .align 2 - .globl shmobile_scu_base -shmobile_scu_base: - .space 4 diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c index 64663110ab6c..4c7d2caf3730 100644 --- a/arch/arm/mach-shmobile/platsmp-scu.c +++ b/arch/arm/mach-shmobile/platsmp-scu.c @@ -17,6 +17,10 @@ #include #include "common.h" + +static phys_addr_t shmobile_scu_base_phys; +static void __iomem *shmobile_scu_base; + static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -26,7 +30,7 @@ static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb, case CPU_UP_PREPARE: /* For this particular CPU register SCU SMP boot vector */ shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), - (unsigned long)shmobile_scu_base); + shmobile_scu_base_phys); break; }; @@ -37,13 +41,16 @@ static struct notifier_block shmobile_smp_scu_notifier = { .notifier_call = shmobile_smp_scu_notifier_call, }; -void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) +void __init shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys, + unsigned int max_cpus) { /* install boot code shared by all CPUs */ shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); shmobile_boot_arg = MPIDR_HWID_BITMASK; /* enable SCU and cache coherency on booting CPU */ + shmobile_scu_base_phys = scu_base_phys; + shmobile_scu_base = ioremap(scu_base_phys, PAGE_SIZE); scu_enable(shmobile_scu_base); scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index 10b7cb5dcb3a..3c99aaf65325 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -18,35 +18,17 @@ #include #include #include -#include "common.h" - -static struct map_desc emev2_io_desc[] __initdata = { -#ifdef CONFIG_SMP - /* 2M mapping for SCU + L2 controller */ - { - .virtual = 0xf0000000, - .pfn = __phys_to_pfn(0x1e000000), - .length = SZ_2M, - .type = MT_DEVICE - }, -#endif -}; -static void __init emev2_map_io(void) -{ - iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc)); -} +#include "common.h" +#include "emev2.h" static const char *const emev2_boards_compat_dt[] __initconst = { "renesas,emev2", NULL, }; -extern const struct smp_operations emev2_smp_ops; - DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)") .smp = smp_ops(emev2_smp_ops), - .map_io = emev2_map_io, .init_early = shmobile_init_delay, .init_late = shmobile_init_late, .dt_compat = emev2_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 0c8f80c5b04d..db6dbfbaf9f1 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -23,41 +23,9 @@ #include #include #include -#include #include "common.h" -static struct map_desc r8a7740_io_desc[] __initdata = { - /* - * for CPGA/INTC/PFC - * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 160 << 20, - .type = MT_DEVICE_NONSHARED - }, -#ifdef CONFIG_CACHE_L2X0 - /* - * for l2x0_init() - * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000 - */ - { - .virtual = 0xf0002000, - .pfn = __phys_to_pfn(0xf0100000), - .length = PAGE_SIZE, - .type = MT_DEVICE_NONSHARED - }, -#endif -}; - -static void __init r8a7740_map_io(void) -{ - debug_ll_io_init(); - iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc)); -} - /* * r8a7740 chip has lasting errata on MERAM buffer. * this is work-around for it. @@ -110,10 +78,6 @@ static void __init r8a7740_generic_init(void) { r8a7740_meram_workaround(); -#ifdef CONFIG_CACHE_L2X0 - /* Shared attribute override enable, 32K*8way */ - l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff); -#endif of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } @@ -123,7 +87,8 @@ static const char *const r8a7740_boards_compat_dt[] __initconst = { }; DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)") - .map_io = r8a7740_map_io, + .l2c_aux_val = 0, + .l2c_aux_mask = ~0, .init_early = shmobile_init_delay, .init_irq = r8a7740_init_irq_of, .init_machine = r8a7740_generic_init, diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index 9eccde3c7b13..6d0ebdfb03a2 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -182,8 +182,6 @@ static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname, return 0; } -struct cma *rcar_gen2_dma_contiguous; - void __init rcar_gen2_reserve(void) { struct memory_reserve_config mrc; @@ -194,8 +192,11 @@ void __init rcar_gen2_reserve(void) of_scan_flat_dt(rcar_gen2_scan_mem, &mrc); #ifdef CONFIG_DMA_CMA - if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) + if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) { + static struct cma *rcar_gen2_dma_contiguous; + dma_contiguous_reserve_area(mrc.size, mrc.base, 0, &rcar_gen2_dma_contiguous, true); + } #endif } diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index adbac6963f2b..3a732199cf5e 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -21,7 +21,9 @@ #include #include #include + #include "common.h" +#include "emev2.h" #define EMEV2_SCU_BASE 0x1e000000 #define EMEV2_SMU_BASE 0xe0110000 @@ -45,8 +47,7 @@ static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) } /* setup EMEV2 specific SCU bits */ - shmobile_scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE); - shmobile_smp_scu_prepare_cpus(max_cpus); + shmobile_smp_scu_prepare_cpus(EMEV2_SCU_BASE, max_cpus); } const struct smp_operations emev2_smp_ops __initconst = { diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index b854fe2095ad..f5c31fbc10b2 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -92,12 +92,9 @@ static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) { /* Map the reset vector (in headsmp-scu.S, headsmp.S) */ __raw_writel(__pa(shmobile_boot_vector), AVECR); - shmobile_boot_fn = virt_to_phys(shmobile_boot_scu); - shmobile_boot_arg = (unsigned long)shmobile_scu_base; /* setup r8a7779 specific SCU bits */ - shmobile_scu_base = IOMEM(R8A7779_SCU_BASE); - shmobile_smp_scu_prepare_cpus(max_cpus); + shmobile_smp_scu_prepare_cpus(R8A7779_SCU_BASE, max_cpus); r8a7779_pm_init(); diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index ee1a4b70604b..41137404382e 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -52,8 +52,7 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) __raw_writel(__pa(shmobile_boot_vector), SBAR); /* setup sh73a0 specific SCU bits */ - shmobile_scu_base = IOMEM(SH73A0_SCU_BASE); - shmobile_smp_scu_prepare_cpus(max_cpus); + shmobile_smp_scu_prepare_cpus(SH73A0_SCU_BASE, max_cpus); } const struct smp_operations sh73a0_smp_ops __initconst = { diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c index 5d92b5dd486b..74b30bade2c1 100644 --- a/arch/arm/mach-shmobile/suspend.c +++ b/arch/arm/mach-shmobile/suspend.c @@ -17,6 +17,8 @@ #include #include +#include "common.h" + static int shmobile_suspend_default_enter(suspend_state_t suspend_state) { cpu_do_idle(); diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index c17d4d3881ff..ad008e4b0c49 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c @@ -18,6 +18,8 @@ #include #include +#include "common.h" + static void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz, unsigned int mult, unsigned int div) { diff --git a/arch/arm/mach-spear/Makefile.boot b/arch/arm/mach-spear/Makefile.boot deleted file mode 100644 index 4674a4c221db..000000000000 --- a/arch/arm/mach-spear/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ -zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index c2be98f38e73..3c156190a1d4 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c @@ -69,6 +69,7 @@ MACHINE_END static const char * const sun8i_board_dt_compat[] = { "allwinner,sun8i-a23", "allwinner,sun8i-a33", + "allwinner,sun8i-a83t", "allwinner,sun8i-h3", NULL, }; diff --git a/arch/arm/mach-tango/Kconfig b/arch/arm/mach-tango/Kconfig index d6a3714b096e..ebe15b93bbe8 100644 --- a/arch/arm/mach-tango/Kconfig +++ b/arch/arm/mach-tango/Kconfig @@ -1,5 +1,6 @@ config ARCH_TANGO - bool "Sigma Designs Tango4 (SMP87xx)" if ARCH_MULTI_V7 + bool "Sigma Designs Tango4 (SMP87xx)" + depends on ARCH_MULTI_V7 # Cortex-A9 MPCore r3p0, PL310 r3p2 select ARCH_HAS_HOLES_MEMORYMODEL select ARM_ERRATA_754322 diff --git a/arch/arm/mach-tango/platsmp.c b/arch/arm/mach-tango/platsmp.c index a18d5a34e2f5..a21f55e000d2 100644 --- a/arch/arm/mach-tango/platsmp.c +++ b/arch/arm/mach-tango/platsmp.c @@ -9,7 +9,7 @@ static int tango_boot_secondary(unsigned int cpu, struct task_struct *idle) return 0; } -static struct smp_operations tango_smp_ops __initdata = { +static const struct smp_operations tango_smp_ops __initconst = { .smp_boot_secondary = tango_boot_secondary, }; diff --git a/arch/arm/mach-u300/Makefile.boot b/arch/arm/mach-u300/Makefile.boot deleted file mode 100644 index 87811de0bd94..000000000000 --- a/arch/arm/mach-u300/Makefile.boot +++ /dev/null @@ -1,4 +0,0 @@ - zreladdr-y += 0x48008000 -params_phys-y := 0x48000100 -# This isn't used. -#initrd_phys-y := 0x48800000 diff --git a/arch/arm/mach-ux500/Makefile.boot b/arch/arm/mach-ux500/Makefile.boot deleted file mode 100644 index 760a0efe7580..000000000000 --- a/arch/arm/mach-ux500/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-zynq/Makefile.boot b/arch/arm/mach-zynq/Makefile.boot deleted file mode 100644 index 760a0efe7580..000000000000 --- a/arch/arm/mach-zynq/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 549f6d3aec5b..4daeda0a5b7f 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -1037,24 +1037,26 @@ config ARCH_SUPPORTS_BIG_ENDIAN This option specifies the architecture can support big endian operation. -config ARM_KERNMEM_PERMS - bool "Restrict kernel memory permissions" +config DEBUG_RODATA + bool "Make kernel text and rodata read-only" depends on MMU + default y if CPU_V7 help - If this is set, kernel memory other than kernel text (and rodata) - will be made non-executable. The tradeoff is that each region is - padded to section-size (1MiB) boundaries (because their permissions - are different and splitting the 1M pages into 4K ones causes TLB - performance problems), wasting memory. + If this is set, kernel text and rodata memory will be made + read-only, and non-text kernel memory will be made non-executable. + The tradeoff is that each region is padded to section-size (1MiB) + boundaries (because their permissions are different and splitting + the 1M pages into 4K ones causes TLB performance problems), which + can waste memory. -config DEBUG_RODATA - bool "Make kernel text and rodata read-only" - depends on ARM_KERNMEM_PERMS +config DEBUG_ALIGN_RODATA + bool "Make rodata strictly non-executable" + depends on DEBUG_RODATA default y help - If this is set, kernel text and rodata will be made read-only. This - is to help catch accidental or malicious attempts to change the - kernel's executable code. Additionally splits rodata from kernel - text so it can be made explicitly non-executable. This creates - another section-size padded region, so it can waste more memory - space while gaining the read-only protections. + If this is set, rodata will be made explicitly non-executable. This + provides protection on the rare chance that attackers might find and + use ROP gadgets that exist in the rodata section. This adds an + additional section-aligned split of rodata from kernel text so it + can be made explicitly non-executable. This padding may waste memory + space to gain the additional protection. diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c index 1e373d268c04..88255bea65e4 100644 --- a/arch/arm/mm/cache-tauros2.c +++ b/arch/arm/mm/cache-tauros2.c @@ -22,6 +22,11 @@ #include #include +/* CP15 PJ4 Control configuration register */ +#define CCR_L2C_PREFETCH_DISABLE BIT(24) +#define CCR_L2C_ECC_ENABLE BIT(23) +#define CCR_L2C_WAY7_4_DISABLE BIT(21) +#define CCR_L2C_BURST8_ENABLE BIT(20) /* * When Tauros2 is used on a CPU that supports the v7 hierarchical @@ -182,18 +187,18 @@ static void enable_extra_feature(unsigned int features) u = read_extra_features(); if (features & CACHE_TAUROS2_PREFETCH_ON) - u &= ~0x01000000; + u &= ~CCR_L2C_PREFETCH_DISABLE; else - u |= 0x01000000; + u |= CCR_L2C_PREFETCH_DISABLE; pr_info("Tauros2: %s L2 prefetch.\n", (features & CACHE_TAUROS2_PREFETCH_ON) ? "Enabling" : "Disabling"); if (features & CACHE_TAUROS2_LINEFILL_BURST8) - u |= 0x00100000; + u |= CCR_L2C_BURST8_ENABLE; else - u &= ~0x00100000; - pr_info("Tauros2: %s line fill burt8.\n", + u &= ~CCR_L2C_BURST8_ENABLE; + pr_info("Tauros2: %s burst8 line fill.\n", (features & CACHE_TAUROS2_LINEFILL_BURST8) ? "Enabling" : "Disabling"); @@ -287,16 +292,15 @@ void __init tauros2_init(unsigned int features) node = of_find_matching_node(NULL, tauros2_ids); if (!node) { pr_info("Not found marvell,tauros2-cache, disable it\n"); - return; + } else { + ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f); + if (ret) { + pr_info("Not found marvell,tauros-cache-features property, " + "disable extra features\n"); + features = 0; + } else + features = f; } - - ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f); - if (ret) { - pr_info("Not found marvell,tauros-cache-features property, " - "disable extra features\n"); - features = 0; - } else - features = f; #endif tauros2_internal_init(features); } diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index d65909697165..bd274a05b8ff 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -15,7 +15,7 @@ * page tables. */ pgd_t *idmap_pgd; -phys_addr_t (*arch_virt_to_idmap) (unsigned long x); +unsigned long (*arch_virt_to_idmap)(unsigned long x); #ifdef CONFIG_ARM_LPAE static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 49bd08178008..53f42508025b 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -572,8 +572,9 @@ void __init mem_init(void) } } -#ifdef CONFIG_ARM_KERNMEM_PERMS +#ifdef CONFIG_DEBUG_RODATA struct section_perm { + const char *name; unsigned long start; unsigned long end; pmdval_t mask; @@ -584,6 +585,7 @@ struct section_perm { static struct section_perm nx_perms[] = { /* Make pages tables, etc before _stext RW (set NX). */ { + .name = "pre-text NX", .start = PAGE_OFFSET, .end = (unsigned long)_stext, .mask = ~PMD_SECT_XN, @@ -591,14 +593,16 @@ static struct section_perm nx_perms[] = { }, /* Make init RW (set NX). */ { + .name = "init NX", .start = (unsigned long)__init_begin, .end = (unsigned long)_sdata, .mask = ~PMD_SECT_XN, .prot = PMD_SECT_XN, }, -#ifdef CONFIG_DEBUG_RODATA +#ifdef CONFIG_DEBUG_ALIGN_RODATA /* Make rodata NX (set RO in ro_perms below). */ { + .name = "rodata NX", .start = (unsigned long)__start_rodata, .end = (unsigned long)__init_begin, .mask = ~PMD_SECT_XN, @@ -607,10 +611,10 @@ static struct section_perm nx_perms[] = { #endif }; -#ifdef CONFIG_DEBUG_RODATA static struct section_perm ro_perms[] = { /* Make kernel code and rodata RX (set RO). */ { + .name = "text/rodata RO", .start = (unsigned long)_stext, .end = (unsigned long)__init_begin, #ifdef CONFIG_ARM_LPAE @@ -623,7 +627,6 @@ static struct section_perm ro_perms[] = { #endif }, }; -#endif /* * Updates section permissions only for the current mm (sections are @@ -670,8 +673,8 @@ void set_section_perms(struct section_perm *perms, int n, bool set, for (i = 0; i < n; i++) { if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) || !IS_ALIGNED(perms[i].end, SECTION_SIZE)) { - pr_err("BUG: section %lx-%lx not aligned to %lx\n", - perms[i].start, perms[i].end, + pr_err("BUG: %s section %lx-%lx not aligned to %lx\n", + perms[i].name, perms[i].start, perms[i].end, SECTION_SIZE); continue; } @@ -712,7 +715,6 @@ void fix_kernmem_perms(void) stop_machine(__fix_kernmem_perms, NULL, NULL); } -#ifdef CONFIG_DEBUG_RODATA int __mark_rodata_ro(void *unused) { update_sections_early(ro_perms, ARRAY_SIZE(ro_perms)); @@ -735,11 +737,10 @@ void set_kernel_text_ro(void) set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true, current->active_mm); } -#endif /* CONFIG_DEBUG_RODATA */ #else static inline void fix_kernmem_perms(void) { } -#endif /* CONFIG_ARM_KERNMEM_PERMS */ +#endif /* CONFIG_DEBUG_RODATA */ void free_tcmmem(void) { diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index 8085a8aac812..ffb93db68e9c 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c @@ -18,6 +18,7 @@ #include #include #include +#include /* * MBus bridge block registers. @@ -188,6 +189,15 @@ orion_time_set_base(void __iomem *_timer_base) timer_base = _timer_base; } +static unsigned long orion_delay_timer_read(void) +{ + return ~readl(timer_base + TIMER0_VAL_OFF); +} + +static struct delay_timer orion_delay_timer = { + .read_current_timer = orion_delay_timer_read, +}; + void __init orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, unsigned int irq, unsigned int tclk) @@ -202,6 +212,9 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, ticks_per_jiffy = (tclk + HZ/2) / HZ; + orion_delay_timer.freq = tclk; + register_current_timer_delay(&orion_delay_timer); + /* * Set scale and timer for sched_clock. */ diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index efa6e85619ad..daf3db9f0058 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -422,8 +422,7 @@ static int s3c_adc_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int s3c_adc_suspend(struct device *dev) { - struct platform_device *pdev = container_of(dev, - struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct adc_device *adc = platform_get_drvdata(pdev); unsigned long flags; u32 con; @@ -444,8 +443,7 @@ static int s3c_adc_suspend(struct device *dev) static int s3c_adc_resume(struct device *dev) { - struct platform_device *pdev = container_of(dev, - struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct adc_device *adc = platform_get_drvdata(pdev); enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data; int ret; diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index b53d4ff3befb..84baa16f4c0b 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -727,15 +727,6 @@ static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set) return -ENOMEM; } - if (set->ecc_layout) { - ptr = kmemdup(set->ecc_layout, - sizeof(struct nand_ecclayout), GFP_KERNEL); - set->ecc_layout = ptr; - - if (!ptr) - return -ENOMEM; - } - return 0; } diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h index f5cf2bd208e0..e5557693fa92 100644 --- a/arch/arm/plat-samsung/include/plat/map-s5p.h +++ b/arch/arm/plat-samsung/include/plat/map-s5p.h @@ -18,7 +18,6 @@ #define S5P_VA_DMC0 S3C_ADDR(0x02440000) #define S5P_VA_DMC1 S3C_ADDR(0x02480000) -#define S5P_VA_SROMC S3C_ADDR(0x024C0000) #define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000) #define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x)) diff --git a/arch/arm/plat-samsung/pm-check.c b/arch/arm/plat-samsung/pm-check.c index 04aff2c31b46..70f2f699bed3 100644 --- a/arch/arm/plat-samsung/pm-check.c +++ b/arch/arm/plat-samsung/pm-check.c @@ -53,8 +53,8 @@ static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg) if (ptr->child != NULL) s3c_pm_run_res(ptr->child, fn, arg); - if ((ptr->flags & IORESOURCE_MEM) && - strcmp(ptr->name, "System RAM") == 0) { + if ((ptr->flags & IORESOURCE_SYSTEM_RAM) + == IORESOURCE_SYSTEM_RAM) { S3C_PMDBG("Found system RAM at %08lx..%08lx\n", (unsigned long)ptr->start, (unsigned long)ptr->end); diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 8cc62289a63e..af7c045e812b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -14,6 +14,7 @@ config ARM64 select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_COMPAT_IPC_PARSE_VERSION select ARCH_WANT_FRAME_POINTERS + select ARCH_HAS_UBSAN_SANITIZE_ALL select ARM_AMBA select ARM_ARCH_TIMER select ARM_GIC @@ -49,6 +50,7 @@ config ARM64 select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_BITREVERSE + select HAVE_ARCH_HUGE_VMAP select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP && !(ARM64_16K_PAGES && ARM64_VA_BITS_48) select HAVE_ARCH_KGDB @@ -537,6 +539,9 @@ config HOTPLUG_CPU source kernel/Kconfig.preempt source kernel/Kconfig.hz +config ARCH_SUPPORTS_DEBUG_PAGEALLOC + def_bool y + config ARCH_HAS_HOLES_MEMORYMODEL def_bool y if SPARSEMEM @@ -756,6 +761,15 @@ endmenu menu "Boot options" +config ARM64_ACPI_PARKING_PROTOCOL + bool "Enable support for the ARM64 ACPI parking protocol" + depends on ACPI + help + Enable support for the ARM64 ACPI parking protocol. If disabled + the kernel will not allow booting through the ARM64 ACPI parking + protocol even if the corresponding data is present in the ACPI + MADT table. + config CMDLINE string "Default kernel command string" default "" diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 21074f674bde..8a0952275291 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -60,6 +60,7 @@ config ARCH_ROCKCHIP select ARCH_REQUIRE_GPIOLIB select PINCTRL select PINCTRL_ROCKCHIP + select ROCKCHIP_TIMER help This enables support for the ARMv8 based Rockchip chipsets, like the RK3368. diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index cd822d8454c0..307237cfe728 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -27,6 +27,8 @@ $(warning LSE atomics not supported by binutils) endif KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) +KBUILD_CFLAGS += -fno-asynchronous-unwind-tables +KBUILD_CFLAGS += $(call cc-option, -mpc-relative-literal-loads) KBUILD_AFLAGS += $(lseinstr) ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) diff --git a/arch/arm64/boot/dts/amd/Makefile b/arch/arm64/boot/dts/amd/Makefile index cfdf701e05df..ba84770f789f 100644 --- a/arch/arm64/boot/dts/amd/Makefile +++ b/arch/arm64/boot/dts/amd/Makefile @@ -1,4 +1,6 @@ -dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb +dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb \ + amd-overdrive-rev-b0.dtb amd-overdrive-rev-b1.dtb \ + husky.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts new file mode 100644 index 000000000000..8e3074a4947d --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts @@ -0,0 +1,87 @@ +/* + * DTS file for AMD Seattle Overdrive Development Board + * Note: For Seattle Rev.B0 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "AMD Seattle (Rev.B0) Development Board (Overdrive)"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&ipmi_kcs { + status = "ok"; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts new file mode 100644 index 000000000000..ed5e043f37aa --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts @@ -0,0 +1,91 @@ +/* + * DTS file for AMD Seattle Overdrive Development Board + * Note: For Seattle Rev.B1 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "AMD Seattle (Rev.B1) Development Board (Overdrive)"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&sata1 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&ipmi_kcs { + status = "ok"; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index 2874d92881fd..a7fc059a7cd9 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -18,8 +18,8 @@ #size-cells = <2>; reg = <0x0 0xe1110000 0 0x1000>, <0x0 0xe112f000 0 0x2000>, - <0x0 0xe1140000 0 0x10000>, - <0x0 0xe1160000 0 0x10000>; + <0x0 0xe1140000 0 0x2000>, + <0x0 0xe1160000 0 0x2000>; interrupts = <1 9 0xf04>; ranges = <0 0 0 0xe1100000 0 0x100000>; v2m0: v2m@e0080000 { @@ -55,25 +55,47 @@ #size-cells = <2>; ranges; - /* DDR range is 40-bit addressing */ - dma-ranges = <0x80 0x0 0x80 0x0 0x7f 0xffffffff>; + /* + * dma-ranges is 40-bit address space containing: + * - GICv2m MSI register is at 0xe0080000 + * - DRAM range [0x8000000000 to 0xffffffffff] + */ + dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>; /include/ "amd-seattle-clks.dtsi" sata0: sata@e0300000 { compatible = "snps,dwc-ahci"; - reg = <0 0xe0300000 0 0x800>; + reg = <0 0xe0300000 0 0xf0000>; interrupts = <0 355 4>; clocks = <&sataclk_333mhz>; dma-coherent; }; + /* This is for Rev B only */ + sata1: sata@e0d00000 { + status = "disabled"; + compatible = "snps,dwc-ahci"; + reg = <0 0xe0d00000 0 0xf0000>; + interrupts = <0 354 4>; + clocks = <&sataclk_333mhz>; + dma-coherent; + }; + i2c0: i2c@e1000000 { status = "disabled"; compatible = "snps,designware-i2c"; reg = <0 0xe1000000 0 0x1000>; interrupts = <0 357 4>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; + }; + + i2c1: i2c@e0050000 { + status = "disabled"; + compatible = "snps,designware-i2c"; + reg = <0 0xe0050000 0 0x1000>; + interrupts = <0 340 4>; + clocks = <&miscclk_250mhz>; }; serial0: serial@e1010000 { @@ -87,7 +109,6 @@ spi0: ssp@e1020000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell"; - #gpio-cells = <2>; reg = <0 0xe1020000 0 0x1000>; spi-controller; interrupts = <0 330 4>; @@ -98,7 +119,6 @@ spi1: ssp@e1030000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell"; - #gpio-cells = <2>; reg = <0 0xe1030000 0 0x1000>; spi-controller; interrupts = <0 329 4>; @@ -109,7 +129,7 @@ #size-cells = <0>; }; - gpio0: gpio@e1040000 { + gpio0: gpio@e1040000 { /* Not available to OS for B0 */ status = "disabled"; compatible = "arm,pl061", "arm,primecell"; #gpio-cells = <2>; @@ -118,18 +138,59 @@ interrupts = <0 359 4>; interrupt-controller; #interrupt-cells = <2>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; clock-names = "apb_pclk"; }; - gpio1: gpio@e1050000 { + gpio1: gpio@e1050000 { /* [0:7] */ status = "disabled"; compatible = "arm,pl061", "arm,primecell"; #gpio-cells = <2>; reg = <0 0xe1050000 0 0x1000>; gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; interrupts = <0 358 4>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio2: gpio@e0020000 { /* [8:15] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0020000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 366 4>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio3: gpio@e0030000 { /* [16:23] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0030000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 365 4>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio4: gpio@e0080000 { /* [24] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0080000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 361 4>; + clocks = <&miscclk_250mhz>; clock-names = "apb_pclk"; }; @@ -159,7 +220,7 @@ <0x1000 0x0 0x0 0x4 &gic0 0x0 0x0 0x0 0x123 0x1>; dma-coherent; - dma-ranges = <0x43000000 0x80 0x0 0x80 0x0 0x7f 0xffffffff>; + dma-ranges = <0x43000000 0x0 0x0 0x0 0x0 0x100 0x0>; ranges = /* I/O Memory (size=64K) */ <0x01000000 0x00 0x00000000 0x00 0xefff0000 0x00 0x00010000>, @@ -168,5 +229,23 @@ /* 64-bit MMIO (size= 124G) */ <0x03000000 0x01 0x00000000 0x01 0x00000000 0x7f 0x00000000>; }; + + /* Perf CCN504 PMU */ + ccn: ccn@0xe8000000 { + compatible = "arm,ccn-504"; + reg = <0x0 0xe8000000 0 0x1000000>; + interrupts = <0 380 4>; + }; + + ipmi_kcs: kcs@e0010000 { + status = "disabled"; + compatible = "ipmi-kcs"; + device_type = "ipmi"; + reg = <0x0 0xe0010000 0 0x8>; + interrupts = <0 389 4>; + interrupt-names = "ipmi_kcs"; + reg-size = <1>; + reg-spacing = <4>; + }; }; }; diff --git a/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi new file mode 100644 index 000000000000..8e8631952497 --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi @@ -0,0 +1,117 @@ +/* + * DTS file for AMD Seattle XGBE (RevB) + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + + xgmacclk0_dma_250mhz: clk250mhz_0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk0_dma_250mhz"; + }; + + xgmacclk0_ptp_250mhz: clk250mhz_1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk0_ptp_250mhz"; + }; + + xgmacclk1_dma_250mhz: clk250mhz_2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk1_dma_250mhz"; + }; + + xgmacclk1_ptp_250mhz: clk250mhz_3 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk1_ptp_250mhz"; + }; + + xgmac0: xgmac@e0700000 { + compatible = "amd,xgbe-seattle-v1a"; + reg = <0 0xe0700000 0 0x80000>, + <0 0xe0780000 0 0x80000>, + <0 0xe1240800 0 0x00400>, /* SERDES RX/TX0 */ + <0 0xe1250000 0 0x00060>, /* SERDES IR 1/2 */ + <0 0xe12500f8 0 0x00004>; /* SERDES IR 2/2 */ + interrupts = <0 325 4>, + <0 346 1>, <0 347 1>, <0 348 1>, <0 349 1>, + <0 323 4>; + amd,per-channel-interrupt; + amd,speed-set = <0>; + amd,serdes-blwc = <1>, <1>, <0>; + amd,serdes-cdr-rate = <2>, <2>, <7>; + amd,serdes-pq-skew = <10>, <10>, <18>; + amd,serdes-tx-amp = <0>, <0>, <0>; + amd,serdes-dfe-tap-config = <3>, <3>, <3>; + amd,serdes-dfe-tap-enable = <0>, <0>, <7>; + mac-address = [ 02 A1 A2 A3 A4 A5 ]; + clocks = <&xgmacclk0_dma_250mhz>, <&xgmacclk0_ptp_250mhz>; + clock-names = "dma_clk", "ptp_clk"; + phy-mode = "xgmii"; + #stream-id-cells = <16>; + dma-coherent; + }; + + xgmac1: xgmac@e0900000 { + compatible = "amd,xgbe-seattle-v1a"; + reg = <0 0xe0900000 0 0x80000>, + <0 0xe0980000 0 0x80000>, + <0 0xe1240c00 0 0x00400>, /* SERDES RX/TX1 */ + <0 0xe1250080 0 0x00060>, /* SERDES IR 1/2 */ + <0 0xe12500fc 0 0x00004>; /* SERDES IR 2/2 */ + interrupts = <0 324 4>, + <0 341 1>, <0 342 1>, <0 343 1>, <0 344 1>, + <0 322 4>; + amd,per-channel-interrupt; + amd,speed-set = <0>; + amd,serdes-blwc = <1>, <1>, <0>; + amd,serdes-cdr-rate = <2>, <2>, <7>; + amd,serdes-pq-skew = <10>, <10>, <18>; + amd,serdes-tx-amp = <0>, <0>, <0>; + amd,serdes-dfe-tap-config = <3>, <3>, <3>; + amd,serdes-dfe-tap-enable = <0>, <0>, <7>; + mac-address = [ 02 B1 B2 B3 B4 B5 ]; + clocks = <&xgmacclk1_dma_250mhz>, <&xgmacclk1_ptp_250mhz>; + clock-names = "dma_clk", "ptp_clk"; + phy-mode = "xgmii"; + #stream-id-cells = <16>; + dma-coherent; + }; + + xgmac0_smmu: smmu@e0600000 { + compatible = "arm,mmu-401"; + reg = <0 0xe0600000 0 0x10000>; + #global-interrupts = <1>; + interrupts = /* Uses combined intr for both + * global and context + */ + <0 336 4>, + <0 336 4>; + + mmu-masters = <&xgmac0 + 0 1 2 3 4 5 6 7 + 16 17 18 19 20 21 22 23 + >; + }; + + xgmac1_smmu: smmu@e0800000 { + compatible = "arm,mmu-401"; + reg = <0 0xe0800000 0 0x10000>; + #global-interrupts = <1>; + interrupts = /* Uses combined intr for both + * global and context + */ + <0 335 4>, + <0 335 4>; + + mmu-masters = <&xgmac1 + 0 1 2 3 4 5 6 7 + 16 17 18 19 20 21 22 23 + >; + }; diff --git a/arch/arm64/boot/dts/amd/husky.dts b/arch/arm64/boot/dts/amd/husky.dts new file mode 100644 index 000000000000..1381d4b2bf1b --- /dev/null +++ b/arch/arm64/boot/dts/amd/husky.dts @@ -0,0 +1,83 @@ +/* + * DTS file for AMD/Linaro 96Boards Enterprise Edition Server (Husky) Board + * Note: Based-on AMD Seattle Rev.B0 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "Linaro 96Boards Enterprise Edition Server (Husky) Board"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index fe30f7671ea3..3e40bd469cea 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi @@ -493,6 +493,11 @@ reg = <0x0 0x1054a000 0x0 0x20>; }; + rb: rb@7e000000 { + compatible = "apm,xgene-rb", "syscon"; + reg = <0x0 0x7e000000 0x0 0x10>; + }; + edac@78800000 { compatible = "apm,xgene-edac"; #address-cells = <2>; @@ -502,6 +507,7 @@ regmap-mcba = <&mcba>; regmap-mcbb = <&mcbb>; regmap-efuse = <&efuse>; + regmap-rb = <&rb>; reg = <0x0 0x78800000 0x0 0x100>; interrupts = <0x0 0x20 0x4>, <0x0 0x21 0x4>, diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index dd5158eb5872..7c83e3ac84c9 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -92,8 +92,8 @@ scpi_clk: scpi_clocks@3 { compatible = "arm,scpi-variable-clocks"; #clock-cells = <1>; - clock-indices = <3>, <4>; - clock-output-names = "pxlclk0", "pxlclk1"; + clock-indices = <3>; + clock-output-names = "pxlclk"; }; }; @@ -115,6 +115,7 @@ , , , + , , , , @@ -123,6 +124,34 @@ clock-names = "apb_pclk"; }; + hdlcd@7ff50000 { + compatible = "arm,hdlcd"; + reg = <0 0x7ff50000 0 0x1000>; + interrupts = ; + clocks = <&scpi_clk 3>; + clock-names = "pxlclk"; + + port { + hdlcd1_output: endpoint@0 { + remote-endpoint = <&tda998x_1_input>; + }; + }; + }; + + hdlcd@7ff60000 { + compatible = "arm,hdlcd"; + reg = <0 0x7ff60000 0 0x1000>; + interrupts = ; + clocks = <&scpi_clk 3>; + clock-names = "pxlclk"; + + port { + hdlcd0_output: endpoint@0 { + remote-endpoint = <&tda998x_0_input>; + }; + }; + }; + soc_uart0: uart@7ff80000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0 0x7ff80000 0x0 0x1000>; @@ -141,14 +170,24 @@ i2c-sda-hold-time-ns = <500>; clocks = <&soc_smc50mhz>; - dvi0: dvi-transmitter@70 { + hdmi-transmitter@70 { compatible = "nxp,tda998x"; reg = <0x70>; + port { + tda998x_0_input: endpoint@0 { + remote-endpoint = <&hdlcd0_output>; + }; + }; }; - dvi1: dvi-transmitter@71 { + hdmi-transmitter@71 { compatible = "nxp,tda998x"; reg = <0x71>; + port { + tda998x_1_input: endpoint@0 { + remote-endpoint = <&hdlcd1_output>; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi index da7b6e613257..933cba359918 100644 --- a/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi @@ -23,9 +23,8 @@ soc0: soc@000000000 { }; }; - dsa: dsa@c7000000 { + dsaf0: dsa@c7000000 { compatible = "hisilicon,hns-dsaf-v1"; - dsa_name = "dsaf0"; mode = "6port-16rss"; interrupt-parent = <&mbigen_dsa>; @@ -127,7 +126,7 @@ soc0: soc@000000000 { eth0: ethernet@0{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <0>; local-mac-address = [00 00 00 01 00 58]; status = "disabled"; @@ -135,14 +134,14 @@ soc0: soc@000000000 { }; eth1: ethernet@1{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <1>; status = "disabled"; dma-coherent; }; eth2: ethernet@2{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <2>; local-mac-address = [00 00 00 01 00 5a]; status = "disabled"; @@ -150,7 +149,7 @@ soc0: soc@000000000 { }; eth3: ethernet@3{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <3>; local-mac-address = [00 00 00 01 00 5b]; status = "disabled"; @@ -158,7 +157,7 @@ soc0: soc@000000000 { }; eth4: ethernet@4{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <4>; local-mac-address = [00 00 00 01 00 5c]; status = "disabled"; @@ -166,7 +165,7 @@ soc0: soc@000000000 { }; eth5: ethernet@5{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <5>; local-mac-address = [00 00 00 01 00 5d]; status = "disabled"; @@ -174,7 +173,7 @@ soc0: soc@000000000 { }; eth6: ethernet@6{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <6>; local-mac-address = [00 00 00 01 00 5e]; status = "disabled"; @@ -182,7 +181,7 @@ soc0: soc@000000000 { }; eth7: ethernet@7{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <7>; local-mac-address = [00 00 00 01 00 5f]; status = "disabled"; diff --git a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts index 7dfe1c085966..62f33fc84e3e 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts +++ b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts @@ -12,6 +12,8 @@ rtc1 = "/rtc@0,7000e000"; }; + chosen { }; + memory { device_type = "memory"; reg = <0x0 0x80000000 0x0 0x80000000>; diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi index e8bb46027bed..be0e9d70e6c4 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -315,7 +315,7 @@ * driver and APB DMA based serial driver for higher baudrate * and performace. To enable the 8250 based driver, the compatible * is "nvidia,tegra124-uart", "nvidia,tegra20-uart" and to enable - * the APB DMA based serial driver, the comptible is + * the APB DMA based serial driver, the compatible is * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart". */ uarta: serial@0,70006000 { diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index bc23f4dea002..cd4f45ccd6a7 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -347,7 +347,7 @@ * driver and APB DMA based serial driver for higher baudrate * and performace. To enable the 8250 based driver, the compatible * is "nvidia,tegra124-uart", "nvidia,tegra20-uart" and to enable - * the APB DMA based serial driver, the comptible is + * the APB DMA based serial driver, the compatible is * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart". */ uarta: serial@0,70006000 { diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 8e94af64ee94..fa1f661ccccf 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb msm8916-mtp.dtb +dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index db17c5d5689c..6b4289dd2495 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -24,6 +24,8 @@ i2c0 = &blsp_i2c2; i2c1 = &blsp_i2c6; i2c3 = &blsp_i2c4; + spi0 = &blsp_spi5; + spi1 = &blsp_spi3; }; chosen { @@ -127,9 +129,135 @@ default-state = "off"; }; }; + + sdhci@07824000 { + vmmc-supply = <&pm8916_l8>; + vqmmc-supply = <&pm8916_l5>; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; + status = "okay"; + }; }; }; -&sdhc_1 { - status = "okay"; +&smd_rpm_regulators { + vdd_l1_l2_l3-supply = <&pm8916_s3>; + vdd_l5-supply = <&pm8916_s3>; + vdd_l4_l5_l6-supply = <&pm8916_s4>; + vdd_l7-supply = <&pm8916_s4>; + + s1 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1562000>; + }; + + s3 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1562000>; + }; + + s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-always-on; + regulator-boot-on; + }; + + l1 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + + l2 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + + l3 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + + l4 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l5 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l6 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l7 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l8 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l9 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l10 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l11 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l12 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l13 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l14 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + /** + * 1.8v required on LS expansion + * for mezzanine boards + */ + l15 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + regulator-always-on; + }; + + l16 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l17 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l18 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi index 955c6f174d4c..8d050059e9a8 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -81,8 +81,8 @@ bias-disable; }; pinconf_cs { - pins = "gpio2"; - drive-strength = <2>; + pins = "gpio16"; + drive-strength = <16>; bias-disable; output-high; }; @@ -110,13 +110,13 @@ pins = "gpio6"; }; pinconf { - pins = "gpio4", "gpio5", "gpio6", "gpio7"; + pins = "gpio4", "gpio5", "gpio7"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio6"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -144,13 +144,13 @@ pins = "gpio10"; }; pinconf { - pins = "gpio8", "gpio9", "gpio10", "gpio11"; + pins = "gpio8", "gpio9", "gpio11"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio10"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -178,13 +178,13 @@ pins = "gpio14"; }; pinconf { - pins = "gpio12", "gpio13", "gpio14", "gpio15"; + pins = "gpio12", "gpio13", "gpio15"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio14"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -212,13 +212,13 @@ pins = "gpio18"; }; pinconf { - pins = "gpio16", "gpio17", "gpio18", "gpio19"; + pins = "gpio16", "gpio17", "gpio19"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio18"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -246,13 +246,13 @@ pins = "gpio22"; }; pinconf { - pins = "gpio20", "gpio21", "gpio22", "gpio23"; + pins = "gpio20", "gpio21", "gpio23"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio22"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 915321479998..7705207872a5 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -61,24 +61,33 @@ device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0>; + next-level-cache = <&L2_0>; }; CPU1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x1>; + next-level-cache = <&L2_0>; }; CPU2: cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x2>; + next-level-cache = <&L2_0>; }; CPU3: cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x3>; + next-level-cache = <&L2_0>; + }; + + L2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; }; }; @@ -134,7 +143,7 @@ #interrupt-cells = <2>; }; - gcc: qcom,gcc@1800000 { + gcc: clock-controller@1800000 { compatible = "qcom,gcc-msm8916"; #clock-cells = <1>; #reset-cells = <1>; @@ -515,11 +524,15 @@ compatible = "qcom,rpm-msm8916"; qcom,smd-channels = "rpm_requests"; - pm8916-regulators { + rpmcc: qcom,rpmcc { + compatible = "qcom,rpmcc-msm8916", "qcom,rpmcc"; + #clock-cells = <1>; + }; + + smd_rpm_regulators: pm8916-regulators { compatible = "qcom,rpm-pm8916-regulators"; pm8916_s1: s1 {}; - pm8916_s2: s2 {}; pm8916_s3: s3 {}; pm8916_s4: s4 {}; diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dts b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts new file mode 100644 index 000000000000..619af44a595d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2014-2015, 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. + */ + +/dts-v1/; + +#include "msm8996-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8996 MTP"; + compatible = "qcom,msm8996-mtp"; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi new file mode 100644 index 000000000000..9bab5c011c07 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014-2015, 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 "msm8996.dtsi" + +/ { + aliases { + serial0 = &blsp2_uart1; + }; + + chosen { + stdout-path = "serial0"; + }; + + soc { + serial@75b0000 { + status = "okay"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi new file mode 100644 index 000000000000..2c2736d6c28e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -0,0 +1,267 @@ +/* Copyright (c) 2014-2015, 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 +#include + +/ { + model = "Qualcomm Technologies, Inc. MSM8996"; + + interrupt-parent = <&intc>; + + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + memory { + device_type = "memory"; + /* We expect the bootloader to fill in the reg */ + reg = <0 0 0 0>; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x0>; + enable-method = "psci"; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; + }; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x1>; + enable-method = "psci"; + next-level-cache = <&L2_0>; + }; + + CPU2: cpu@100 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x100>; + enable-method = "psci"; + next-level-cache = <&L2_1>; + L2_1: l2-cache { + compatible = "cache"; + cache-level = <2>; + }; + }; + + CPU3: cpu@101 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x101>; + enable-method = "psci"; + next-level-cache = <&L2_1>; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + + core1 { + cpu = <&CPU1>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU2>; + }; + + core1 { + cpu = <&CPU3>; + }; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + clocks { + xo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + clock-output-names = "xo_board"; + }; + + sleep_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32764>; + clock-output-names = "sleep_clk"; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + soc: soc { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + + intc: interrupt-controller@9bc0000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-controller; + #redistributor-regions = <1>; + redistributor-stride = <0x0 0x40000>; + reg = <0x09bc0000 0x10000>, + <0x09c00000 0x100000>; + interrupts = ; + }; + + gcc: clock-controller@300000 { + compatible = "qcom,gcc-msm8996"; + #clock-cells = <1>; + #reset-cells = <1>; + reg = <0x300000 0x90000>; + }; + + blsp2_uart1: serial@75b0000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x75b0000 0x1000>; + interrupts = ; + clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>, + <&gcc GCC_BLSP2_AHB_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + + pinctrl@1010000 { + compatible = "qcom,msm8996-pinctrl"; + reg = <0x01010000 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + timer@09840000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0x09840000 0x1000>; + clock-frequency = <19200000>; + + frame@9850000 { + frame-number = <0>; + interrupts = , + ; + reg = <0x09850000 0x1000>, + <0x09860000 0x1000>; + }; + + frame@9870000 { + frame-number = <1>; + interrupts = ; + reg = <0x09870000 0x1000>; + status = "disabled"; + }; + + frame@9880000 { + frame-number = <2>; + interrupts = ; + reg = <0x09880000 0x1000>; + status = "disabled"; + }; + + frame@9890000 { + frame-number = <3>; + interrupts = ; + reg = <0x09890000 0x1000>; + status = "disabled"; + }; + + frame@98a0000 { + frame-number = <4>; + interrupts = ; + reg = <0x098a0000 0x1000>; + status = "disabled"; + }; + + frame@98b0000 { + frame-number = <5>; + interrupts = ; + reg = <0x098b0000 0x1000>; + status = "disabled"; + }; + + frame@98c0000 { + frame-number = <6>; + interrupts = ; + reg = <0x098c0000 0x1000>; + status = "disabled"; + }; + }; + + spmi_bus: qcom,spmi@400f000 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0x400f000 0x1000>, + <0x4400000 0x800000>, + <0x4c00000 0x800000>, + <0x5800000 0x200000>, + <0x400a000 0x002100>; + reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; + interrupt-names = "periph_irq"; + interrupts = ; + qcom,ee = <0>; + qcom,channel = <0>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <4>; + }; + + mmcc: clock-controller@8c0000 { + compatible = "qcom,mmcc-msm8996"; + #clock-cells = <1>; + #reset-cells = <1>; + reg = <0x8c0000 0x40000>; + assigned-clocks = <&mmcc MMPLL9_PLL>, + <&mmcc MMPLL1_PLL>, + <&mmcc MMPLL3_PLL>, + <&mmcc MMPLL4_PLL>, + <&mmcc MMPLL5_PLL>; + assigned-clock-rates = <624000000>, + <810000000>, + <980000000>, + <960000000>, + <825000000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pm8004.dtsi b/arch/arm64/boot/dts/qcom/pm8004.dtsi new file mode 100644 index 000000000000..ef2207afa86b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pm8004.dtsi @@ -0,0 +1,19 @@ +#include +#include + +&spmi_bus { + + pmic@4 { + compatible = "qcom,pm8004", "qcom,spmi-pmic"; + reg = <0x4 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; + + pmic@5 { + compatible = "qcom,pm8004", "qcom,spmi-pmic"; + reg = <0x5 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pm8994.dtsi b/arch/arm64/boot/dts/qcom/pm8994.dtsi new file mode 100644 index 000000000000..1732f1d32f4c --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pm8994.dtsi @@ -0,0 +1,62 @@ +#include +#include + +&spmi_bus { + + pmic@0 { + compatible = "qcom,pm8994", "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pm8994_gpios: gpios@c000 { + compatible = "qcom,pm8994-gpio"; + reg = <0xc000 0x1500>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <0 0xc0 0 IRQ_TYPE_NONE>, + <0 0xc1 0 IRQ_TYPE_NONE>, + <0 0xc2 0 IRQ_TYPE_NONE>, + <0 0xc3 0 IRQ_TYPE_NONE>, + <0 0xc4 0 IRQ_TYPE_NONE>, + <0 0xc5 0 IRQ_TYPE_NONE>, + <0 0xc6 0 IRQ_TYPE_NONE>, + <0 0xc7 0 IRQ_TYPE_NONE>, + <0 0xc8 0 IRQ_TYPE_NONE>, + <0 0xc9 0 IRQ_TYPE_NONE>, + <0 0xca 0 IRQ_TYPE_NONE>, + <0 0xcb 0 IRQ_TYPE_NONE>, + <0 0xcc 0 IRQ_TYPE_NONE>, + <0 0xcd 0 IRQ_TYPE_NONE>, + <0 0xce 0 IRQ_TYPE_NONE>, + <0 0xd0 0 IRQ_TYPE_NONE>, + <0 0xd1 0 IRQ_TYPE_NONE>, + <0 0xd2 0 IRQ_TYPE_NONE>, + <0 0xd3 0 IRQ_TYPE_NONE>, + <0 0xd4 0 IRQ_TYPE_NONE>, + <0 0xd5 0 IRQ_TYPE_NONE>; + }; + + pm8994_mpps: mpps@a000 { + compatible = "qcom,pm8994-mpp"; + reg = <0xa000 0x700>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <0 0xa0 0 IRQ_TYPE_NONE>, + <0 0xa1 0 IRQ_TYPE_NONE>, + <0 0xa2 0 IRQ_TYPE_NONE>, + <0 0xa3 0 IRQ_TYPE_NONE>, + <0 0xa4 0 IRQ_TYPE_NONE>, + <0 0xa5 0 IRQ_TYPE_NONE>, + <0 0xa6 0 IRQ_TYPE_NONE>, + <0 0xa7 0 IRQ_TYPE_NONE>; + }; + }; + + pmic@1 { + compatible = "qcom,pm8994", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi b/arch/arm64/boot/dts/qcom/pmi8994.dtsi new file mode 100644 index 000000000000..d3879a4e8076 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi @@ -0,0 +1,19 @@ +#include +#include + +&spmi_bus { + + pmic@2 { + compatible = "qcom,pmi8994", "qcom,spmi-pmic"; + reg = <0x2 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; + + pmic@3 { + compatible = "qcom,pmi8994", "qcom,spmi-pmic"; + reg = <0x3 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts index 265d12ff6022..31ace9c1f79d 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts @@ -93,6 +93,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif1_pins: scif1 { renesas,groups = "scif1_data_a", "scif1_ctrl"; renesas,function = "scif1"; @@ -101,6 +104,10 @@ renesas,groups = "scif2_data_a"; renesas,function = "scif2"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk_a"; + renesas,function = "scif_clk"; + }; i2c2_pins: i2c2 { renesas,groups = "i2c2_a"; @@ -138,6 +145,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &i2c2 { pinctrl-0 = <&i2c2_pins>; pinctrl-names = "default"; @@ -249,3 +261,7 @@ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; }; }; + +&xhci0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index bb353cde1253..b5e46e4ff72a 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -39,6 +39,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x0>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; @@ -46,22 +47,29 @@ compatible = "arm,cortex-a57","arm,armv8"; reg = <0x1>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; a57_2: cpu@2 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x2>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; a57_3: cpu@3 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x3>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; }; + L2_CA57: cache-controller@0 { + compatible = "cache"; + }; + extal_clk: extal { compatible = "fixed-clock"; #clock-cells = <0>; @@ -99,6 +107,14 @@ clock-frequency = <0>; }; + /* External SCIF clock - to be overridden by boards that provide it */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + status = "disabled"; + }; + soc { compatible = "simple-bus"; interrupt-parent = <&gic>; @@ -230,8 +246,8 @@ power-domains = <&cpg>; }; - pmu { - compatible = "arm,armv8-pmuv3"; + pmu_a57 { + compatible = "arm,cortex-a57-pmu"; interrupts = , , , @@ -333,15 +349,102 @@ }; dmac0: dma-controller@e6700000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe6700000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 219>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; dmac1: dma-controller@e7300000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe7300000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 218>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; dmac2: dma-controller@e7310000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe7310000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 217>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; avb: ethernet@e6800000 { @@ -387,11 +490,15 @@ }; hscif0: serial@e6540000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6540000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 520>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 520>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x31>, <&dmac1 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -399,11 +506,15 @@ }; hscif1: serial@e6550000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6550000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 519>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 519>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x33>, <&dmac1 0x32>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -411,11 +522,15 @@ }; hscif2: serial@e6560000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6560000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 518>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 518>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x35>, <&dmac1 0x34>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -423,11 +538,15 @@ }; hscif3: serial@e66a0000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe66a0000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 517>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 517>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x37>, <&dmac0 0x36>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -435,11 +554,15 @@ }; hscif4: serial@e66b0000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe66b0000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 516>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 516>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x38>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -447,11 +570,14 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 207>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 207>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x51>, <&dmac1 0x50>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -459,11 +585,14 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 206>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 206>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x53>, <&dmac1 0x52>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -471,11 +600,14 @@ }; scif2: serial@e6e88000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e88000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 310>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 310>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x13>, <&dmac1 0x12>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -483,11 +615,14 @@ }; scif3: serial@e6c50000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6c50000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 204>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 204>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x57>, <&dmac0 0x56>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -495,11 +630,14 @@ }; scif4: serial@e6c40000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6c40000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 203>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 203>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x59>, <&dmac0 0x58>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -507,11 +645,14 @@ }; scif5: serial@e6f30000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6f30000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 202>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 202>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x5b>, <&dmac1 0x5a>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -775,5 +916,49 @@ clocks = <&cpg CPG_MOD 815>; status = "disabled"; }; + + xhci0: usb@ee000000 { + compatible = "renesas,xhci-r8a7795"; + reg = <0 0xee000000 0 0xc00>; + interrupts = ; + clocks = <&cpg CPG_MOD 328>; + power-domains = <&cpg>; + status = "disabled"; + }; + + xhci1: usb@ee0400000 { + compatible = "renesas,xhci-r8a7795"; + reg = <0 0xee040000 0 0xc00>; + interrupts = ; + clocks = <&cpg CPG_MOD 327>; + power-domains = <&cpg>; + status = "disabled"; + }; + + usb_dmac0: dma-controller@e65a0000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65a0000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 330>; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + usb_dmac1: dma-controller@e65b0000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65b0000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 331>; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <2>; + }; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi index 8c219ccf67a3..6e27b22704df 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi @@ -111,7 +111,7 @@ pinctrl-0 = <&pwr_key>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts index 104cbee762bb..1f2b642e794a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts @@ -71,7 +71,7 @@ pinctrl-0 = <&pwr_key>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index 122777b1441e..49d119103e31 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -231,8 +231,9 @@ compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0c0000 0x0 0x4000>; clock-freq-min-max = <400000 150000000>; - clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; - clock-names = "biu", "ciu"; + 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 = ; status = "disabled"; @@ -254,8 +255,9 @@ compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0f0000 0x0 0x4000>; clock-freq-min-max = <400000 150000000>; - clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>; - clock-names = "biu", "ciu"; + 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 = ; status = "disabled"; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 18ca9fb9e65f..91ae2634cae9 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -16,7 +16,6 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y -CONFIG_MEMCG_KMEM=y CONFIG_CGROUP_HUGETLB=y # CONFIG_UTS_NS is not set # CONFIG_IPC_NS is not set @@ -37,15 +36,13 @@ CONFIG_ARCH_EXYNOS7=y CONFIG_ARCH_LAYERSCAPE=y CONFIG_ARCH_HISI=y CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_QCOM=y CONFIG_ARCH_ROCKCHIP=y CONFIG_ARCH_SEATTLE=y CONFIG_ARCH_RENESAS=y CONFIG_ARCH_R8A7795=y CONFIG_ARCH_STRATIX10=y CONFIG_ARCH_TEGRA=y -CONFIG_ARCH_TEGRA_132_SOC=y -CONFIG_ARCH_TEGRA_210_SOC=y -CONFIG_ARCH_QCOM=y CONFIG_ARCH_SPRD=y CONFIG_ARCH_THUNDER=y CONFIG_ARCH_UNIPHIER=y @@ -54,14 +51,19 @@ CONFIG_ARCH_XGENE=y CONFIG_ARCH_ZYNQMP=y CONFIG_PCI=y CONFIG_PCI_MSI=y +CONFIG_PCI_IOV=y +CONFIG_PCI_RCAR_GEN2_PCIE=y CONFIG_PCI_HOST_GENERIC=y CONFIG_PCI_XGENE=y -CONFIG_SMP=y +CONFIG_PCI_LAYERSCAPE=y +CONFIG_PCI_HISI=y +CONFIG_PCIE_QCOM=y CONFIG_SCHED_MC=y CONFIG_PREEMPT=y CONFIG_KSM=y CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_CMA=y +CONFIG_XEN=y CONFIG_CMDLINE="console=ttyAMA0" # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y @@ -100,7 +102,11 @@ CONFIG_PATA_OF_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_TUN=y CONFIG_VIRTIO_NET=y +CONFIG_AMD_XGBE=y CONFIG_NET_XGENE=y +CONFIG_E1000E=y +CONFIG_IGB=y +CONFIG_IGBVF=y CONFIG_SKY2=y CONFIG_RAVB=y CONFIG_SMC91X=y @@ -117,39 +123,41 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_8250_MT6577=y CONFIG_SERIAL_8250_UNIPHIER=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_SAMSUNG=y -CONFIG_SERIAL_SAMSUNG_UARTS_4=y -CONFIG_SERIAL_SAMSUNG_UARTS=4 CONFIG_SERIAL_SAMSUNG_CONSOLE=y +CONFIG_SERIAL_TEGRA=y CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=11 CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_TEGRA=y CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y CONFIG_VIRTIO_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_I2C=y CONFIG_I2C_QUP=y +CONFIG_I2C_UNIPHIER_F=y CONFIG_I2C_RCAR=y CONFIG_SPI=y CONFIG_SPI_PL022=y CONFIG_SPI_QUP=y +CONFIG_SPMI=y CONFIG_PINCTRL_MSM8916=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_GPIO_PL061=y CONFIG_GPIO_RCAR=y CONFIG_GPIO_XGENE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set +CONFIG_MFD_SPMI_PMIC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_QCOM_SMD_RPM=y +CONFIG_REGULATOR_QCOM_SPMI=y CONFIG_FB=y CONFIG_FB_ARMCLCD=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -162,13 +170,21 @@ CONFIG_SND_SOC=y CONFIG_SND_SOC_RCAR=y CONFIG_SND_SOC_AK4613=y CONFIG_USB=y +CONFIG_USB_OTG=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MSM=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_ISP1760=y +CONFIG_USB_HSIC_USB3503=y +CONFIG_USB_MSM_OTG=y CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y @@ -176,8 +192,6 @@ CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_TEGRA=y CONFIG_MMC_SPI=y CONFIG_MMC_DW=y -CONFIG_MMC_DW_IDMAC=y -CONFIG_MMC_DW_PLTFM=y CONFIG_MMC_DW_EXYNOS=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y @@ -187,28 +201,34 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_PL031=y CONFIG_RTC_DRV_XGENE=y CONFIG_DMADEVICES=y -CONFIG_RCAR_DMAC=y CONFIG_QCOM_BAM_DMA=y CONFIG_TEGRA20_APB_DMA=y +CONFIG_RCAR_DMAC=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_MMIO=y +CONFIG_XEN_GNTDEV=y +CONFIG_XEN_GRANT_DEV_ALLOC=y CONFIG_COMMON_CLK_CS2000_CP=y CONFIG_COMMON_CLK_QCOM=y CONFIG_MSM_GCC_8916=y CONFIG_HWSPINLOCK_QCOM=y -# CONFIG_IOMMU_SUPPORT is not set +CONFIG_ARM_SMMU=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SMD=y CONFIG_QCOM_SMD_RPM=y +CONFIG_ARCH_TEGRA_132_SOC=y +CONFIG_ARCH_TEGRA_210_SOC=y +CONFIG_HISILICON_IRQ_MBIGEN=y +CONFIG_EXTCON_USB_GPIO=y CONFIG_PHY_XGENE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y CONFIG_FANOTIFY=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y CONFIG_QUOTA=y @@ -239,6 +259,7 @@ CONFIG_LOCKUP_DETECTOR=y # CONFIG_FTRACE is not set CONFIG_MEMTEST=y CONFIG_SECURITY=y +CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM64_CE=y diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index 70fd9ffb58cf..cff532a6744e 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -1,5 +1,3 @@ - - generic-y += bug.h generic-y += bugs.h generic-y += checksum.h @@ -31,7 +29,6 @@ generic-y += msgbuf.h generic-y += msi.h generic-y += mutex.h generic-y += pci.h -generic-y += pci-bridge.h generic-y += poll.h generic-y += preempt.h generic-y += resource.h diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index caafd63b8092..aee323b13802 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -87,9 +87,26 @@ void __init acpi_init_cpus(void); static inline void acpi_init_cpus(void) { } #endif /* CONFIG_ACPI */ +#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL +bool acpi_parking_protocol_valid(int cpu); +void __init +acpi_set_mailbox_entry(int cpu, struct acpi_madt_generic_interrupt *processor); +#else +static inline bool acpi_parking_protocol_valid(int cpu) { return false; } +static inline void +acpi_set_mailbox_entry(int cpu, struct acpi_madt_generic_interrupt *processor) +{} +#endif + static inline const char *acpi_get_enable_method(int cpu) { - return acpi_psci_present() ? "psci" : NULL; + if (acpi_psci_present()) + return "psci"; + + if (acpi_parking_protocol_valid(cpu)) + return "parking-protocol"; + + return NULL; } #ifdef CONFIG_ACPI_APEI diff --git a/arch/arm64/include/asm/boot.h b/arch/arm64/include/asm/boot.h index 81151b67b26b..ebf2481889c3 100644 --- a/arch/arm64/include/asm/boot.h +++ b/arch/arm64/include/asm/boot.h @@ -11,4 +11,10 @@ #define MIN_FDT_ALIGN 8 #define MAX_FDT_SIZE SZ_2M +/* + * arm64 requires the kernel image to placed + * TEXT_OFFSET bytes beyond a 2 MB aligned base + */ +#define MIN_KIMG_ALIGN SZ_2M + #endif diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 8f271b83f910..8d56bd8550dc 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -30,8 +30,9 @@ #define ARM64_HAS_LSE_ATOMICS 5 #define ARM64_WORKAROUND_CAVIUM_23154 6 #define ARM64_WORKAROUND_834220 7 +#define ARM64_HAS_NO_HW_PREFETCH 8 -#define ARM64_NCAPS 8 +#define ARM64_NCAPS 9 #ifndef __ASSEMBLY__ diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 1a5949364ed0..7540284a17fe 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -57,11 +57,22 @@ #define MIDR_IMPLEMENTOR(midr) \ (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT) -#define MIDR_CPU_PART(imp, partnum) \ +#define MIDR_CPU_MODEL(imp, partnum) \ (((imp) << MIDR_IMPLEMENTOR_SHIFT) | \ (0xf << MIDR_ARCHITECTURE_SHIFT) | \ ((partnum) << MIDR_PARTNUM_SHIFT)) +#define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \ + MIDR_ARCHITECTURE_MASK) + +#define MIDR_IS_CPU_MODEL_RANGE(midr, model, rv_min, rv_max) \ +({ \ + u32 _model = (midr) & MIDR_CPU_MODEL_MASK; \ + u32 rv = (midr) & (MIDR_REVISION_MASK | MIDR_VARIANT_MASK); \ + \ + _model == (model) && rv >= (rv_min) && rv <= (rv_max); \ + }) + #define ARM_CPU_IMP_ARM 0x41 #define ARM_CPU_IMP_APM 0x50 #define ARM_CPU_IMP_CAVIUM 0x43 @@ -75,6 +86,10 @@ #define CAVIUM_CPU_PART_THUNDERX 0x0A1 +#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) +#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) +#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) + #ifndef __ASSEMBLY__ /* diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h index 309704544d22..1a617d46fce9 100644 --- a/arch/arm64/include/asm/fixmap.h +++ b/arch/arm64/include/asm/fixmap.h @@ -62,6 +62,16 @@ enum fixed_addresses { FIX_BTMAP_END = __end_of_permanent_fixed_addresses, FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1, + + /* + * Used for kernel page table creation, so unmapped memory may be used + * for tables. + */ + FIX_PTE, + FIX_PMD, + FIX_PUD, + FIX_PGD, + __end_of_fixed_addresses }; diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index 007a69fc4f40..5f3ab8c1db55 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h @@ -121,6 +121,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; asm volatile("// futex_atomic_cmpxchg_inatomic\n" +ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, CONFIG_ARM64_PAN) " prfm pstl1strm, %2\n" "1: ldxr %w1, %2\n" " sub %w3, %w1, %w4\n" @@ -137,6 +138,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, " .align 3\n" " .quad 1b, 4b, 2b, 4b\n" " .popsection\n" +ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN) : "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp) : "r" (oldval), "r" (newval), "Ir" (-EFAULT) : "memory"); diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h index a57601f9d17c..8740297dac77 100644 --- a/arch/arm64/include/asm/hardirq.h +++ b/arch/arm64/include/asm/hardirq.h @@ -20,7 +20,7 @@ #include #include -#define NR_IPI 5 +#define NR_IPI 6 typedef struct { unsigned int __softirq_pending; diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h index 2774fa384c47..71ad0f93eb71 100644 --- a/arch/arm64/include/asm/kasan.h +++ b/arch/arm64/include/asm/kasan.h @@ -7,13 +7,14 @@ #include #include +#include /* * KASAN_SHADOW_START: beginning of the kernel virtual addresses. * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/8 of kernel virtual addresses. */ #define KASAN_SHADOW_START (VA_START) -#define KASAN_SHADOW_END (KASAN_SHADOW_START + (1UL << (VA_BITS - 3))) +#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE) /* * This value is used to map an address to the corresponding shadow @@ -28,10 +29,12 @@ #define KASAN_SHADOW_OFFSET (KASAN_SHADOW_END - (1ULL << (64 - 3))) void kasan_init(void); +void kasan_copy_shadow(pgd_t *pgdir); asmlinkage void kasan_early_init(void); #else static inline void kasan_init(void) { } +static inline void kasan_copy_shadow(pgd_t *pgdir) { } #endif #endif diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h index a459714ee29e..5c6375d8528b 100644 --- a/arch/arm64/include/asm/kernel-pgtable.h +++ b/arch/arm64/include/asm/kernel-pgtable.h @@ -79,5 +79,17 @@ #define SWAPPER_MM_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS) #endif +/* + * To make optimal use of block mappings when laying out the linear + * mapping, round down the base of physical memory to a size that can + * be mapped efficiently, i.e., either PUD_SIZE (4k granule) or PMD_SIZE + * (64k granule), or a multiple that can be mapped using contiguous bits + * in the page tables: 32 * PMD_SIZE (16k granule) + */ +#ifdef CONFIG_ARM64_64K_PAGES +#define ARM64_MEMSTART_ALIGN SZ_512M +#else +#define ARM64_MEMSTART_ALIGN SZ_1G +#endif #endif /* __ASM_KERNEL_PGTABLE_H */ diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 738a95f93e49..bef6e9243c63 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -182,6 +182,7 @@ #define CPTR_EL2_TCPAC (1 << 31) #define CPTR_EL2_TTA (1 << 20) #define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT) +#define CPTR_EL2_DEFAULT 0x000033ff /* Hyp Debug Configuration Register bits */ #define MDCR_EL2_TDRA (1 << 11) diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 52b777b7d407..054ac25e7c2e 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -26,6 +26,8 @@ #define KVM_ARM64_DEBUG_DIRTY_SHIFT 0 #define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT) +#define kvm_ksym_ref(sym) phys_to_virt((u64)&sym - kimage_voffset) + #ifndef __ASSEMBLY__ struct kvm; struct kvm_vcpu; diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 3066328cd86b..779a5872a2c5 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -127,10 +127,14 @@ static inline unsigned long *vcpu_spsr(const struct kvm_vcpu *vcpu) static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu) { - u32 mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK; + u32 mode; - if (vcpu_mode_is_32bit(vcpu)) + if (vcpu_mode_is_32bit(vcpu)) { + mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK; return mode > COMPAT_PSR_MODE_USR; + } + + mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK; return mode != PSR_MODE_EL0t; } diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 689d4c95e12f..e3d67ff8798b 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -307,7 +307,7 @@ static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, struct kvm_vcpu *kvm_arm_get_running_vcpu(void); struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void); -u64 kvm_call_hyp(void *hypfn, ...); +u64 __kvm_call_hyp(void *hypfn, ...); void force_vm_exit(const cpumask_t *mask); void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot); @@ -328,8 +328,8 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr, * Call initialization code, and switch to the full blown * HYP code. */ - kvm_call_hyp((void *)boot_pgd_ptr, pgd_ptr, - hyp_stack_ptr, vector_ptr); + __kvm_call_hyp((void *)boot_pgd_ptr, pgd_ptr, + hyp_stack_ptr, vector_ptr); } static inline void kvm_arch_hardware_disable(void) {} @@ -343,4 +343,6 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu); void kvm_arm_clear_debug(struct kvm_vcpu *vcpu); void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu); +#define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__) + #endif /* __ARM64_KVM_HOST_H__ */ diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 853953cd1f08..61005e7dd6cb 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -45,15 +45,15 @@ * VA_START - the first kernel virtual address. * TASK_SIZE - the maximum size of a user space task. * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area. - * The module space lives between the addresses given by TASK_SIZE - * and PAGE_OFFSET - it must be within 128MB of the kernel text. */ #define VA_BITS (CONFIG_ARM64_VA_BITS) #define VA_START (UL(0xffffffffffffffff) << VA_BITS) #define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1)) -#define MODULES_END (PAGE_OFFSET) -#define MODULES_VADDR (MODULES_END - SZ_64M) -#define PCI_IO_END (MODULES_VADDR - SZ_2M) +#define KIMAGE_VADDR (MODULES_END) +#define MODULES_END (MODULES_VADDR + MODULES_VSIZE) +#define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE) +#define MODULES_VSIZE (SZ_64M) +#define PCI_IO_END (PAGE_OFFSET - SZ_2M) #define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE) #define FIXADDR_TOP (PCI_IO_START - SZ_2M) #define TASK_SIZE_64 (UL(1) << VA_BITS) @@ -70,13 +70,28 @@ #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 4)) +/* + * The size of the KASAN shadow region. This should be 1/8th of the + * size of the entire kernel virtual address space. + */ +#ifdef CONFIG_KASAN +#define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - 3)) +#else +#define KASAN_SHADOW_SIZE (0) +#endif + /* * Physical vs virtual RAM address space conversion. These are * private definitions which should NOT be used outside memory.h * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. */ -#define __virt_to_phys(x) (((phys_addr_t)(x) - PAGE_OFFSET + PHYS_OFFSET)) +#define __virt_to_phys(x) ({ \ + phys_addr_t __x = (phys_addr_t)(x); \ + __x >= PAGE_OFFSET ? (__x - PAGE_OFFSET + PHYS_OFFSET) : \ + (__x - kimage_voffset); }) + #define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET + PAGE_OFFSET)) +#define __phys_to_kimg(x) ((unsigned long)((x) + kimage_voffset)) /* * Convert a page to/from a physical address @@ -100,19 +115,26 @@ #define MT_S2_NORMAL 0xf #define MT_S2_DEVICE_nGnRE 0x1 +#ifdef CONFIG_ARM64_4K_PAGES +#define IOREMAP_MAX_ORDER (PUD_SHIFT) +#else +#define IOREMAP_MAX_ORDER (PMD_SHIFT) +#endif + #ifndef __ASSEMBLY__ extern phys_addr_t memstart_addr; /* PHYS_OFFSET - the physical address of the start of memory. */ #define PHYS_OFFSET ({ memstart_addr; }) +/* the offset between the kernel virtual and physical mappings */ +extern u64 kimage_voffset; + /* - * The maximum physical address that the linear direct mapping - * of system RAM can cover. (PAGE_OFFSET can be interpreted as - * a 2's complement signed quantity and negated to derive the - * maximum size of the linear mapping.) + * Allow all memory at the discovery stage. We will clip it later. */ -#define MAX_MEMBLOCK_ADDR ({ memstart_addr - PAGE_OFFSET - 1; }) +#define MIN_MEMBLOCK_ADDR 0 +#define MAX_MEMBLOCK_ADDR U64_MAX /* * PFNs are used to describe any physical page; this means diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h index 24165784b803..a00f7cf35bbd 100644 --- a/arch/arm64/include/asm/mmu_context.h +++ b/arch/arm64/include/asm/mmu_context.h @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef CONFIG_PID_IN_CONTEXTIDR static inline void contextidr_thread_switch(struct task_struct *next) @@ -48,7 +49,7 @@ static inline void contextidr_thread_switch(struct task_struct *next) */ static inline void cpu_set_reserved_ttbr0(void) { - unsigned long ttbr = page_to_phys(empty_zero_page); + unsigned long ttbr = virt_to_phys(empty_zero_page); asm( " msr ttbr0_el1, %0 // set TTBR0\n" @@ -73,7 +74,7 @@ static inline bool __cpu_uses_extended_idmap(void) /* * Set TCR.T0SZ to its default value (based on VA_BITS) */ -static inline void cpu_set_default_tcr_t0sz(void) +static inline void __cpu_set_tcr_t0sz(unsigned long t0sz) { unsigned long tcr; @@ -86,7 +87,62 @@ static inline void cpu_set_default_tcr_t0sz(void) " msr tcr_el1, %0 ;" " isb" : "=&r" (tcr) - : "r"(TCR_T0SZ(VA_BITS)), "I"(TCR_T0SZ_OFFSET), "I"(TCR_TxSZ_WIDTH)); + : "r"(t0sz), "I"(TCR_T0SZ_OFFSET), "I"(TCR_TxSZ_WIDTH)); +} + +#define cpu_set_default_tcr_t0sz() __cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS)) +#define cpu_set_idmap_tcr_t0sz() __cpu_set_tcr_t0sz(idmap_t0sz) + +/* + * Remove the idmap from TTBR0_EL1 and install the pgd of the active mm. + * + * The idmap lives in the same VA range as userspace, but uses global entries + * and may use a different TCR_EL1.T0SZ. To avoid issues resulting from + * speculative TLB fetches, we must temporarily install the reserved page + * tables while we invalidate the TLBs and set up the correct TCR_EL1.T0SZ. + * + * If current is a not a user task, the mm covers the TTBR1_EL1 page tables, + * which should not be installed in TTBR0_EL1. In this case we can leave the + * reserved page tables in place. + */ +static inline void cpu_uninstall_idmap(void) +{ + struct mm_struct *mm = current->active_mm; + + cpu_set_reserved_ttbr0(); + local_flush_tlb_all(); + cpu_set_default_tcr_t0sz(); + + if (mm != &init_mm) + cpu_switch_mm(mm->pgd, mm); +} + +static inline void cpu_install_idmap(void) +{ + cpu_set_reserved_ttbr0(); + local_flush_tlb_all(); + cpu_set_idmap_tcr_t0sz(); + + cpu_switch_mm(idmap_pg_dir, &init_mm); +} + +/* + * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD, + * avoiding the possibility of conflicting TLB entries being allocated. + */ +static inline void cpu_replace_ttbr1(pgd_t *pgd) +{ + typedef void (ttbr_replace_func)(phys_addr_t); + extern ttbr_replace_func idmap_cpu_replace_ttbr1; + ttbr_replace_func *replace_phys; + + phys_addr_t pgd_phys = virt_to_phys(pgd); + + replace_phys = (void *)virt_to_phys(idmap_cpu_replace_ttbr1); + + cpu_install_idmap(); + replace_phys(pgd_phys); + cpu_uninstall_idmap(); } /* diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 9b2f5a9d019d..ae615b9d9a55 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -39,6 +39,7 @@ #ifndef __ASSEMBLY__ +#include /* for READ_IMPLIES_EXEC */ #include extern void __cpu_clear_user_page(void *p, unsigned long user); diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h index b008a72f8bc0..f75b04e8d732 100644 --- a/arch/arm64/include/asm/pci.h +++ b/arch/arm64/include/asm/pci.h @@ -7,7 +7,6 @@ #include #include -#include #include #define PCIBIOS_MIN_IO 0x1000 diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h index c15053902942..ff98585d085a 100644 --- a/arch/arm64/include/asm/pgalloc.h +++ b/arch/arm64/include/asm/pgalloc.h @@ -42,11 +42,20 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) free_page((unsigned long)pmd); } -static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) +static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot) { - set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE)); + set_pud(pud, __pud(pmd | prot)); } +static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) +{ + __pud_populate(pud, __pa(pmd), PMD_TYPE_TABLE); +} +#else +static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot) +{ + BUILD_BUG(); +} #endif /* CONFIG_PGTABLE_LEVELS > 2 */ #if CONFIG_PGTABLE_LEVELS > 3 @@ -62,11 +71,20 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud) free_page((unsigned long)pud); } -static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) +static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot) { - set_pgd(pgd, __pgd(__pa(pud) | PUD_TYPE_TABLE)); + set_pgd(pgdp, __pgd(pud | prot)); } +static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) +{ + __pgd_populate(pgd, __pa(pud), PUD_TYPE_TABLE); +} +#else +static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot) +{ + BUILD_BUG(); +} #endif /* CONFIG_PGTABLE_LEVELS > 3 */ extern pgd_t *pgd_alloc(struct mm_struct *mm); diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 2d545d7aa80b..a440f5a85d08 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -36,19 +36,13 @@ * * VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array * (rounded up to PUD_SIZE). - * VMALLOC_START: beginning of the kernel VA space + * VMALLOC_START: beginning of the kernel vmalloc space * VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space, * fixed mappings and modules */ #define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE) -#ifndef CONFIG_KASAN -#define VMALLOC_START (VA_START) -#else -#include -#define VMALLOC_START (KASAN_SHADOW_END + SZ_64K) -#endif - +#define VMALLOC_START (MODULES_END) #define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K) #define vmemmap ((struct page *)(VMALLOC_END + SZ_64K)) @@ -57,6 +51,7 @@ #ifndef __ASSEMBLY__ +#include #include extern void __pte_error(const char *file, int line, unsigned long val); @@ -67,11 +62,11 @@ extern void __pgd_error(const char *file, int line, unsigned long val); #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) #define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) -#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRnE)) -#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) -#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_NC)) -#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_WT)) -#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL)) +#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE)) +#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE)) +#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC)) +#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT)) +#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL)) #define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL)) @@ -81,7 +76,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val); #define PAGE_KERNEL __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE) #define PAGE_KERNEL_RO __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY) -#define PAGE_KERNEL_ROX __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY) +#define PAGE_KERNEL_ROX __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY) #define PAGE_KERNEL_EXEC __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE) #define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT) @@ -121,8 +116,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val); * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. */ -extern struct page *empty_zero_page; -#define ZERO_PAGE(vaddr) (empty_zero_page) +extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) #define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) @@ -134,16 +129,6 @@ extern struct page *empty_zero_page; #define pte_clear(mm,addr,ptep) set_pte(ptep, __pte(0)) #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) -/* Find an entry in the third-level page table. */ -#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) - -#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + pte_index(addr)) - -#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) -#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr)) -#define pte_unmap(pte) do { } while (0) -#define pte_unmap_nested(pte) do { } while (0) - /* * The following only work if pte_present(). Undefined behaviour otherwise. */ @@ -153,6 +138,7 @@ extern struct page *empty_zero_page; #define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE)) #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) #define pte_cont(pte) (!!(pte_val(pte) & PTE_CONT)) +#define pte_user(pte) (!!(pte_val(pte) & PTE_USER)) #ifdef CONFIG_ARM64_HW_AFDBM #define pte_hw_dirty(pte) (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY)) @@ -163,8 +149,6 @@ extern struct page *empty_zero_page; #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte)) #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) -#define pte_valid_user(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) #define pte_valid_not_user(pte) \ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) #define pte_valid_young(pte) \ @@ -278,13 +262,13 @@ 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_valid_user(pte)) { - if (!pte_special(pte) && pte_exec(pte)) - __sync_icache_dcache(pte, addr); + if (pte_valid(pte)) { if (pte_sw_dirty(pte) && pte_write(pte)) pte_val(pte) &= ~PTE_RDONLY; else pte_val(pte) |= PTE_RDONLY; + if (pte_user(pte) && pte_exec(pte) && !pte_special(pte)) + __sync_icache_dcache(pte, addr); } /* @@ -433,13 +417,31 @@ static inline void pmd_clear(pmd_t *pmdp) set_pmd(pmdp, __pmd(0)); } -static inline pte_t *pmd_page_vaddr(pmd_t pmd) +static inline phys_addr_t pmd_page_paddr(pmd_t pmd) { - return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK); + return pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK; } +/* 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_kernel(dir,addr) ((pte_t *)__va(pte_offset_phys((dir), (addr)))) + +#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) +#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr)) +#define pte_unmap(pte) do { } while (0) +#define pte_unmap_nested(pte) do { } while (0) + +#define pte_set_fixmap(addr) ((pte_t *)set_fixmap_offset(FIX_PTE, addr)) +#define pte_set_fixmap_offset(pmd, addr) pte_set_fixmap(pte_offset_phys(pmd, addr)) +#define pte_clear_fixmap() clear_fixmap(FIX_PTE) + #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK)) +/* use ONLY for statically allocated translation tables */ +#define pte_offset_kimg(dir,addr) ((pte_t *)__phys_to_kimg(pte_offset_phys((dir), (addr)))) + /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. @@ -466,21 +468,37 @@ static inline void pud_clear(pud_t *pudp) set_pud(pudp, __pud(0)); } -static inline pmd_t *pud_page_vaddr(pud_t pud) +static inline phys_addr_t pud_page_paddr(pud_t pud) { - return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK); + return pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK; } /* Find an entry in the second-level page table. */ #define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) -static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) -{ - return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr); -} +#define pmd_offset_phys(dir, addr) (pud_page_paddr(*(dir)) + pmd_index(addr) * sizeof(pmd_t)) +#define pmd_offset(dir, addr) ((pmd_t *)__va(pmd_offset_phys((dir), (addr)))) + +#define pmd_set_fixmap(addr) ((pmd_t *)set_fixmap_offset(FIX_PMD, addr)) +#define pmd_set_fixmap_offset(pud, addr) pmd_set_fixmap(pmd_offset_phys(pud, addr)) +#define pmd_clear_fixmap() clear_fixmap(FIX_PMD) #define pud_page(pud) pfn_to_page(__phys_to_pfn(pud_val(pud) & PHYS_MASK)) +/* use ONLY for statically allocated translation tables */ +#define pmd_offset_kimg(dir,addr) ((pmd_t *)__phys_to_kimg(pmd_offset_phys((dir), (addr)))) + +#else + +#define pud_page_paddr(pud) ({ BUILD_BUG(); 0; }) + +/* Match pmd_offset folding in */ +#define pmd_set_fixmap(addr) NULL +#define pmd_set_fixmap_offset(pudp, addr) ((pmd_t *)pudp) +#define pmd_clear_fixmap() + +#define pmd_offset_kimg(dir,addr) ((pmd_t *)dir) + #endif /* CONFIG_PGTABLE_LEVELS > 2 */ #if CONFIG_PGTABLE_LEVELS > 3 @@ -502,21 +520,37 @@ static inline void pgd_clear(pgd_t *pgdp) set_pgd(pgdp, __pgd(0)); } -static inline pud_t *pgd_page_vaddr(pgd_t pgd) +static inline phys_addr_t pgd_page_paddr(pgd_t pgd) { - return __va(pgd_val(pgd) & PHYS_MASK & (s32)PAGE_MASK); + return pgd_val(pgd) & PHYS_MASK & (s32)PAGE_MASK; } /* Find an entry in the frst-level page table. */ #define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)) -static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr) -{ - return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(addr); -} +#define pud_offset_phys(dir, addr) (pgd_page_paddr(*(dir)) + pud_index(addr) * sizeof(pud_t)) +#define pud_offset(dir, addr) ((pud_t *)__va(pud_offset_phys((dir), (addr)))) + +#define pud_set_fixmap(addr) ((pud_t *)set_fixmap_offset(FIX_PUD, addr)) +#define pud_set_fixmap_offset(pgd, addr) pud_set_fixmap(pud_offset_phys(pgd, addr)) +#define pud_clear_fixmap() clear_fixmap(FIX_PUD) #define pgd_page(pgd) pfn_to_page(__phys_to_pfn(pgd_val(pgd) & PHYS_MASK)) +/* use ONLY for statically allocated translation tables */ +#define pud_offset_kimg(dir,addr) ((pud_t *)__phys_to_kimg(pud_offset_phys((dir), (addr)))) + +#else + +#define pgd_page_paddr(pgd) ({ BUILD_BUG(); 0;}) + +/* Match pud_offset folding in */ +#define pud_set_fixmap(addr) NULL +#define pud_set_fixmap_offset(pgdp, addr) ((pud_t *)pgdp) +#define pud_clear_fixmap() + +#define pud_offset_kimg(dir,addr) ((pud_t *)dir) + #endif /* CONFIG_PGTABLE_LEVELS > 3 */ #define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) @@ -524,11 +558,16 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr) /* to find an entry in a page-table-directory */ #define pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) -#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr)) +#define pgd_offset_raw(pgd, addr) ((pgd) + pgd_index(addr)) + +#define pgd_offset(mm, addr) (pgd_offset_raw((mm)->pgd, (addr))) /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(addr) pgd_offset(&init_mm, addr) +#define pgd_set_fixmap(addr) ((pgd_t *)set_fixmap_offset(FIX_PGD, addr)) +#define pgd_clear_fixmap() clear_fixmap(FIX_PGD) + static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 4acb7ca94fcd..5bb1d763d17a 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -29,8 +29,10 @@ #include +#include #include #include +#include #include #include #include @@ -177,9 +179,11 @@ static inline void prefetchw(const void *ptr) } #define ARCH_HAS_SPINLOCK_PREFETCH -static inline void spin_lock_prefetch(const void *x) +static inline void spin_lock_prefetch(const void *ptr) { - prefetchw(x); + asm volatile(ARM64_LSE_ATOMIC_INSN( + "prfm pstl1strm, %a0", + "nop") : : "p" (ptr)); } #define HAVE_ARCH_PICK_MMAP_LAYOUT diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index d9c3d6a6100a..2013a4dc5124 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -64,6 +64,15 @@ extern void secondary_entry(void); extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); +#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL +extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask); +#else +static inline void arch_send_wakeup_ipi_mask(const struct cpumask *mask) +{ + BUILD_BUG(); +} +#endif + extern int __cpu_disable(void); extern void __cpu_die(unsigned int cpu); diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 83cd7e68e83b..8a9c65ccb636 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -41,6 +41,7 @@ arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o arm64-obj-$(CONFIG_PCI) += pci.o arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o arm64-obj-$(CONFIG_ACPI) += acpi.o +arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o obj-y += $(arm64-obj-y) vdso/ diff --git a/arch/arm64/kernel/acpi_parking_protocol.c b/arch/arm64/kernel/acpi_parking_protocol.c new file mode 100644 index 000000000000..4b1e5a7a98da --- /dev/null +++ b/arch/arm64/kernel/acpi_parking_protocol.c @@ -0,0 +1,153 @@ +/* + * ARM64 ACPI Parking Protocol implementation + * + * Authors: Lorenzo Pieralisi + * Mark Salter + * + * 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 + +struct cpu_mailbox_entry { + phys_addr_t mailbox_addr; + u8 version; + u8 gic_cpu_id; +}; + +static struct cpu_mailbox_entry cpu_mailbox_entries[NR_CPUS]; + +void __init acpi_set_mailbox_entry(int cpu, + struct acpi_madt_generic_interrupt *p) +{ + struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu]; + + cpu_entry->mailbox_addr = p->parked_address; + cpu_entry->version = p->parking_version; + cpu_entry->gic_cpu_id = p->cpu_interface_number; +} + +bool acpi_parking_protocol_valid(int cpu) +{ + struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu]; + + return cpu_entry->mailbox_addr && cpu_entry->version; +} + +static int acpi_parking_protocol_cpu_init(unsigned int cpu) +{ + pr_debug("%s: ACPI parked addr=%llx\n", __func__, + cpu_mailbox_entries[cpu].mailbox_addr); + + return 0; +} + +static int acpi_parking_protocol_cpu_prepare(unsigned int cpu) +{ + return 0; +} + +struct parking_protocol_mailbox { + __le32 cpu_id; + __le32 reserved; + __le64 entry_point; +}; + +static int acpi_parking_protocol_cpu_boot(unsigned int cpu) +{ + struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu]; + struct parking_protocol_mailbox __iomem *mailbox; + __le32 cpu_id; + + /* + * Map mailbox memory with attribute device nGnRE (ie ioremap - + * this deviates from the parking protocol specifications since + * the mailboxes are required to be mapped nGnRnE; the attribute + * discrepancy is harmless insofar as the protocol specification + * is concerned). + * If the mailbox is mistakenly allocated in the linear mapping + * by FW ioremap will fail since the mapping will be prevented + * by the kernel (it clashes with the linear mapping attributes + * specifications). + */ + mailbox = ioremap(cpu_entry->mailbox_addr, sizeof(*mailbox)); + if (!mailbox) + return -EIO; + + cpu_id = readl_relaxed(&mailbox->cpu_id); + /* + * Check if firmware has set-up the mailbox entry properly + * before kickstarting the respective cpu. + */ + if (cpu_id != ~0U) { + iounmap(mailbox); + return -ENXIO; + } + + /* + * We write the entry point and cpu id as LE regardless of the + * native endianness of the kernel. Therefore, any boot-loaders + * that read this address need to convert this address to the + * Boot-Loader's endianness before jumping. + */ + writeq_relaxed(__pa(secondary_entry), &mailbox->entry_point); + writel_relaxed(cpu_entry->gic_cpu_id, &mailbox->cpu_id); + + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + + iounmap(mailbox); + + return 0; +} + +static void acpi_parking_protocol_cpu_postboot(void) +{ + int cpu = smp_processor_id(); + struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu]; + struct parking_protocol_mailbox __iomem *mailbox; + __le64 entry_point; + + /* + * Map mailbox memory with attribute device nGnRE (ie ioremap - + * this deviates from the parking protocol specifications since + * the mailboxes are required to be mapped nGnRnE; the attribute + * discrepancy is harmless insofar as the protocol specification + * is concerned). + * If the mailbox is mistakenly allocated in the linear mapping + * by FW ioremap will fail since the mapping will be prevented + * by the kernel (it clashes with the linear mapping attributes + * specifications). + */ + mailbox = ioremap(cpu_entry->mailbox_addr, sizeof(*mailbox)); + if (!mailbox) + return; + + entry_point = readl_relaxed(&mailbox->entry_point); + /* + * Check if firmware has cleared the entry_point as expected + * by the protocol specification. + */ + WARN_ON(entry_point); + + iounmap(mailbox); +} + +const struct cpu_operations acpi_parking_protocol_ops = { + .name = "parking-protocol", + .cpu_init = acpi_parking_protocol_cpu_init, + .cpu_prepare = acpi_parking_protocol_cpu_prepare, + .cpu_boot = acpi_parking_protocol_cpu_boot, + .cpu_postboot = acpi_parking_protocol_cpu_postboot +}; diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index feb6b4efa641..e6bc988e8dbf 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -21,24 +21,12 @@ #include #include -#define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) -#define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) -#define MIDR_THUNDERX MIDR_CPU_PART(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) - -#define CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \ - MIDR_ARCHITECTURE_MASK) - static bool __maybe_unused is_affected_midr_range(const struct arm64_cpu_capabilities *entry) { - u32 midr = read_cpuid_id(); - - if ((midr & CPU_MODEL_MASK) != entry->midr_model) - return false; - - midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK; - - return (midr >= entry->midr_range_min && midr <= entry->midr_range_max); + return MIDR_IS_CPU_MODEL_RANGE(read_cpuid_id(), entry->midr_model, + entry->midr_range_min, + entry->midr_range_max); } #define MIDR_RANGE(model, min, max) \ diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c index b6bd7d447768..c7cfb8fe06f9 100644 --- a/arch/arm64/kernel/cpu_ops.c +++ b/arch/arm64/kernel/cpu_ops.c @@ -25,19 +25,30 @@ #include extern const struct cpu_operations smp_spin_table_ops; +extern const struct cpu_operations acpi_parking_protocol_ops; extern const struct cpu_operations cpu_psci_ops; const struct cpu_operations *cpu_ops[NR_CPUS]; -static const struct cpu_operations *supported_cpu_ops[] __initconst = { +static const struct cpu_operations *dt_supported_cpu_ops[] __initconst = { &smp_spin_table_ops, &cpu_psci_ops, NULL, }; +static const struct cpu_operations *acpi_supported_cpu_ops[] __initconst = { +#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL + &acpi_parking_protocol_ops, +#endif + &cpu_psci_ops, + NULL, +}; + static const struct cpu_operations * __init cpu_get_ops(const char *name) { - const struct cpu_operations **ops = supported_cpu_ops; + const struct cpu_operations **ops; + + ops = acpi_disabled ? dt_supported_cpu_ops : acpi_supported_cpu_ops; while (*ops) { if (!strcmp(name, (*ops)->name)) @@ -75,8 +86,16 @@ static const char *__init cpu_read_enable_method(int cpu) } } else { enable_method = acpi_get_enable_method(cpu); - if (!enable_method) - pr_err("Unsupported ACPI enable-method\n"); + if (!enable_method) { + /* + * In ACPI systems the boot CPU does not require + * checking the enable method since for some + * boot protocol (ie parking protocol) it need not + * be initialized. Don't warn spuriously. + */ + if (cpu != 0) + pr_err("Unsupported ACPI enable-method\n"); + } } return enable_method; diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 5c90aa490a2b..3615d7d7c9af 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -621,6 +621,18 @@ static bool has_useable_gicv3_cpuif(const struct arm64_cpu_capabilities *entry) return has_sre; } +static bool has_no_hw_prefetch(const struct arm64_cpu_capabilities *entry) +{ + u32 midr = read_cpuid_id(); + u32 rv_min, rv_max; + + /* Cavium ThunderX pass 1.x and 2.x */ + rv_min = 0; + rv_max = (1 << MIDR_VARIANT_SHIFT) | MIDR_REVISION_MASK; + + return MIDR_IS_CPU_MODEL_RANGE(midr, MIDR_THUNDERX, rv_min, rv_max); +} + static const struct arm64_cpu_capabilities arm64_features[] = { { .desc = "GIC system register CPU interface", @@ -651,6 +663,11 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .min_field_value = 2, }, #endif /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */ + { + .desc = "Software prefetching using PRFM", + .capability = ARM64_HAS_NO_HW_PREFETCH, + .matches = has_no_hw_prefetch, + }, {}, }; diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 8aee3aeec3e6..c1492ba1f6d1 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -186,20 +186,21 @@ static void clear_regs_spsr_ss(struct pt_regs *regs) /* EL1 Single Step Handler hooks */ static LIST_HEAD(step_hook); -static DEFINE_RWLOCK(step_hook_lock); +static DEFINE_SPINLOCK(step_hook_lock); void register_step_hook(struct step_hook *hook) { - write_lock(&step_hook_lock); - list_add(&hook->node, &step_hook); - write_unlock(&step_hook_lock); + spin_lock(&step_hook_lock); + list_add_rcu(&hook->node, &step_hook); + spin_unlock(&step_hook_lock); } void unregister_step_hook(struct step_hook *hook) { - write_lock(&step_hook_lock); - list_del(&hook->node); - write_unlock(&step_hook_lock); + spin_lock(&step_hook_lock); + list_del_rcu(&hook->node); + spin_unlock(&step_hook_lock); + synchronize_rcu(); } /* @@ -213,15 +214,15 @@ static int call_step_hook(struct pt_regs *regs, unsigned int esr) struct step_hook *hook; int retval = DBG_HOOK_ERROR; - read_lock(&step_hook_lock); + rcu_read_lock(); - list_for_each_entry(hook, &step_hook, node) { + list_for_each_entry_rcu(hook, &step_hook, node) { retval = hook->fn(regs, esr); if (retval == DBG_HOOK_HANDLED) break; } - read_unlock(&step_hook_lock); + rcu_read_unlock(); return retval; } diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index ffe9c2b6431b..05b98289093e 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -389,7 +389,7 @@ __create_page_tables: * Map the kernel image (starting with PHYS_OFFSET). */ mov x0, x26 // swapper_pg_dir - mov x5, #PAGE_OFFSET + ldr x5, =KIMAGE_VADDR create_pgd_entry x0, x5, x3, x6 ldr x6, =KERNEL_END // __va(KERNEL_END) mov x3, x24 // phys offset @@ -421,13 +421,18 @@ __mmap_switched: adr_l x2, __bss_stop sub x2, x2, x0 bl __pi_memset + dsb ishst // Make zero page visible to PTW adr_l sp, initial_sp, x4 mov x4, sp and x4, x4, #~(THREAD_SIZE - 1) msr sp_el0, x4 // Save thread_info str_l x21, __fdt_pointer, x5 // Save FDT pointer - str_l x24, memstart_addr, x6 // Save PHYS_OFFSET + + ldr x4, =KIMAGE_VADDR // Save the offset between + sub x4, x4, x24 // the kernel virtual and + str_l x4, kimage_voffset, x5 // physical mappings + mov x29, #0 #ifdef CONFIG_KASAN bl kasan_early_init @@ -514,9 +519,14 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems #endif /* EL2 debug */ + mrs x0, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer + sbfx x0, x0, #8, #4 + cmp x0, #1 + b.lt 4f // Skip if no PMU present mrs x0, pmcr_el0 // Disable debug access traps ubfx x0, x0, #11, #5 // to EL2 and allow access to msr mdcr_el2, x0 // all PMU counters from EL1 +4: /* Stage-2 translation */ msr vttbr_el2, xzr diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h index bc2abb8b1599..c9c62cab25a4 100644 --- a/arch/arm64/kernel/image.h +++ b/arch/arm64/kernel/image.h @@ -42,15 +42,18 @@ #endif #ifdef CONFIG_CPU_BIG_ENDIAN -#define __HEAD_FLAG_BE 1 +#define __HEAD_FLAG_BE 1 #else -#define __HEAD_FLAG_BE 0 +#define __HEAD_FLAG_BE 0 #endif -#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2) +#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2) -#define __HEAD_FLAGS ((__HEAD_FLAG_BE << 0) | \ - (__HEAD_FLAG_PAGE_SIZE << 1)) +#define __HEAD_FLAG_PHYS_BASE 1 + +#define __HEAD_FLAGS ((__HEAD_FLAG_BE << 0) | \ + (__HEAD_FLAG_PAGE_SIZE << 1) | \ + (__HEAD_FLAG_PHYS_BASE << 3)) /* * These will output as part of the Image header, which should be little-endian @@ -64,6 +67,16 @@ #ifdef CONFIG_EFI +/* + * Prevent the symbol aliases below from being emitted into the kallsyms + * table, by forcing them to be absolute symbols (which are conveniently + * ignored by scripts/kallsyms) rather than section relative symbols. + * The distinction is only relevant for partial linking, and only for symbols + * that are defined within a section declaration (which is not the case for + * the definitions below) so the resulting values will be identical. + */ +#define KALLSYMS_HIDE(sym) ABSOLUTE(sym) + /* * The EFI stub has its own symbol namespace prefixed by __efistub_, to * isolate it from the kernel proper. The following symbols are legally @@ -73,25 +86,25 @@ * linked at. The routines below are all implemented in assembler in a * position independent manner */ -__efistub_memcmp = __pi_memcmp; -__efistub_memchr = __pi_memchr; -__efistub_memcpy = __pi_memcpy; -__efistub_memmove = __pi_memmove; -__efistub_memset = __pi_memset; -__efistub_strlen = __pi_strlen; -__efistub_strcmp = __pi_strcmp; -__efistub_strncmp = __pi_strncmp; -__efistub___flush_dcache_area = __pi___flush_dcache_area; +__efistub_memcmp = KALLSYMS_HIDE(__pi_memcmp); +__efistub_memchr = KALLSYMS_HIDE(__pi_memchr); +__efistub_memcpy = KALLSYMS_HIDE(__pi_memcpy); +__efistub_memmove = KALLSYMS_HIDE(__pi_memmove); +__efistub_memset = KALLSYMS_HIDE(__pi_memset); +__efistub_strlen = KALLSYMS_HIDE(__pi_strlen); +__efistub_strcmp = KALLSYMS_HIDE(__pi_strcmp); +__efistub_strncmp = KALLSYMS_HIDE(__pi_strncmp); +__efistub___flush_dcache_area = KALLSYMS_HIDE(__pi___flush_dcache_area); #ifdef CONFIG_KASAN -__efistub___memcpy = __pi_memcpy; -__efistub___memmove = __pi_memmove; -__efistub___memset = __pi_memset; +__efistub___memcpy = KALLSYMS_HIDE(__pi_memcpy); +__efistub___memmove = KALLSYMS_HIDE(__pi_memmove); +__efistub___memset = KALLSYMS_HIDE(__pi_memset); #endif -__efistub__text = _text; -__efistub__end = _end; -__efistub__edata = _edata; +__efistub__text = KALLSYMS_HIDE(_text); +__efistub__end = KALLSYMS_HIDE(_end); +__efistub__edata = KALLSYMS_HIDE(_edata); #endif diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index b3d098bd34aa..c72de668e1d4 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -19,8 +19,6 @@ #include #include -#include - /* * Called after each bus is probed, but before its children are examined */ diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index f67f35b6edb1..42816bebb1e0 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c @@ -20,7 +20,6 @@ #include #include #include -#include #include @@ -28,73 +27,6 @@ #include #include #include -#include - -static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state); - -static int __maybe_unused cpu_psci_cpu_init_idle(unsigned int cpu) -{ - int i, ret, count = 0; - u32 *psci_states; - struct device_node *state_node, *cpu_node; - - cpu_node = of_get_cpu_node(cpu, NULL); - if (!cpu_node) - return -ENODEV; - - /* - * If the PSCI cpu_suspend function hook has not been initialized - * idle states must not be enabled, so bail out - */ - if (!psci_ops.cpu_suspend) - return -EOPNOTSUPP; - - /* Count idle states */ - while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states", - count))) { - count++; - of_node_put(state_node); - } - - if (!count) - return -ENODEV; - - psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL); - if (!psci_states) - return -ENOMEM; - - for (i = 0; i < count; i++) { - u32 state; - - state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i); - - ret = of_property_read_u32(state_node, - "arm,psci-suspend-param", - &state); - if (ret) { - pr_warn(" * %s missing arm,psci-suspend-param property\n", - state_node->full_name); - of_node_put(state_node); - goto free_mem; - } - - of_node_put(state_node); - pr_debug("psci-power-state %#x index %d\n", state, i); - if (!psci_power_state_is_valid(state)) { - pr_warn("Invalid PSCI power state %#x\n", state); - ret = -EINVAL; - goto free_mem; - } - psci_states[i] = state; - } - /* Idle states parsed correctly, initialize per-cpu pointer */ - per_cpu(psci_power_state, cpu) = psci_states; - return 0; - -free_mem: - kfree(psci_states); - return ret; -} static int __init cpu_psci_cpu_init(unsigned int cpu) { @@ -178,38 +110,11 @@ static int cpu_psci_cpu_kill(unsigned int cpu) } #endif -static int psci_suspend_finisher(unsigned long index) -{ - u32 *state = __this_cpu_read(psci_power_state); - - return psci_ops.cpu_suspend(state[index - 1], - virt_to_phys(cpu_resume)); -} - -static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index) -{ - int ret; - u32 *state = __this_cpu_read(psci_power_state); - /* - * idle state index 0 corresponds to wfi, should never be called - * from the cpu_suspend operations - */ - if (WARN_ON_ONCE(!index)) - return -EINVAL; - - if (!psci_power_state_loses_context(state[index - 1])) - ret = psci_ops.cpu_suspend(state[index - 1], 0); - else - ret = cpu_suspend(index, psci_suspend_finisher); - - return ret; -} - const struct cpu_operations cpu_psci_ops = { .name = "psci", #ifdef CONFIG_CPU_IDLE - .cpu_init_idle = cpu_psci_cpu_init_idle, - .cpu_suspend = cpu_psci_cpu_suspend, + .cpu_init_idle = psci_cpu_init_idle, + .cpu_suspend = psci_cpu_suspend_enter, #endif .cpu_init = cpu_psci_cpu_init, .cpu_prepare = cpu_psci_cpu_prepare, diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 8119479147db..28c0f90c9c10 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -62,6 +62,7 @@ #include #include #include +#include phys_addr_t __fdt_pointer __initdata; @@ -73,13 +74,13 @@ static struct resource mem_res[] = { .name = "Kernel code", .start = 0, .end = 0, - .flags = IORESOURCE_MEM + .flags = IORESOURCE_SYSTEM_RAM }, { .name = "Kernel data", .start = 0, .end = 0, - .flags = IORESOURCE_MEM + .flags = IORESOURCE_SYSTEM_RAM } }; @@ -210,7 +211,7 @@ static void __init request_standard_resources(void) res->name = "System RAM"; res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); @@ -313,6 +314,12 @@ void __init setup_arch(char **cmdline_p) */ local_async_enable(); + /* + * TTBR0 is only used for the identity mapping at this stage. Make it + * point to zero page to avoid speculatively fetching new entries. + */ + cpu_uninstall_idmap(); + efi_init(); arm64_memblock_init(); diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index b1adc51b2c2e..24cb4f800033 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -70,6 +70,7 @@ enum ipi_msg_type { IPI_CPU_STOP, IPI_TIMER, IPI_IRQ_WORK, + IPI_WAKEUP }; /* @@ -149,9 +150,7 @@ asmlinkage void secondary_start_kernel(void) * TTBR0 is only used for the identity mapping at this stage. Make it * point to zero page to avoid speculatively fetching new entries. */ - cpu_set_reserved_ttbr0(); - local_flush_tlb_all(); - cpu_set_default_tcr_t0sz(); + cpu_uninstall_idmap(); preempt_disable(); trace_hardirqs_off(); @@ -445,6 +444,17 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor) /* map the logical cpu id to cpu MPIDR */ cpu_logical_map(cpu_count) = hwid; + /* + * Set-up the ACPI parking protocol cpu entries + * while initializing the cpu_logical_map to + * avoid parsing MADT entries multiple times for + * nothing (ie a valid cpu_logical_map entry should + * contain a valid parking protocol data set to + * initialize the cpu if the parking protocol is + * the only available enable method). + */ + acpi_set_mailbox_entry(cpu_count, processor); + cpu_count++; } @@ -627,6 +637,7 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = { S(IPI_CPU_STOP, "CPU stop interrupts"), S(IPI_TIMER, "Timer broadcast interrupts"), S(IPI_IRQ_WORK, "IRQ work interrupts"), + S(IPI_WAKEUP, "CPU wake-up interrupts"), }; static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) @@ -670,6 +681,13 @@ void arch_send_call_function_single_ipi(int cpu) smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC); } +#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL +void arch_send_wakeup_ipi_mask(const struct cpumask *mask) +{ + smp_cross_call(mask, IPI_WAKEUP); +} +#endif + #ifdef CONFIG_IRQ_WORK void arch_irq_work_raise(void) { @@ -747,6 +765,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs) break; #endif +#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL + case IPI_WAKEUP: + WARN_ONCE(!acpi_parking_protocol_valid(cpu), + "CPU%u: Wake-up IPI outside the ACPI parking protocol\n", + cpu); + break; +#endif + default: pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index 1095aa483a1c..66055392f445 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c @@ -60,7 +60,6 @@ void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *)) */ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) { - struct mm_struct *mm = current->active_mm; int ret; unsigned long flags; @@ -87,22 +86,11 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) ret = __cpu_suspend_enter(arg, fn); if (ret == 0) { /* - * We are resuming from reset with TTBR0_EL1 set to the - * idmap to enable the MMU; set the TTBR0 to the reserved - * page tables to prevent speculative TLB allocations, flush - * the local tlb and set the default tcr_el1.t0sz so that - * the TTBR0 address space set-up is properly restored. - * If the current active_mm != &init_mm we entered cpu_suspend - * with mappings in TTBR0 that must be restored, so we switch - * them back to complete the address space configuration - * restoration before returning. + * We are resuming from reset with the idmap active in TTBR0_EL1. + * We must uninstall the idmap and restore the expected MMU + * state before we can possibly return to userspace. */ - cpu_set_reserved_ttbr0(); - local_flush_tlb_all(); - cpu_set_default_tcr_t0sz(); - - if (mm != &init_mm) - cpu_switch_mm(mm->pgd, mm); + cpu_uninstall_idmap(); /* * Restore per-cpu offset before any kernel diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index e3928f578891..282e3e64a17e 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -89,13 +89,13 @@ SECTIONS *(.discard.*) } - . = PAGE_OFFSET + TEXT_OFFSET; + . = KIMAGE_VADDR + TEXT_OFFSET; .head.text : { _text = .; HEAD_TEXT } - ALIGN_DEBUG_RO + ALIGN_DEBUG_RO_MIN(PAGE_SIZE) .text : { /* Real text segment */ _stext = .; /* Text and read-only data */ __exception_text_start = .; @@ -116,10 +116,9 @@ SECTIONS RO_DATA(PAGE_SIZE) EXCEPTION_TABLE(8) NOTES - ALIGN_DEBUG_RO - _etext = .; /* End of text and rodata section */ ALIGN_DEBUG_RO_MIN(PAGE_SIZE) + _etext = .; /* End of text and rodata section */ __init_begin = .; INIT_TEXT_SECTION(8) @@ -187,4 +186,4 @@ ASSERT(__idmap_text_end - (__idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K, /* * If padding is applied before .head.text, virt<->phys conversions will fail. */ -ASSERT(_text == (PAGE_OFFSET + TEXT_OFFSET), "HEAD is misaligned") +ASSERT(_text == (KIMAGE_VADDR + TEXT_OFFSET), "HEAD is misaligned") diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S index 0ccdcbbef3c2..870578f84b1c 100644 --- a/arch/arm64/kvm/hyp.S +++ b/arch/arm64/kvm/hyp.S @@ -20,7 +20,7 @@ #include /* - * u64 kvm_call_hyp(void *hypfn, ...); + * u64 __kvm_call_hyp(void *hypfn, ...); * * This is not really a variadic function in the classic C-way and care must * be taken when calling this to ensure parameters are passed in registers @@ -37,7 +37,7 @@ * used to implement __hyp_get_vectors in the same way as in * arch/arm64/kernel/hyp_stub.S. */ -ENTRY(kvm_call_hyp) +ENTRY(__kvm_call_hyp) hvc #0 ret -ENDPROC(kvm_call_hyp) +ENDPROC(__kvm_call_hyp) diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index ca8f5a5e2f96..f0e7bdfae134 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c @@ -36,7 +36,11 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu) write_sysreg(val, hcr_el2); /* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */ write_sysreg(1 << 15, hstr_el2); - write_sysreg(CPTR_EL2_TTA | CPTR_EL2_TFP, cptr_el2); + + val = CPTR_EL2_DEFAULT; + val |= CPTR_EL2_TTA | CPTR_EL2_TFP; + write_sysreg(val, cptr_el2); + write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); } @@ -45,7 +49,7 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu) write_sysreg(HCR_RW, hcr_el2); write_sysreg(0, hstr_el2); write_sysreg(read_sysreg(mdcr_el2) & MDCR_EL2_HPMN_MASK, mdcr_el2); - write_sysreg(0, cptr_el2); + write_sysreg(CPTR_EL2_DEFAULT, cptr_el2); } static void __hyp_text __activate_vm(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c index 648112e90ed5..4d1ac81870d2 100644 --- a/arch/arm64/kvm/inject_fault.c +++ b/arch/arm64/kvm/inject_fault.c @@ -27,7 +27,11 @@ #define PSTATE_FAULT_BITS_64 (PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | \ PSR_I_BIT | PSR_D_BIT) -#define EL1_EXCEPT_SYNC_OFFSET 0x200 + +#define CURRENT_EL_SP_EL0_VECTOR 0x0 +#define CURRENT_EL_SP_ELx_VECTOR 0x200 +#define LOWER_EL_AArch64_VECTOR 0x400 +#define LOWER_EL_AArch32_VECTOR 0x600 static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset) { @@ -97,6 +101,34 @@ static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt, *fsr = 0x14; } +enum exception_type { + except_type_sync = 0, + except_type_irq = 0x80, + except_type_fiq = 0x100, + except_type_serror = 0x180, +}; + +static u64 get_except_vector(struct kvm_vcpu *vcpu, enum exception_type type) +{ + u64 exc_offset; + + switch (*vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT)) { + case PSR_MODE_EL1t: + exc_offset = CURRENT_EL_SP_EL0_VECTOR; + break; + case PSR_MODE_EL1h: + exc_offset = CURRENT_EL_SP_ELx_VECTOR; + break; + case PSR_MODE_EL0t: + exc_offset = LOWER_EL_AArch64_VECTOR; + break; + default: + exc_offset = LOWER_EL_AArch32_VECTOR; + } + + return vcpu_sys_reg(vcpu, VBAR_EL1) + exc_offset + type; +} + static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr) { unsigned long cpsr = *vcpu_cpsr(vcpu); @@ -108,8 +140,8 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr *vcpu_spsr(vcpu) = cpsr; *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu); + *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync); *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; - *vcpu_pc(vcpu) = vcpu_sys_reg(vcpu, VBAR_EL1) + EL1_EXCEPT_SYNC_OFFSET; vcpu_sys_reg(vcpu, FAR_EL1) = addr; @@ -143,8 +175,8 @@ static void inject_undef64(struct kvm_vcpu *vcpu) *vcpu_spsr(vcpu) = cpsr; *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu); + *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync); *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; - *vcpu_pc(vcpu) = vcpu_sys_reg(vcpu, VBAR_EL1) + EL1_EXCEPT_SYNC_OFFSET; /* * Build an unknown exception, depending on the instruction diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index eec3598b4184..2e90371cfb37 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1007,10 +1007,9 @@ static int emulate_cp(struct kvm_vcpu *vcpu, if (likely(r->access(vcpu, params, r))) { /* Skip instruction, since it was emulated */ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + /* Handled */ + return 0; } - - /* Handled */ - return 0; } /* Not handled */ @@ -1043,7 +1042,7 @@ static void unhandled_cp_access(struct kvm_vcpu *vcpu, } /** - * kvm_handle_cp_64 -- handles a mrrc/mcrr trap on a guest CP15 access + * kvm_handle_cp_64 -- handles a mrrc/mcrr trap on a guest CP14/CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ @@ -1095,7 +1094,7 @@ out: } /** - * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access + * kvm_handle_cp_32 -- handles a mrc/mcr trap on a guest CP14/CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S index 512b9a7b980e..4c1e700840b6 100644 --- a/arch/arm64/lib/copy_page.S +++ b/arch/arm64/lib/copy_page.S @@ -18,6 +18,8 @@ #include #include #include +#include +#include /* * Copy a page from src to dest (both are page aligned) @@ -27,20 +29,65 @@ * x1 - src */ ENTRY(copy_page) - /* Assume cache line size is 64 bytes. */ - prfm pldl1strm, [x1, #64] -1: ldp x2, x3, [x1] +alternative_if_not ARM64_HAS_NO_HW_PREFETCH + nop + nop +alternative_else + # Prefetch two cache lines ahead. + prfm pldl1strm, [x1, #128] + prfm pldl1strm, [x1, #256] +alternative_endif + + ldp x2, x3, [x1] ldp x4, x5, [x1, #16] ldp x6, x7, [x1, #32] ldp x8, x9, [x1, #48] - add x1, x1, #64 - prfm pldl1strm, [x1, #64] + ldp x10, x11, [x1, #64] + ldp x12, x13, [x1, #80] + ldp x14, x15, [x1, #96] + ldp x16, x17, [x1, #112] + + mov x18, #(PAGE_SIZE - 128) + add x1, x1, #128 +1: + subs x18, x18, #128 + +alternative_if_not ARM64_HAS_NO_HW_PREFETCH + nop +alternative_else + prfm pldl1strm, [x1, #384] +alternative_endif + stnp x2, x3, [x0] + ldp x2, x3, [x1] stnp x4, x5, [x0, #16] + ldp x4, x5, [x1, #16] stnp x6, x7, [x0, #32] + ldp x6, x7, [x1, #32] stnp x8, x9, [x0, #48] - add x0, x0, #64 - tst x1, #(PAGE_SIZE - 1) - b.ne 1b + ldp x8, x9, [x1, #48] + stnp x10, x11, [x0, #64] + ldp x10, x11, [x1, #64] + stnp x12, x13, [x0, #80] + ldp x12, x13, [x1, #80] + stnp x14, x15, [x0, #96] + ldp x14, x15, [x1, #96] + stnp x16, x17, [x0, #112] + ldp x16, x17, [x1, #112] + + add x0, x0, #128 + add x1, x1, #128 + + b.gt 1b + + stnp x2, x3, [x0] + stnp x4, x5, [x0, #16] + stnp x6, x7, [x0, #32] + stnp x8, x9, [x0, #48] + stnp x10, x11, [x0, #64] + stnp x12, x13, [x0, #80] + stnp x14, x15, [x0, #96] + stnp x16, x17, [x0, #112] + ret ENDPROC(copy_page) diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c index 5a22a119a74c..6be918478f85 100644 --- a/arch/arm64/mm/dump.c +++ b/arch/arm64/mm/dump.c @@ -35,7 +35,9 @@ struct addr_marker { }; enum address_markers_idx { - VMALLOC_START_NR = 0, + MODULES_START_NR = 0, + MODULES_END_NR, + VMALLOC_START_NR, VMALLOC_END_NR, #ifdef CONFIG_SPARSEMEM_VMEMMAP VMEMMAP_START_NR, @@ -45,12 +47,12 @@ enum address_markers_idx { FIXADDR_END_NR, PCI_START_NR, PCI_END_NR, - MODULES_START_NR, - MODUELS_END_NR, KERNEL_SPACE_NR, }; static struct addr_marker address_markers[] = { + { MODULES_VADDR, "Modules start" }, + { MODULES_END, "Modules end" }, { VMALLOC_START, "vmalloc() Area" }, { VMALLOC_END, "vmalloc() End" }, #ifdef CONFIG_SPARSEMEM_VMEMMAP @@ -61,9 +63,7 @@ static struct addr_marker address_markers[] = { { FIXADDR_TOP, "Fixmap end" }, { PCI_IO_START, "PCI I/O start" }, { PCI_IO_END, "PCI I/O end" }, - { MODULES_VADDR, "Modules start" }, - { MODULES_END, "Modules end" }, - { PAGE_OFFSET, "Kernel Mapping" }, + { PAGE_OFFSET, "Linear Mapping" }, { -1, NULL }, }; @@ -90,6 +90,11 @@ struct prot_bits { static const struct prot_bits pte_bits[] = { { + .mask = PTE_VALID, + .val = PTE_VALID, + .set = " ", + .clear = "F", + }, { .mask = PTE_USER, .val = PTE_USER, .set = "USR", diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index f3b061e67bfe..a1df35c85395 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -35,7 +35,10 @@ #include #include +#include #include +#include +#include #include #include #include @@ -159,7 +162,33 @@ early_param("mem", early_mem); void __init arm64_memblock_init(void) { - memblock_enforce_memory_limit(memory_limit); + const s64 linear_region_size = -(s64)PAGE_OFFSET; + + /* + * Select a suitable value for the base of physical memory. + */ + memstart_addr = round_down(memblock_start_of_DRAM(), + ARM64_MEMSTART_ALIGN); + + /* + * Remove the memory that we will not be able to cover with the + * linear mapping. Take care not to clip the kernel which may be + * high in memory. + */ + memblock_remove(max(memstart_addr + linear_region_size, __pa(_end)), + ULLONG_MAX); + if (memblock_end_of_DRAM() > linear_region_size) + memblock_remove(0, memblock_end_of_DRAM() - linear_region_size); + + /* + * Apply the memory limit if it was set. Since the kernel may be loaded + * high up in memory, add back the kernel region that must be accessible + * via the linear mapping. + */ + if (memory_limit != (phys_addr_t)ULLONG_MAX) { + memblock_enforce_memory_limit(memory_limit); + memblock_add(__pa(_text), (u64)(_end - _text)); + } /* * Register the kernel text, kernel data, initrd, and initial @@ -302,22 +331,26 @@ void __init mem_init(void) #ifdef CONFIG_KASAN " kasan : 0x%16lx - 0x%16lx (%6ld GB)\n" #endif + " modules : 0x%16lx - 0x%16lx (%6ld MB)\n" " vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n" + " .init : 0x%p" " - 0x%p" " (%6ld KB)\n" + " .text : 0x%p" " - 0x%p" " (%6ld KB)\n" + " .data : 0x%p" " - 0x%p" " (%6ld KB)\n" #ifdef CONFIG_SPARSEMEM_VMEMMAP " vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n" " 0x%16lx - 0x%16lx (%6ld MB actual)\n" #endif " fixed : 0x%16lx - 0x%16lx (%6ld KB)\n" " PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n" - " modules : 0x%16lx - 0x%16lx (%6ld MB)\n" - " memory : 0x%16lx - 0x%16lx (%6ld MB)\n" - " .init : 0x%p" " - 0x%p" " (%6ld KB)\n" - " .text : 0x%p" " - 0x%p" " (%6ld KB)\n" - " .data : 0x%p" " - 0x%p" " (%6ld KB)\n", + " memory : 0x%16lx - 0x%16lx (%6ld MB)\n", #ifdef CONFIG_KASAN MLG(KASAN_SHADOW_START, KASAN_SHADOW_END), #endif + MLM(MODULES_VADDR, MODULES_END), MLG(VMALLOC_START, VMALLOC_END), + MLK_ROUNDUP(__init_begin, __init_end), + MLK_ROUNDUP(_text, _etext), + MLK_ROUNDUP(_sdata, _edata), #ifdef CONFIG_SPARSEMEM_VMEMMAP MLG((unsigned long)vmemmap, (unsigned long)vmemmap + VMEMMAP_SIZE), @@ -326,11 +359,7 @@ void __init mem_init(void) #endif MLK(FIXADDR_START, FIXADDR_TOP), MLM(PCI_IO_START, PCI_IO_END), - MLM(MODULES_VADDR, MODULES_END), - MLM(PAGE_OFFSET, (unsigned long)high_memory), - MLK_ROUNDUP(__init_begin, __init_end), - MLK_ROUNDUP(_text, _etext), - MLK_ROUNDUP(_sdata, _edata)); + MLM(PAGE_OFFSET, (unsigned long)high_memory)); #undef MLK #undef MLM @@ -358,8 +387,8 @@ void __init mem_init(void) void free_initmem(void) { - fixup_init(); free_initmem_default(0); + fixup_init(); } #ifdef CONFIG_BLK_DEV_INITRD @@ -380,3 +409,28 @@ static int __init keepinitrd_setup(char *__unused) __setup("keepinitrd", keepinitrd_setup); #endif + +/* + * Dump out memory limit information on panic. + */ +static int dump_mem_limit(struct notifier_block *self, unsigned long v, void *p) +{ + if (memory_limit != (phys_addr_t)ULLONG_MAX) { + pr_emerg("Memory Limit: %llu MB\n", memory_limit >> 20); + } else { + pr_emerg("Memory Limit: none\n"); + } + return 0; +} + +static struct notifier_block mem_limit_notifier = { + .notifier_call = dump_mem_limit, +}; + +static int __init register_mem_limit_dumper(void) +{ + atomic_notifier_chain_register(&panic_notifier_list, + &mem_limit_notifier); + return 0; +} +__initcall(register_mem_limit_dumper); diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index cf038c7d9fa9..66c246871d2e 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c @@ -16,9 +16,12 @@ #include #include +#include +#include #include #include #include +#include #include static pgd_t tmp_pg_dir[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE); @@ -32,7 +35,7 @@ static void __init kasan_early_pte_populate(pmd_t *pmd, unsigned long addr, if (pmd_none(*pmd)) pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte); - pte = pte_offset_kernel(pmd, addr); + pte = pte_offset_kimg(pmd, addr); do { next = addr + PAGE_SIZE; set_pte(pte, pfn_pte(virt_to_pfn(kasan_zero_page), @@ -50,7 +53,7 @@ static void __init kasan_early_pmd_populate(pud_t *pud, if (pud_none(*pud)) pud_populate(&init_mm, pud, kasan_zero_pmd); - pmd = pmd_offset(pud, addr); + pmd = pmd_offset_kimg(pud, addr); do { next = pmd_addr_end(addr, end); kasan_early_pte_populate(pmd, addr, next); @@ -67,7 +70,7 @@ static void __init kasan_early_pud_populate(pgd_t *pgd, if (pgd_none(*pgd)) pgd_populate(&init_mm, pgd, kasan_zero_pud); - pud = pud_offset(pgd, addr); + pud = pud_offset_kimg(pgd, addr); do { next = pud_addr_end(addr, end); kasan_early_pmd_populate(pud, addr, next); @@ -96,6 +99,21 @@ asmlinkage void __init kasan_early_init(void) kasan_map_early_shadow(); } +/* + * Copy the current shadow region into a new pgdir. + */ +void __init kasan_copy_shadow(pgd_t *pgdir) +{ + pgd_t *pgd, *pgd_new, *pgd_end; + + pgd = pgd_offset_k(KASAN_SHADOW_START); + pgd_end = pgd_offset_k(KASAN_SHADOW_END); + pgd_new = pgd_offset_raw(pgdir, KASAN_SHADOW_START); + do { + set_pgd(pgd_new, *pgd); + } while (pgd++, pgd_new++, pgd != pgd_end); +} + static void __init clear_pgds(unsigned long start, unsigned long end) { @@ -108,18 +126,14 @@ static void __init clear_pgds(unsigned long start, set_pgd(pgd_offset_k(start), __pgd(0)); } -static void __init cpu_set_ttbr1(unsigned long ttbr1) -{ - asm( - " msr ttbr1_el1, %0\n" - " isb" - : - : "r" (ttbr1)); -} - void __init kasan_init(void) { + u64 kimg_shadow_start, kimg_shadow_end; struct memblock_region *reg; + int i; + + kimg_shadow_start = (u64)kasan_mem_to_shadow(_text); + kimg_shadow_end = (u64)kasan_mem_to_shadow(_end); /* * We are going to perform proper setup of shadow memory. @@ -129,13 +143,30 @@ void __init kasan_init(void) * setup will be finished. */ memcpy(tmp_pg_dir, swapper_pg_dir, sizeof(tmp_pg_dir)); - cpu_set_ttbr1(__pa(tmp_pg_dir)); - flush_tlb_all(); + dsb(ishst); + cpu_replace_ttbr1(tmp_pg_dir); clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END); + vmemmap_populate(kimg_shadow_start, kimg_shadow_end, NUMA_NO_NODE); + + /* + * vmemmap_populate() has populated the shadow region that covers the + * kernel image with SWAPPER_BLOCK_SIZE mappings, so we have to round + * the start and end addresses to SWAPPER_BLOCK_SIZE as well, to prevent + * kasan_populate_zero_shadow() from replacing the PMD block mappings + * with PMD table mappings at the edges of the shadow region for the + * kernel image. + */ + if (ARM64_SWAPPER_USES_SECTION_MAPS) { + kimg_shadow_start = round_down(kimg_shadow_start, + SWAPPER_BLOCK_SIZE); + kimg_shadow_end = round_up(kimg_shadow_end, SWAPPER_BLOCK_SIZE); + } kasan_populate_zero_shadow((void *)KASAN_SHADOW_START, - kasan_mem_to_shadow((void *)MODULES_VADDR)); + (void *)kimg_shadow_start); + kasan_populate_zero_shadow((void *)kimg_shadow_end, + kasan_mem_to_shadow((void *)PAGE_OFFSET)); for_each_memblock(memory, reg) { void *start = (void *)__phys_to_virt(reg->base); @@ -155,9 +186,16 @@ void __init kasan_init(void) pfn_to_nid(virt_to_pfn(start))); } + /* + * KAsan may reuse the contents of kasan_zero_pte directly, so we + * should make sure that it maps the zero page read-only. + */ + for (i = 0; i < PTRS_PER_PTE; i++) + set_pte(&kasan_zero_pte[i], + pfn_pte(virt_to_pfn(kasan_zero_page), PAGE_KERNEL_RO)); + memset(kasan_zero_page, 0, PAGE_SIZE); - cpu_set_ttbr1(__pa(swapper_pg_dir)); - flush_tlb_all(); + cpu_replace_ttbr1(swapper_pg_dir); /* At this point kasan is fully initialized. Enable error messages */ init_task.kasan_depth = 0; diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 58faeaa7fbdc..c3e5df62671e 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -30,8 +30,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -44,13 +46,20 @@ u64 idmap_t0sz = TCR_T0SZ(VA_BITS); +u64 kimage_voffset __read_mostly; +EXPORT_SYMBOL(kimage_voffset); + /* * Empty_zero_page is a special page that is used for zero-initialized data * and COW. */ -struct page *empty_zero_page; +unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] __page_aligned_bss; EXPORT_SYMBOL(empty_zero_page); +static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss; +static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused; +static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss __maybe_unused; + pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot) { @@ -62,16 +71,30 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, } EXPORT_SYMBOL(phys_mem_access_prot); -static void __init *early_alloc(unsigned long sz) +static phys_addr_t __init early_pgtable_alloc(void) { phys_addr_t phys; void *ptr; - phys = memblock_alloc(sz, sz); + phys = memblock_alloc(PAGE_SIZE, PAGE_SIZE); BUG_ON(!phys); - ptr = __va(phys); - memset(ptr, 0, sz); - return ptr; + + /* + * The FIX_{PGD,PUD,PMD} slots may be in active use, but the FIX_PTE + * slot will be free, so we can (ab)use the FIX_PTE slot to initialise + * any level of table. + */ + ptr = pte_set_fixmap(phys); + + memset(ptr, 0, PAGE_SIZE); + + /* + * Implicit barriers also ensure the zeroed page is visible to the page + * table walker + */ + pte_clear_fixmap(); + + return phys; } /* @@ -95,24 +118,30 @@ static void split_pmd(pmd_t *pmd, pte_t *pte) static void alloc_init_pte(pmd_t *pmd, unsigned long addr, unsigned long end, unsigned long pfn, pgprot_t prot, - void *(*alloc)(unsigned long size)) + phys_addr_t (*pgtable_alloc)(void)) { pte_t *pte; if (pmd_none(*pmd) || pmd_sect(*pmd)) { - pte = alloc(PTRS_PER_PTE * sizeof(pte_t)); + phys_addr_t pte_phys; + BUG_ON(!pgtable_alloc); + pte_phys = pgtable_alloc(); + pte = pte_set_fixmap(pte_phys); if (pmd_sect(*pmd)) split_pmd(pmd, pte); - __pmd_populate(pmd, __pa(pte), PMD_TYPE_TABLE); + __pmd_populate(pmd, pte_phys, PMD_TYPE_TABLE); flush_tlb_all(); + pte_clear_fixmap(); } BUG_ON(pmd_bad(*pmd)); - pte = pte_offset_kernel(pmd, addr); + pte = pte_set_fixmap_offset(pmd, addr); do { set_pte(pte, pfn_pte(pfn, prot)); pfn++; } while (pte++, addr += PAGE_SIZE, addr != end); + + pte_clear_fixmap(); } static void split_pud(pud_t *old_pud, pmd_t *pmd) @@ -127,10 +156,29 @@ static void split_pud(pud_t *old_pud, pmd_t *pmd) } while (pmd++, i++, i < PTRS_PER_PMD); } -static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud, - unsigned long addr, unsigned long end, +#ifdef CONFIG_DEBUG_PAGEALLOC +static bool block_mappings_allowed(phys_addr_t (*pgtable_alloc)(void)) +{ + + /* + * If debug_page_alloc is enabled we must map the linear map + * using pages. However, other mappings created by + * create_mapping_noalloc must use sections in some cases. Allow + * sections to be used in those cases, where no pgtable_alloc + * function is provided. + */ + return !pgtable_alloc || !debug_pagealloc_enabled(); +} +#else +static bool block_mappings_allowed(phys_addr_t (*pgtable_alloc)(void)) +{ + return true; +} +#endif + +static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end, phys_addr_t phys, pgprot_t prot, - void *(*alloc)(unsigned long size)) + phys_addr_t (*pgtable_alloc)(void)) { pmd_t *pmd; unsigned long next; @@ -139,7 +187,10 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud, * Check for initial section mappings in the pgd/pud and remove them. */ if (pud_none(*pud) || pud_sect(*pud)) { - pmd = alloc(PTRS_PER_PMD * sizeof(pmd_t)); + phys_addr_t pmd_phys; + BUG_ON(!pgtable_alloc); + pmd_phys = pgtable_alloc(); + pmd = pmd_set_fixmap(pmd_phys); if (pud_sect(*pud)) { /* * need to have the 1G of mappings continue to be @@ -147,16 +198,18 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud, */ split_pud(pud, pmd); } - pud_populate(mm, pud, pmd); + __pud_populate(pud, pmd_phys, PUD_TYPE_TABLE); flush_tlb_all(); + pmd_clear_fixmap(); } BUG_ON(pud_bad(*pud)); - pmd = pmd_offset(pud, addr); + pmd = pmd_set_fixmap_offset(pud, addr); do { next = pmd_addr_end(addr, end); /* try section mapping first */ - if (((addr | next | phys) & ~SECTION_MASK) == 0) { + if (((addr | next | phys) & ~SECTION_MASK) == 0 && + block_mappings_allowed(pgtable_alloc)) { pmd_t old_pmd =*pmd; set_pmd(pmd, __pmd(phys | pgprot_val(mk_sect_prot(prot)))); @@ -167,17 +220,19 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud, if (!pmd_none(old_pmd)) { flush_tlb_all(); if (pmd_table(old_pmd)) { - phys_addr_t table = __pa(pte_offset_map(&old_pmd, 0)); + phys_addr_t table = pmd_page_paddr(old_pmd); if (!WARN_ON_ONCE(slab_is_available())) memblock_free(table, PAGE_SIZE); } } } else { alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), - prot, alloc); + prot, pgtable_alloc); } phys += next - addr; } while (pmd++, addr = next, addr != end); + + pmd_clear_fixmap(); } static inline bool use_1G_block(unsigned long addr, unsigned long next, @@ -192,28 +247,30 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next, return true; } -static void alloc_init_pud(struct mm_struct *mm, pgd_t *pgd, - unsigned long addr, unsigned long end, +static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, phys_addr_t phys, pgprot_t prot, - void *(*alloc)(unsigned long size)) + phys_addr_t (*pgtable_alloc)(void)) { pud_t *pud; unsigned long next; if (pgd_none(*pgd)) { - pud = alloc(PTRS_PER_PUD * sizeof(pud_t)); - pgd_populate(mm, pgd, pud); + phys_addr_t pud_phys; + BUG_ON(!pgtable_alloc); + pud_phys = pgtable_alloc(); + __pgd_populate(pgd, pud_phys, PUD_TYPE_TABLE); } BUG_ON(pgd_bad(*pgd)); - pud = pud_offset(pgd, addr); + pud = pud_set_fixmap_offset(pgd, addr); do { next = pud_addr_end(addr, end); /* * For 4K granule only, attempt to put down a 1GB block */ - if (use_1G_block(addr, next, phys)) { + if (use_1G_block(addr, next, phys) && + block_mappings_allowed(pgtable_alloc)) { pud_t old_pud = *pud; set_pud(pud, __pud(phys | pgprot_val(mk_sect_prot(prot)))); @@ -228,26 +285,28 @@ static void alloc_init_pud(struct mm_struct *mm, pgd_t *pgd, if (!pud_none(old_pud)) { flush_tlb_all(); if (pud_table(old_pud)) { - phys_addr_t table = __pa(pmd_offset(&old_pud, 0)); + phys_addr_t table = pud_page_paddr(old_pud); if (!WARN_ON_ONCE(slab_is_available())) memblock_free(table, PAGE_SIZE); } } } else { - alloc_init_pmd(mm, pud, addr, next, phys, prot, alloc); + alloc_init_pmd(pud, addr, next, phys, prot, + pgtable_alloc); } phys += next - addr; } while (pud++, addr = next, addr != end); + + pud_clear_fixmap(); } /* * Create the page directory entries and any necessary page tables for the * mapping specified by 'md'. */ -static void __create_mapping(struct mm_struct *mm, pgd_t *pgd, - phys_addr_t phys, unsigned long virt, +static void init_pgd(pgd_t *pgd, phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot, - void *(*alloc)(unsigned long size)) + phys_addr_t (*pgtable_alloc)(void)) { unsigned long addr, length, end, next; @@ -265,22 +324,35 @@ static void __create_mapping(struct mm_struct *mm, pgd_t *pgd, end = addr + length; do { next = pgd_addr_end(addr, end); - alloc_init_pud(mm, pgd, addr, next, phys, prot, alloc); + alloc_init_pud(pgd, addr, next, phys, prot, pgtable_alloc); phys += next - addr; } while (pgd++, addr = next, addr != end); } -static void *late_alloc(unsigned long size) +static phys_addr_t late_pgtable_alloc(void) { - void *ptr; - - BUG_ON(size > PAGE_SIZE); - ptr = (void *)__get_free_page(PGALLOC_GFP); + void *ptr = (void *)__get_free_page(PGALLOC_GFP); BUG_ON(!ptr); - return ptr; + + /* Ensure the zeroed page is visible to the page table walker */ + dsb(ishst); + return __pa(ptr); +} + +static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, + unsigned long virt, phys_addr_t size, + pgprot_t prot, + phys_addr_t (*alloc)(void)) +{ + init_pgd(pgd_offset_raw(pgdir, virt), phys, virt, size, prot, alloc); } -static void __init create_mapping(phys_addr_t phys, unsigned long virt, +/* + * This function can only be used to modify existing table entries, + * without allocating new levels of table. Note that this permits the + * creation of new section or page entries. + */ +static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot) { if (virt < VMALLOC_START) { @@ -288,16 +360,16 @@ static void __init create_mapping(phys_addr_t phys, unsigned long virt, &phys, virt); return; } - __create_mapping(&init_mm, pgd_offset_k(virt), phys, virt, - size, prot, early_alloc); + __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, + NULL); } void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot) { - __create_mapping(mm, pgd_offset(mm, virt), phys, virt, size, prot, - late_alloc); + __create_pgd_mapping(mm->pgd, phys, virt, size, prot, + late_pgtable_alloc); } static void create_mapping_late(phys_addr_t phys, unsigned long virt, @@ -309,69 +381,48 @@ static void create_mapping_late(phys_addr_t phys, unsigned long virt, return; } - return __create_mapping(&init_mm, pgd_offset_k(virt), - phys, virt, size, prot, late_alloc); + __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, + late_pgtable_alloc); } -#ifdef CONFIG_DEBUG_RODATA -static void __init __map_memblock(phys_addr_t start, phys_addr_t end) +static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end) { + + unsigned long kernel_start = __pa(_stext); + unsigned long kernel_end = __pa(_etext); + /* - * Set up the executable regions using the existing section mappings - * for now. This will get more fine grained later once all memory - * is mapped + * Take care not to create a writable alias for the + * read-only text and rodata sections of the kernel image. */ - unsigned long kernel_x_start = round_down(__pa(_stext), SWAPPER_BLOCK_SIZE); - unsigned long kernel_x_end = round_up(__pa(__init_end), SWAPPER_BLOCK_SIZE); - - if (end < kernel_x_start) { - create_mapping(start, __phys_to_virt(start), - end - start, PAGE_KERNEL); - } else if (start >= kernel_x_end) { - create_mapping(start, __phys_to_virt(start), - end - start, PAGE_KERNEL); - } else { - if (start < kernel_x_start) - create_mapping(start, __phys_to_virt(start), - kernel_x_start - start, - PAGE_KERNEL); - create_mapping(kernel_x_start, - __phys_to_virt(kernel_x_start), - kernel_x_end - kernel_x_start, - PAGE_KERNEL_EXEC); - if (kernel_x_end < end) - create_mapping(kernel_x_end, - __phys_to_virt(kernel_x_end), - end - kernel_x_end, - PAGE_KERNEL); + + /* No overlap with the kernel text */ + if (end < kernel_start || start >= kernel_end) { + __create_pgd_mapping(pgd, start, __phys_to_virt(start), + end - start, PAGE_KERNEL, + early_pgtable_alloc); + return; } + /* + * This block overlaps the kernel text mapping. Map the portion(s) which + * don't overlap. + */ + if (start < kernel_start) + __create_pgd_mapping(pgd, start, + __phys_to_virt(start), + kernel_start - start, PAGE_KERNEL, + early_pgtable_alloc); + if (kernel_end < end) + __create_pgd_mapping(pgd, kernel_end, + __phys_to_virt(kernel_end), + end - kernel_end, PAGE_KERNEL, + early_pgtable_alloc); } -#else -static void __init __map_memblock(phys_addr_t start, phys_addr_t end) -{ - create_mapping(start, __phys_to_virt(start), end - start, - PAGE_KERNEL_EXEC); -} -#endif -static void __init map_mem(void) +static void __init map_mem(pgd_t *pgd) { struct memblock_region *reg; - phys_addr_t limit; - - /* - * Temporarily limit the memblock range. We need to do this as - * create_mapping requires puds, pmds and ptes to be allocated from - * memory addressable from the initial direct kernel mapping. - * - * The initial direct kernel mapping, located at swapper_pg_dir, gives - * us PUD_SIZE (with SECTION maps) or PMD_SIZE (without SECTION maps, - * memory starting from PHYS_OFFSET (which must be aligned to 2MB as - * per Documentation/arm64/booting.txt). - */ - limit = PHYS_OFFSET + SWAPPER_INIT_MAP_SIZE; - memblock_set_current_limit(limit); /* map all the memory banks */ for_each_memblock(memory, reg) { @@ -383,69 +434,87 @@ static void __init map_mem(void) if (memblock_is_nomap(reg)) continue; - if (ARM64_SWAPPER_USES_SECTION_MAPS) { - /* - * For the first memory bank align the start address and - * current memblock limit to prevent create_mapping() from - * allocating pte page tables from unmapped memory. With - * the section maps, if the first block doesn't end on section - * size boundary, create_mapping() will try to allocate a pte - * page, which may be returned from an unmapped area. - * When section maps are not used, the pte page table for the - * current limit is already present in swapper_pg_dir. - */ - if (start < limit) - start = ALIGN(start, SECTION_SIZE); - if (end < limit) { - limit = end & SECTION_MASK; - memblock_set_current_limit(limit); - } - } - __map_memblock(start, end); + __map_memblock(pgd, start, end); } - - /* Limit no longer required. */ - memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE); } -static void __init fixup_executable(void) +void mark_rodata_ro(void) { -#ifdef CONFIG_DEBUG_RODATA - /* now that we are actually fully mapped, make the start/end more fine grained */ - if (!IS_ALIGNED((unsigned long)_stext, SWAPPER_BLOCK_SIZE)) { - unsigned long aligned_start = round_down(__pa(_stext), - SWAPPER_BLOCK_SIZE); + if (!IS_ENABLED(CONFIG_DEBUG_RODATA)) + return; - create_mapping(aligned_start, __phys_to_virt(aligned_start), - __pa(_stext) - aligned_start, - PAGE_KERNEL); - } + create_mapping_late(__pa(_stext), (unsigned long)_stext, + (unsigned long)_etext - (unsigned long)_stext, + PAGE_KERNEL_ROX); +} - if (!IS_ALIGNED((unsigned long)__init_end, SWAPPER_BLOCK_SIZE)) { - unsigned long aligned_end = round_up(__pa(__init_end), - SWAPPER_BLOCK_SIZE); - create_mapping(__pa(__init_end), (unsigned long)__init_end, - aligned_end - __pa(__init_end), - PAGE_KERNEL); - } -#endif +void fixup_init(void) +{ + /* + * Unmap the __init region but leave the VM area in place. This + * prevents the region from being reused for kernel modules, which + * is not supported by kallsyms. + */ + unmap_kernel_range((u64)__init_begin, (u64)(__init_end - __init_begin)); } -#ifdef CONFIG_DEBUG_RODATA -void mark_rodata_ro(void) +static void __init map_kernel_chunk(pgd_t *pgd, void *va_start, void *va_end, + pgprot_t prot, struct vm_struct *vma) { - create_mapping_late(__pa(_stext), (unsigned long)_stext, - (unsigned long)_etext - (unsigned long)_stext, - PAGE_KERNEL_ROX); + phys_addr_t pa_start = __pa(va_start); + unsigned long size = va_end - va_start; + + BUG_ON(!PAGE_ALIGNED(pa_start)); + BUG_ON(!PAGE_ALIGNED(size)); + __create_pgd_mapping(pgd, pa_start, (unsigned long)va_start, size, prot, + early_pgtable_alloc); + + vma->addr = va_start; + vma->phys_addr = pa_start; + vma->size = size; + vma->flags = VM_MAP; + vma->caller = map_kernel_chunk; + + vm_area_add_early(vma); } -#endif -void fixup_init(void) +/* + * Create fine-grained mappings for the kernel. + */ +static void __init map_kernel(pgd_t *pgd) { - create_mapping_late(__pa(__init_begin), (unsigned long)__init_begin, - (unsigned long)__init_end - (unsigned long)__init_begin, - PAGE_KERNEL); + static struct vm_struct vmlinux_text, vmlinux_init, vmlinux_data; + + map_kernel_chunk(pgd, _stext, _etext, PAGE_KERNEL_EXEC, &vmlinux_text); + map_kernel_chunk(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC, + &vmlinux_init); + map_kernel_chunk(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data); + + if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) { + /* + * The fixmap falls in a separate pgd to the kernel, and doesn't + * live in the carveout for the swapper_pg_dir. We can simply + * re-use the existing dir for the fixmap. + */ + set_pgd(pgd_offset_raw(pgd, FIXADDR_START), + *pgd_offset_k(FIXADDR_START)); + } else if (CONFIG_PGTABLE_LEVELS > 3) { + /* + * The fixmap shares its top level pgd entry with the kernel + * mapping. This can really only occur when we are running + * with 16k/4 levels, so we can simply reuse the pud level + * entry instead. + */ + BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); + set_pud(pud_set_fixmap_offset(pgd, FIXADDR_START), + __pud(__pa(bm_pmd) | PUD_TYPE_TABLE)); + pud_clear_fixmap(); + } else { + BUG(); + } + + kasan_copy_shadow(pgd); } /* @@ -454,28 +523,35 @@ void fixup_init(void) */ void __init paging_init(void) { - void *zero_page; - - map_mem(); - fixup_executable(); + phys_addr_t pgd_phys = early_pgtable_alloc(); + pgd_t *pgd = pgd_set_fixmap(pgd_phys); - /* allocate the zero page. */ - zero_page = early_alloc(PAGE_SIZE); + map_kernel(pgd); + map_mem(pgd); - bootmem_init(); - - empty_zero_page = virt_to_page(zero_page); + /* + * We want to reuse the original swapper_pg_dir so we don't have to + * communicate the new address to non-coherent secondaries in + * secondary_entry, and so cpu_switch_mm can generate the address with + * adrp+add rather than a load from some global variable. + * + * To do this we need to go via a temporary pgd. + */ + cpu_replace_ttbr1(__va(pgd_phys)); + memcpy(swapper_pg_dir, pgd, PAGE_SIZE); + cpu_replace_ttbr1(swapper_pg_dir); - /* Ensure the zero page is visible to the page table walker */ - dsb(ishst); + pgd_clear_fixmap(); + memblock_free(pgd_phys, PAGE_SIZE); /* - * TTBR0 is only used for the identity mapping at this stage. Make it - * point to zero page to avoid speculatively fetching new entries. + * We only reuse the PGD from the swapper_pg_dir, not the pud + pmd + * allocated with it. */ - cpu_set_reserved_ttbr0(); - local_flush_tlb_all(); - cpu_set_default_tcr_t0sz(); + memblock_free(__pa(swapper_pg_dir) + PAGE_SIZE, + SWAPPER_DIR_SIZE - PAGE_SIZE); + + bootmem_init(); } /* @@ -562,21 +638,13 @@ void vmemmap_free(unsigned long start, unsigned long end) } #endif /* CONFIG_SPARSEMEM_VMEMMAP */ -static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss; -#if CONFIG_PGTABLE_LEVELS > 2 -static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss; -#endif -#if CONFIG_PGTABLE_LEVELS > 3 -static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss; -#endif - static inline pud_t * fixmap_pud(unsigned long addr) { pgd_t *pgd = pgd_offset_k(addr); BUG_ON(pgd_none(*pgd) || pgd_bad(*pgd)); - return pud_offset(pgd, addr); + return pud_offset_kimg(pgd, addr); } static inline pmd_t * fixmap_pmd(unsigned long addr) @@ -585,16 +653,12 @@ static inline pmd_t * fixmap_pmd(unsigned long addr) BUG_ON(pud_none(*pud) || pud_bad(*pud)); - return pmd_offset(pud, addr); + return pmd_offset_kimg(pud, addr); } static inline pte_t * fixmap_pte(unsigned long addr) { - pmd_t *pmd = fixmap_pmd(addr); - - BUG_ON(pmd_none(*pmd) || pmd_bad(*pmd)); - - return pte_offset_kernel(pmd, addr); + return &bm_pte[pte_index(addr)]; } void __init early_fixmap_init(void) @@ -605,15 +669,25 @@ void __init early_fixmap_init(void) unsigned long addr = FIXADDR_START; pgd = pgd_offset_k(addr); - pgd_populate(&init_mm, pgd, bm_pud); - pud = pud_offset(pgd, addr); + if (CONFIG_PGTABLE_LEVELS > 3 && !pgd_none(*pgd)) { + /* + * We only end up here if the kernel mapping and the fixmap + * share the top level pgd entry, which should only happen on + * 16k/4 levels configurations. + */ + BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES)); + pud = pud_offset_kimg(pgd, addr); + } else { + pgd_populate(&init_mm, pgd, bm_pud); + pud = fixmap_pud(addr); + } pud_populate(&init_mm, pud, bm_pmd); - pmd = pmd_offset(pud, addr); + pmd = fixmap_pmd(addr); pmd_populate_kernel(&init_mm, pmd, bm_pte); /* * The boot-ioremap range spans multiple pmds, for which - * we are not preparted: + * we are not prepared: */ BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT) != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT)); @@ -673,7 +747,7 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys) /* * Make sure that the FDT region can be mapped without the need to * allocate additional translation table pages, so that it is safe - * to call create_mapping() this early. + * to call create_mapping_noalloc() this early. * * On 64k pages, the FDT will be mapped using PTEs, so we need to * be in the same PMD as the rest of the fixmap. @@ -689,8 +763,8 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys) dt_virt = (void *)dt_virt_base + offset; /* map the first chunk so we can read the size from the header */ - create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base, - SWAPPER_BLOCK_SIZE, prot); + create_mapping_noalloc(round_down(dt_phys, SWAPPER_BLOCK_SIZE), + dt_virt_base, SWAPPER_BLOCK_SIZE, prot); if (fdt_check_header(dt_virt) != 0) return NULL; @@ -700,10 +774,51 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys) return NULL; if (offset + size > SWAPPER_BLOCK_SIZE) - create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base, + create_mapping_noalloc(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base, round_up(offset + size, SWAPPER_BLOCK_SIZE), prot); memblock_reserve(dt_phys, size); return dt_virt; } + +int __init arch_ioremap_pud_supported(void) +{ + /* only 4k granule supports level 1 block mappings */ + return IS_ENABLED(CONFIG_ARM64_4K_PAGES); +} + +int __init arch_ioremap_pmd_supported(void) +{ + return 1; +} + +int pud_set_huge(pud_t *pud, phys_addr_t phys, pgprot_t prot) +{ + BUG_ON(phys & ~PUD_MASK); + set_pud(pud, __pud(phys | PUD_TYPE_SECT | pgprot_val(mk_sect_prot(prot)))); + return 1; +} + +int pmd_set_huge(pmd_t *pmd, phys_addr_t phys, pgprot_t prot) +{ + BUG_ON(phys & ~PMD_MASK); + set_pmd(pmd, __pmd(phys | PMD_TYPE_SECT | pgprot_val(mk_sect_prot(prot)))); + return 1; +} + +int pud_clear_huge(pud_t *pud) +{ + if (!pud_sect(*pud)) + return 0; + pud_clear(pud); + return 1; +} + +int pmd_clear_huge(pmd_t *pmd) +{ + if (!pmd_sect(*pmd)) + return 0; + pmd_clear(pmd); + return 1; +} diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index 3571c7309c5e..ca6d268e3313 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -36,14 +37,32 @@ static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr, return 0; } +/* + * This function assumes that the range is mapped with PAGE_SIZE pages. + */ +static int __change_memory_common(unsigned long start, unsigned long size, + pgprot_t set_mask, pgprot_t clear_mask) +{ + struct page_change_data data; + int ret; + + data.set_mask = set_mask; + data.clear_mask = clear_mask; + + ret = apply_to_page_range(&init_mm, start, size, change_page_range, + &data); + + flush_tlb_kernel_range(start, start + size); + return ret; +} + static int change_memory_common(unsigned long addr, int numpages, pgprot_t set_mask, pgprot_t clear_mask) { unsigned long start = addr; unsigned long size = PAGE_SIZE*numpages; unsigned long end = start + size; - int ret; - struct page_change_data data; + struct vm_struct *area; if (!PAGE_ALIGNED(addr)) { start &= PAGE_MASK; @@ -51,20 +70,29 @@ static int change_memory_common(unsigned long addr, int numpages, WARN_ON_ONCE(1); } - if (start < MODULES_VADDR || start >= MODULES_END) - return -EINVAL; - - if (end < MODULES_VADDR || end >= MODULES_END) + /* + * Kernel VA mappings are always live, and splitting live section + * mappings into page mappings may cause TLB conflicts. This means + * we have to ensure that changing the permission bits of the range + * we are operating on does not result in such splitting. + * + * Let's restrict ourselves to mappings created by vmalloc (or vmap). + * Those are guaranteed to consist entirely of page mappings, and + * splitting is never needed. + * + * So check whether the [addr, addr + size) interval is entirely + * covered by precisely one VM area that has the VM_ALLOC flag set. + */ + area = find_vm_area((void *)addr); + if (!area || + end > (unsigned long)area->addr + area->size || + !(area->flags & VM_ALLOC)) return -EINVAL; - data.set_mask = set_mask; - data.clear_mask = clear_mask; - - ret = apply_to_page_range(&init_mm, start, size, change_page_range, - &data); + if (!numpages) + return 0; - flush_tlb_kernel_range(start, end); - return ret; + return __change_memory_common(start, size, set_mask, clear_mask); } int set_memory_ro(unsigned long addr, int numpages) @@ -96,3 +124,19 @@ int set_memory_x(unsigned long addr, int numpages) __pgprot(PTE_PXN)); } EXPORT_SYMBOL_GPL(set_memory_x); + +#ifdef CONFIG_DEBUG_PAGEALLOC +void __kernel_map_pages(struct page *page, int numpages, int enable) +{ + unsigned long addr = (unsigned long) page_address(page); + + if (enable) + __change_memory_common(addr, PAGE_SIZE * numpages, + __pgprot(PTE_VALID), + __pgprot(0)); + else + __change_memory_common(addr, PAGE_SIZE * numpages, + __pgprot(0), + __pgprot(PTE_VALID)); +} +#endif diff --git a/arch/arm64/mm/proc-macros.S b/arch/arm64/mm/proc-macros.S index 146bd99a7532..e6a30e1268a8 100644 --- a/arch/arm64/mm/proc-macros.S +++ b/arch/arm64/mm/proc-macros.S @@ -84,3 +84,15 @@ b.lo 9998b dsb \domain .endm + +/* + * reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present + */ + .macro reset_pmuserenr_el0, tmpreg + mrs \tmpreg, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer + sbfx \tmpreg, \tmpreg, #8, #4 + cmp \tmpreg, #1 // Skip if no PMU present + b.lt 9000f + msr pmuserenr_el0, xzr // Disable PMU access from EL0 +9000: + .endm diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index a3d867e723b4..0c19534a901e 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -117,7 +117,7 @@ ENTRY(cpu_do_resume) */ ubfx x11, x11, #1, #1 msr oslar_el1, x11 - msr pmuserenr_el0, xzr // Disable PMU access from EL0 + reset_pmuserenr_el0 x0 // Disable PMU access from EL0 mov x0, x12 dsb nsh // Make sure local tlb invalidation completed isb @@ -140,6 +140,34 @@ ENTRY(cpu_do_switch_mm) ret ENDPROC(cpu_do_switch_mm) + .pushsection ".idmap.text", "ax" +/* + * void idmap_cpu_replace_ttbr1(phys_addr_t new_pgd) + * + * This is the low-level counterpart to cpu_replace_ttbr1, and should not be + * called by anything else. It can only be executed from a TTBR0 mapping. + */ +ENTRY(idmap_cpu_replace_ttbr1) + mrs x2, daif + msr daifset, #0xf + + adrp x1, empty_zero_page + msr ttbr1_el1, x1 + isb + + tlbi vmalle1 + dsb nsh + isb + + msr ttbr1_el1, x0 + isb + + msr daif, x2 + + ret +ENDPROC(idmap_cpu_replace_ttbr1) + .popsection + /* * __cpu_setup * @@ -154,7 +182,7 @@ ENTRY(__cpu_setup) msr cpacr_el1, x0 // Enable FP/ASIMD mov x0, #1 << 12 // Reset mdscr_el1 and disable msr mdscr_el1, x0 // access to the DCC from EL0 - msr pmuserenr_el0, xzr // Disable PMU access from EL0 + reset_pmuserenr_el0 x0 // Disable PMU access from EL0 /* * Memory region attributes for LPAE: * diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index 209ae5ad3495..e6928896da2a 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c @@ -49,13 +49,13 @@ static struct resource __initdata kernel_data = { .name = "Kernel data", .start = 0, .end = 0, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_SYSTEM_RAM, }; static struct resource __initdata kernel_code = { .name = "Kernel code", .start = 0, .end = 0, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_SYSTEM_RAM, .sibling = &kernel_data, }; @@ -134,7 +134,7 @@ add_physical_memory(resource_size_t start, resource_size_t end) new->start = start; new->end = end; new->name = "System RAM"; - new->flags = IORESOURCE_MEM; + new->flags = IORESOURCE_SYSTEM_RAM; *pprev = new; } diff --git a/arch/c6x/kernel/setup.c b/arch/c6x/kernel/setup.c index 72e17f7ebd6f..786e36e2f61d 100644 --- a/arch/c6x/kernel/setup.c +++ b/arch/c6x/kernel/setup.c @@ -281,8 +281,6 @@ notrace void __init machine_init(unsigned long dt_ptr) */ set_ist(_vectors_start); - lockdep_init(); - /* * dtb is passed in from bootloader. * fdt is linked in blob. diff --git a/arch/h8300/boot/dts/edosk2674.dts b/arch/h8300/boot/dts/edosk2674.dts index 4ce9fa874a57..6ae884bf66a5 100644 --- a/arch/h8300/boot/dts/edosk2674.dts +++ b/arch/h8300/boot/dts/edosk2674.dts @@ -88,20 +88,20 @@ reg = <0xffff78 8>; interrupts = <88 0>, <89 0>, <90 0>, <91 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; sci1: serial@ffff80 { compatible = "renesas,sci"; reg = <0xffff80 8>; interrupts = <92 0>, <93 0>, <94 0>, <95 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; sci2: serial@ffff88 { compatible = "renesas,sci"; reg = <0xffff88 8>; interrupts = <96 0>, <97 0>, <98 0>, <99 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; }; diff --git a/arch/h8300/boot/dts/h8300h_sim.dts b/arch/h8300/boot/dts/h8300h_sim.dts index 545bfb57af9a..9c733d920f1f 100644 --- a/arch/h8300/boot/dts/h8300h_sim.dts +++ b/arch/h8300/boot/dts/h8300h_sim.dts @@ -83,7 +83,7 @@ reg = <0xffffb0 8>; interrupts = <52 0>, <53 0>, <54 0>, <55 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; sci1: serial@ffffb8 { @@ -91,6 +91,6 @@ reg = <0xffffb8 8>; interrupts = <56 0>, <57 0>, <58 0>, <59 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; }; diff --git a/arch/h8300/boot/dts/h8s_sim.dts b/arch/h8300/boot/dts/h8s_sim.dts index bcedba5a3ce7..97e1f4b17ef0 100644 --- a/arch/h8300/boot/dts/h8s_sim.dts +++ b/arch/h8300/boot/dts/h8s_sim.dts @@ -87,13 +87,13 @@ reg = <0xffff78 8>; interrupts = <88 0>, <89 0>, <90 0>, <91 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; sci1: serial@ffff80 { compatible = "renesas,sci"; reg = <0xffff80 8>; interrupts = <92 0>, <93 0>, <94 0>, <95 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; }; diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index caae3f4e4341..300dac3702f1 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -1178,7 +1178,7 @@ efi_initialize_iomem_resources(struct resource *code_resource, efi_memory_desc_t *md; u64 efi_desc_size; char *name; - unsigned long flags; + unsigned long flags, desc; efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; @@ -1193,6 +1193,8 @@ efi_initialize_iomem_resources(struct resource *code_resource, continue; flags = IORESOURCE_MEM | IORESOURCE_BUSY; + desc = IORES_DESC_NONE; + switch (md->type) { case EFI_MEMORY_MAPPED_IO: @@ -1207,14 +1209,17 @@ efi_initialize_iomem_resources(struct resource *code_resource, if (md->attribute & EFI_MEMORY_WP) { name = "System ROM"; flags |= IORESOURCE_READONLY; - } else if (md->attribute == EFI_MEMORY_UC) + } else if (md->attribute == EFI_MEMORY_UC) { name = "Uncached RAM"; - else + } else { name = "System RAM"; + flags |= IORESOURCE_SYSRAM; + } break; case EFI_ACPI_MEMORY_NVS: name = "ACPI Non-volatile Storage"; + desc = IORES_DESC_ACPI_NV_STORAGE; break; case EFI_UNUSABLE_MEMORY: @@ -1224,6 +1229,7 @@ efi_initialize_iomem_resources(struct resource *code_resource, case EFI_PERSISTENT_MEMORY: name = "Persistent Memory"; + desc = IORES_DESC_PERSISTENT_MEMORY; break; case EFI_RESERVED_TYPE: @@ -1246,6 +1252,7 @@ efi_initialize_iomem_resources(struct resource *code_resource, res->start = md->phys_addr; res->end = md->phys_addr + efi_md_size(md) - 1; res->flags = flags; + res->desc = desc; if (insert_resource(&iomem_resource, res) < 0) kfree(res); diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 4f118b0d3091..2029a38a72ae 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -80,17 +80,17 @@ unsigned long vga_console_membase; static struct resource data_resource = { .name = "Kernel data", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; static struct resource code_resource = { .name = "Kernel code", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; static struct resource bss_resource = { .name = "Kernel bss", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; unsigned long ia64_max_cacheline_size; diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 836ac5a963c8..2841c0a3fd3b 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -276,6 +276,7 @@ source "kernel/Kconfig.preempt" config SMP bool "Symmetric multi-processing support" + depends on MMU ---help--- This enables support for systems with more than one CPU. If you have a system with only one CPU, say N. If you have a system with more diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index a5ecef7188ba..136c69f1fb8a 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c @@ -70,14 +70,14 @@ static struct resource data_resource = { .name = "Kernel data", .start = 0, .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; static struct resource code_resource = { .name = "Kernel code", .start = 0, .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; unsigned long memory_start; diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c index 71ea4c02795d..a0fc0c192427 100644 --- a/arch/m68k/coldfire/device.c +++ b/arch/m68k/coldfire/device.c @@ -89,7 +89,7 @@ static struct platform_device mcf_uart = { .dev.platform_data = mcf_uart_platform_data, }; -#ifdef CONFIG_FEC +#if IS_ENABLED(CONFIG_FEC) #ifdef CONFIG_M5441x #define FEC_NAME "enet-fec" @@ -329,7 +329,7 @@ static struct platform_device mcf_qspi = { static struct platform_device *mcf_devices[] __initdata = { &mcf_uart, -#ifdef CONFIG_FEC +#if IS_ENABLED(CONFIG_FEC) &mcf_fec0, #ifdef MCFFEC_BASE1 &mcf_fec1, diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index fc96e814188e..d1fc4796025e 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -108,6 +108,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -266,6 +268,12 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_ATALK=m CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -366,6 +374,7 @@ CONFIG_ARIADNE=y # CONFIG_NET_VENDOR_INTEL is not set # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NETRONOME is not set CONFIG_HYDRA=y CONFIG_APNE=y CONFIG_ZORRO8390=y diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index 05c904f08d9d..9bfe8be3658c 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -106,6 +106,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -264,6 +266,12 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_ATALK=m CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -344,6 +352,7 @@ CONFIG_VETH=m # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RENESAS is not set # CONFIG_NET_VENDOR_ROCKER is not set diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index d572b731c510..ebdcfae55580 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -106,6 +106,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -264,6 +266,12 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_ATALK=m CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -353,6 +361,7 @@ CONFIG_ATARILANCE=y # CONFIG_NET_VENDOR_INTEL is not set # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NETRONOME is not set CONFIG_NE2000=y # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RENESAS is not set diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index 11a30c65ad44..8acc65e54995 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -104,6 +104,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -262,6 +264,12 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_ATALK=m CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -343,6 +351,7 @@ CONFIG_BVME6000_NET=y # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RENESAS is not set # CONFIG_NET_VENDOR_ROCKER is not set diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index 6630a5154b9d..0c6a3d52b26e 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -106,6 +106,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -264,6 +266,12 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_ATALK=m CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -345,6 +353,7 @@ CONFIG_HPLANCE=y # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RENESAS is not set # CONFIG_NET_VENDOR_ROCKER is not set diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 1d90b71d0903..12a8a6cb32f4 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -105,6 +105,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -266,6 +268,12 @@ CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -362,6 +370,7 @@ CONFIG_MAC89x0=y # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set CONFIG_MACSONIC=y +# CONFIG_NET_VENDOR_NETRONOME is not set CONFIG_MAC8390=y # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RENESAS is not set diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index 1fd21c1ca87f..64ff2dcb34c8 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -115,6 +115,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -276,6 +278,12 @@ CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -404,6 +412,7 @@ CONFIG_MVME16x_NET=y # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set CONFIG_MACSONIC=y +# CONFIG_NET_VENDOR_NETRONOME is not set CONFIG_HYDRA=y CONFIG_MAC8390=y CONFIG_NE2000=y diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 74e10f79d7b1..07fc6abcfe0c 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -103,6 +103,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -261,6 +263,12 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_ATALK=m CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -343,6 +351,7 @@ CONFIG_MVME147_NET=y # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RENESAS is not set # CONFIG_NET_VENDOR_ROCKER is not set diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 7034e716f166..69903ded88f7 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -104,6 +104,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -262,6 +264,12 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_ATALK=m CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -343,6 +351,7 @@ CONFIG_MVME16x_NET=y # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RENESAS is not set # CONFIG_NET_VENDOR_ROCKER is not set diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index f7deb5f702a6..bd8401686dde 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -104,6 +104,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -262,6 +264,12 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_ATALK=m CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -352,6 +360,7 @@ CONFIG_VETH=m # CONFIG_NET_VENDOR_INTEL is not set # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NETRONOME is not set CONFIG_NE2000=y # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RENESAS is not set diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 0ce79eb0d805..5f9fb3ab9636 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -101,6 +101,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -259,6 +261,12 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_ATALK=m CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -340,6 +348,7 @@ CONFIG_SUN3_82586=y # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RENESAS is not set # CONFIG_NET_VENDOR_ROCKER is not set diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index 4cb787e4991f..5d1c674530e2 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -101,6 +101,8 @@ CONFIG_NFT_NAT=m CONFIG_NFT_QUEUE=m CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -259,6 +261,12 @@ CONFIG_L2TP=m CONFIG_BRIDGE=m CONFIG_ATALK=m CONFIG_6LOWPAN=m +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_DAT=y @@ -341,6 +349,7 @@ CONFIG_SUN3LANCE=y # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RENESAS is not set # CONFIG_NET_VENDOR_ROCKER is not set diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index f9d96bf86910..bafaff6dcd7b 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -4,7 +4,7 @@ #include -#define NR_syscalls 376 +#define NR_syscalls 377 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT diff --git a/arch/m68k/include/uapi/asm/unistd.h b/arch/m68k/include/uapi/asm/unistd.h index 36cf129de663..0ca729665f29 100644 --- a/arch/m68k/include/uapi/asm/unistd.h +++ b/arch/m68k/include/uapi/asm/unistd.h @@ -381,5 +381,6 @@ #define __NR_userfaultfd 373 #define __NR_membarrier 374 #define __NR_mlock2 375 +#define __NR_copy_file_range 376 #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 282cd903f4c4..8bb94261ff97 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S @@ -396,3 +396,4 @@ ENTRY(sys_call_table) .long sys_userfaultfd .long sys_membarrier .long sys_mlock2 /* 375 */ + .long sys_copy_file_range diff --git a/arch/metag/kernel/ftrace.c b/arch/metag/kernel/ftrace.c index ac8c039b0318..f7b23d300881 100644 --- a/arch/metag/kernel/ftrace.c +++ b/arch/metag/kernel/ftrace.c @@ -115,7 +115,6 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) return ftrace_modify_code(ip, old, new); } -/* run from kstop_machine */ int __init ftrace_dyn_arch_init(void) { return 0; diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h index 76ed17b56fea..805ae5d712e8 100644 --- a/arch/microblaze/include/asm/unistd.h +++ b/arch/microblaze/include/asm/unistd.h @@ -38,6 +38,6 @@ #endif /* __ASSEMBLY__ */ -#define __NR_syscalls 389 +#define __NR_syscalls 392 #endif /* _ASM_MICROBLAZE_UNISTD_H */ diff --git a/arch/microblaze/include/uapi/asm/unistd.h b/arch/microblaze/include/uapi/asm/unistd.h index 32850c73be09..a8bd3fa28bc7 100644 --- a/arch/microblaze/include/uapi/asm/unistd.h +++ b/arch/microblaze/include/uapi/asm/unistd.h @@ -404,5 +404,8 @@ #define __NR_memfd_create 386 #define __NR_bpf 387 #define __NR_execveat 388 +#define __NR_userfaultfd 389 +#define __NR_membarrier 390 +#define __NR_mlock2 391 #endif /* _UAPI_ASM_MICROBLAZE_UNISTD_H */ diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 89a2a9394927..f31ebb5dc26c 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -130,8 +130,6 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, memset(__bss_start, 0, __bss_stop-__bss_start); memset(_ssbss, 0, _esbss-_ssbss); - lockdep_init(); - /* initialize device tree for usage in early_printk */ early_init_devtree(_fdt_start); diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index 29c8568ec55c..6b3dd99126d7 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -389,3 +389,6 @@ ENTRY(sys_call_table) .long sys_memfd_create .long sys_bpf .long sys_execveat + .long sys_userfaultfd + .long sys_membarrier /* 390 */ + .long sys_mlock2 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 57a945e832f4..cc172671797d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -137,7 +137,7 @@ config ATH79 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_MIPS16 - select SYS_SUPPORTS_ZBOOT + select SYS_SUPPORTS_ZBOOT_UART_PROM select USE_OF help Support for the Atheros AR71XX/AR724X/AR913X SoCs. @@ -151,6 +151,7 @@ config BMIPS_GENERIC select CSRC_R4K select SYNC_R4K select COMMON_CLK + select BCM6345_L1_IRQ select BCM7038_L1_IRQ select BCM7120_L2_IRQ select BRCMSTB_L2_IRQ diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 13c04cf54afa..dfc60209dc63 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig @@ -71,18 +71,6 @@ config ATH79_MACH_UBNT_XM Say 'Y' here if you want your kernel to support the Ubiquiti Networks XM (rev 1.0) board. -choice - prompt "Build a DTB in the kernel" - optional - help - Select a devicetree that should be built into the kernel. - - config DTB_TL_WR1043ND_V1 - bool "TL-WR1043ND Version 1" - select BUILTIN_DTB - select SOC_AR913X -endchoice - endmenu config SOC_AR71XX diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index be451ee4a5ea..01808e85e263 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -203,10 +203,8 @@ void __init plat_mem_setup(void) fdt_start = fw_getenvl("fdt_start"); if (fdt_start) __dt_setup_arch((void *)KSEG0ADDR(fdt_start)); -#ifdef CONFIG_BUILTIN_DTB - else - __dt_setup_arch(__dtb_start); -#endif + else if (fw_arg0 == -2) + __dt_setup_arch((void *)KSEG0ADDR(fw_arg1)); ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, AR71XX_RESET_SIZE); @@ -215,10 +213,11 @@ void __init plat_mem_setup(void) ath79_detect_sys_type(); ath79_ddr_ctrl_init(); - if (mips_machtype != ATH79_MACH_GENERIC_OF) + if (mips_machtype != ATH79_MACH_GENERIC_OF) { detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); - - _machine_restart = ath79_restart; + /* OF machines should use the reset driver */ + _machine_restart = ath79_restart; + } _machine_halt = ath79_halt; pm_power_off = ath79_halt; } diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index 5f2bc1e10eae..05757aed016c 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c @@ -19,6 +19,8 @@ #include +#define BCM63XX_DEFAULT_PSI_SIZE 64 + static struct bcm963xx_nvram nvram; static int mac_addr_used; @@ -85,3 +87,12 @@ int bcm63xx_nvram_get_mac_address(u8 *mac) return 0; } EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); + +int bcm63xx_nvram_get_psi_size(void) +{ + if (nvram.psi_size > 0) + return nvram.psi_size; + + return BCM63XX_DEFAULT_PSI_SIZE; +} +EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size); diff --git a/arch/mips/bmips/irq.c b/arch/mips/bmips/irq.c index e7fc6f9348ba..7efefcf44033 100644 --- a/arch/mips/bmips/irq.c +++ b/arch/mips/bmips/irq.c @@ -15,6 +15,12 @@ #include #include +static const struct of_device_id smp_intc_dt_match[] = { + { .compatible = "brcm,bcm7038-l1-intc" }, + { .compatible = "brcm,bcm6345-l1-intc" }, + {} +}; + unsigned int get_c0_compare_int(void) { return CP0_LEGACY_COMPARE_IRQ; @@ -24,8 +30,8 @@ void __init arch_init_irq(void) { struct device_node *dn; - /* Only the STB (bcm7038) controller supports SMP IRQ affinity */ - dn = of_find_compatible_node(NULL, NULL, "brcm,bcm7038-l1-intc"); + /* Only these controllers support SMP IRQ affinity */ + dn = of_find_matching_node(NULL, smp_intc_dt_match); if (dn) of_node_put(dn); else diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 4eff1ef02eff..90aca95fe314 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -37,12 +37,18 @@ vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT) += $(obj)/dbg.o vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM) += $(obj)/uart-prom.o vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o +vmlinuzobjs-$(CONFIG_ATH79) += $(obj)/uart-ath79.o endif -vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o +extra-y += uart-ath79.c +$(obj)/uart-ath79.c: $(srctree)/arch/mips/ath79/early_printk.c + $(call cmd,shipped) + +vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o $(obj)/bswapsi.o -$(obj)/ashldi3.o: KBUILD_CFLAGS += -I$(srctree)/arch/mips/lib -$(obj)/ashldi3.c: $(srctree)/arch/mips/lib/ashldi3.c +extra-y += ashldi3.c bswapsi.c +$(obj)/ashldi3.o $(obj)/bswapsi.o: KBUILD_CFLAGS += -I$(srctree)/arch/mips/lib +$(obj)/ashldi3.c $(obj)/bswapsi.c: $(obj)/%.c: $(srctree)/arch/mips/lib/%.c $(call cmd,shipped) targets := $(notdir $(vmlinuzobjs-y)) diff --git a/arch/mips/boot/dts/brcm/bcm6328.dtsi b/arch/mips/boot/dts/brcm/bcm6328.dtsi index 459b9b252c3b..d61b1616b604 100644 --- a/arch/mips/boot/dts/brcm/bcm6328.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6328.dtsi @@ -74,6 +74,7 @@ timer: timer@10000040 { compatible = "syscon"; reg = <0x10000040 0x2c>; + little-endian; }; reboot { diff --git a/arch/mips/boot/dts/brcm/bcm7125.dtsi b/arch/mips/boot/dts/brcm/bcm7125.dtsi index 4fc7ecee273c..1a7efa883c5e 100644 --- a/arch/mips/boot/dts/brcm/bcm7125.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7125.dtsi @@ -98,6 +98,7 @@ sun_top_ctrl: syscon@404000 { compatible = "brcm,bcm7125-sun-top-ctrl", "syscon"; reg = <0x404000 0x60c>; + little-endian; }; reboot { diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi index a3039bb53477..d4bf52cfcf17 100644 --- a/arch/mips/boot/dts/brcm/bcm7346.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi @@ -118,6 +118,7 @@ sun_top_ctrl: syscon@404000 { compatible = "brcm,bcm7346-sun-top-ctrl", "syscon"; reg = <0x404000 0x51c>; + little-endian; }; reboot { diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi index 4274ff41ec21..8e2501694d03 100644 --- a/arch/mips/boot/dts/brcm/bcm7358.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7358.dtsi @@ -112,6 +112,7 @@ sun_top_ctrl: syscon@404000 { compatible = "brcm,bcm7358-sun-top-ctrl", "syscon"; reg = <0x404000 0x51c>; + little-endian; }; reboot { diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi index 0dcc9163c27b..7e5f76040fb8 100644 --- a/arch/mips/boot/dts/brcm/bcm7360.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi @@ -112,6 +112,7 @@ sun_top_ctrl: syscon@404000 { compatible = "brcm,bcm7360-sun-top-ctrl", "syscon"; reg = <0x404000 0x51c>; + little-endian; }; reboot { diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi index 2f3f9fc2c478..c739ea77acb0 100644 --- a/arch/mips/boot/dts/brcm/bcm7362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi @@ -118,6 +118,7 @@ sun_top_ctrl: syscon@404000 { compatible = "brcm,bcm7362-sun-top-ctrl", "syscon"; reg = <0x404000 0x51c>; + little-endian; }; reboot { diff --git a/arch/mips/boot/dts/brcm/bcm7420.dtsi b/arch/mips/boot/dts/brcm/bcm7420.dtsi index bee221b3b568..5f55d0a50a28 100644 --- a/arch/mips/boot/dts/brcm/bcm7420.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7420.dtsi @@ -99,6 +99,7 @@ sun_top_ctrl: syscon@404000 { compatible = "brcm,bcm7420-sun-top-ctrl", "syscon"; reg = <0x404000 0x60c>; + little-endian; }; reboot { diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi index 571f30f52e3f..e24d41ab4e30 100644 --- a/arch/mips/boot/dts/brcm/bcm7425.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi @@ -100,6 +100,7 @@ sun_top_ctrl: syscon@404000 { compatible = "brcm,bcm7425-sun-top-ctrl", "syscon"; reg = <0x404000 0x51c>; + little-endian; }; reboot { diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi index 614ee211f71a..8b9432cc062b 100644 --- a/arch/mips/boot/dts/brcm/bcm7435.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi @@ -114,6 +114,7 @@ sun_top_ctrl: syscon@404000 { compatible = "brcm,bcm7425-sun-top-ctrl", "syscon"; reg = <0x404000 0x51c>; + little-endian; }; reboot { diff --git a/arch/mips/boot/dts/qca/Makefile b/arch/mips/boot/dts/qca/Makefile index 2d61455d585d..14bd22514283 100644 --- a/arch/mips/boot/dts/qca/Makefile +++ b/arch/mips/boot/dts/qca/Makefile @@ -1,9 +1,6 @@ # All DTBs dtb-$(CONFIG_ATH79) += ar9132_tl_wr1043nd_v1.dtb -# Select a DTB to build in the kernel -obj-$(CONFIG_DTB_TL_WR1043ND_V1) += ar9132_tl_wr1043nd_v1.dtb.o - # Force kbuild to make empty built-in.o if necessary obj- += dummy.o diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index b7fa9ae28c36..0449d935db0a 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -242,7 +242,7 @@ static int octeon_cpu_disable(void) cpumask_clear_cpu(cpu, &cpu_callin_map); octeon_fixup_irqs(); - flush_cache_all(); + __flush_cache_all(); local_flush_tlb_all(); return 0; diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index 01880b34a209..64f2500d891b 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h @@ -19,8 +19,10 @@ #ifdef __KERNEL__ +#include #include #include +#include #include /* undef for production */ @@ -50,7 +52,7 @@ extern void *kmap_atomic(struct page *page); extern void __kunmap_atomic(void *kvaddr); extern void *kmap_atomic_pfn(unsigned long pfn); -#define flush_cache_kmaps() flush_cache_all() +#define flush_cache_kmaps() BUG_ON(cpu_has_dc_aliases) extern void kmap_init(void); diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h index 4e0b6bc1165e..348df49dcc9f 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h @@ -30,4 +30,6 @@ u8 *bcm63xx_nvram_get_name(void); */ int bcm63xx_nvram_get_mac_address(u8 *mac); +int bcm63xx_nvram_get_psi_size(void); + #endif /* BCM63XX_NVRAM_H */ diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h index 79cff26d8b36..398733e3e2cf 100644 --- a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h +++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h @@ -25,8 +25,6 @@ struct jz_nand_platform_data { int num_partitions; struct mtd_partition *partitions; - struct nand_ecclayout *ecc_layout; - unsigned char banks[JZ_NAND_NUM_BANKS]; void (*ident_callback)(struct platform_device *, struct nand_chip *, diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 98c31e5d9579..108d19376bb1 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -102,7 +102,6 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, #include #include #include -#include struct pci_dev; diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 569a7d5242dd..c745f0ea2577 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -732,21 +732,23 @@ static void __init resource_init(void) end = HIGHMEM_START - 1; res = alloc_bootmem(sizeof(struct resource)); + + res->start = start; + res->end = end; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + switch (boot_mem_map.map[i].type) { case BOOT_MEM_RAM: case BOOT_MEM_INIT_RAM: case BOOT_MEM_ROM_DATA: res->name = "System RAM"; + res->flags |= IORESOURCE_SYSRAM; break; case BOOT_MEM_RESERVED: default: res->name = "reserved"; } - res->start = start; - res->end = end; - - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); /* diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c index 509832a9836c..b913cd240d77 100644 --- a/arch/mips/loongson64/loongson-3/smp.c +++ b/arch/mips/loongson64/loongson-3/smp.c @@ -421,7 +421,6 @@ static int loongson3_cpu_disable(void) local_irq_save(flags); fixup_irqs(); local_irq_restore(flags); - flush_cache_all(); local_flush_tlb_all(); return 0; diff --git a/arch/mips/pmcs-msp71xx/msp_setup.c b/arch/mips/pmcs-msp71xx/msp_setup.c index 9d293b3e9130..a63b73610fd4 100644 --- a/arch/mips/pmcs-msp71xx/msp_setup.c +++ b/arch/mips/pmcs-msp71xx/msp_setup.c @@ -118,7 +118,7 @@ void msp_restart(char *command) /* No chip-specific reset code, just jump to the ROM reset vector */ set_c0_status(ST0_BEV | ST0_ERL); change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - flush_cache_all(); + __flush_cache_all(); write_c0_wired(0); __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c index d7f755833c3f..39a0db3e2b34 100644 --- a/arch/mips/vr41xx/common/pmu.c +++ b/arch/mips/vr41xx/common/pmu.c @@ -73,7 +73,7 @@ static inline void software_reset(void) default: set_c0_status(ST0_BEV | ST0_ERL); change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - flush_cache_all(); + __flush_cache_all(); write_c0_wired(0); __asm__("jr %0"::"r"(0xbfc00000)); break; diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 1b366c477687..3c07d6b96877 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -55,12 +55,12 @@ signed char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; static struct resource data_resource = { .name = "Kernel data", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, }; static struct resource code_resource = { .name = "Kernel code", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, }; static struct resource pdcdata_resource = { @@ -201,7 +201,7 @@ static void __init setup_bootmem(void) res->name = "System RAM"; res->start = pmem_ranges[i].start_pfn << PAGE_SHIFT; res->end = res->start + (pmem_ranges[i].pages << PAGE_SHIFT)-1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); } diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e4824fd04bb7..9faa18c4f3f7 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -557,7 +557,7 @@ choice config PPC_4K_PAGES bool "4k page size" - select HAVE_ARCH_SOFT_DIRTY if CHECKPOINT_RESTORE && PPC_BOOK3S + select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64 config PPC_16K_PAGES bool "16k page size" @@ -566,7 +566,7 @@ config PPC_16K_PAGES config PPC_64K_PAGES bool "64k page size" depends on !PPC_FSL_BOOK3E && (44x || PPC_STD_MMU_64 || PPC_BOOK3E_64) - select HAVE_ARCH_SOFT_DIRTY if CHECKPOINT_RESTORE && PPC_BOOK3S + select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64 config PPC_256K_PAGES bool "256k page size" diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 06f17e778c27..8d1c8162f0c1 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -50,7 +50,9 @@ * set of bits not changed in pmd_modify. */ #define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_THP_HUGE) + _PAGE_ACCESSED | _PAGE_THP_HUGE | _PAGE_PTE | \ + _PAGE_SOFT_DIRTY) + #ifdef CONFIG_PPC_64K_PAGES #include diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 8204b0c393aa..ac07a30a7934 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -223,7 +223,6 @@ static inline pte_t *pmdp_ptep(pmd_t *pmd) #define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd)) #define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd)) #define pmd_young(pmd) pte_young(pmd_pte(pmd)) -#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd)) #define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd))) #define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd))) #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) @@ -282,6 +281,10 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp); +#define __HAVE_ARCH_PMDP_HUGE_SPLIT_PREPARE +extern void pmdp_huge_split_prepare(struct vm_area_struct *vma, + unsigned long address, pmd_t *pmdp); + #define pmd_move_must_withdraw pmd_move_must_withdraw struct spinlock; static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl, diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index c5eb86f3d452..867c39b45df6 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -81,6 +81,7 @@ struct pci_dn; #define EEH_PE_KEEP (1 << 8) /* Keep PE on hotplug */ #define EEH_PE_CFG_RESTRICTED (1 << 9) /* Block config on error */ #define EEH_PE_REMOVED (1 << 10) /* Removed permanently */ +#define EEH_PE_PRI_BUS (1 << 11) /* Cached primary bus */ struct eeh_pe { int type; /* PE type: PHB/Bus/Device */ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 271fefbbe521..9d08d8cbed1a 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -38,8 +38,7 @@ #define KVM_MAX_VCPUS NR_CPUS #define KVM_MAX_VCORES NR_CPUS -#define KVM_USER_MEM_SLOTS 32 -#define KVM_MEM_SLOTS_NUM KVM_USER_MEM_SLOTS +#define KVM_USER_MEM_SLOTS 512 #ifdef CONFIG_KVM_MMIO #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 54843ca5fa2b..78968c1ff931 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -10,7 +10,6 @@ #include #include #include -#include struct device_node; diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 5654ece02c0d..3fa9df70aa20 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -383,3 +383,4 @@ SYSCALL(ni_syscall) SYSCALL(ni_syscall) SYSCALL(ni_syscall) SYSCALL(mlock2) +SYSCALL(copy_file_range) diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h index 8e86b48d0369..32e36b16773f 100644 --- a/arch/powerpc/include/asm/trace.h +++ b/arch/powerpc/include/asm/trace.h @@ -57,12 +57,14 @@ DEFINE_EVENT(ppc64_interrupt_class, timer_interrupt_exit, extern void hcall_tracepoint_regfunc(void); extern void hcall_tracepoint_unregfunc(void); -TRACE_EVENT_FN(hcall_entry, +TRACE_EVENT_FN_COND(hcall_entry, TP_PROTO(unsigned long opcode, unsigned long *args), TP_ARGS(opcode, args), + TP_CONDITION(cpu_online(raw_smp_processor_id())), + TP_STRUCT__entry( __field(unsigned long, opcode) ), @@ -76,13 +78,15 @@ TRACE_EVENT_FN(hcall_entry, hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc ); -TRACE_EVENT_FN(hcall_exit, +TRACE_EVENT_FN_COND(hcall_exit, TP_PROTO(unsigned long opcode, unsigned long retval, unsigned long *retbuf), TP_ARGS(opcode, retval, retbuf), + TP_CONDITION(cpu_online(raw_smp_processor_id())), + TP_STRUCT__entry( __field(unsigned long, opcode) __field(unsigned long, retval) diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 6a5ace5fa0c8..1f2594d45605 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -12,7 +12,7 @@ #include -#define NR_syscalls 379 +#define NR_syscalls 380 #define __NR__exit __NR_exit diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h index 12a05652377a..940290d45b08 100644 --- a/arch/powerpc/include/uapi/asm/unistd.h +++ b/arch/powerpc/include/uapi/asm/unistd.h @@ -389,5 +389,6 @@ #define __NR_userfaultfd 364 #define __NR_membarrier 365 #define __NR_mlock2 378 +#define __NR_copy_file_range 379 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 938742135ee0..301be3126ae3 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -564,6 +564,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) */ eeh_pe_state_mark(pe, EEH_PE_KEEP); if (bus) { + eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); pci_lock_rescan_remove(); pcibios_remove_pci_devices(bus); pci_unlock_rescan_remove(); @@ -803,6 +804,7 @@ perm_error: * the their PCI config any more. */ if (frozen_bus) { + eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); pci_lock_rescan_remove(); @@ -886,6 +888,7 @@ static void eeh_handle_special_event(void) continue; /* Notify all devices to be down */ + eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); bus = eeh_pe_bus_get(phb_pe); eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 8654cb166c19..98f81800e00c 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -883,32 +883,29 @@ void eeh_pe_restore_bars(struct eeh_pe *pe) const char *eeh_pe_loc_get(struct eeh_pe *pe) { struct pci_bus *bus = eeh_pe_bus_get(pe); - struct device_node *dn = pci_bus_to_OF_node(bus); + struct device_node *dn; const char *loc = NULL; - if (!dn) - goto out; + while (bus) { + dn = pci_bus_to_OF_node(bus); + if (!dn) { + bus = bus->parent; + continue; + } - /* PHB PE or root PE ? */ - if (pci_is_root_bus(bus)) { - loc = of_get_property(dn, "ibm,loc-code", NULL); - if (!loc) + if (pci_is_root_bus(bus)) loc = of_get_property(dn, "ibm,io-base-loc-code", NULL); + else + loc = of_get_property(dn, "ibm,slot-location-code", + NULL); + if (loc) - goto out; + return loc; - /* Check the root port */ - dn = dn->child; - if (!dn) - goto out; + bus = bus->parent; } - loc = of_get_property(dn, "ibm,loc-code", NULL); - if (!loc) - loc = of_get_property(dn, "ibm,slot-location-code", NULL); - -out: - return loc ? loc : "N/A"; + return "N/A"; } /** @@ -931,7 +928,7 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe) bus = pe->phb->bus; } else if (pe->type & EEH_PE_BUS || pe->type & EEH_PE_DEVICE) { - if (pe->bus) { + if (pe->state & EEH_PE_PRI_BUS) { bus = pe->bus; goto out; } diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index db475d41b57a..f28754c497e5 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -701,31 +701,3 @@ _GLOBAL(kexec_sequence) li r5,0 blr /* image->start(physid, image->start, 0); */ #endif /* CONFIG_KEXEC */ - -#ifdef CONFIG_MODULES -#if defined(_CALL_ELF) && _CALL_ELF == 2 - -#ifdef CONFIG_MODVERSIONS -.weak __crc_TOC. -.section "___kcrctab+TOC.","a" -.globl __kcrctab_TOC. -__kcrctab_TOC.: - .llong __crc_TOC. -#endif - -/* - * Export a fake .TOC. since both modpost and depmod will complain otherwise. - * Both modpost and depmod strip the leading . so we do the same here. - */ -.section "__ksymtab_strings","a" -__kstrtab_TOC.: - .asciz "TOC." - -.section "___ksymtab+TOC.","a" -/* This symbol name is important: it's used by modpost to find exported syms */ -.globl __ksymtab_TOC. -__ksymtab_TOC.: - .llong 0 /* .value */ - .llong __kstrtab_TOC. -#endif /* ELFv2 */ -#endif /* MODULES */ diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 59663af9315f..08b7a40de5f8 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -326,7 +326,10 @@ static void dedotify_versions(struct modversion_info *vers, } } -/* Undefined symbols which refer to .funcname, hack to funcname (or .TOC.) */ +/* + * Undefined symbols which refer to .funcname, hack to funcname. Make .TOC. + * seem to be defined (value set later). + */ static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) { unsigned int i; @@ -334,8 +337,11 @@ static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) for (i = 1; i < numsyms; i++) { if (syms[i].st_shndx == SHN_UNDEF) { char *name = strtab + syms[i].st_name; - if (name[0] == '.') - memmove(name, name+1, strlen(name)); + if (name[0] == '.') { + if (strcmp(name+1, "TOC.") == 0) + syms[i].st_shndx = SHN_ABS; + syms[i].st_name++; + } } } } @@ -351,7 +357,7 @@ static Elf64_Sym *find_dot_toc(Elf64_Shdr *sechdrs, numsyms = sechdrs[symindex].sh_size / sizeof(Elf64_Sym); for (i = 1; i < numsyms; i++) { - if (syms[i].st_shndx == SHN_UNDEF + if (syms[i].st_shndx == SHN_ABS && strcmp(strtab + syms[i].st_name, "TOC.") == 0) return &syms[i]; } diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index ad8c9db61237..d544fa311757 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -114,8 +114,6 @@ extern unsigned int memset_nocache_branch; /* Insn to be replaced by NOP */ notrace void __init machine_init(u64 dt_ptr) { - lockdep_init(); - /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 5c03a6a9b054..f98be8383a39 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -255,9 +255,6 @@ void __init early_setup(unsigned long dt_ptr) setup_paca(&boot_paca); fixup_boot_paca(); - /* Initialize lockdep early or else spinlocks will blow */ - lockdep_init(); - /* -------- printk is now safe to use ------- */ /* Enable early debugging if any specified (see udbg.h) */ diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 774a253ca4e1..9bf7031a67ff 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c @@ -377,15 +377,12 @@ no_seg_found: static void kvmppc_mmu_book3s_64_slbmte(struct kvm_vcpu *vcpu, u64 rs, u64 rb) { - struct kvmppc_vcpu_book3s *vcpu_book3s; u64 esid, esid_1t; int slb_nr; struct kvmppc_slb *slbe; dprintk("KVM MMU: slbmte(0x%llx, 0x%llx)\n", rs, rb); - vcpu_book3s = to_book3s(vcpu); - esid = GET_ESID(rb); esid_1t = GET_ESID_1T(rb); slb_nr = rb & 0xfff; diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index cff207b72c46..baeddb06811d 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -833,6 +833,24 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, vcpu->stat.sum_exits++; + /* + * This can happen if an interrupt occurs in the last stages + * of guest entry or the first stages of guest exit (i.e. after + * setting paca->kvm_hstate.in_guest to KVM_GUEST_MODE_GUEST_HV + * and before setting it to KVM_GUEST_MODE_HOST_HV). + * That can happen due to a bug, or due to a machine check + * occurring at just the wrong time. + */ + if (vcpu->arch.shregs.msr & MSR_HV) { + printk(KERN_EMERG "KVM trap in HV mode!\n"); + printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n", + vcpu->arch.trap, kvmppc_get_pc(vcpu), + vcpu->arch.shregs.msr); + kvmppc_dump_regs(vcpu); + run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + run->hw.hardware_exit_reason = vcpu->arch.trap; + return RESUME_HOST; + } run->exit_reason = KVM_EXIT_UNKNOWN; run->ready_for_interrupt_injection = 1; switch (vcpu->arch.trap) { diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 3c6badcd53ef..6ee26de9a1de 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -2153,7 +2153,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) /* Emulate H_SET_DABR/X on P8 for the sake of compat mode guests */ 2: rlwimi r5, r4, 5, DAWRX_DR | DAWRX_DW - rlwimi r5, r4, 1, DAWRX_WT + rlwimi r5, r4, 2, DAWRX_WT clrrdi r4, r4, 3 std r4, VCPU_DAWR(r3) std r5, VCPU_DAWRX(r3) @@ -2404,6 +2404,8 @@ machine_check_realmode: * guest as machine check causing guest to crash. */ ld r11, VCPU_MSR(r9) + rldicl. r0, r11, 64-MSR_HV_LG, 63 /* check if it happened in HV mode */ + bne mc_cont /* if so, exit to host */ andi. r10, r11, MSR_RI /* check for unrecoverable exception */ beq 1f /* Deliver a machine check to guest */ ld r10, VCPU_PC(r9) diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 6fd2405c7f4a..a3b182dcb823 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -919,21 +919,17 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) r = -ENXIO; break; } - vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval; + val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0]; break; case KVM_REG_PPC_VSCR: if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { r = -ENXIO; break; } - vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val); + val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]); break; case KVM_REG_PPC_VRSAVE: - if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { - r = -ENXIO; - break; - } - vcpu->arch.vrsave = set_reg_val(reg->id, val); + val = get_reg_val(reg->id, vcpu->arch.vrsave); break; #endif /* CONFIG_ALTIVEC */ default: @@ -974,17 +970,21 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) r = -ENXIO; break; } - val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0]; + vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval; break; case KVM_REG_PPC_VSCR: if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { r = -ENXIO; break; } - val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]); + vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val); break; case KVM_REG_PPC_VRSAVE: - val = get_reg_val(reg->id, vcpu->arch.vrsave); + if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { + r = -ENXIO; + break; + } + vcpu->arch.vrsave = set_reg_val(reg->id, val); break; #endif /* CONFIG_ALTIVEC */ default: diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 22d94c3e6fc4..f078a1f94fc2 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -541,7 +541,7 @@ static int __init add_system_ram_resources(void) res->name = "System RAM"; res->start = base; res->end = base + size - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; WARN_ON(request_resource(&iomem_resource, res) < 0); } } @@ -560,12 +560,12 @@ subsys_initcall(add_system_ram_resources); */ int devmem_is_allowed(unsigned long pfn) { + if (page_is_rtas_user_buf(pfn)) + return 1; if (iomem_is_exclusive(PFN_PHYS(pfn))) return 0; if (!page_is_ram(pfn)) return 1; - if (page_is_rtas_user_buf(pfn)) - return 1; return 0; } #endif /* CONFIG_STRICT_DEVMEM */ diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 3124a20d0fab..593341f2cf11 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -646,6 +646,28 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) return pgtable; } +void pmdp_huge_split_prepare(struct vm_area_struct *vma, + unsigned long address, pmd_t *pmdp) +{ + VM_BUG_ON(address & ~HPAGE_PMD_MASK); + VM_BUG_ON(REGION_ID(address) != USER_REGION_ID); + + /* + * We can't mark the pmd none here, because that will cause a race + * against exit_mmap. We need to continue mark pmd TRANS HUGE, while + * we spilt, but at the same time we wan't rest of the ppc64 code + * not to insert hash pte on this, because we will be modifying + * the deposited pgtable in the caller of this function. Hence + * clear the _PAGE_USER so that we move the fault handling to + * higher level function and that will serialize against ptl. + * We need to flush existing hash pte entries here even though, + * the translation is still valid, because we will withdraw + * pgtable_t after this. + */ + pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_USER, 0); +} + + /* * set a new huge pmd. We should not be called for updating * an existing pmd entry. That should go via pmd_hugepage_update. @@ -663,10 +685,19 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd)); } +/* + * We use this to invalidate a pmdp entry before switching from a + * hugepte to regular pmd entry. + */ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp) { - pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, 0); + pmd_hugepage_update(vma->vm_mm, address, pmdp, ~0UL, 0); + /* + * This ensures that generic code that rely on IRQ disabling + * to prevent a parallel THP split work as expected. + */ + kick_all_cpus_sync(); } /* diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c index 7d5e295255b7..9958ba8bf0d2 100644 --- a/arch/powerpc/perf/power8-pmu.c +++ b/arch/powerpc/perf/power8-pmu.c @@ -816,7 +816,7 @@ static struct power_pmu power8_pmu = { .get_constraint = power8_get_constraint, .get_alternatives = power8_get_alternatives, .disable_pmc = power8_disable_pmc, - .flags = PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_ARCH_207S, + .flags = PPMU_HAS_SIER | PPMU_ARCH_207S, .n_generic = ARRAY_SIZE(power8_generic_events), .generic_events = power8_generic_events, .cache_events = &power8_cache_events, diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 5f152b95ca0c..87f47e55aab6 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -444,9 +444,12 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) * PCI devices of the PE are expected to be removed prior * to PE reset. */ - if (!edev->pe->bus) + if (!(edev->pe->state & EEH_PE_PRI_BUS)) { edev->pe->bus = pci_find_bus(hose->global_number, pdn->busno); + if (edev->pe->bus) + edev->pe->state |= EEH_PE_PRI_BUS; + } /* * Enable EEH explicitly so that we will do EEH check diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 573ae1994097..f90dc04395bf 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -3180,6 +3180,7 @@ static void pnv_pci_ioda_shutdown(struct pci_controller *hose) static const struct pci_controller_ops pnv_pci_ioda_controller_ops = { .dma_dev_setup = pnv_pci_dma_dev_setup, + .dma_bus_setup = pnv_pci_dma_bus_setup, #ifdef CONFIG_PCI_MSI .setup_msi_irqs = pnv_setup_msi_irqs, .teardown_msi_irqs = pnv_teardown_msi_irqs, diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 2f55c86df703..cf8417dd4dfc 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -760,6 +760,26 @@ void pnv_pci_dma_dev_setup(struct pci_dev *pdev) phb->dma_dev_setup(phb, pdev); } +void pnv_pci_dma_bus_setup(struct pci_bus *bus) +{ + struct pci_controller *hose = bus->sysdata; + struct pnv_phb *phb = hose->private_data; + struct pnv_ioda_pe *pe; + + list_for_each_entry(pe, &phb->ioda.pe_list, list) { + if (!(pe->flags | (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL))) + continue; + + if (!pe->pbus) + continue; + + if (bus->number == ((pe->rid >> 8) & 0xFF)) { + pe->pbus = bus; + break; + } + } +} + 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 7f56313e8d72..00691a9b99af 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -242,6 +242,7 @@ extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev); extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option); extern void pnv_pci_dma_dev_setup(struct pci_dev *pdev); +extern void pnv_pci_dma_bus_setup(struct pci_bus *bus); extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type); extern void pnv_teardown_msi_irqs(struct pci_dev *pdev); diff --git a/arch/s390/include/asm/irqflags.h b/arch/s390/include/asm/irqflags.h index 16aa0c779e07..595a275c36f8 100644 --- a/arch/s390/include/asm/irqflags.h +++ b/arch/s390/include/asm/irqflags.h @@ -8,6 +8,8 @@ #include +#define ARCH_IRQ_ENABLED (3UL << (BITS_PER_LONG - 8)) + /* store then OR system mask. */ #define __arch_local_irq_stosm(__or) \ ({ \ @@ -54,14 +56,17 @@ static inline notrace void arch_local_irq_enable(void) __arch_local_irq_stosm(0x03); } +/* This only restores external and I/O interrupt state */ static inline notrace void arch_local_irq_restore(unsigned long flags) { - __arch_local_irq_ssm(flags); + /* only disabled->disabled and disabled->enabled is valid */ + if (flags & ARCH_IRQ_ENABLED) + arch_local_irq_enable(); } static inline notrace bool arch_irqs_disabled_flags(unsigned long flags) { - return !(flags & (3UL << (BITS_PER_LONG - 8))); + return !(flags & ARCH_IRQ_ENABLED); } static inline notrace bool arch_irqs_disabled(void) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 6742414dbd6f..8959ebb6d2c9 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -546,7 +546,6 @@ struct kvm_vcpu_arch { struct kvm_s390_sie_block *sie_block; unsigned int host_acrs[NUM_ACRS]; struct fpu host_fpregs; - struct fpu guest_fpregs; struct kvm_s390_local_interrupt local_int; struct hrtimer ckc_timer; struct kvm_s390_pgm_info pgm; diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h index 1a9a98de5bde..69aa18be61af 100644 --- a/arch/s390/include/asm/pci_io.h +++ b/arch/s390/include/asm/pci_io.h @@ -8,10 +8,13 @@ #include /* I/O Map */ -#define ZPCI_IOMAP_MAX_ENTRIES 0x7fff -#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000ULL -#define ZPCI_IOMAP_ADDR_IDX_MASK 0x7fff000000000000ULL -#define ZPCI_IOMAP_ADDR_OFF_MASK 0x0000ffffffffffffULL +#define ZPCI_IOMAP_SHIFT 48 +#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL +#define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1) +#define ZPCI_IOMAP_MAX_ENTRIES \ + ((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT)) +#define ZPCI_IOMAP_ADDR_IDX_MASK \ + (~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE) struct zpci_iomap_entry { u32 fh; @@ -21,8 +24,9 @@ struct zpci_iomap_entry { extern struct zpci_iomap_entry *zpci_iomap_start; +#define ZPCI_ADDR(idx) (ZPCI_IOMAP_ADDR_BASE | ((u64) idx << ZPCI_IOMAP_SHIFT)) #define ZPCI_IDX(addr) \ - (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> 48) + (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> ZPCI_IOMAP_SHIFT) #define ZPCI_OFFSET(addr) \ ((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK) diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index f16debf6a612..1c4fe129486d 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -166,14 +166,14 @@ extern __vector128 init_task_fpu_regs[__NUM_VXRS]; */ #define start_thread(regs, new_psw, new_stackp) do { \ regs->psw.mask = PSW_USER_BITS | PSW_MASK_EA | PSW_MASK_BA; \ - regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ + regs->psw.addr = new_psw; \ regs->gprs[15] = new_stackp; \ execve_tail(); \ } while (0) #define start_thread31(regs, new_psw, new_stackp) do { \ regs->psw.mask = PSW_USER_BITS | PSW_MASK_BA; \ - regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ + regs->psw.addr = new_psw; \ regs->gprs[15] = new_stackp; \ crst_table_downgrade(current->mm, 1UL << 31); \ execve_tail(); \ diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index f00cd35c8ac4..99bc456cc26a 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -149,7 +149,7 @@ static inline int test_pt_regs_flag(struct pt_regs *regs, int flag) #define arch_has_block_step() (1) #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) -#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) +#define instruction_pointer(regs) ((regs)->psw.addr) #define user_stack_pointer(regs)((regs)->gprs[15]) #define profile_pc(regs) instruction_pointer(regs) @@ -161,7 +161,7 @@ static inline long regs_return_value(struct pt_regs *regs) static inline void instruction_pointer_set(struct pt_regs *regs, unsigned long val) { - regs->psw.addr = val | PSW_ADDR_AMODE; + regs->psw.addr = val; } int regs_query_register_offset(const char *name); @@ -171,7 +171,7 @@ unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n); static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) { - return regs->gprs[15] & PSW_ADDR_INSN; + return regs->gprs[15]; } #endif /* __ASSEMBLY__ */ diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h index 34ec202472c6..ab3aa6875a59 100644 --- a/arch/s390/include/uapi/asm/unistd.h +++ b/arch/s390/include/uapi/asm/unistd.h @@ -310,7 +310,8 @@ #define __NR_recvmsg 372 #define __NR_shutdown 373 #define __NR_mlock2 374 -#define NR_syscalls 375 +#define __NR_copy_file_range 375 +#define NR_syscalls 376 /* * There are some system calls that are not present on 64 bit, some diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index fac4eeddef91..ae2cda5eee5a 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c @@ -177,3 +177,4 @@ COMPAT_SYSCALL_WRAP3(getsockname, int, fd, struct sockaddr __user *, usockaddr, COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len); COMPAT_SYSCALL_WRAP6(sendto, int, fd, void __user *, buff, size_t, len, unsigned int, flags, struct sockaddr __user *, addr, int, addr_len); COMPAT_SYSCALL_WRAP3(mlock2, unsigned long, start, size_t, len, int, flags); +COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags); diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index a92b39fd0e63..3986c9f62191 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -59,8 +59,6 @@ struct save_area * __init save_area_alloc(bool is_boot_cpu) struct save_area *sa; sa = (void *) memblock_alloc(sizeof(*sa), 8); - if (!sa) - return NULL; if (is_boot_cpu) list_add(&sa->list, &dump_save_areas); else diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 6fca0e46464e..c890a5589e59 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -1470,7 +1470,7 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, except_str = "*"; else except_str = "-"; - caller = ((unsigned long) entry->caller) & PSW_ADDR_INSN; + caller = (unsigned long) entry->caller; rc += sprintf(out_buf, "%02i %011lld:%06lu %1u %1s %02i %p ", area, (long long)time_spec.tv_sec, time_spec.tv_nsec / 1000, level, except_str, diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index dc8e20473484..02bd02ff648b 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -34,22 +34,21 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) unsigned long addr; while (1) { - sp = sp & PSW_ADDR_INSN; if (sp < low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - addr = sf->gprs[8] & PSW_ADDR_INSN; + addr = sf->gprs[8]; printk("([<%016lx>] %pSR)\n", addr, (void *)addr); /* Follow the backchain. */ while (1) { low = sp; - sp = sf->back_chain & PSW_ADDR_INSN; + sp = sf->back_chain; if (!sp) break; if (sp <= low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - addr = sf->gprs[8] & PSW_ADDR_INSN; + addr = sf->gprs[8]; printk(" [<%016lx>] %pSR\n", addr, (void *)addr); } /* Zero backchain detected, check for interrupt frame. */ @@ -57,7 +56,7 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) if (sp <= low || sp > high - sizeof(*regs)) return sp; regs = (struct pt_regs *) sp; - addr = regs->psw.addr & PSW_ADDR_INSN; + addr = regs->psw.addr; printk(" [<%016lx>] %pSR\n", addr, (void *)addr); low = sp; sp = regs->gprs[15]; diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 20a5caf6d981..a0684de5a93b 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -252,14 +252,14 @@ static void early_pgm_check_handler(void) unsigned long addr; addr = S390_lowcore.program_old_psw.addr; - fixup = search_exception_tables(addr & PSW_ADDR_INSN); + fixup = search_exception_tables(addr); if (!fixup) disabled_wait(0); /* Disable low address protection before storing into lowcore. */ __ctl_store(cr0, 0, 0); cr0_new = cr0 & ~(1UL << 28); __ctl_load(cr0_new, 0, 0); - S390_lowcore.program_old_psw.addr = extable_fixup(fixup)|PSW_ADDR_AMODE; + S390_lowcore.program_old_psw.addr = extable_fixup(fixup); __ctl_load(cr0, 0, 0); } @@ -268,9 +268,9 @@ static noinline __init void setup_lowcore_early(void) psw_t psw; psw.mask = PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA; - psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_ext_handler; + psw.addr = (unsigned long) s390_base_ext_handler; S390_lowcore.external_new_psw = psw; - psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler; + psw.addr = (unsigned long) s390_base_pgm_handler; S390_lowcore.program_new_psw = psw; s390_base_pgm_handler_fn = early_pgm_check_handler; } @@ -448,7 +448,6 @@ void __init startup_init(void) rescue_initrd(); clear_bss_section(); init_kernel_storage_key(); - lockdep_init(); lockdep_off(); setup_lowcore_early(); setup_facility_list(); diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index e0eaf11134b4..0f7bfeba6da6 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -203,7 +203,7 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip) goto out; if (unlikely(atomic_read(¤t->tracing_graph_pause))) goto out; - ip = (ip & PSW_ADDR_INSN) - MCOUNT_INSN_SIZE; + ip -= MCOUNT_INSN_SIZE; trace.func = ip; trace.depth = current->curr_ret_stack + 1; /* Only trace if the calling function expects to. */ diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 0a5a6b661b93..f20abdb5630a 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -2057,12 +2057,12 @@ void s390_reset_system(void) /* Set new machine check handler */ S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT; S390_lowcore.mcck_new_psw.addr = - PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler; + (unsigned long) s390_base_mcck_handler; /* Set new program check handler */ S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT; S390_lowcore.program_new_psw.addr = - PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler; + (unsigned long) s390_base_pgm_handler; /* * Clear subchannel ID and number to signal new kernel that no CCW or diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 389db56a2208..250f5972536a 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -226,7 +226,7 @@ static void enable_singlestep(struct kprobe_ctlblk *kcb, __ctl_load(per_kprobe, 9, 11); regs->psw.mask |= PSW_MASK_PER; regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT); - regs->psw.addr = ip | PSW_ADDR_AMODE; + regs->psw.addr = ip; } NOKPROBE_SYMBOL(enable_singlestep); @@ -238,7 +238,7 @@ static void disable_singlestep(struct kprobe_ctlblk *kcb, __ctl_load(kcb->kprobe_saved_ctl, 9, 11); regs->psw.mask &= ~PSW_MASK_PER; regs->psw.mask |= kcb->kprobe_saved_imask; - regs->psw.addr = ip | PSW_ADDR_AMODE; + regs->psw.addr = ip; } NOKPROBE_SYMBOL(disable_singlestep); @@ -310,7 +310,7 @@ static int kprobe_handler(struct pt_regs *regs) */ preempt_disable(); kcb = get_kprobe_ctlblk(); - p = get_kprobe((void *)((regs->psw.addr & PSW_ADDR_INSN) - 2)); + p = get_kprobe((void *)(regs->psw.addr - 2)); if (p) { if (kprobe_running()) { @@ -460,7 +460,7 @@ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) break; } - regs->psw.addr = orig_ret_address | PSW_ADDR_AMODE; + regs->psw.addr = orig_ret_address; pop_kprobe(get_kprobe_ctlblk()); kretprobe_hash_unlock(current, &flags); @@ -490,7 +490,7 @@ NOKPROBE_SYMBOL(trampoline_probe_handler); static void resume_execution(struct kprobe *p, struct pt_regs *regs) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); - unsigned long ip = regs->psw.addr & PSW_ADDR_INSN; + unsigned long ip = regs->psw.addr; int fixup = probe_get_fixup_type(p->ainsn.insn); /* Check if the kprobes location is an enabled ftrace caller */ @@ -605,9 +605,9 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr) * In case the user-specified fault handler returned * zero, try to fix up. */ - entry = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); + entry = search_exception_tables(regs->psw.addr); if (entry) { - regs->psw.addr = extable_fixup(entry) | PSW_ADDR_AMODE; + regs->psw.addr = extable_fixup(entry); return 1; } @@ -683,7 +683,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs)); /* setup return addr to the jprobe handler routine */ - regs->psw.addr = (unsigned long) jp->entry | PSW_ADDR_AMODE; + regs->psw.addr = (unsigned long) jp->entry; regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT); /* r15 is the stack pointer */ diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c index 61595c1f0a0f..0943b11a2f6e 100644 --- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c @@ -74,7 +74,7 @@ static unsigned long guest_is_user_mode(struct pt_regs *regs) static unsigned long instruction_pointer_guest(struct pt_regs *regs) { - return sie_block(regs)->gpsw.addr & PSW_ADDR_INSN; + return sie_block(regs)->gpsw.addr; } unsigned long perf_instruction_pointer(struct pt_regs *regs) @@ -231,29 +231,27 @@ static unsigned long __store_trace(struct perf_callchain_entry *entry, struct pt_regs *regs; while (1) { - sp = sp & PSW_ADDR_INSN; if (sp < low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - perf_callchain_store(entry, sf->gprs[8] & PSW_ADDR_INSN); + perf_callchain_store(entry, sf->gprs[8]); /* Follow the backchain. */ while (1) { low = sp; - sp = sf->back_chain & PSW_ADDR_INSN; + sp = sf->back_chain; if (!sp) break; if (sp <= low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - perf_callchain_store(entry, - sf->gprs[8] & PSW_ADDR_INSN); + perf_callchain_store(entry, sf->gprs[8]); } /* Zero backchain detected, check for interrupt frame. */ sp = (unsigned long) (sf + 1); if (sp <= low || sp > high - sizeof(*regs)) return sp; regs = (struct pt_regs *) sp; - perf_callchain_store(entry, sf->gprs[8] & PSW_ADDR_INSN); + perf_callchain_store(entry, sf->gprs[8]); low = sp; sp = regs->gprs[15]; } @@ -262,12 +260,13 @@ static unsigned long __store_trace(struct perf_callchain_entry *entry, void perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) { - unsigned long head; + unsigned long head, frame_size; struct stack_frame *head_sf; if (user_mode(regs)) return; + frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); head = regs->gprs[15]; head_sf = (struct stack_frame *) head; @@ -275,8 +274,9 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, return; head = head_sf->back_chain; - head = __store_trace(entry, head, S390_lowcore.async_stack - ASYNC_SIZE, - S390_lowcore.async_stack); + head = __store_trace(entry, head, + S390_lowcore.async_stack + frame_size - ASYNC_SIZE, + S390_lowcore.async_stack + frame_size); __store_trace(entry, head, S390_lowcore.thread_info, S390_lowcore.thread_info + THREAD_SIZE); diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 114ee8b96f17..2bba7df4ac51 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -56,10 +56,10 @@ unsigned long thread_saved_pc(struct task_struct *tsk) return 0; low = task_stack_page(tsk); high = (struct stack_frame *) task_pt_regs(tsk); - sf = (struct stack_frame *) (tsk->thread.ksp & PSW_ADDR_INSN); + sf = (struct stack_frame *) tsk->thread.ksp; if (sf <= low || sf > high) return 0; - sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN); + sf = (struct stack_frame *) sf->back_chain; if (sf <= low || sf > high) return 0; return sf->gprs[8]; @@ -154,7 +154,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp, memset(&frame->childregs, 0, sizeof(struct pt_regs)); frame->childregs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; - frame->childregs.psw.addr = PSW_ADDR_AMODE | + frame->childregs.psw.addr = (unsigned long) kernel_thread_starter; frame->childregs.gprs[9] = new_stackp; /* function */ frame->childregs.gprs[10] = arg; @@ -220,14 +220,14 @@ unsigned long get_wchan(struct task_struct *p) return 0; low = task_stack_page(p); high = (struct stack_frame *) task_pt_regs(p); - sf = (struct stack_frame *) (p->thread.ksp & PSW_ADDR_INSN); + sf = (struct stack_frame *) p->thread.ksp; if (sf <= low || sf > high) return 0; for (count = 0; count < 16; count++) { - sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN); + sf = (struct stack_frame *) sf->back_chain; if (sf <= low || sf > high) return 0; - return_address = sf->gprs[8] & PSW_ADDR_INSN; + return_address = sf->gprs[8]; if (!in_sched_functions(return_address)) return return_address; } diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 01c37b36caf9..49b1c13bf6c9 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -84,7 +84,7 @@ void update_cr_regs(struct task_struct *task) if (test_tsk_thread_flag(task, TIF_UPROBE_SINGLESTEP)) new.control |= PER_EVENT_IFETCH; new.start = 0; - new.end = PSW_ADDR_INSN; + new.end = -1UL; } /* Take care of the PER enablement bit in the PSW. */ @@ -148,7 +148,7 @@ static inline unsigned long __peek_user_per(struct task_struct *child, else if (addr == (addr_t) &dummy->cr11) /* End address of the active per set. */ return test_thread_flag(TIF_SINGLE_STEP) ? - PSW_ADDR_INSN : child->thread.per_user.end; + -1UL : child->thread.per_user.end; else if (addr == (addr_t) &dummy->bits) /* Single-step bit. */ return test_thread_flag(TIF_SINGLE_STEP) ? @@ -495,8 +495,6 @@ long arch_ptrace(struct task_struct *child, long request, } return 0; default: - /* Removing high order bit from addr (only for 31 bit). */ - addr &= PSW_ADDR_INSN; return ptrace_request(child, request, addr, data); } } diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index c6878fbbcf13..cedb0198675f 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -301,25 +301,21 @@ static void __init setup_lowcore(void) BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * 4096); lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); lc->restart_psw.mask = PSW_KERNEL_BITS; - lc->restart_psw.addr = - PSW_ADDR_AMODE | (unsigned long) restart_int_handler; + lc->restart_psw.addr = (unsigned long) restart_int_handler; lc->external_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; - lc->external_new_psw.addr = - PSW_ADDR_AMODE | (unsigned long) ext_int_handler; + lc->external_new_psw.addr = (unsigned long) ext_int_handler; lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; - lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call; + lc->svc_new_psw.addr = (unsigned long) system_call; lc->program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; - lc->program_new_psw.addr = - PSW_ADDR_AMODE | (unsigned long) pgm_check_handler; + lc->program_new_psw.addr = (unsigned long) pgm_check_handler; lc->mcck_new_psw.mask = PSW_KERNEL_BITS; - lc->mcck_new_psw.addr = - PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; + lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler; lc->io_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; - lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; + lc->io_new_psw.addr = (unsigned long) io_int_handler; lc->clock_comparator = -1ULL; lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); @@ -378,17 +374,17 @@ static void __init setup_lowcore(void) static struct resource code_resource = { .name = "Kernel code", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, }; static struct resource data_resource = { .name = "Kernel data", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, }; static struct resource bss_resource = { .name = "Kernel bss", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, }; static struct resource __initdata *standard_resources[] = { @@ -412,7 +408,7 @@ static void __init setup_resources(void) for_each_memblock(memory, reg) { res = alloc_bootmem_low(sizeof(*res)); - res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; + res->flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM; res->name = "System RAM"; res->start = reg->base; diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 028cc46cb82a..d82562cf0a0e 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -331,13 +331,13 @@ static int setup_frame(int sig, struct k_sigaction *ka, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - restorer = (unsigned long) ka->sa.sa_restorer | PSW_ADDR_AMODE; + restorer = (unsigned long) ka->sa.sa_restorer; } else { /* Signal frame without vector registers are short ! */ __u16 __user *svc = (void __user *) frame + frame_size - 2; if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc)) return -EFAULT; - restorer = (unsigned long) svc | PSW_ADDR_AMODE; + restorer = (unsigned long) svc; } /* Set up registers for signal handler */ @@ -347,7 +347,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | (PSW_USER_BITS & PSW_MASK_ASC) | (regs->psw.mask & ~PSW_MASK_ASC); - regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; + regs->psw.addr = (unsigned long) ka->sa.sa_handler; regs->gprs[2] = sig; regs->gprs[3] = (unsigned long) &frame->sc; @@ -394,13 +394,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ksig->ka.sa.sa_flags & SA_RESTORER) { - restorer = (unsigned long) - ksig->ka.sa.sa_restorer | PSW_ADDR_AMODE; + restorer = (unsigned long) ksig->ka.sa.sa_restorer; } else { __u16 __user *svc = &frame->svc_insn; if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc)) return -EFAULT; - restorer = (unsigned long) svc | PSW_ADDR_AMODE; + restorer = (unsigned long) svc; } /* Create siginfo on the signal stack */ @@ -426,7 +425,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | (PSW_USER_BITS & PSW_MASK_ASC) | (regs->psw.mask & ~PSW_MASK_ASC); - regs->psw.addr = (unsigned long) ksig->ka.sa.sa_handler | PSW_ADDR_AMODE; + regs->psw.addr = (unsigned long) ksig->ka.sa.sa_handler; regs->gprs[2] = ksig->sig; regs->gprs[3] = (unsigned long) &frame->info; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index a13468b9a913..3c65a8eae34d 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -623,8 +623,6 @@ void __init smp_save_dump_cpus(void) return; /* Allocate a page as dumping area for the store status sigps */ page = memblock_alloc_base(PAGE_SIZE, PAGE_SIZE, 1UL << 31); - if (!page) - panic("could not allocate memory for save area\n"); /* Set multi-threading state to the previous system. */ pcpu_set_smt(sclp.mtid_prev); boot_cpu_addr = stap(); diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index 1785cd82253c..8f64ebd63767 100644 --- a/arch/s390/kernel/stacktrace.c +++ b/arch/s390/kernel/stacktrace.c @@ -21,12 +21,11 @@ static unsigned long save_context_stack(struct stack_trace *trace, unsigned long addr; while(1) { - sp &= PSW_ADDR_INSN; if (sp < low || sp > high) return sp; sf = (struct stack_frame *)sp; while(1) { - addr = sf->gprs[8] & PSW_ADDR_INSN; + addr = sf->gprs[8]; if (!trace->skip) trace->entries[trace->nr_entries++] = addr; else @@ -34,7 +33,7 @@ static unsigned long save_context_stack(struct stack_trace *trace, if (trace->nr_entries >= trace->max_entries) return sp; low = sp; - sp = sf->back_chain & PSW_ADDR_INSN; + sp = sf->back_chain; if (!sp) break; if (sp <= low || sp > high - sizeof(*sf)) @@ -46,7 +45,7 @@ static unsigned long save_context_stack(struct stack_trace *trace, if (sp <= low || sp > high - sizeof(*regs)) return sp; regs = (struct pt_regs *)sp; - addr = regs->psw.addr & PSW_ADDR_INSN; + addr = regs->psw.addr; if (savesched || !in_sched_functions(addr)) { if (!trace->skip) trace->entries[trace->nr_entries++] = addr; @@ -60,33 +59,43 @@ static unsigned long save_context_stack(struct stack_trace *trace, } } -void save_stack_trace(struct stack_trace *trace) +static void __save_stack_trace(struct stack_trace *trace, unsigned long sp) { - register unsigned long sp asm ("15"); - unsigned long orig_sp, new_sp; + unsigned long new_sp, frame_size; - orig_sp = sp & PSW_ADDR_INSN; - new_sp = save_context_stack(trace, orig_sp, - S390_lowcore.panic_stack - PAGE_SIZE, - S390_lowcore.panic_stack, 1); - if (new_sp != orig_sp) - return; + frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); + new_sp = save_context_stack(trace, sp, + S390_lowcore.panic_stack + frame_size - PAGE_SIZE, + S390_lowcore.panic_stack + frame_size, 1); new_sp = save_context_stack(trace, new_sp, - S390_lowcore.async_stack - ASYNC_SIZE, - S390_lowcore.async_stack, 1); - if (new_sp != orig_sp) - return; + S390_lowcore.async_stack + frame_size - ASYNC_SIZE, + S390_lowcore.async_stack + frame_size, 1); save_context_stack(trace, new_sp, S390_lowcore.thread_info, S390_lowcore.thread_info + THREAD_SIZE, 1); } + +void save_stack_trace(struct stack_trace *trace) +{ + register unsigned long r15 asm ("15"); + unsigned long sp; + + sp = r15; + __save_stack_trace(trace, sp); + if (trace->nr_entries < trace->max_entries) + trace->entries[trace->nr_entries++] = ULONG_MAX; +} EXPORT_SYMBOL_GPL(save_stack_trace); void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) { unsigned long sp, low, high; - sp = tsk->thread.ksp & PSW_ADDR_INSN; + sp = tsk->thread.ksp; + if (tsk == current) { + /* Get current stack pointer. */ + asm volatile("la %0,0(15)" : "=a" (sp)); + } low = (unsigned long) task_stack_page(tsk); high = (unsigned long) task_pt_regs(tsk); save_context_stack(trace, sp, low, high, 0); @@ -94,3 +103,14 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) trace->entries[trace->nr_entries++] = ULONG_MAX; } EXPORT_SYMBOL_GPL(save_stack_trace_tsk); + +void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) +{ + unsigned long sp; + + sp = kernel_stack_pointer(regs); + __save_stack_trace(trace, sp); + if (trace->nr_entries < trace->max_entries) + trace->entries[trace->nr_entries++] = ULONG_MAX; +} +EXPORT_SYMBOL_GPL(save_stack_trace_regs); diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 5378c3ea1b98..293d8b98fd52 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -383,3 +383,4 @@ SYSCALL(sys_recvfrom,compat_sys_recvfrom) SYSCALL(sys_recvmsg,compat_sys_recvmsg) SYSCALL(sys_shutdown,sys_shutdown) SYSCALL(sys_mlock2,compat_sys_mlock2) +SYSCALL(sys_copy_file_range,compat_sys_copy_file_range) /* 375 */ diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index d69d648759c9..017eb03daee2 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -32,8 +32,7 @@ static inline void __user *get_trap_ip(struct pt_regs *regs) address = *(unsigned long *)(current->thread.trap_tdb + 24); else address = regs->psw.addr; - return (void __user *) - ((address - (regs->int_code >> 16)) & PSW_ADDR_INSN); + return (void __user *) (address - (regs->int_code >> 16)); } static inline void report_user_fault(struct pt_regs *regs, int signr) @@ -46,7 +45,7 @@ static inline void report_user_fault(struct pt_regs *regs, int signr) return; printk("User process fault: interruption code %04x ilc:%d ", regs->int_code & 0xffff, regs->int_code >> 17); - print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); + print_vma_addr("in ", regs->psw.addr); printk("\n"); show_regs(regs); } @@ -69,13 +68,13 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str) report_user_fault(regs, si_signo); } else { const struct exception_table_entry *fixup; - fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); + fixup = search_exception_tables(regs->psw.addr); if (fixup) - regs->psw.addr = extable_fixup(fixup) | PSW_ADDR_AMODE; + regs->psw.addr = extable_fixup(fixup); else { enum bug_trap_type btt; - btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs); + btt = report_bug(regs->psw.addr, regs); if (btt == BUG_TRAP_TYPE_WARN) return; die(regs, str); diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index 5fce52cf0e57..5ea5af3c7db7 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig @@ -29,6 +29,7 @@ config KVM select HAVE_KVM_IRQFD select HAVE_KVM_IRQ_ROUTING select SRCU + select KVM_VFIO ---help--- Support hosting paravirtualized guest machines using the SIE virtualization capability on the mainframe. This should work diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile index b3b553469650..d42fa38c2429 100644 --- a/arch/s390/kvm/Makefile +++ b/arch/s390/kvm/Makefile @@ -7,7 +7,7 @@ # as published by the Free Software Foundation. KVM := ../../../virt/kvm -common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o +common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o $(KVM)/vfio.o ccflags-y := -Ivirt/kvm -Iarch/s390/kvm diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c index 47518a324d75..d697312ce9ee 100644 --- a/arch/s390/kvm/guestdbg.c +++ b/arch/s390/kvm/guestdbg.c @@ -116,7 +116,7 @@ static void enable_all_hw_wp(struct kvm_vcpu *vcpu) if (*cr9 & PER_EVENT_STORE && *cr9 & PER_CONTROL_ALTERATION) { *cr9 &= ~PER_CONTROL_ALTERATION; *cr10 = 0; - *cr11 = PSW_ADDR_INSN; + *cr11 = -1UL; } else { *cr9 &= ~PER_CONTROL_ALTERATION; *cr9 |= PER_EVENT_STORE; @@ -159,7 +159,7 @@ void kvm_s390_patch_guest_per_regs(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->gcr[0] &= ~0x800ul; vcpu->arch.sie_block->gcr[9] |= PER_EVENT_IFETCH; vcpu->arch.sie_block->gcr[10] = 0; - vcpu->arch.sie_block->gcr[11] = PSW_ADDR_INSN; + vcpu->arch.sie_block->gcr[11] = -1UL; } if (guestdbg_hw_bp_enabled(vcpu)) { diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 835d60bedb54..4af21c771f9b 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -1423,44 +1423,18 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) return 0; } -/* - * Backs up the current FP/VX register save area on a particular - * destination. Used to switch between different register save - * areas. - */ -static inline void save_fpu_to(struct fpu *dst) -{ - dst->fpc = current->thread.fpu.fpc; - dst->regs = current->thread.fpu.regs; -} - -/* - * Switches the FP/VX register save area from which to lazy - * restore register contents. - */ -static inline void load_fpu_from(struct fpu *from) -{ - current->thread.fpu.fpc = from->fpc; - current->thread.fpu.regs = from->regs; -} - void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { /* Save host register state */ save_fpu_regs(); - save_fpu_to(&vcpu->arch.host_fpregs); - - if (test_kvm_facility(vcpu->kvm, 129)) { - current->thread.fpu.fpc = vcpu->run->s.regs.fpc; - /* - * Use the register save area in the SIE-control block - * for register restore and save in kvm_arch_vcpu_put() - */ - current->thread.fpu.vxrs = - (__vector128 *)&vcpu->run->s.regs.vrs; - } else - load_fpu_from(&vcpu->arch.guest_fpregs); + vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc; + vcpu->arch.host_fpregs.regs = current->thread.fpu.regs; + /* Depending on MACHINE_HAS_VX, data stored to vrs either + * has vector register or floating point register format. + */ + current->thread.fpu.regs = vcpu->run->s.regs.vrs; + current->thread.fpu.fpc = vcpu->run->s.regs.fpc; if (test_fp_ctl(current->thread.fpu.fpc)) /* User space provided an invalid FPC, let's clear it */ current->thread.fpu.fpc = 0; @@ -1476,19 +1450,13 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) atomic_andnot(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); gmap_disable(vcpu->arch.gmap); + /* Save guest register state */ save_fpu_regs(); + vcpu->run->s.regs.fpc = current->thread.fpu.fpc; - if (test_kvm_facility(vcpu->kvm, 129)) - /* - * kvm_arch_vcpu_load() set up the register save area to - * the &vcpu->run->s.regs.vrs and, thus, the vector registers - * are already saved. Only the floating-point control must be - * copied. - */ - vcpu->run->s.regs.fpc = current->thread.fpu.fpc; - else - save_fpu_to(&vcpu->arch.guest_fpregs); - load_fpu_from(&vcpu->arch.host_fpregs); + /* Restore host register state */ + current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc; + current->thread.fpu.regs = vcpu->arch.host_fpregs.regs; save_access_regs(vcpu->run->s.regs.acrs); restore_access_regs(vcpu->arch.host_acrs); @@ -1506,8 +1474,9 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu) memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64)); vcpu->arch.sie_block->gcr[0] = 0xE0UL; vcpu->arch.sie_block->gcr[14] = 0xC2000000UL; - vcpu->arch.guest_fpregs.fpc = 0; - asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc)); + /* make sure the new fpc will be lazily loaded */ + save_fpu_regs(); + current->thread.fpu.fpc = 0; vcpu->arch.sie_block->gbea = 1; vcpu->arch.sie_block->pp = 0; vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; @@ -1648,17 +1617,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, vcpu->arch.local_int.wq = &vcpu->wq; vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags; - /* - * Allocate a save area for floating-point registers. If the vector - * extension is available, register contents are saved in the SIE - * control block. The allocated save area is still required in - * particular places, for example, in kvm_s390_vcpu_store_status(). - */ - vcpu->arch.guest_fpregs.fprs = kzalloc(sizeof(freg_t) * __NUM_FPRS, - GFP_KERNEL); - if (!vcpu->arch.guest_fpregs.fprs) - goto out_free_sie_block; - rc = kvm_vcpu_init(vcpu, kvm, id); if (rc) goto out_free_sie_block; @@ -1879,19 +1837,27 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { + /* make sure the new values will be lazily loaded */ + save_fpu_regs(); if (test_fp_ctl(fpu->fpc)) return -EINVAL; - memcpy(vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs)); - vcpu->arch.guest_fpregs.fpc = fpu->fpc; - save_fpu_regs(); - load_fpu_from(&vcpu->arch.guest_fpregs); + current->thread.fpu.fpc = fpu->fpc; + if (MACHINE_HAS_VX) + convert_fp_to_vx(current->thread.fpu.vxrs, (freg_t *)fpu->fprs); + else + memcpy(current->thread.fpu.fprs, &fpu->fprs, sizeof(fpu->fprs)); return 0; } int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { - memcpy(&fpu->fprs, vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs)); - fpu->fpc = vcpu->arch.guest_fpregs.fpc; + /* make sure we have the latest values */ + save_fpu_regs(); + if (MACHINE_HAS_VX) + convert_vx_to_fp((freg_t *)fpu->fprs, current->thread.fpu.vxrs); + else + memcpy(fpu->fprs, current->thread.fpu.fprs, sizeof(fpu->fprs)); + fpu->fpc = current->thread.fpu.fpc; return 0; } @@ -2396,6 +2362,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa) { unsigned char archmode = 1; + freg_t fprs[NUM_FPRS]; unsigned int px; u64 clkcomp; int rc; @@ -2411,8 +2378,16 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa) gpa = px; } else gpa -= __LC_FPREGS_SAVE_AREA; - rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA, - vcpu->arch.guest_fpregs.fprs, 128); + + /* manually convert vector registers if necessary */ + if (MACHINE_HAS_VX) { + convert_vx_to_fp(fprs, current->thread.fpu.vxrs); + rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA, + fprs, 128); + } else { + rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA, + vcpu->run->s.regs.vrs, 128); + } rc |= write_guest_abs(vcpu, gpa + __LC_GPREGS_SAVE_AREA, vcpu->run->s.regs.gprs, 128); rc |= write_guest_abs(vcpu, gpa + __LC_PSW_SAVE_AREA, @@ -2420,7 +2395,7 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa) rc |= write_guest_abs(vcpu, gpa + __LC_PREFIX_SAVE_AREA, &px, 4); rc |= write_guest_abs(vcpu, gpa + __LC_FP_CREG_SAVE_AREA, - &vcpu->arch.guest_fpregs.fpc, 4); + &vcpu->run->s.regs.fpc, 4); rc |= write_guest_abs(vcpu, gpa + __LC_TOD_PROGREG_SAVE_AREA, &vcpu->arch.sie_block->todpr, 4); rc |= write_guest_abs(vcpu, gpa + __LC_CPU_TIMER_SAVE_AREA, @@ -2443,19 +2418,7 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) * it into the save area */ save_fpu_regs(); - if (test_kvm_facility(vcpu->kvm, 129)) { - /* - * If the vector extension is available, the vector registers - * which overlaps with floating-point registers are saved in - * the SIE-control block. Hence, extract the floating-point - * registers and the FPC value and store them in the - * guest_fpregs structure. - */ - vcpu->arch.guest_fpregs.fpc = current->thread.fpu.fpc; - convert_vx_to_fp(vcpu->arch.guest_fpregs.fprs, - current->thread.fpu.vxrs); - } else - save_fpu_to(&vcpu->arch.guest_fpregs); + vcpu->run->s.regs.fpc = current->thread.fpu.fpc; save_access_regs(vcpu->run->s.regs.acrs); return kvm_s390_store_status_unloaded(vcpu, addr); diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 1b903f6ad54a..791a4146052c 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -228,7 +228,7 @@ static inline void report_user_fault(struct pt_regs *regs, long signr) return; printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d ", regs->int_code & 0xffff, regs->int_code >> 17); - print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); + print_vma_addr(KERN_CONT "in ", regs->psw.addr); printk(KERN_CONT "\n"); printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n", regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long); @@ -256,9 +256,9 @@ static noinline void do_no_context(struct pt_regs *regs) const struct exception_table_entry *fixup; /* Are we prepared to handle this kernel fault? */ - fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); + fixup = search_exception_tables(regs->psw.addr); if (fixup) { - regs->psw.addr = extable_fixup(fixup) | PSW_ADDR_AMODE; + regs->psw.addr = extable_fixup(fixup); return; } diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index c722400c7697..73e290337092 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -98,7 +98,7 @@ void __init paging_init(void) __ctl_load(S390_lowcore.kernel_asce, 1, 1); __ctl_load(S390_lowcore.kernel_asce, 7, 7); __ctl_load(S390_lowcore.kernel_asce, 13, 13); - arch_local_irq_restore(4UL << (BITS_PER_LONG - 8)); + __arch_local_irq_stosm(0x04); sparse_memory_present_with_active_regions(MAX_NUMNODES); sparse_init(); diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index ea01477b4aa6..45c4daa49930 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -169,12 +169,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, int s390_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) { - if (is_compat_task() || (TASK_SIZE >= (1UL << 53))) + if (is_compat_task() || TASK_SIZE >= TASK_MAX_SIZE) return 0; if (!(flags & MAP_FIXED)) addr = 0; if ((addr + len) >= TASK_SIZE) - return crst_table_upgrade(current->mm, 1UL << 53); + return crst_table_upgrade(current->mm, TASK_MAX_SIZE); return 0; } @@ -189,9 +189,9 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); if (!(area & ~PAGE_MASK)) return area; - if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) { + if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) { /* Upgrade the page table to 4 levels and retry. */ - rc = crst_table_upgrade(mm, 1UL << 53); + rc = crst_table_upgrade(mm, TASK_MAX_SIZE); if (rc) return (unsigned long) rc; area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); @@ -211,9 +211,9 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); if (!(area & ~PAGE_MASK)) return area; - if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) { + if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) { /* Upgrade the page table to 4 levels and retry. */ - rc = crst_table_upgrade(mm, 1UL << 53); + rc = crst_table_upgrade(mm, TASK_MAX_SIZE); if (rc) return (unsigned long) rc; area = arch_get_unmapped_area_topdown(filp, addr, len, diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index a809fa8e6f8b..5109827883ac 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -55,7 +55,7 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long limit) unsigned long entry; int flush; - BUG_ON(limit > (1UL << 53)); + BUG_ON(limit > TASK_MAX_SIZE); flush = 0; repeat: table = crst_table_alloc(mm); diff --git a/arch/s390/numa/numa.c b/arch/s390/numa/numa.c index 43f32ce60aa3..2794845061c6 100644 --- a/arch/s390/numa/numa.c +++ b/arch/s390/numa/numa.c @@ -57,9 +57,7 @@ static __init pg_data_t *alloc_node_data(void) { pg_data_t *res; - res = (pg_data_t *) memblock_alloc(sizeof(pg_data_t), 1); - if (!res) - panic("Could not allocate memory for node data!\n"); + res = (pg_data_t *) memblock_alloc(sizeof(pg_data_t), 8); memset(res, 0, sizeof(pg_data_t)); return res; } @@ -162,7 +160,7 @@ static int __init numa_init_late(void) register_one_node(nid); return 0; } -device_initcall(numa_init_late); +arch_initcall(numa_init_late); static int __init parse_debug(char *parm) { diff --git a/arch/s390/oprofile/backtrace.c b/arch/s390/oprofile/backtrace.c index 8a6811b2cdb9..1884e1759529 100644 --- a/arch/s390/oprofile/backtrace.c +++ b/arch/s390/oprofile/backtrace.c @@ -16,24 +16,23 @@ __show_trace(unsigned int *depth, unsigned long sp, struct pt_regs *regs; while (*depth) { - sp = sp & PSW_ADDR_INSN; if (sp < low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; (*depth)--; - oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN); + oprofile_add_trace(sf->gprs[8]); /* Follow the backchain. */ while (*depth) { low = sp; - sp = sf->back_chain & PSW_ADDR_INSN; + sp = sf->back_chain; if (!sp) break; if (sp <= low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; (*depth)--; - oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN); + oprofile_add_trace(sf->gprs[8]); } @@ -46,7 +45,7 @@ __show_trace(unsigned int *depth, unsigned long sp, return sp; regs = (struct pt_regs *) sp; (*depth)--; - oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN); + oprofile_add_trace(sf->gprs[8]); low = sp; sp = regs->gprs[15]; } @@ -55,12 +54,13 @@ __show_trace(unsigned int *depth, unsigned long sp, void s390_backtrace(struct pt_regs * const regs, unsigned int depth) { - unsigned long head; + unsigned long head, frame_size; struct stack_frame* head_sf; if (user_mode(regs)) return; + frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); head = regs->gprs[15]; head_sf = (struct stack_frame*)head; @@ -69,8 +69,9 @@ void s390_backtrace(struct pt_regs * const regs, unsigned int depth) head = head_sf->back_chain; - head = __show_trace(&depth, head, S390_lowcore.async_stack - ASYNC_SIZE, - S390_lowcore.async_stack); + head = __show_trace(&depth, head, + S390_lowcore.async_stack + frame_size - ASYNC_SIZE, + S390_lowcore.async_stack + frame_size); __show_trace(&depth, head, S390_lowcore.thread_info, S390_lowcore.thread_info + THREAD_SIZE); diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 11d4f277e9f6..8f19c8f9d660 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -68,9 +68,12 @@ static struct airq_struct zpci_airq = { .isc = PCI_ISC, }; -/* I/O Map */ +#define ZPCI_IOMAP_ENTRIES \ + min(((unsigned long) CONFIG_PCI_NR_FUNCTIONS * PCI_BAR_COUNT), \ + ZPCI_IOMAP_MAX_ENTRIES) + static DEFINE_SPINLOCK(zpci_iomap_lock); -static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); +static unsigned long *zpci_iomap_bitmap; struct zpci_iomap_entry *zpci_iomap_start; EXPORT_SYMBOL_GPL(zpci_iomap_start); @@ -265,27 +268,20 @@ void __iomem *pci_iomap_range(struct pci_dev *pdev, unsigned long max) { struct zpci_dev *zdev = to_zpci(pdev); - u64 addr; int idx; - if ((bar & 7) != bar) + if (!pci_resource_len(pdev, bar)) return NULL; idx = zdev->bars[bar].map_idx; spin_lock(&zpci_iomap_lock); - if (zpci_iomap_start[idx].count++) { - BUG_ON(zpci_iomap_start[idx].fh != zdev->fh || - zpci_iomap_start[idx].bar != bar); - } else { - zpci_iomap_start[idx].fh = zdev->fh; - zpci_iomap_start[idx].bar = bar; - } /* Detect overrun */ - BUG_ON(!zpci_iomap_start[idx].count); + WARN_ON(!++zpci_iomap_start[idx].count); + zpci_iomap_start[idx].fh = zdev->fh; + zpci_iomap_start[idx].bar = bar; spin_unlock(&zpci_iomap_lock); - addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48); - return (void __iomem *) addr + offset; + return (void __iomem *) ZPCI_ADDR(idx) + offset; } EXPORT_SYMBOL(pci_iomap_range); @@ -297,12 +293,11 @@ EXPORT_SYMBOL(pci_iomap); void pci_iounmap(struct pci_dev *pdev, void __iomem *addr) { - unsigned int idx; + unsigned int idx = ZPCI_IDX(addr); - idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48; spin_lock(&zpci_iomap_lock); /* Detect underrun */ - BUG_ON(!zpci_iomap_start[idx].count); + WARN_ON(!zpci_iomap_start[idx].count); if (!--zpci_iomap_start[idx].count) { zpci_iomap_start[idx].fh = 0; zpci_iomap_start[idx].bar = 0; @@ -544,15 +539,15 @@ static void zpci_irq_exit(void) static int zpci_alloc_iomap(struct zpci_dev *zdev) { - int entry; + unsigned long entry; spin_lock(&zpci_iomap_lock); - entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); - if (entry == ZPCI_IOMAP_MAX_ENTRIES) { + entry = find_first_zero_bit(zpci_iomap_bitmap, ZPCI_IOMAP_ENTRIES); + if (entry == ZPCI_IOMAP_ENTRIES) { spin_unlock(&zpci_iomap_lock); return -ENOSPC; } - set_bit(entry, zpci_iomap); + set_bit(entry, zpci_iomap_bitmap); spin_unlock(&zpci_iomap_lock); return entry; } @@ -561,7 +556,7 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) { spin_lock(&zpci_iomap_lock); memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry)); - clear_bit(entry, zpci_iomap); + clear_bit(entry, zpci_iomap_bitmap); spin_unlock(&zpci_iomap_lock); } @@ -611,8 +606,7 @@ static int zpci_setup_bus_resources(struct zpci_dev *zdev, if (zdev->bars[i].val & 4) flags |= IORESOURCE_MEM_64; - addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48); - + addr = ZPCI_ADDR(entry); size = 1UL << zdev->bars[i].size; res = __alloc_res(zdev, addr, size, flags); @@ -873,23 +867,30 @@ static int zpci_mem_init(void) zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb), 16, 0, NULL); if (!zdev_fmb_cache) - goto error_zdev; + goto error_fmb; - /* TODO: use realloc */ - zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), - GFP_KERNEL); + zpci_iomap_start = kcalloc(ZPCI_IOMAP_ENTRIES, + sizeof(*zpci_iomap_start), GFP_KERNEL); if (!zpci_iomap_start) goto error_iomap; - return 0; + zpci_iomap_bitmap = kcalloc(BITS_TO_LONGS(ZPCI_IOMAP_ENTRIES), + sizeof(*zpci_iomap_bitmap), GFP_KERNEL); + if (!zpci_iomap_bitmap) + goto error_iomap_bitmap; + + return 0; +error_iomap_bitmap: + kfree(zpci_iomap_start); error_iomap: kmem_cache_destroy(zdev_fmb_cache); -error_zdev: +error_fmb: return -ENOMEM; } static void zpci_mem_exit(void) { + kfree(zpci_iomap_bitmap); kfree(zpci_iomap_start); kmem_cache_destroy(zdev_fmb_cache); } diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c index 369a3e05d468..b0e04751c5d5 100644 --- a/arch/s390/pci/pci_event.c +++ b/arch/s390/pci/pci_event.c @@ -53,6 +53,11 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf) pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n", pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid); + + if (!pdev) + return; + + pdev->error_state = pci_channel_io_perm_failure; } void zpci_event_error(void *data) diff --git a/arch/score/kernel/setup.c b/arch/score/kernel/setup.c index b48459afefdd..f3a0649ab521 100644 --- a/arch/score/kernel/setup.c +++ b/arch/score/kernel/setup.c @@ -101,7 +101,7 @@ static void __init resource_init(void) res->name = "System RAM"; res->start = MEMORY_START; res->end = MEMORY_START + MEMORY_SIZE - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); request_resource(res, &code_resource); diff --git a/arch/sh/include/asm/barrier.h b/arch/sh/include/asm/barrier.h index f887c6465a82..8a84e05adb2e 100644 --- a/arch/sh/include/asm/barrier.h +++ b/arch/sh/include/asm/barrier.h @@ -33,7 +33,6 @@ #endif #define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0) -#define smp_store_mb(var, value) __smp_store_mb(var, value) #include diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index de19cfa768f2..3f1c18b28e8a 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -78,17 +78,17 @@ static char __initdata command_line[COMMAND_LINE_SIZE] = { 0, }; static struct resource code_resource = { .name = "Kernel code", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, }; static struct resource data_resource = { .name = "Kernel data", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, }; static struct resource bss_resource = { .name = "Kernel bss", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, }; unsigned long memory_start; @@ -202,7 +202,7 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn, res->name = "System RAM"; res->start = start; res->end = end - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; if (request_resource(&iomem_resource, res)) { pr_err("unable to request memory_resource 0x%lx 0x%lx\n", diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index 1c26d440d288..b6de8b10a55b 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h @@ -422,8 +422,9 @@ #define __NR_listen 354 #define __NR_setsockopt 355 #define __NR_mlock2 356 +#define __NR_copy_file_range 357 -#define NR_syscalls 357 +#define NR_syscalls 358 /* Bitmask values returned from kern_features system call. */ #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 33c02b15f478..a83707c83be8 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -948,7 +948,24 @@ linux_syscall_trace: cmp %o0, 0 bne 3f mov -ENOSYS, %o0 + + /* Syscall tracing can modify the registers. */ + ld [%sp + STACKFRAME_SZ + PT_G1], %g1 + sethi %hi(sys_call_table), %l7 + ld [%sp + STACKFRAME_SZ + PT_I0], %i0 + or %l7, %lo(sys_call_table), %l7 + ld [%sp + STACKFRAME_SZ + PT_I1], %i1 + ld [%sp + STACKFRAME_SZ + PT_I2], %i2 + ld [%sp + STACKFRAME_SZ + PT_I3], %i3 + ld [%sp + STACKFRAME_SZ + PT_I4], %i4 + ld [%sp + STACKFRAME_SZ + PT_I5], %i5 + cmp %g1, NR_syscalls + bgeu 3f + mov -ENOSYS, %o0 + + sll %g1, 2, %l4 mov %i0, %o0 + ld [%l7 + %l4], %l7 mov %i1, %o1 mov %i2, %o2 mov %i3, %o3 diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index f2d30cab5b3f..cd1f592cd347 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -696,14 +696,6 @@ tlb_fixup_done: call __bzero sub %o1, %o0, %o1 -#ifdef CONFIG_LOCKDEP - /* We have this call this super early, as even prom_init can grab - * spinlocks and thus call into the lockdep code. - */ - call lockdep_init - nop -#endif - call prom_init mov %l7, %o0 ! OpenPROM cif handler diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S index afbaba52d2f1..d127130bf424 100644 --- a/arch/sparc/kernel/hvcalls.S +++ b/arch/sparc/kernel/hvcalls.S @@ -338,8 +338,9 @@ ENTRY(sun4v_mach_set_watchdog) mov %o1, %o4 mov HV_FAST_MACH_SET_WATCHDOG, %o5 ta HV_FAST_TRAP + brnz,a,pn %o4, 0f stx %o1, [%o4] - retl +0: retl nop ENDPROC(sun4v_mach_set_watchdog) diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c index a92d5d2c46a3..9e034f29dcc5 100644 --- a/arch/sparc/kernel/sparc_ksyms_64.c +++ b/arch/sparc/kernel/sparc_ksyms_64.c @@ -37,6 +37,7 @@ EXPORT_SYMBOL(sun4v_niagara_getperf); EXPORT_SYMBOL(sun4v_niagara_setperf); EXPORT_SYMBOL(sun4v_niagara2_getperf); EXPORT_SYMBOL(sun4v_niagara2_setperf); +EXPORT_SYMBOL(sun4v_mach_set_watchdog); /* from hweight.S */ EXPORT_SYMBOL(__arch_hweight8); diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index bb0008927598..c4a1b5c40e4e 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -158,7 +158,25 @@ linux_syscall_trace32: add %sp, PTREGS_OFF, %o0 brnz,pn %o0, 3f mov -ENOSYS, %o0 + + /* Syscall tracing can modify the registers. */ + ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 + sethi %hi(sys_call_table32), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 + or %l7, %lo(sys_call_table32), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 + ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2 + ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3 + ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4 + ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5 + + cmp %g1, NR_syscalls + bgeu,pn %xcc, 3f + mov -ENOSYS, %o0 + + sll %g1, 2, %l4 srl %i0, 0, %o0 + lduw [%l7 + %l4], %l7 srl %i4, 0, %o4 srl %i1, 0, %o1 srl %i2, 0, %o2 @@ -170,7 +188,25 @@ linux_syscall_trace: add %sp, PTREGS_OFF, %o0 brnz,pn %o0, 3f mov -ENOSYS, %o0 + + /* Syscall tracing can modify the registers. */ + ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 + sethi %hi(sys_call_table64), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 + or %l7, %lo(sys_call_table64), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 + ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2 + ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3 + ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4 + ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5 + + cmp %g1, NR_syscalls + bgeu,pn %xcc, 3f + mov -ENOSYS, %o0 + + sll %g1, 2, %l4 mov %i0, %o0 + lduw [%l7 + %l4], %l7 mov %i1, %o1 mov %i2, %o2 mov %i3, %o3 diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index e663b6c78de2..6c3dd6c52f8b 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -88,4 +88,4 @@ sys_call_table: /*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr /*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf /*350*/ .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen -/*355*/ .long sys_setsockopt, sys_mlock2 +/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 1557121f4cdc..12b524cfcfa0 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -89,7 +89,7 @@ sys_call_table32: /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf /*350*/ .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen - .word compat_sys_setsockopt, sys_mlock2 + .word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range #endif /* CONFIG_COMPAT */ @@ -170,4 +170,4 @@ sys_call_table: /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf /*350*/ .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen - .word sys_setsockopt, sys_mlock2 + .word sys_setsockopt, sys_mlock2, sys_copy_file_range diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 6f216853f272..1cfe6aab7a11 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -2863,17 +2863,17 @@ void hugetlb_setup(struct pt_regs *regs) static struct resource code_resource = { .name = "Kernel code", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; static struct resource data_resource = { .name = "Kernel data", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; static struct resource bss_resource = { .name = "Kernel bss", - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; static inline resource_size_t compute_kern_paddr(void *addr) @@ -2909,7 +2909,7 @@ static int __init report_memory(void) res->name = "System RAM"; res->start = pavail[i].phys_addr; res->end = pavail[i].phys_addr + pavail[i].reg_size - 1; - res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; + res->flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM; if (insert_resource(&iomem_resource, res) < 0) { pr_warn("Resource insertion failed.\n"); diff --git a/arch/tile/kernel/kgdb.c b/arch/tile/kernel/kgdb.c index a506c2c28943..6ad99925900e 100644 --- a/arch/tile/kernel/kgdb.c +++ b/arch/tile/kernel/kgdb.c @@ -126,15 +126,15 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) { struct pt_regs *thread_regs; + const int NGPRS = TREG_LAST_GPR + 1; if (task == NULL) return; - /* Initialize to zero. */ - memset(gdb_regs, 0, NUMREGBYTES); - thread_regs = task_pt_regs(task); - memcpy(gdb_regs, thread_regs, TREG_LAST_GPR * sizeof(unsigned long)); + memcpy(gdb_regs, thread_regs, NGPRS * sizeof(unsigned long)); + memset(&gdb_regs[NGPRS], 0, + (TILEGX_PC_REGNUM - NGPRS) * sizeof(unsigned long)); gdb_regs[TILEGX_PC_REGNUM] = thread_regs->pc; gdb_regs[TILEGX_FAULTNUM_REGNUM] = thread_regs->faultnum; } diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index bbb855de6569..a992238e9b58 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c @@ -1632,14 +1632,14 @@ static struct resource data_resource = { .name = "Kernel data", .start = 0, .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; static struct resource code_resource = { .name = "Kernel code", .start = 0, .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; /* @@ -1673,10 +1673,15 @@ insert_ram_resource(u64 start_pfn, u64 end_pfn, bool reserved) kzalloc(sizeof(struct resource), GFP_ATOMIC); if (!res) return NULL; - res->name = reserved ? "Reserved" : "System RAM"; res->start = start_pfn << PAGE_SHIFT; res->end = (end_pfn << PAGE_SHIFT) - 1; res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; + if (reserved) { + res->name = "Reserved"; + } else { + res->name = "System RAM"; + res->flags |= IORESOURCE_SYSRAM; + } if (insert_resource(&iomem_resource, res)) { kfree(res); return NULL; diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h index e13d41c392ae..f878bec23576 100644 --- a/arch/um/include/asm/page.h +++ b/arch/um/include/asm/page.h @@ -34,21 +34,18 @@ struct page; #if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64BIT) -typedef struct { unsigned long pte_low, pte_high; } pte_t; +typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; -#define pte_val(x) ((x).pte_low | ((unsigned long long) (x).pte_high << 32)) - -#define pte_get_bits(pte, bits) ((pte).pte_low & (bits)) -#define pte_set_bits(pte, bits) ((pte).pte_low |= (bits)) -#define pte_clear_bits(pte, bits) ((pte).pte_low &= ~(bits)) -#define pte_copy(to, from) ({ (to).pte_high = (from).pte_high; \ - smp_wmb(); \ - (to).pte_low = (from).pte_low; }) -#define pte_is_zero(pte) (!((pte).pte_low & ~_PAGE_NEWPAGE) && !(pte).pte_high) -#define pte_set_val(pte, phys, prot) \ - ({ (pte).pte_high = (phys) >> 32; \ - (pte).pte_low = (phys) | pgprot_val(prot); }) +#define pte_val(p) ((p).pte) + +#define pte_get_bits(p, bits) ((p).pte & (bits)) +#define pte_set_bits(p, bits) ((p).pte |= (bits)) +#define pte_clear_bits(p, bits) ((p).pte &= ~(bits)) +#define pte_copy(to, from) ({ (to).pte = (from).pte; }) +#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEWPAGE)) +#define pte_set_val(p, phys, prot) \ + ({ (p).pte = (phys) | pgprot_val(prot); }) #define pmd_val(x) ((x).pmd) #define __pmd(x) ((pmd_t) { (x) } ) diff --git a/arch/unicore32/include/asm/pci.h b/arch/unicore32/include/asm/pci.h index 38b3f3785c3c..eb9dccecb338 100644 --- a/arch/unicore32/include/asm/pci.h +++ b/arch/unicore32/include/asm/pci.h @@ -14,7 +14,6 @@ #ifdef __KERNEL__ #include -#include #include #include /* for PCIBIOS_MIN_* */ @@ -23,5 +22,4 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); #endif /* __KERNEL__ */ - #endif diff --git a/arch/unicore32/kernel/setup.c b/arch/unicore32/kernel/setup.c index 3fa317f96122..c2bffa5614a4 100644 --- a/arch/unicore32/kernel/setup.c +++ b/arch/unicore32/kernel/setup.c @@ -72,13 +72,13 @@ static struct resource mem_res[] = { .name = "Kernel code", .start = 0, .end = 0, - .flags = IORESOURCE_MEM + .flags = IORESOURCE_SYSTEM_RAM }, { .name = "Kernel data", .start = 0, .end = 0, - .flags = IORESOURCE_MEM + .flags = IORESOURCE_SYSTEM_RAM } }; @@ -211,7 +211,7 @@ request_standard_resources(struct meminfo *mi) res->name = "System RAM"; res->start = mi->bank[i].start; res->end = mi->bank[i].start + mi->bank[i].size - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild index 1538562cc720..eb3abf8ac44e 100644 --- a/arch/x86/Kbuild +++ b/arch/x86/Kbuild @@ -1,6 +1,7 @@ - obj-y += entry/ +obj-$(CONFIG_PERF_EVENTS) += events/ + obj-$(CONFIG_KVM) += kvm/ # Xen paravirtualization support diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 330e738ccfc1..405b1858134b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -509,11 +509,10 @@ config X86_INTEL_CE config X86_INTEL_MID bool "Intel MID platform support" - depends on X86_32 depends on X86_EXTENDED_PLATFORM depends on X86_PLATFORM_DEVICES depends on PCI - depends on PCI_GOANY + depends on X86_64 || (PCI_GOANY && X86_32) depends on X86_IO_APIC select SFI select I2C @@ -1160,22 +1159,23 @@ config MICROCODE bool "CPU microcode loading support" default y depends on CPU_SUP_AMD || CPU_SUP_INTEL - depends on BLK_DEV_INITRD select FW_LOADER ---help--- - If you say Y here, you will be able to update the microcode on - certain Intel and AMD processors. The Intel support is for the - IA32 family, e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4, - Xeon etc. The AMD support is for families 0x10 and later. You will - obviously need the actual microcode binary data itself which is not - shipped with the Linux kernel. - - This option selects the general module only, you need to select - at least one vendor specific module as well. - - To compile this driver as a module, choose M here: the module - will be called microcode. + Intel and AMD processors. The Intel support is for the IA32 family, + e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4, Xeon etc. The + AMD support is for families 0x10 and later. You will obviously need + the actual microcode binary data itself which is not shipped with + the Linux kernel. + + The preferred method to load microcode from a detached initrd is described + in Documentation/x86/early-microcode.txt. For that you need to enable + CONFIG_BLK_DEV_INITRD in order for the loader to be able to scan the + initrd for microcode blobs. + + In addition, you can build-in the microcode into the kernel. For that you + need to enable FIRMWARE_IN_KERNEL and add the vendor-supplied microcode + to the CONFIG_EXTRA_FIRMWARE config option. config MICROCODE_INTEL bool "Intel microcode loading support" diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 9b18ed97a8a2..68a2d1f0a683 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -350,16 +350,6 @@ config DEBUG_IMR_SELFTEST If unsure say N here. -config X86_DEBUG_STATIC_CPU_HAS - bool "Debug alternatives" - depends on DEBUG_KERNEL - ---help--- - This option causes additional code to be generated which - fails if static_cpu_has() is used before alternatives have - run. - - If unsure, say N. - config X86_DEBUG_FPU bool "Debug the x86 FPU code" depends on DEBUG_KERNEL diff --git a/arch/x86/boot/cpuflags.h b/arch/x86/boot/cpuflags.h index ea97697e51e4..4cb404fd45ce 100644 --- a/arch/x86/boot/cpuflags.h +++ b/arch/x86/boot/cpuflags.h @@ -1,7 +1,7 @@ #ifndef BOOT_CPUFLAGS_H #define BOOT_CPUFLAGS_H -#include +#include #include struct cpu_features { diff --git a/arch/x86/boot/mkcpustr.c b/arch/x86/boot/mkcpustr.c index 637097e66a62..f72498dc90d2 100644 --- a/arch/x86/boot/mkcpustr.c +++ b/arch/x86/boot/mkcpustr.c @@ -17,7 +17,7 @@ #include "../include/asm/required-features.h" #include "../include/asm/disabled-features.h" -#include "../include/asm/cpufeature.h" +#include "../include/asm/cpufeatures.h" #include "../kernel/cpu/capflags.c" int main(void) diff --git a/arch/x86/crypto/chacha20-ssse3-x86_64.S b/arch/x86/crypto/chacha20-ssse3-x86_64.S index 712b13047b41..3a33124e9112 100644 --- a/arch/x86/crypto/chacha20-ssse3-x86_64.S +++ b/arch/x86/crypto/chacha20-ssse3-x86_64.S @@ -157,7 +157,9 @@ ENTRY(chacha20_4block_xor_ssse3) # done with the slightly better performing SSSE3 byte shuffling, # 7/12-bit word rotation uses traditional shift+OR. - sub $0x40,%rsp + mov %rsp,%r11 + sub $0x80,%rsp + and $~63,%rsp # x0..15[0-3] = s0..3[0..3] movq 0x00(%rdi),%xmm1 @@ -620,6 +622,6 @@ ENTRY(chacha20_4block_xor_ssse3) pxor %xmm1,%xmm15 movdqu %xmm15,0xf0(%rsi) - add $0x40,%rsp + mov %r11,%rsp ret ENDPROC(chacha20_4block_xor_ssse3) diff --git a/arch/x86/crypto/crc32-pclmul_glue.c b/arch/x86/crypto/crc32-pclmul_glue.c index 07d2c6c86a54..27226df3f7d8 100644 --- a/arch/x86/crypto/crc32-pclmul_glue.c +++ b/arch/x86/crypto/crc32-pclmul_glue.c @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c index 0e9871693f24..0857b1a1de3b 100644 --- a/arch/x86/crypto/crc32c-intel_glue.c +++ b/arch/x86/crypto/crc32c-intel_glue.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include diff --git a/arch/x86/crypto/crct10dif-pclmul_glue.c b/arch/x86/crypto/crct10dif-pclmul_glue.c index a3fcfc97a311..cd4df9322501 100644 --- a/arch/x86/crypto/crct10dif-pclmul_glue.c +++ b/arch/x86/crypto/crct10dif-pclmul_glue.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include asmlinkage __u16 crc_t10dif_pcl(__u16 crc, const unsigned char *buf, diff --git a/arch/x86/crypto/sha-mb/sha1_mb.c b/arch/x86/crypto/sha-mb/sha1_mb.c index a841e9765bd6..a8a0224fa0f8 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb.c +++ b/arch/x86/crypto/sha-mb/sha1_mb.c @@ -762,6 +762,38 @@ static int sha1_mb_async_digest(struct ahash_request *req) return crypto_ahash_digest(mcryptd_req); } +static int sha1_mb_async_export(struct ahash_request *req, void *out) +{ + struct ahash_request *mcryptd_req = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm); + struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm; + + memcpy(mcryptd_req, req, sizeof(*req)); + ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base); + return crypto_ahash_export(mcryptd_req, out); +} + +static int sha1_mb_async_import(struct ahash_request *req, const void *in) +{ + struct ahash_request *mcryptd_req = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm); + struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm; + struct crypto_shash *child = mcryptd_ahash_child(mcryptd_tfm); + struct mcryptd_hash_request_ctx *rctx; + struct shash_desc *desc; + + memcpy(mcryptd_req, req, sizeof(*req)); + ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base); + rctx = ahash_request_ctx(mcryptd_req); + desc = &rctx->desc; + desc->tfm = child; + desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + + return crypto_ahash_import(mcryptd_req, in); +} + static int sha1_mb_async_init_tfm(struct crypto_tfm *tfm) { struct mcryptd_ahash *mcryptd_tfm; @@ -796,8 +828,11 @@ static struct ahash_alg sha1_mb_async_alg = { .final = sha1_mb_async_final, .finup = sha1_mb_async_finup, .digest = sha1_mb_async_digest, + .export = sha1_mb_async_export, + .import = sha1_mb_async_import, .halg = { .digestsize = SHA1_DIGEST_SIZE, + .statesize = sizeof(struct sha1_hash_ctx), .base = { .cra_name = "sha1", .cra_driver_name = "sha1_mb", diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S b/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S index 2ab9560b53c8..c420d89b175f 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S +++ b/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S @@ -197,7 +197,7 @@ len_is_0: vpinsrd $1, _args_digest+1*32(state , idx, 4), %xmm0, %xmm0 vpinsrd $2, _args_digest+2*32(state , idx, 4), %xmm0, %xmm0 vpinsrd $3, _args_digest+3*32(state , idx, 4), %xmm0, %xmm0 - movl 4*32(state, idx, 4), DWORD_tmp + movl _args_digest+4*32(state, idx, 4), DWORD_tmp vmovdqu %xmm0, _result_digest(job_rax) movl DWORD_tmp, _result_digest+1*16(job_rax) diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index e32206e09868..9a9e5884066c 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h @@ -201,37 +201,6 @@ For 32-bit we have the following conventions - kernel is built with .byte 0xf1 .endm -#else /* CONFIG_X86_64 */ - -/* - * For 32bit only simplified versions of SAVE_ALL/RESTORE_ALL. These - * are different from the entry_32.S versions in not changing the segment - * registers. So only suitable for in kernel use, not when transitioning - * from or to user space. The resulting stack frame is not a standard - * pt_regs frame. The main use case is calling C code from assembler - * when all the registers need to be preserved. - */ - - .macro SAVE_ALL - pushl %eax - pushl %ebp - pushl %edi - pushl %esi - pushl %edx - pushl %ecx - pushl %ebx - .endm - - .macro RESTORE_ALL - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp - popl %eax - .endm - #endif /* CONFIG_X86_64 */ /* diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 03663740c866..c6ab2ebb5f4f 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -26,6 +26,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -344,6 +345,32 @@ __visible inline void syscall_return_slowpath(struct pt_regs *regs) prepare_exit_to_usermode(regs); } +#ifdef CONFIG_X86_64 +__visible void do_syscall_64(struct pt_regs *regs) +{ + struct thread_info *ti = pt_regs_to_thread_info(regs); + unsigned long nr = regs->orig_ax; + + local_irq_enable(); + + if (READ_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY) + nr = syscall_trace_enter(regs); + + /* + * NB: Native and x32 syscalls are dispatched from the same + * table. The only functional difference is the x32 bit in + * regs->orig_ax, which changes the behavior of some syscalls. + */ + if (likely((nr & __SYSCALL_MASK) < NR_syscalls)) { + regs->ax = sys_call_table[nr & __SYSCALL_MASK]( + regs->di, regs->si, regs->dx, + regs->r10, regs->r8, regs->r9); + } + + syscall_return_slowpath(regs); +} +#endif + #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) /* * Does a 32-bit syscall. Called with IRQs on and does all entry and diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index 77d8c5112900..4c5228352744 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 9d34d3cfceb6..70eadb0ea5fa 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -145,17 +145,11 @@ GLOBAL(entry_SYSCALL_64_after_swapgs) movq %rsp, PER_CPU_VAR(rsp_scratch) movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp + TRACE_IRQS_OFF + /* Construct struct pt_regs on stack */ pushq $__USER_DS /* pt_regs->ss */ pushq PER_CPU_VAR(rsp_scratch) /* pt_regs->sp */ - /* - * Re-enable interrupts. - * We use 'rsp_scratch' as a scratch space, hence irq-off block above - * must execute atomically in the face of possible interrupt-driven - * task preemption. We must enable interrupts only after we're done - * with using rsp_scratch: - */ - ENABLE_INTERRUPTS(CLBR_NONE) pushq %r11 /* pt_regs->flags */ pushq $__USER_CS /* pt_regs->cs */ pushq %rcx /* pt_regs->ip */ @@ -171,9 +165,21 @@ GLOBAL(entry_SYSCALL_64_after_swapgs) pushq %r11 /* pt_regs->r11 */ sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */ - testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) - jnz tracesys + /* + * If we need to do entry work or if we guess we'll need to do + * exit work, go straight to the slow path. + */ + testl $_TIF_WORK_SYSCALL_ENTRY|_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) + jnz entry_SYSCALL64_slow_path + entry_SYSCALL_64_fastpath: + /* + * Easy case: enable interrupts and issue the syscall. If the syscall + * needs pt_regs, we'll call a stub that disables interrupts again + * and jumps to the slow path. + */ + TRACE_IRQS_ON + ENABLE_INTERRUPTS(CLBR_NONE) #if __SYSCALL_MASK == ~0 cmpq $__NR_syscall_max, %rax #else @@ -182,103 +188,56 @@ entry_SYSCALL_64_fastpath: #endif ja 1f /* return -ENOSYS (already in pt_regs->ax) */ movq %r10, %rcx + + /* + * This call instruction is handled specially in stub_ptregs_64. + * It might end up jumping to the slow path. If it jumps, RAX + * and all argument registers are clobbered. + */ call *sys_call_table(, %rax, 8) +.Lentry_SYSCALL_64_after_fastpath_call: + movq %rax, RAX(%rsp) 1: -/* - * Syscall return path ending with SYSRET (fast path). - * Has incompletely filled pt_regs. - */ - LOCKDEP_SYS_EXIT - /* - * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON, - * it is too small to ever cause noticeable irq latency. - */ - DISABLE_INTERRUPTS(CLBR_NONE) /* - * We must check ti flags with interrupts (or at least preemption) - * off because we must *never* return to userspace without - * processing exit work that is enqueued if we're preempted here. - * In particular, returning to userspace with any of the one-shot - * flags (TIF_NOTIFY_RESUME, TIF_USER_RETURN_NOTIFY, etc) set is - * very bad. + * If we get here, then we know that pt_regs is clean for SYSRET64. + * If we see that no exit work is required (which we are required + * to check with IRQs off), then we can go straight to SYSRET64. */ + DISABLE_INTERRUPTS(CLBR_NONE) + TRACE_IRQS_OFF testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) - jnz int_ret_from_sys_call_irqs_off /* Go to the slow path */ + jnz 1f - RESTORE_C_REGS_EXCEPT_RCX_R11 + LOCKDEP_SYS_EXIT + TRACE_IRQS_ON /* user mode is traced as IRQs on */ movq RIP(%rsp), %rcx movq EFLAGS(%rsp), %r11 + RESTORE_C_REGS_EXCEPT_RCX_R11 movq RSP(%rsp), %rsp - /* - * 64-bit SYSRET restores rip from rcx, - * rflags from r11 (but RF and VM bits are forced to 0), - * cs and ss are loaded from MSRs. - * Restoration of rflags re-enables interrupts. - * - * NB: On AMD CPUs with the X86_BUG_SYSRET_SS_ATTRS bug, the ss - * descriptor is not reinitialized. This means that we should - * avoid SYSRET with SS == NULL, which could happen if we schedule, - * exit the kernel, and re-enter using an interrupt vector. (All - * interrupt entries on x86_64 set SS to NULL.) We prevent that - * from happening by reloading SS in __switch_to. (Actually - * detecting the failure in 64-bit userspace is tricky but can be - * done.) - */ USERGS_SYSRET64 -GLOBAL(int_ret_from_sys_call_irqs_off) +1: + /* + * The fast path looked good when we started, but something changed + * along the way and we need to switch to the slow path. Calling + * raise(3) will trigger this, for example. IRQs are off. + */ TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_NONE) - jmp int_ret_from_sys_call - - /* Do syscall entry tracing */ -tracesys: - movq %rsp, %rdi - movl $AUDIT_ARCH_X86_64, %esi - call syscall_trace_enter_phase1 - test %rax, %rax - jnz tracesys_phase2 /* if needed, run the slow path */ - RESTORE_C_REGS_EXCEPT_RAX /* else restore clobbered regs */ - movq ORIG_RAX(%rsp), %rax - jmp entry_SYSCALL_64_fastpath /* and return to the fast path */ - -tracesys_phase2: SAVE_EXTRA_REGS movq %rsp, %rdi - movl $AUDIT_ARCH_X86_64, %esi - movq %rax, %rdx - call syscall_trace_enter_phase2 - - /* - * Reload registers from stack in case ptrace changed them. - * We don't reload %rax because syscall_trace_entry_phase2() returned - * the value it wants us to use in the table lookup. - */ - RESTORE_C_REGS_EXCEPT_RAX - RESTORE_EXTRA_REGS -#if __SYSCALL_MASK == ~0 - cmpq $__NR_syscall_max, %rax -#else - andl $__SYSCALL_MASK, %eax - cmpl $__NR_syscall_max, %eax -#endif - ja 1f /* return -ENOSYS (already in pt_regs->ax) */ - movq %r10, %rcx /* fixup for C */ - call *sys_call_table(, %rax, 8) - movq %rax, RAX(%rsp) -1: - /* Use IRET because user could have changed pt_regs->foo */ + call syscall_return_slowpath /* returns with IRQs disabled */ + jmp return_from_SYSCALL_64 -/* - * Syscall return path ending with IRET. - * Has correct iret frame. - */ -GLOBAL(int_ret_from_sys_call) +entry_SYSCALL64_slow_path: + /* IRQs are off. */ SAVE_EXTRA_REGS movq %rsp, %rdi - call syscall_return_slowpath /* returns with IRQs disabled */ + call do_syscall_64 /* returns with IRQs disabled */ + +return_from_SYSCALL_64: RESTORE_EXTRA_REGS TRACE_IRQS_IRETQ /* we're about to change IF */ @@ -355,83 +314,45 @@ opportunistic_sysret_failed: jmp restore_c_regs_and_iret END(entry_SYSCALL_64) +ENTRY(stub_ptregs_64) + /* + * Syscalls marked as needing ptregs land here. + * If we are on the fast path, we need to save the extra regs, + * which we achieve by trying again on the slow path. If we are on + * the slow path, the extra regs are already saved. + * + * RAX stores a pointer to the C function implementing the syscall. + * IRQs are on. + */ + cmpq $.Lentry_SYSCALL_64_after_fastpath_call, (%rsp) + jne 1f - .macro FORK_LIKE func -ENTRY(stub_\func) - SAVE_EXTRA_REGS 8 - jmp sys_\func -END(stub_\func) - .endm - - FORK_LIKE clone - FORK_LIKE fork - FORK_LIKE vfork - -ENTRY(stub_execve) - call sys_execve -return_from_execve: - testl %eax, %eax - jz 1f - /* exec failed, can use fast SYSRET code path in this case */ - ret -1: - /* must use IRET code path (pt_regs->cs may have changed) */ - addq $8, %rsp - ZERO_EXTRA_REGS - movq %rax, RAX(%rsp) - jmp int_ret_from_sys_call -END(stub_execve) -/* - * Remaining execve stubs are only 7 bytes long. - * ENTRY() often aligns to 16 bytes, which in this case has no benefits. - */ - .align 8 -GLOBAL(stub_execveat) - call sys_execveat - jmp return_from_execve -END(stub_execveat) - -#if defined(CONFIG_X86_X32_ABI) - .align 8 -GLOBAL(stub_x32_execve) - call compat_sys_execve - jmp return_from_execve -END(stub_x32_execve) - .align 8 -GLOBAL(stub_x32_execveat) - call compat_sys_execveat - jmp return_from_execve -END(stub_x32_execveat) -#endif - -/* - * sigreturn is special because it needs to restore all registers on return. - * This cannot be done with SYSRET, so use the IRET return path instead. - */ -ENTRY(stub_rt_sigreturn) /* - * SAVE_EXTRA_REGS result is not normally needed: - * sigreturn overwrites all pt_regs->GPREGS. - * But sigreturn can fail (!), and there is no easy way to detect that. - * To make sure RESTORE_EXTRA_REGS doesn't restore garbage on error, - * we SAVE_EXTRA_REGS here. + * Called from fast path -- disable IRQs again, pop return address + * and jump to slow path */ - SAVE_EXTRA_REGS 8 - call sys_rt_sigreturn -return_from_stub: - addq $8, %rsp - RESTORE_EXTRA_REGS - movq %rax, RAX(%rsp) - jmp int_ret_from_sys_call -END(stub_rt_sigreturn) + DISABLE_INTERRUPTS(CLBR_NONE) + TRACE_IRQS_OFF + popq %rax + jmp entry_SYSCALL64_slow_path -#ifdef CONFIG_X86_X32_ABI -ENTRY(stub_x32_rt_sigreturn) - SAVE_EXTRA_REGS 8 - call sys32_x32_rt_sigreturn - jmp return_from_stub -END(stub_x32_rt_sigreturn) -#endif +1: + /* Called from C */ + jmp *%rax /* called from C */ +END(stub_ptregs_64) + +.macro ptregs_stub func +ENTRY(ptregs_\func) + leaq \func(%rip), %rax + jmp stub_ptregs_64 +END(ptregs_\func) +.endm + +/* Instantiate ptregs_stub for each ptregs-using syscall */ +#define __SYSCALL_64_QUAL_(sym) +#define __SYSCALL_64_QUAL_ptregs(sym) ptregs_stub sym +#define __SYSCALL_64(nr, sym, qual) __SYSCALL_64_QUAL_##qual(sym) +#include /* * A newly forked process directly context switches into this address. @@ -439,7 +360,6 @@ END(stub_x32_rt_sigreturn) * rdi: prev task we switched from */ ENTRY(ret_from_fork) - LOCK ; btr $TIF_FORK, TI_flags(%r8) pushq $0x0002 @@ -447,28 +367,32 @@ ENTRY(ret_from_fork) call schedule_tail /* rdi: 'prev' task parameter */ - RESTORE_EXTRA_REGS - testb $3, CS(%rsp) /* from kernel_thread? */ + jnz 1f /* - * By the time we get here, we have no idea whether our pt_regs, - * ti flags, and ti status came from the 64-bit SYSCALL fast path, - * the slow path, or one of the 32-bit compat paths. - * Use IRET code path to return, since it can safely handle - * all of the above. + * We came from kernel_thread. This code path is quite twisted, and + * someone should clean it up. + * + * copy_thread_tls stashes the function pointer in RBX and the + * parameter to be passed in RBP. The called function is permitted + * to call do_execve and thereby jump to user mode. */ - jnz int_ret_from_sys_call + movq RBP(%rsp), %rdi + call *RBX(%rsp) + movl $0, RAX(%rsp) /* - * We came from kernel_thread - * nb: we depend on RESTORE_EXTRA_REGS above + * Fall through as though we're exiting a syscall. This makes a + * twisted sort of sense if we just called do_execve. */ - movq %rbp, %rdi - call *%rbx - movl $0, RAX(%rsp) - RESTORE_EXTRA_REGS - jmp int_ret_from_sys_call + +1: + movq %rsp, %rdi + call syscall_return_slowpath /* returns with IRQs disabled */ + TRACE_IRQS_ON /* user mode is traced as IRQS on */ + SWAPGS + jmp restore_regs_and_iret END(ret_from_fork) /* diff --git a/arch/x86/entry/syscall_32.c b/arch/x86/entry/syscall_32.c index 9a6649857106..8f895ee13a1c 100644 --- a/arch/x86/entry/syscall_32.c +++ b/arch/x86/entry/syscall_32.c @@ -6,17 +6,11 @@ #include #include -#ifdef CONFIG_IA32_EMULATION -#define SYM(sym, compat) compat -#else -#define SYM(sym, compat) sym -#endif - -#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage long SYM(sym, compat)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; +#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; #include #undef __SYSCALL_I386 -#define __SYSCALL_I386(nr, sym, compat) [nr] = SYM(sym, compat), +#define __SYSCALL_I386(nr, sym, qual) [nr] = sym, extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); diff --git a/arch/x86/entry/syscall_64.c b/arch/x86/entry/syscall_64.c index 41283d22be7a..9dbc5abb6162 100644 --- a/arch/x86/entry/syscall_64.c +++ b/arch/x86/entry/syscall_64.c @@ -6,19 +6,14 @@ #include #include -#define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat) +#define __SYSCALL_64_QUAL_(sym) sym +#define __SYSCALL_64_QUAL_ptregs(sym) ptregs_##sym -#ifdef CONFIG_X86_X32_ABI -# define __SYSCALL_X32(nr, sym, compat) __SYSCALL_64(nr, sym, compat) -#else -# define __SYSCALL_X32(nr, sym, compat) /* nothing */ -#endif - -#define __SYSCALL_64(nr, sym, compat) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; +#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long __SYSCALL_64_QUAL_##qual(sym)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); #include #undef __SYSCALL_64 -#define __SYSCALL_64(nr, sym, compat) [nr] = sym, +#define __SYSCALL_64(nr, sym, qual) [nr] = __SYSCALL_64_QUAL_##qual(sym), extern long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index dc1040a50bdc..2e5b565adacc 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -21,7 +21,7 @@ 12 common brk sys_brk 13 64 rt_sigaction sys_rt_sigaction 14 common rt_sigprocmask sys_rt_sigprocmask -15 64 rt_sigreturn stub_rt_sigreturn +15 64 rt_sigreturn sys_rt_sigreturn/ptregs 16 64 ioctl sys_ioctl 17 common pread64 sys_pread64 18 common pwrite64 sys_pwrite64 @@ -62,10 +62,10 @@ 53 common socketpair sys_socketpair 54 64 setsockopt sys_setsockopt 55 64 getsockopt sys_getsockopt -56 common clone stub_clone -57 common fork stub_fork -58 common vfork stub_vfork -59 64 execve stub_execve +56 common clone sys_clone/ptregs +57 common fork sys_fork/ptregs +58 common vfork sys_vfork/ptregs +59 64 execve sys_execve/ptregs 60 common exit sys_exit 61 common wait4 sys_wait4 62 common kill sys_kill @@ -178,7 +178,7 @@ 169 common reboot sys_reboot 170 common sethostname sys_sethostname 171 common setdomainname sys_setdomainname -172 common iopl sys_iopl +172 common iopl sys_iopl/ptregs 173 common ioperm sys_ioperm 174 64 create_module 175 common init_module sys_init_module @@ -328,7 +328,7 @@ 319 common memfd_create sys_memfd_create 320 common kexec_file_load sys_kexec_file_load 321 common bpf sys_bpf -322 64 execveat stub_execveat +322 64 execveat sys_execveat/ptregs 323 common userfaultfd sys_userfaultfd 324 common membarrier sys_membarrier 325 common mlock2 sys_mlock2 @@ -339,14 +339,14 @@ # for native 64-bit operation. # 512 x32 rt_sigaction compat_sys_rt_sigaction -513 x32 rt_sigreturn stub_x32_rt_sigreturn +513 x32 rt_sigreturn sys32_x32_rt_sigreturn 514 x32 ioctl compat_sys_ioctl 515 x32 readv compat_sys_readv 516 x32 writev compat_sys_writev 517 x32 recvfrom compat_sys_recvfrom 518 x32 sendmsg compat_sys_sendmsg 519 x32 recvmsg compat_sys_recvmsg -520 x32 execve stub_x32_execve +520 x32 execve compat_sys_execve/ptregs 521 x32 ptrace compat_sys_ptrace 522 x32 rt_sigpending compat_sys_rt_sigpending 523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait @@ -371,4 +371,4 @@ 542 x32 getsockopt compat_sys_getsockopt 543 x32 io_setup compat_sys_io_setup 544 x32 io_submit compat_sys_io_submit -545 x32 execveat stub_x32_execveat +545 x32 execveat compat_sys_execveat/ptregs diff --git a/arch/x86/entry/syscalls/syscalltbl.sh b/arch/x86/entry/syscalls/syscalltbl.sh index 0e7f8ec071e7..cd3d3015d7df 100644 --- a/arch/x86/entry/syscalls/syscalltbl.sh +++ b/arch/x86/entry/syscalls/syscalltbl.sh @@ -3,13 +3,63 @@ in="$1" out="$2" +syscall_macro() { + abi="$1" + nr="$2" + entry="$3" + + # Entry can be either just a function name or "function/qualifier" + real_entry="${entry%%/*}" + qualifier="${entry:${#real_entry}}" # Strip the function name + qualifier="${qualifier:1}" # Strip the slash, if any + + echo "__SYSCALL_${abi}($nr, $real_entry, $qualifier)" +} + +emit() { + abi="$1" + nr="$2" + entry="$3" + compat="$4" + + if [ "$abi" == "64" -a -n "$compat" ]; then + echo "a compat entry for a 64-bit syscall makes no sense" >&2 + exit 1 + fi + + if [ -z "$compat" ]; then + if [ -n "$entry" ]; then + syscall_macro "$abi" "$nr" "$entry" + fi + else + echo "#ifdef CONFIG_X86_32" + if [ -n "$entry" ]; then + syscall_macro "$abi" "$nr" "$entry" + fi + echo "#else" + syscall_macro "$abi" "$nr" "$compat" + echo "#endif" + fi +} + grep '^[0-9]' "$in" | sort -n | ( while read nr abi name entry compat; do abi=`echo "$abi" | tr '[a-z]' '[A-Z]'` - if [ -n "$compat" ]; then - echo "__SYSCALL_${abi}($nr, $entry, $compat)" - elif [ -n "$entry" ]; then - echo "__SYSCALL_${abi}($nr, $entry, $entry)" + if [ "$abi" == "COMMON" -o "$abi" == "64" ]; then + # COMMON is the same as 64, except that we don't expect X32 + # programs to use it. Our expectation has nothing to do with + # any generated code, so treat them the same. + emit 64 "$nr" "$entry" "$compat" + elif [ "$abi" == "X32" ]; then + # X32 is equivalent to 64 on an X32-compatible kernel. + echo "#ifdef CONFIG_X86_X32_ABI" + emit 64 "$nr" "$entry" "$compat" + echo "#endif" + elif [ "$abi" == "I386" ]; then + emit "$abi" "$nr" "$entry" "$compat" + else + echo "Unknown abi $abi" >&2 + exit 1 fi done ) > "$out" diff --git a/arch/x86/entry/vdso/vdso2c.h b/arch/x86/entry/vdso/vdso2c.h index 0224987556ce..abe961c7c71c 100644 --- a/arch/x86/entry/vdso/vdso2c.h +++ b/arch/x86/entry/vdso/vdso2c.h @@ -150,16 +150,9 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len, } fprintf(outfile, "\n};\n\n"); - fprintf(outfile, "static struct page *pages[%lu];\n\n", - mapping_size / 4096); - fprintf(outfile, "const struct vdso_image %s = {\n", name); fprintf(outfile, "\t.data = raw_data,\n"); fprintf(outfile, "\t.size = %lu,\n", mapping_size); - fprintf(outfile, "\t.text_mapping = {\n"); - fprintf(outfile, "\t\t.name = \"[vdso]\",\n"); - fprintf(outfile, "\t\t.pages = pages,\n"); - fprintf(outfile, "\t},\n"); if (alt_sec) { fprintf(outfile, "\t.alt = %lu,\n", (unsigned long)GET_LE(&alt_sec->sh_offset)); diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c index 08a317a9ae4b..7853b53959cd 100644 --- a/arch/x86/entry/vdso/vdso32-setup.c +++ b/arch/x86/entry/vdso/vdso32-setup.c @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/arch/x86/entry/vdso/vdso32/system_call.S b/arch/x86/entry/vdso/vdso32/system_call.S index 3a1d9297074b..0109ac6cb79c 100644 --- a/arch/x86/entry/vdso/vdso32/system_call.S +++ b/arch/x86/entry/vdso/vdso32/system_call.S @@ -3,7 +3,7 @@ */ #include -#include +#include #include /* diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index b8f69e264ac4..10f704584922 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -20,6 +20,7 @@ #include #include #include +#include #if defined(CONFIG_X86_64) unsigned int __read_mostly vdso64_enabled = 1; @@ -27,13 +28,7 @@ unsigned int __read_mostly vdso64_enabled = 1; void __init init_vdso_image(const struct vdso_image *image) { - int i; - int npages = (image->size) / PAGE_SIZE; - BUG_ON(image->size % PAGE_SIZE != 0); - for (i = 0; i < npages; i++) - image->text_mapping.pages[i] = - virt_to_page(image->data + i*PAGE_SIZE); apply_alternatives((struct alt_instr *)(image->data + image->alt), (struct alt_instr *)(image->data + image->alt + @@ -90,18 +85,87 @@ static unsigned long vdso_addr(unsigned long start, unsigned len) #endif } +static int vdso_fault(const struct vm_special_mapping *sm, + struct vm_area_struct *vma, struct vm_fault *vmf) +{ + const struct vdso_image *image = vma->vm_mm->context.vdso_image; + + if (!image || (vmf->pgoff << PAGE_SHIFT) >= image->size) + return VM_FAULT_SIGBUS; + + vmf->page = virt_to_page(image->data + (vmf->pgoff << PAGE_SHIFT)); + get_page(vmf->page); + return 0; +} + +static const struct vm_special_mapping text_mapping = { + .name = "[vdso]", + .fault = vdso_fault, +}; + +static int vvar_fault(const struct vm_special_mapping *sm, + struct vm_area_struct *vma, struct vm_fault *vmf) +{ + const struct vdso_image *image = vma->vm_mm->context.vdso_image; + long sym_offset; + int ret = -EFAULT; + + if (!image) + return VM_FAULT_SIGBUS; + + sym_offset = (long)(vmf->pgoff << PAGE_SHIFT) + + image->sym_vvar_start; + + /* + * Sanity check: a symbol offset of zero means that the page + * does not exist for this vdso image, not that the page is at + * offset zero relative to the text mapping. This should be + * impossible here, because sym_offset should only be zero for + * the page past the end of the vvar mapping. + */ + if (sym_offset == 0) + return VM_FAULT_SIGBUS; + + if (sym_offset == image->sym_vvar_page) { + ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, + __pa_symbol(&__vvar_page) >> PAGE_SHIFT); + } else if (sym_offset == image->sym_hpet_page) { +#ifdef CONFIG_HPET_TIMER + if (hpet_address && vclock_was_used(VCLOCK_HPET)) { + ret = vm_insert_pfn_prot( + vma, + (unsigned long)vmf->virtual_address, + hpet_address >> PAGE_SHIFT, + pgprot_noncached(PAGE_READONLY)); + } +#endif + } else if (sym_offset == image->sym_pvclock_page) { + struct pvclock_vsyscall_time_info *pvti = + pvclock_pvti_cpu0_va(); + if (pvti && vclock_was_used(VCLOCK_PVCLOCK)) { + ret = vm_insert_pfn( + vma, + (unsigned long)vmf->virtual_address, + __pa(pvti) >> PAGE_SHIFT); + } + } + + if (ret == 0 || ret == -EBUSY) + return VM_FAULT_NOPAGE; + + return VM_FAULT_SIGBUS; +} + static int map_vdso(const struct vdso_image *image, bool calculate_addr) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; unsigned long addr, text_start; int ret = 0; - static struct page *no_pages[] = {NULL}; - static struct vm_special_mapping vvar_mapping = { + static const struct vm_special_mapping vvar_mapping = { .name = "[vvar]", - .pages = no_pages, + .fault = vvar_fault, }; - struct pvclock_vsyscall_time_info *pvti; if (calculate_addr) { addr = vdso_addr(current->mm->start_stack, @@ -121,6 +185,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr) text_start = addr - image->sym_vvar_start; current->mm->context.vdso = (void __user *)text_start; + current->mm->context.vdso_image = image; /* * MAYWRITE to allow gdb to COW and set breakpoints @@ -130,7 +195,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr) image->size, VM_READ|VM_EXEC| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, - &image->text_mapping); + &text_mapping); if (IS_ERR(vma)) { ret = PTR_ERR(vma); @@ -140,7 +205,8 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr) vma = _install_special_mapping(mm, addr, -image->sym_vvar_start, - VM_READ|VM_MAYREAD, + VM_READ|VM_MAYREAD|VM_IO|VM_DONTDUMP| + VM_PFNMAP, &vvar_mapping); if (IS_ERR(vma)) { @@ -148,41 +214,6 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr) goto up_fail; } - if (image->sym_vvar_page) - ret = remap_pfn_range(vma, - text_start + image->sym_vvar_page, - __pa_symbol(&__vvar_page) >> PAGE_SHIFT, - PAGE_SIZE, - PAGE_READONLY); - - if (ret) - goto up_fail; - -#ifdef CONFIG_HPET_TIMER - if (hpet_address && image->sym_hpet_page) { - ret = io_remap_pfn_range(vma, - text_start + image->sym_hpet_page, - hpet_address >> PAGE_SHIFT, - PAGE_SIZE, - pgprot_noncached(PAGE_READONLY)); - - if (ret) - goto up_fail; - } -#endif - - pvti = pvclock_pvti_cpu0_va(); - if (pvti && image->sym_pvclock_page) { - ret = remap_pfn_range(vma, - text_start + image->sym_pvclock_page, - __pa(pvti) >> PAGE_SHIFT, - PAGE_SIZE, - PAGE_READONLY); - - if (ret) - goto up_fail; - } - up_fail: if (ret) current->mm->context.vdso = NULL; @@ -254,7 +285,7 @@ static void vgetcpu_cpu_init(void *arg) #ifdef CONFIG_NUMA node = cpu_to_node(cpu); #endif - if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP)) + if (static_cpu_has(X86_FEATURE_RDTSCP)) write_rdtscp_aux((node << 12) | cpu); /* diff --git a/arch/x86/entry/vsyscall/vsyscall_gtod.c b/arch/x86/entry/vsyscall/vsyscall_gtod.c index 51e330416995..0fb3a104ac62 100644 --- a/arch/x86/entry/vsyscall/vsyscall_gtod.c +++ b/arch/x86/entry/vsyscall/vsyscall_gtod.c @@ -16,6 +16,8 @@ #include #include +int vclocks_used __read_mostly; + DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data); void update_vsyscall_tz(void) @@ -26,12 +28,17 @@ void update_vsyscall_tz(void) void update_vsyscall(struct timekeeper *tk) { + int vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data; + /* Mark the new vclock used. */ + BUILD_BUG_ON(VCLOCK_MAX >= 32); + WRITE_ONCE(vclocks_used, READ_ONCE(vclocks_used) | (1 << vclock_mode)); + gtod_write_begin(vdata); /* copy vsyscall data */ - vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; + vdata->vclock_mode = vclock_mode; vdata->cycle_last = tk->tkr_mono.cycle_last; vdata->mask = tk->tkr_mono.mask; vdata->mult = tk->tkr_mono.mult; diff --git a/arch/x86/events/Makefile b/arch/x86/events/Makefile new file mode 100644 index 000000000000..7d1ecff583b0 --- /dev/null +++ b/arch/x86/events/Makefile @@ -0,0 +1,7 @@ +obj-y += core.o + +obj-$(CONFIG_CPU_SUP_AMD) += amd/core.o amd/uncore.o +obj-$(CONFIG_X86_LOCAL_APIC) += amd/ibs.o +ifdef CONFIG_AMD_IOMMU +obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o +endif diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/events/amd/core.c similarity index 99% rename from arch/x86/kernel/cpu/perf_event_amd.c rename to arch/x86/events/amd/core.c index 58610539b048..51b16583679c 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/events/amd/core.c @@ -5,7 +5,7 @@ #include #include -#include "perf_event.h" +#include "../../kernel/cpu/perf_event.h" static __initconst const u64 amd_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/events/amd/ibs.c similarity index 98% rename from arch/x86/kernel/cpu/perf_event_amd_ibs.c rename to arch/x86/events/amd/ibs.c index 989d3c215d2b..a8abd082d932 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -14,7 +14,7 @@ #include -#include "perf_event.h" +#include "../../kernel/cpu/perf_event.h" static u32 ibs_caps; @@ -670,7 +670,7 @@ static __init int perf_event_ibs_init(void) perf_ibs_pmu_init(&perf_ibs_op, "ibs_op"); register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs"); - printk(KERN_INFO "perf: AMD IBS detected (0x%08x)\n", ibs_caps); + pr_info("perf: AMD IBS detected (0x%08x)\n", ibs_caps); return 0; } @@ -774,14 +774,14 @@ static int setup_ibs_ctl(int ibs_eilvt_off) pci_read_config_dword(cpu_cfg, IBSCTL, &value); if (value != (ibs_eilvt_off | IBSCTL_LVT_OFFSET_VALID)) { pci_dev_put(cpu_cfg); - printk(KERN_DEBUG "Failed to setup IBS LVT offset, " - "IBSCTL = 0x%08x\n", value); + pr_debug("Failed to setup IBS LVT offset, IBSCTL = 0x%08x\n", + value); return -EINVAL; } } while (1); if (!nodes) { - printk(KERN_DEBUG "No CPU node configured for IBS\n"); + pr_debug("No CPU node configured for IBS\n"); return -ENODEV; } @@ -810,7 +810,7 @@ static void force_ibs_eilvt_setup(void) preempt_enable(); if (offset == APIC_EILVT_NR_MAX) { - printk(KERN_DEBUG "No EILVT entry available\n"); + pr_debug("No EILVT entry available\n"); return; } diff --git a/arch/x86/kernel/cpu/perf_event_amd_iommu.c b/arch/x86/events/amd/iommu.c similarity index 99% rename from arch/x86/kernel/cpu/perf_event_amd_iommu.c rename to arch/x86/events/amd/iommu.c index 97242a9242bd..629bc700eb08 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_iommu.c +++ b/arch/x86/events/amd/iommu.c @@ -16,8 +16,8 @@ #include #include -#include "perf_event.h" -#include "perf_event_amd_iommu.h" +#include "../../kernel/cpu/perf_event.h" +#include "iommu.h" #define COUNTER_SHIFT 16 diff --git a/arch/x86/kernel/cpu/perf_event_amd_iommu.h b/arch/x86/events/amd/iommu.h similarity index 100% rename from arch/x86/kernel/cpu/perf_event_amd_iommu.h rename to arch/x86/events/amd/iommu.h diff --git a/arch/x86/kernel/cpu/perf_event_amd_uncore.c b/arch/x86/events/amd/uncore.c similarity index 99% rename from arch/x86/kernel/cpu/perf_event_amd_uncore.c rename to arch/x86/events/amd/uncore.c index 49742746a6c9..19a17363a21d 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_uncore.c +++ b/arch/x86/events/amd/uncore.c @@ -536,7 +536,7 @@ static int __init amd_uncore_init(void) if (ret) goto fail_nb; - printk(KERN_INFO "perf: AMD NB counters detected\n"); + pr_info("perf: AMD NB counters detected\n"); ret = 0; } @@ -550,7 +550,7 @@ static int __init amd_uncore_init(void) if (ret) goto fail_l2; - printk(KERN_INFO "perf: AMD L2I counters detected\n"); + pr_info("perf: AMD L2I counters detected\n"); ret = 0; } diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/events/core.c similarity index 99% rename from arch/x86/kernel/cpu/perf_event.c rename to arch/x86/events/core.c index 1b443db2db50..90ca601b5d5c 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/events/core.c @@ -37,7 +37,7 @@ #include #include -#include "perf_event.h" +#include "../kernel/cpu/perf_event.h" struct x86_pmu x86_pmu __read_mostly; @@ -254,15 +254,16 @@ static bool check_hw_exists(void) * We still allow the PMU driver to operate: */ if (bios_fail) { - printk(KERN_CONT "Broken BIOS detected, complain to your hardware vendor.\n"); - printk(KERN_ERR FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg_fail, val_fail); + pr_cont("Broken BIOS detected, complain to your hardware vendor.\n"); + pr_err(FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", + reg_fail, val_fail); } return true; msr_fail: - printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n"); - printk("%sFailed to access perfctr msr (MSR %x is %Lx)\n", + pr_cont("Broken PMU hardware detected, using software events only.\n"); + pr_info("%sFailed to access perfctr msr (MSR %x is %Lx)\n", boot_cpu_has(X86_FEATURE_HYPERVISOR) ? KERN_INFO : KERN_ERR, reg, val_new); diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 7bfc85bbb8ff..99afb665a004 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -151,12 +151,6 @@ static inline int alternatives_text_reserved(void *start, void *end) ALTINSTR_REPLACEMENT(newinstr2, feature2, 2) \ ".popsection" -/* - * This must be included *after* the definition of ALTERNATIVE due to - * - */ -#include - /* * Alternative instructions for different CPU types or capabilities. * diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index c80f6b6f3da2..0899cfc8dfe8 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h index 259a7c1ef709..02e799fa43d1 100644 --- a/arch/x86/include/asm/arch_hweight.h +++ b/arch/x86/include/asm/arch_hweight.h @@ -1,6 +1,8 @@ #ifndef _ASM_X86_HWEIGHT_H #define _ASM_X86_HWEIGHT_H +#include + #ifdef CONFIG_64BIT /* popcnt %edi, %eax -- redundant REX prefix for alignment */ #define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7" diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h index a584e1c50918..bfb28caf97b1 100644 --- a/arch/x86/include/asm/barrier.h +++ b/arch/x86/include/asm/barrier.h @@ -6,18 +6,17 @@ /* * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking + * And yes, this might be required on UP too when we're talking * to devices. */ #ifdef CONFIG_X86_32 -/* - * Some non-Intel clones support out of order store. wmb() ceases to be a - * nop for these. - */ -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) +#define mb() asm volatile(ALTERNATIVE("lock; addl $0,0(%%esp)", "mfence", \ + X86_FEATURE_XMM2) ::: "memory", "cc") +#define rmb() asm volatile(ALTERNATIVE("lock; addl $0,0(%%esp)", "lfence", \ + X86_FEATURE_XMM2) ::: "memory", "cc") +#define wmb() asm volatile(ALTERNATIVE("lock; addl $0,0(%%esp)", "sfence", \ + X86_FEATURE_XMM2) ::: "memory", "cc") #else #define mb() asm volatile("mfence":::"memory") #define rmb() asm volatile("lfence":::"memory") diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index cfe3b954d5e4..7766d1cf096e 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -91,7 +91,7 @@ set_bit(long nr, volatile unsigned long *addr) * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -static inline void __set_bit(long nr, volatile unsigned long *addr) +static __always_inline void __set_bit(long nr, volatile unsigned long *addr) { asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory"); } @@ -128,13 +128,13 @@ clear_bit(long nr, volatile unsigned long *addr) * clear_bit() is atomic and implies release semantics before the memory * operation. It can be used for an unlock. */ -static inline void clear_bit_unlock(long nr, volatile unsigned long *addr) +static __always_inline void clear_bit_unlock(long nr, volatile unsigned long *addr) { barrier(); clear_bit(nr, addr); } -static inline void __clear_bit(long nr, volatile unsigned long *addr) +static __always_inline void __clear_bit(long nr, volatile unsigned long *addr) { asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); } @@ -151,7 +151,7 @@ static inline void __clear_bit(long nr, volatile unsigned long *addr) * No memory barrier is required here, because x86 cannot reorder stores past * older loads. Same principle as spin_unlock. */ -static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr) +static __always_inline void __clear_bit_unlock(long nr, volatile unsigned long *addr) { barrier(); __clear_bit(nr, addr); @@ -166,7 +166,7 @@ static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr) * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -static inline void __change_bit(long nr, volatile unsigned long *addr) +static __always_inline void __change_bit(long nr, volatile unsigned long *addr) { asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); } @@ -180,7 +180,7 @@ static inline void __change_bit(long nr, volatile unsigned long *addr) * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -static inline void change_bit(long nr, volatile unsigned long *addr) +static __always_inline void change_bit(long nr, volatile unsigned long *addr) { if (IS_IMMEDIATE(nr)) { asm volatile(LOCK_PREFIX "xorb %1,%0" @@ -201,7 +201,7 @@ static inline void change_bit(long nr, volatile unsigned long *addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static inline int test_and_set_bit(long nr, volatile unsigned long *addr) +static __always_inline int test_and_set_bit(long nr, volatile unsigned long *addr) { GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", "c"); } @@ -228,7 +228,7 @@ test_and_set_bit_lock(long nr, volatile unsigned long *addr) * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -static inline int __test_and_set_bit(long nr, volatile unsigned long *addr) +static __always_inline int __test_and_set_bit(long nr, volatile unsigned long *addr) { int oldbit; @@ -247,7 +247,7 @@ static inline int __test_and_set_bit(long nr, volatile unsigned long *addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static inline int test_and_clear_bit(long nr, volatile unsigned long *addr) +static __always_inline int test_and_clear_bit(long nr, volatile unsigned long *addr) { GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, "Ir", nr, "%0", "c"); } @@ -268,7 +268,7 @@ static inline int test_and_clear_bit(long nr, volatile unsigned long *addr) * accessed from a hypervisor on the same CPU if running in a VM: don't change * this without also updating arch/x86/kernel/kvm.c */ -static inline int __test_and_clear_bit(long nr, volatile unsigned long *addr) +static __always_inline int __test_and_clear_bit(long nr, volatile unsigned long *addr) { int oldbit; @@ -280,7 +280,7 @@ static inline int __test_and_clear_bit(long nr, volatile unsigned long *addr) } /* WARNING: non atomic and it can be reordered! */ -static inline int __test_and_change_bit(long nr, volatile unsigned long *addr) +static __always_inline int __test_and_change_bit(long nr, volatile unsigned long *addr) { int oldbit; @@ -300,7 +300,7 @@ static inline int __test_and_change_bit(long nr, volatile unsigned long *addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static inline int test_and_change_bit(long nr, volatile unsigned long *addr) +static __always_inline int test_and_change_bit(long nr, volatile unsigned long *addr) { GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, "Ir", nr, "%0", "c"); } @@ -311,7 +311,7 @@ static __always_inline int constant_test_bit(long nr, const volatile unsigned lo (addr[nr >> _BITOPS_LONG_SHIFT])) != 0; } -static inline int variable_test_bit(long nr, volatile const unsigned long *addr) +static __always_inline int variable_test_bit(long nr, volatile const unsigned long *addr) { int oldbit; @@ -343,7 +343,7 @@ static int test_bit(int nr, const volatile unsigned long *addr); * * Undefined if no bit exists, so code should check against 0 first. */ -static inline unsigned long __ffs(unsigned long word) +static __always_inline unsigned long __ffs(unsigned long word) { asm("rep; bsf %1,%0" : "=r" (word) @@ -357,7 +357,7 @@ static inline unsigned long __ffs(unsigned long word) * * Undefined if no zero exists, so code should check against ~0UL first. */ -static inline unsigned long ffz(unsigned long word) +static __always_inline unsigned long ffz(unsigned long word) { asm("rep; bsf %1,%0" : "=r" (word) @@ -371,7 +371,7 @@ static inline unsigned long ffz(unsigned long word) * * Undefined if no set bit exists, so code should check against 0 first. */ -static inline unsigned long __fls(unsigned long word) +static __always_inline unsigned long __fls(unsigned long word) { asm("bsr %1,%0" : "=r" (word) @@ -393,7 +393,7 @@ static inline unsigned long __fls(unsigned long word) * set bit if value is nonzero. The first (least significant) bit * is at position 1. */ -static inline int ffs(int x) +static __always_inline int ffs(int x) { int r; @@ -434,7 +434,7 @@ static inline int ffs(int x) * set bit if value is nonzero. The last (most significant) bit is * at position 32. */ -static inline int fls(int x) +static __always_inline int fls(int x) { int r; diff --git a/arch/x86/include/asm/clocksource.h b/arch/x86/include/asm/clocksource.h index eda81dc0f4ae..d194266acb28 100644 --- a/arch/x86/include/asm/clocksource.h +++ b/arch/x86/include/asm/clocksource.h @@ -3,10 +3,11 @@ #ifndef _ASM_X86_CLOCKSOURCE_H #define _ASM_X86_CLOCKSOURCE_H -#define VCLOCK_NONE 0 /* No vDSO clock available. */ -#define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */ -#define VCLOCK_HPET 2 /* vDSO should use vread_hpet. */ -#define VCLOCK_PVCLOCK 3 /* vDSO should use vread_pvclock. */ +#define VCLOCK_NONE 0 /* No vDSO clock available. */ +#define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */ +#define VCLOCK_HPET 2 /* vDSO should use vread_hpet. */ +#define VCLOCK_PVCLOCK 3 /* vDSO should use vread_pvclock. */ +#define VCLOCK_MAX 3 struct arch_clocksource_data { int vclock_mode; diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h index ad19841eddfe..9733361fed6f 100644 --- a/arch/x86/include/asm/cmpxchg.h +++ b/arch/x86/include/asm/cmpxchg.h @@ -2,6 +2,7 @@ #define ASM_X86_CMPXCHG_H #include +#include #include /* Provides LOCK_PREFIX */ /* diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 7ad8c9464297..9fba7a5dd24a 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -1,288 +1,7 @@ -/* - * Defines x86 CPU feature bits - */ #ifndef _ASM_X86_CPUFEATURE_H #define _ASM_X86_CPUFEATURE_H -#ifndef _ASM_X86_REQUIRED_FEATURES_H -#include -#endif - -#ifndef _ASM_X86_DISABLED_FEATURES_H -#include -#endif - -#define NCAPINTS 16 /* N 32-bit words worth of info */ -#define NBUGINTS 1 /* N 32-bit bug flags */ - -/* - * Note: If the comment begins with a quoted string, that string is used - * in /proc/cpuinfo instead of the macro name. If the string is "", - * this feature bit is not displayed in /proc/cpuinfo at all. - */ - -/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ -#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */ -#define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */ -#define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */ -#define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */ -#define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */ -#define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */ -#define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */ -#define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */ -#define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */ -#define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */ -#define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */ -#define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */ -#define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */ -#define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */ -#define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */ - /* (plus FCMOVcc, FCOMI with FPU) */ -#define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */ -#define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */ -#define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */ -#define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */ -#define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */ -#define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */ -#define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */ -#define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */ -#define X86_FEATURE_XMM ( 0*32+25) /* "sse" */ -#define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */ -#define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */ -#define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */ -#define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */ -#define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */ -#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */ - -/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ -/* Don't duplicate feature flags which are redundant with Intel! */ -#define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */ -#define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */ -#define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */ -#define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */ -#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */ -#define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */ -#define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */ -#define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */ -#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */ -#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */ - -/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ -#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */ -#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */ -#define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */ - -/* Other features, Linux-defined mapping, word 3 */ -/* This range is used for feature bits which conflict or are synthesized */ -#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */ -#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */ -#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */ -#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */ -/* cpu types for specific tunings: */ -#define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */ -#define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */ -#define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */ -#define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */ -#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */ -#define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */ -/* free, was #define X86_FEATURE_FXSAVE_LEAK ( 3*32+10) * "" FXSAVE leaks FOP/FIP/FOP */ -#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */ -#define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */ -#define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */ -#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */ -#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */ -#define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */ -#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */ -#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */ -/* free, was #define X86_FEATURE_11AP ( 3*32+19) * "" Bad local APIC aka 11AP */ -#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ -#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */ -#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */ -#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */ -#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */ -/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */ -#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */ -#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */ -#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */ -#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */ -#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ - -/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ -#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */ -#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */ -#define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */ -#define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */ -#define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */ -#define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */ -#define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */ -#define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */ -#define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */ -#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */ -#define X86_FEATURE_CID ( 4*32+10) /* Context ID */ -#define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */ -#define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */ -#define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */ -#define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */ -#define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */ -#define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */ -#define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */ -#define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */ -#define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */ -#define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */ -#define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */ -#define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */ -#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */ -#define X86_FEATURE_AES ( 4*32+25) /* AES instructions */ -#define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */ -#define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */ -#define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */ -#define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */ -#define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */ -#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */ - -/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ -#define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */ -#define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */ -#define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */ -#define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */ -#define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */ -#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */ -#define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */ -#define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */ -#define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */ -#define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */ - -/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ -#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */ -#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */ -#define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */ -#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */ -#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */ -#define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */ -#define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */ -#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */ -#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */ -#define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */ -#define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */ -#define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */ -#define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */ -#define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */ -#define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */ -#define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */ -#define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */ -#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */ -#define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */ -#define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */ -#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */ -#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_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ -#define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */ - -/* - * Auxiliary flags: Linux defined - For features scattered in various - * CPUID levels like 0x6, 0xA etc, word 7. - * - * Reuse free bits when adding new feature flags! - */ - -#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */ -#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */ - -#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ -#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ - -#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ - -/* Virtualization flags: Linux defined, word 8 */ -#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ -#define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */ -#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */ -#define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */ -#define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */ - -#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */ -#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */ - - -/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ -#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ -#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */ -#define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */ -#define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */ -#define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */ -#define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */ -#define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */ -#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */ -#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */ -#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */ -#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */ -#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */ -#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */ -#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */ -#define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */ -#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */ -#define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */ -#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */ -#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */ -#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */ -#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */ -#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */ -#define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */ - -/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */ -#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */ -#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */ -#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */ -#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */ - -/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */ -#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */ - -/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */ -#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */ - -/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */ -#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */ - -/* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */ -#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ -#define X86_FEATURE_IDA (14*32+ 1) /* Intel Dynamic Acceleration */ -#define X86_FEATURE_ARAT (14*32+ 2) /* Always Running APIC Timer */ -#define X86_FEATURE_PLN (14*32+ 4) /* Intel Power Limit Notification */ -#define X86_FEATURE_PTS (14*32+ 6) /* Intel Package Thermal Status */ -#define X86_FEATURE_HWP (14*32+ 7) /* Intel Hardware P-states */ -#define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* HWP Notification */ -#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */ -#define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */ -#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */ - -/* AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15 */ -#define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */ -#define X86_FEATURE_LBRV (15*32+ 1) /* LBR Virtualization support */ -#define X86_FEATURE_SVML (15*32+ 2) /* "svm_lock" SVM locking MSR */ -#define X86_FEATURE_NRIPS (15*32+ 3) /* "nrip_save" SVM next_rip save */ -#define X86_FEATURE_TSCRATEMSR (15*32+ 4) /* "tsc_scale" TSC scaling support */ -#define X86_FEATURE_VMCBCLEAN (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */ -#define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */ -#define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */ -#define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */ -#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ - -/* - * BUG word(s) - */ -#define X86_BUG(x) (NCAPINTS*32 + (x)) - -#define X86_BUG_F00F X86_BUG(0) /* Intel F00F */ -#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */ -#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */ -#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */ -#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */ -#define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */ -#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */ -#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */ -#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */ +#include #if defined(__KERNEL__) && !defined(__ASSEMBLY__) @@ -406,106 +125,19 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; #define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE) #define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) /* - * Do not add any more of those clumsy macros - use static_cpu_has_safe() for + * Do not add any more of those clumsy macros - use static_cpu_has() for * fast paths and boot_cpu_has() otherwise! */ -#if __GNUC__ >= 4 && defined(CONFIG_X86_FAST_FEATURE_TESTS) -extern void warn_pre_alternatives(void); -extern bool __static_cpu_has_safe(u16 bit); - +#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_X86_FAST_FEATURE_TESTS) /* * Static testing of CPU features. Used the same as boot_cpu_has(). - * These are only valid after alternatives have run, but will statically - * patch the target code for additional performance. + * These will statically patch the target code for additional + * performance. */ -static __always_inline __pure bool __static_cpu_has(u16 bit) -{ -#ifdef CC_HAVE_ASM_GOTO - -#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS - - /* - * Catch too early usage of this before alternatives - * have run. - */ - asm_volatile_goto("1: jmp %l[t_warn]\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" - " .long 0\n" /* no replacement */ - " .word %P0\n" /* 1: do replace */ - " .byte 2b - 1b\n" /* source len */ - " .byte 0\n" /* replacement len */ - " .byte 0\n" /* pad len */ - ".previous\n" - /* skipping size check since replacement size = 0 */ - : : "i" (X86_FEATURE_ALWAYS) : : t_warn); - -#endif - - asm_volatile_goto("1: jmp %l[t_no]\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" - " .long 0\n" /* no replacement */ - " .word %P0\n" /* feature bit */ - " .byte 2b - 1b\n" /* source len */ - " .byte 0\n" /* replacement len */ - " .byte 0\n" /* pad len */ - ".previous\n" - /* skipping size check since replacement size = 0 */ - : : "i" (bit) : : t_no); - return true; - t_no: - return false; - -#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS - t_warn: - warn_pre_alternatives(); - return false; -#endif - -#else /* CC_HAVE_ASM_GOTO */ - - u8 flag; - /* Open-coded due to __stringify() in ALTERNATIVE() */ - asm volatile("1: movb $0,%0\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" - " .long 3f - .\n" - " .word %P1\n" /* feature bit */ - " .byte 2b - 1b\n" /* source len */ - " .byte 4f - 3f\n" /* replacement len */ - " .byte 0\n" /* pad len */ - ".previous\n" - ".section .discard,\"aw\",@progbits\n" - " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */ - ".previous\n" - ".section .altinstr_replacement,\"ax\"\n" - "3: movb $1,%0\n" - "4:\n" - ".previous\n" - : "=qm" (flag) : "i" (bit)); - return flag; - -#endif /* CC_HAVE_ASM_GOTO */ -} - -#define static_cpu_has(bit) \ -( \ - __builtin_constant_p(boot_cpu_has(bit)) ? \ - boot_cpu_has(bit) : \ - __builtin_constant_p(bit) ? \ - __static_cpu_has(bit) : \ - boot_cpu_has(bit) \ -) - -static __always_inline __pure bool _static_cpu_has_safe(u16 bit) +static __always_inline __pure bool _static_cpu_has(u16 bit) { -#ifdef CC_HAVE_ASM_GOTO - asm_volatile_goto("1: jmp %l[t_dynamic]\n" + asm_volatile_goto("1: jmp 6f\n" "2:\n" ".skip -(((5f-4f) - (2b-1b)) > 0) * " "((5f-4f) - (2b-1b)),0x90\n" @@ -530,66 +162,34 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) " .byte 0\n" /* repl len */ " .byte 0\n" /* pad len */ ".previous\n" - : : "i" (bit), "i" (X86_FEATURE_ALWAYS) - : : t_dynamic, t_no); + ".section .altinstr_aux,\"ax\"\n" + "6:\n" + " testb %[bitnum],%[cap_byte]\n" + " jnz %l[t_yes]\n" + " jmp %l[t_no]\n" + ".previous\n" + : : "i" (bit), "i" (X86_FEATURE_ALWAYS), + [bitnum] "i" (1 << (bit & 7)), + [cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3]) + : : t_yes, t_no); + t_yes: return true; t_no: return false; - t_dynamic: - return __static_cpu_has_safe(bit); -#else - u8 flag; - /* Open-coded due to __stringify() in ALTERNATIVE() */ - asm volatile("1: movb $2,%0\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" /* src offset */ - " .long 3f - .\n" /* repl offset */ - " .word %P2\n" /* always replace */ - " .byte 2b - 1b\n" /* source len */ - " .byte 4f - 3f\n" /* replacement len */ - " .byte 0\n" /* pad len */ - ".previous\n" - ".section .discard,\"aw\",@progbits\n" - " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */ - ".previous\n" - ".section .altinstr_replacement,\"ax\"\n" - "3: movb $0,%0\n" - "4:\n" - ".previous\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" /* src offset */ - " .long 5f - .\n" /* repl offset */ - " .word %P1\n" /* feature bit */ - " .byte 4b - 3b\n" /* src len */ - " .byte 6f - 5f\n" /* repl len */ - " .byte 0\n" /* pad len */ - ".previous\n" - ".section .discard,\"aw\",@progbits\n" - " .byte 0xff + (6f-5f) - (4b-3b)\n" /* size check */ - ".previous\n" - ".section .altinstr_replacement,\"ax\"\n" - "5: movb $1,%0\n" - "6:\n" - ".previous\n" - : "=qm" (flag) - : "i" (bit), "i" (X86_FEATURE_ALWAYS)); - return (flag == 2 ? __static_cpu_has_safe(bit) : flag); -#endif /* CC_HAVE_ASM_GOTO */ } -#define static_cpu_has_safe(bit) \ +#define static_cpu_has(bit) \ ( \ __builtin_constant_p(boot_cpu_has(bit)) ? \ boot_cpu_has(bit) : \ - _static_cpu_has_safe(bit) \ + _static_cpu_has(bit) \ ) #else /* - * gcc 3.x is too stupid to do the static test; fall back to dynamic. + * Fall back to dynamic for gcc versions which don't support asm goto. Should be + * a minority now anyway. */ #define static_cpu_has(bit) boot_cpu_has(bit) -#define static_cpu_has_safe(bit) boot_cpu_has(bit) #endif #define cpu_has_bug(c, bit) cpu_has(c, (bit)) @@ -597,7 +197,6 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) #define clear_cpu_bug(c, bit) clear_cpu_cap(c, (bit)) #define static_cpu_has_bug(bit) static_cpu_has((bit)) -#define static_cpu_has_bug_safe(bit) static_cpu_has_safe((bit)) #define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit)) #define MAX_CPU_FEATURES (NCAPINTS * 32) diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h new file mode 100644 index 000000000000..0ceb6adc8a48 --- /dev/null +++ b/arch/x86/include/asm/cpufeatures.h @@ -0,0 +1,288 @@ +#ifndef _ASM_X86_CPUFEATURES_H +#define _ASM_X86_CPUFEATURES_H + +#ifndef _ASM_X86_REQUIRED_FEATURES_H +#include +#endif + +#ifndef _ASM_X86_DISABLED_FEATURES_H +#include +#endif + +/* + * Defines x86 CPU feature bits + */ +#define NCAPINTS 16 /* N 32-bit words worth of info */ +#define NBUGINTS 1 /* N 32-bit bug flags */ + +/* + * Note: If the comment begins with a quoted string, that string is used + * in /proc/cpuinfo instead of the macro name. If the string is "", + * this feature bit is not displayed in /proc/cpuinfo at all. + */ + +/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ +#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */ +#define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */ +#define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */ +#define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */ +#define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */ +#define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */ +#define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */ +#define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */ +#define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */ +#define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */ +#define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */ +#define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */ +#define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */ +#define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */ +#define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */ + /* (plus FCMOVcc, FCOMI with FPU) */ +#define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */ +#define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */ +#define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */ +#define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */ +#define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */ +#define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */ +#define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */ +#define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */ +#define X86_FEATURE_XMM ( 0*32+25) /* "sse" */ +#define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */ +#define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */ +#define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */ +#define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */ +#define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */ +#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */ + +/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ +/* Don't duplicate feature flags which are redundant with Intel! */ +#define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */ +#define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */ +#define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */ +#define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */ +#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */ +#define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */ +#define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */ +#define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */ +#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */ +#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */ + +/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ +#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */ +#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */ +#define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */ + +/* Other features, Linux-defined mapping, word 3 */ +/* This range is used for feature bits which conflict or are synthesized */ +#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */ +#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */ +#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */ +#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */ +/* cpu types for specific tunings: */ +#define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */ +#define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */ +#define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */ +#define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */ +#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */ +#define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */ +/* free, was #define X86_FEATURE_FXSAVE_LEAK ( 3*32+10) * "" FXSAVE leaks FOP/FIP/FOP */ +#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */ +#define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */ +#define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */ +#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */ +#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */ +#define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */ +#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */ +#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */ +/* free, was #define X86_FEATURE_11AP ( 3*32+19) * "" Bad local APIC aka 11AP */ +#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ +#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */ +#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */ +#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */ +#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */ +/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */ +#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */ +#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */ +#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */ +#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */ +#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ + +/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ +#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */ +#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */ +#define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */ +#define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */ +#define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */ +#define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */ +#define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */ +#define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */ +#define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */ +#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */ +#define X86_FEATURE_CID ( 4*32+10) /* Context ID */ +#define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */ +#define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */ +#define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */ +#define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */ +#define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */ +#define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */ +#define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */ +#define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */ +#define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */ +#define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */ +#define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */ +#define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */ +#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */ +#define X86_FEATURE_AES ( 4*32+25) /* AES instructions */ +#define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */ +#define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */ +#define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */ +#define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */ +#define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */ +#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */ + +/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ +#define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */ +#define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */ +#define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */ +#define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */ +#define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */ +#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */ +#define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */ +#define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */ +#define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */ +#define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */ + +/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ +#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */ +#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */ +#define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */ +#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */ +#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */ +#define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */ +#define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */ +#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */ +#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */ +#define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */ +#define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */ +#define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */ +#define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */ +#define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */ +#define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */ +#define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */ +#define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */ +#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */ +#define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */ +#define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */ +#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */ +#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_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ +#define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */ + +/* + * Auxiliary flags: Linux defined - For features scattered in various + * CPUID levels like 0x6, 0xA etc, word 7. + * + * Reuse free bits when adding new feature flags! + */ + +#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */ +#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */ + +#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ +#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ + +#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ + +/* Virtualization flags: Linux defined, word 8 */ +#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ +#define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */ +#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */ +#define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */ +#define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */ + +#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */ +#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */ + + +/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ +#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ +#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */ +#define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */ +#define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */ +#define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */ +#define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */ +#define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */ +#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */ +#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */ +#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */ +#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */ +#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */ +#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */ +#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */ +#define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */ +#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */ +#define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */ +#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */ +#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */ +#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */ +#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */ +#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */ +#define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */ + +/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */ +#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */ +#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */ +#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */ +#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */ + +/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */ +#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */ + +/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */ +#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */ + +/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */ +#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */ + +/* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */ +#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ +#define X86_FEATURE_IDA (14*32+ 1) /* Intel Dynamic Acceleration */ +#define X86_FEATURE_ARAT (14*32+ 2) /* Always Running APIC Timer */ +#define X86_FEATURE_PLN (14*32+ 4) /* Intel Power Limit Notification */ +#define X86_FEATURE_PTS (14*32+ 6) /* Intel Package Thermal Status */ +#define X86_FEATURE_HWP (14*32+ 7) /* Intel Hardware P-states */ +#define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* HWP Notification */ +#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */ +#define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */ +#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */ + +/* AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15 */ +#define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */ +#define X86_FEATURE_LBRV (15*32+ 1) /* LBR Virtualization support */ +#define X86_FEATURE_SVML (15*32+ 2) /* "svm_lock" SVM locking MSR */ +#define X86_FEATURE_NRIPS (15*32+ 3) /* "nrip_save" SVM next_rip save */ +#define X86_FEATURE_TSCRATEMSR (15*32+ 4) /* "tsc_scale" TSC scaling support */ +#define X86_FEATURE_VMCBCLEAN (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */ +#define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */ +#define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */ +#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 */ + +/* + * BUG word(s) + */ +#define X86_BUG(x) (NCAPINTS*32 + (x)) + +#define X86_BUG_F00F X86_BUG(0) /* Intel F00F */ +#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */ +#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */ +#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */ +#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */ +#define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */ +#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */ +#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */ +#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */ + +#endif /* _ASM_X86_CPUFEATURES_H */ diff --git a/arch/x86/include/asm/dmi.h b/arch/x86/include/asm/dmi.h index 535192f6bfad..3c69fed215c5 100644 --- a/arch/x86/include/asm/dmi.h +++ b/arch/x86/include/asm/dmi.h @@ -15,7 +15,7 @@ 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 +#define dmi_remap ioremap_cache #define dmi_unmap iounmap #endif /* _ASM_X86_DMI_H */ diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 0010c78c4998..8fd9e637629a 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -3,6 +3,7 @@ #include #include +#include /* * We map the EFI regions needed for runtime services non-contiguously, @@ -64,6 +65,17 @@ extern u64 asmlinkage efi_call(void *fp, ...); #define efi_call_phys(f, args...) efi_call((f), args) +/* + * Scratch space used for switching the pagetable in the EFI stub + */ +struct efi_scratch { + u64 r15; + u64 prev_cr3; + pgd_t *efi_pgt; + bool use_pgd; + u64 phys_stack; +} __packed; + #define efi_call_virt(f, ...) \ ({ \ efi_status_t __s; \ @@ -71,7 +83,20 @@ extern u64 asmlinkage efi_call(void *fp, ...); efi_sync_low_kernel_mappings(); \ preempt_disable(); \ __kernel_fpu_begin(); \ + \ + if (efi_scratch.use_pgd) { \ + efi_scratch.prev_cr3 = read_cr3(); \ + write_cr3((unsigned long)efi_scratch.efi_pgt); \ + __flush_tlb_all(); \ + } \ + \ __s = efi_call((void *)efi.systab->runtime->f, __VA_ARGS__); \ + \ + if (efi_scratch.use_pgd) { \ + write_cr3(efi_scratch.prev_cr3); \ + __flush_tlb_all(); \ + } \ + \ __kernel_fpu_end(); \ preempt_enable(); \ __s; \ @@ -111,6 +136,7 @@ extern void __init efi_memory_uc(u64 addr, unsigned long size); extern void __init efi_map_region(efi_memory_desc_t *md); extern void __init efi_map_region_fixed(efi_memory_desc_t *md); extern void efi_sync_low_kernel_mappings(void); +extern int __init efi_alloc_page_tables(void); extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); extern void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages); extern void __init old_map_region(efi_memory_desc_t *md); diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index 1514753fd435..15340e36ddcb 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h @@ -256,7 +256,7 @@ extern int force_personality32; instruction set this CPU supports. This could be done in user space, but it's not easy, and we've already done it here. */ -#define ELF_HWCAP (boot_cpu_data.x86_capability[0]) +#define ELF_HWCAP (boot_cpu_data.x86_capability[CPUID_1_EDX]) /* This yields a string that ld.so will use to load implementation specific libraries for optimization. This is more specific in diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index 6d7d0e52ed5a..8554f960e21b 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h @@ -138,7 +138,7 @@ extern void reserve_top_address(unsigned long reserve); extern int fixmaps_set; extern pte_t *kmap_pte; -extern pgprot_t kmap_prot; +#define kmap_prot PAGE_KERNEL extern pte_t *pkmap_page_table; void __native_set_fixmap(enum fixed_addresses idx, pte_t pte); diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 0fd440df63f1..a2124343edf5 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -17,6 +17,7 @@ #include #include #include +#include /* * High level FPU state handling functions: @@ -58,22 +59,22 @@ extern u64 fpu__get_supported_xfeatures_mask(void); */ static __always_inline __pure bool use_eager_fpu(void) { - return static_cpu_has_safe(X86_FEATURE_EAGER_FPU); + return static_cpu_has(X86_FEATURE_EAGER_FPU); } static __always_inline __pure bool use_xsaveopt(void) { - return static_cpu_has_safe(X86_FEATURE_XSAVEOPT); + return static_cpu_has(X86_FEATURE_XSAVEOPT); } static __always_inline __pure bool use_xsave(void) { - return static_cpu_has_safe(X86_FEATURE_XSAVE); + return static_cpu_has(X86_FEATURE_XSAVE); } static __always_inline __pure bool use_fxsr(void) { - return static_cpu_has_safe(X86_FEATURE_FXSR); + return static_cpu_has(X86_FEATURE_FXSR); } /* @@ -300,7 +301,7 @@ static inline void copy_xregs_to_kernel_booting(struct xregs_state *xstate) WARN_ON(system_state != SYSTEM_BOOTING); - if (static_cpu_has_safe(X86_FEATURE_XSAVES)) + if (static_cpu_has(X86_FEATURE_XSAVES)) XSTATE_OP(XSAVES, xstate, lmask, hmask, err); else XSTATE_OP(XSAVE, xstate, lmask, hmask, err); @@ -322,7 +323,7 @@ static inline void copy_kernel_to_xregs_booting(struct xregs_state *xstate) WARN_ON(system_state != SYSTEM_BOOTING); - if (static_cpu_has_safe(X86_FEATURE_XSAVES)) + if (static_cpu_has(X86_FEATURE_XSAVES)) XSTATE_OP(XRSTORS, xstate, lmask, hmask, err); else XSTATE_OP(XRSTOR, xstate, lmask, hmask, err); @@ -460,7 +461,7 @@ static inline void copy_kernel_to_fpregs(union fpregs_state *fpstate) * pending. Clear the x87 state here by setting it to fixed values. * "m" is a random variable that should be in L1. */ - if (unlikely(static_cpu_has_bug_safe(X86_BUG_FXSAVE_LEAK))) { + if (unlikely(static_cpu_has_bug(X86_BUG_FXSAVE_LEAK))) { asm volatile( "fnclex\n\t" "emms\n\t" @@ -589,7 +590,8 @@ switch_fpu_prepare(struct fpu *old_fpu, struct fpu *new_fpu, int cpu) * If the task has used the math, pre-load the FPU on xsave processors * or if the past 5 consecutive context-switches used math. */ - fpu.preload = new_fpu->fpstate_active && + fpu.preload = static_cpu_has(X86_FEATURE_FPU) && + new_fpu->fpstate_active && (use_eager_fpu() || new_fpu->counter > 5); if (old_fpu->fpregs_active) { diff --git a/arch/x86/include/asm/frame.h b/arch/x86/include/asm/frame.h index 793179cf8e21..6e4d170726b7 100644 --- a/arch/x86/include/asm/frame.h +++ b/arch/x86/include/asm/frame.h @@ -1,23 +1,44 @@ -#ifdef __ASSEMBLY__ +#ifndef _ASM_X86_FRAME_H +#define _ASM_X86_FRAME_H #include -/* The annotation hides the frame from the unwinder and makes it look - like a ordinary ebp save/restore. This avoids some special cases for - frame pointer later */ +/* + * These are stack frame creation macros. They should be used by every + * callable non-leaf asm function to make kernel stack traces more reliable. + */ + #ifdef CONFIG_FRAME_POINTER - .macro FRAME - __ASM_SIZE(push,) %__ASM_REG(bp) - __ASM_SIZE(mov) %__ASM_REG(sp), %__ASM_REG(bp) - .endm - .macro ENDFRAME - __ASM_SIZE(pop,) %__ASM_REG(bp) - .endm -#else - .macro FRAME - .endm - .macro ENDFRAME - .endm -#endif - -#endif /* __ASSEMBLY__ */ + +#ifdef __ASSEMBLY__ + +.macro FRAME_BEGIN + push %_ASM_BP + _ASM_MOV %_ASM_SP, %_ASM_BP +.endm + +.macro FRAME_END + pop %_ASM_BP +.endm + +#else /* !__ASSEMBLY__ */ + +#define FRAME_BEGIN \ + "push %" _ASM_BP "\n" \ + _ASM_MOV "%" _ASM_SP ", %" _ASM_BP "\n" + +#define FRAME_END "pop %" _ASM_BP "\n" + +#endif /* __ASSEMBLY__ */ + +#define FRAME_OFFSET __ASM_SEL(4, 8) + +#else /* !CONFIG_FRAME_POINTER */ + +#define FRAME_BEGIN +#define FRAME_END +#define FRAME_OFFSET 0 + +#endif /* CONFIG_FRAME_POINTER */ + +#endif /* _ASM_X86_FRAME_H */ diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 881b4768644a..e7de5c9a4fbd 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -23,11 +23,13 @@ extern void irq_ctx_init(int cpu); #define __ARCH_HAS_DO_SOFTIRQ +struct irq_desc; + #ifdef CONFIG_HOTPLUG_CPU #include extern int check_irq_vectors_for_cpu_disable(void); extern void fixup_irqs(void); -extern void irq_force_complete_move(int); +extern void irq_force_complete_move(struct irq_desc *desc); #endif #ifdef CONFIG_HAVE_KVM @@ -37,7 +39,6 @@ extern void kvm_set_posted_intr_wakeup_handler(void (*handler)(void)); extern void (*x86_platform_ipi_callback)(void); extern void native_init_IRQ(void); -struct irq_desc; extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs); extern __visible unsigned int do_IRQ(struct pt_regs *regs); diff --git a/arch/x86/include/asm/irq_work.h b/arch/x86/include/asm/irq_work.h index 78162f8e248b..d0afb05c84fc 100644 --- a/arch/x86/include/asm/irq_work.h +++ b/arch/x86/include/asm/irq_work.h @@ -1,7 +1,7 @@ #ifndef _ASM_IRQ_WORK_H #define _ASM_IRQ_WORK_H -#include +#include static inline bool arch_irq_work_has_interrupt(void) { diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index 1e1b07a5a738..9d3a96c4da78 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -3,6 +3,7 @@ #include #include +#include #define native_rdmsr(msr, val1, val2) \ do { \ @@ -143,4 +144,29 @@ static inline void reload_early_microcode(void) { } static inline bool get_builtin_firmware(struct cpio_data *cd, const char *name) { return false; } #endif + +static inline unsigned long get_initrd_start(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + return initrd_start; +#else + return 0; +#endif +} + +static inline unsigned long get_initrd_start_addr(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD +#ifdef CONFIG_X86_32 + unsigned long *initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start); + + return (unsigned long)__pa_nodebug(*initrd_start_p); +#else + return get_initrd_start(); +#endif +#else /* CONFIG_BLK_DEV_INITRD */ + return 0; +#endif +} + #endif /* _ASM_X86_MICROCODE_H */ diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index 55234d5e7160..1ea0baef1175 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h @@ -19,7 +19,8 @@ typedef struct { #endif struct mutex lock; - void __user *vdso; + void __user *vdso; /* vdso base address */ + const struct vdso_image *vdso_image; /* vdso image in use */ atomic_t perf_rdpmc_allowed; /* nonzero if rdpmc is allowed */ } mm_context_t; diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index b05402ef3b84..552346598dab 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -264,6 +264,10 @@ #define MSR_IA32_MC0_CTL2 0x00000280 #define MSR_IA32_MCx_CTL2(x) (MSR_IA32_MC0_CTL2 + (x)) +/* 'SMCA': AMD64 Scalable MCA */ +#define MSR_AMD64_SMCA_MC0_CONFIG 0xc0002004 +#define MSR_AMD64_SMCA_MCx_CONFIG(x) (MSR_AMD64_SMCA_MC0_CONFIG + 0x10*(x)) + #define MSR_P6_PERFCTR0 0x000000c1 #define MSR_P6_PERFCTR1 0x000000c2 #define MSR_P6_EVNTSEL0 0x00000186 diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index c70689b5e5aa..0deeb2d26df7 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -3,6 +3,8 @@ #include +#include + #define MWAIT_SUBSTATE_MASK 0xf #define MWAIT_CSTATE_MASK 0xf #define MWAIT_SUBSTATE_SIZE 4 diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 04c27a013165..4432ab7f407c 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -366,20 +366,18 @@ static inline enum page_cache_mode pgprot2cachemode(pgprot_t pgprot) } static inline pgprot_t pgprot_4k_2_large(pgprot_t pgprot) { + pgprotval_t val = pgprot_val(pgprot); pgprot_t new; - unsigned long val; - val = pgprot_val(pgprot); pgprot_val(new) = (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) | ((val & _PAGE_PAT) << (_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT)); return new; } static inline pgprot_t pgprot_large_2_4k(pgprot_t pgprot) { + pgprotval_t val = pgprot_val(pgprot); pgprot_t new; - unsigned long val; - val = pgprot_val(pgprot); pgprot_val(new) = (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) | ((val & _PAGE_PAT_LARGE) >> (_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT)); diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 2d5a50cb61a2..ecb410310e70 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -13,7 +13,7 @@ struct vm86; #include #include #include -#include +#include #include #include #include @@ -24,7 +24,6 @@ struct vm86; #include #include -#include #include #include #include @@ -766,7 +765,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); * Return saved PC of a blocked thread. * What is this good for? it will be always the scheduler or ret_from_fork. */ -#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8)) +#define thread_saved_pc(t) READ_ONCE_NOCHECK(*(unsigned long *)((t)->thread.sp - 8)) #define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1) extern unsigned long KSTK_ESP(struct task_struct *task); diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h index ba665ebd17bb..db333300bd4b 100644 --- a/arch/x86/include/asm/smap.h +++ b/arch/x86/include/asm/smap.h @@ -15,7 +15,7 @@ #include #include -#include +#include /* "Raw" instruction opcodes */ #define __ASM_CLAC .byte 0x0f,0x01,0xca diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index dfcf0727623b..20a3de5cb3b0 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -16,7 +16,6 @@ #endif #include #include -#include extern int smp_num_siblings; extern unsigned int num_processors; diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index c7b551028740..c0778fcab06d 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -49,7 +49,7 @@ */ #ifndef __ASSEMBLY__ struct task_struct; -#include +#include #include struct thread_info { diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 6df2029405a3..6f9e27aa2aaf 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -5,8 +5,57 @@ #include #include +#include #include +static inline void __invpcid(unsigned long pcid, unsigned long addr, + unsigned long type) +{ + u64 desc[2] = { pcid, addr }; + + /* + * The memory clobber is because the whole point is to invalidate + * stale TLB entries and, especially if we're flushing global + * mappings, we don't want the compiler to reorder any subsequent + * memory accesses before the TLB flush. + * + * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and + * invpcid (%rcx), %rax in long mode. + */ + asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01" + : : "m" (desc), "a" (type), "c" (desc) : "memory"); +} + +#define INVPCID_TYPE_INDIV_ADDR 0 +#define INVPCID_TYPE_SINGLE_CTXT 1 +#define INVPCID_TYPE_ALL_INCL_GLOBAL 2 +#define INVPCID_TYPE_ALL_NON_GLOBAL 3 + +/* Flush all mappings for a given pcid and addr, not including globals. */ +static inline void invpcid_flush_one(unsigned long pcid, + unsigned long addr) +{ + __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); +} + +/* Flush all mappings for a given PCID, not including globals. */ +static inline void invpcid_flush_single_context(unsigned long pcid) +{ + __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); +} + +/* Flush all mappings, including globals, for all PCIDs. */ +static inline void invpcid_flush_all(void) +{ + __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); +} + +/* Flush all mappings for all PCIDs except globals. */ +static inline void invpcid_flush_all_nonglobals(void) +{ + __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); +} + #ifdef CONFIG_PARAVIRT #include #else @@ -104,6 +153,15 @@ static inline void __native_flush_tlb_global(void) { unsigned long flags; + if (static_cpu_has(X86_FEATURE_INVPCID)) { + /* + * Using INVPCID is considerably faster than a pair of writes + * to CR4 sandwiched inside an IRQ flag save/restore. + */ + invpcid_flush_all(); + return; + } + /* * Read-modify-write to CR4 - protect it from preemption and * from interrupts. (Use the raw variant because this code can diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index b89c34c4019b..307698688fa1 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include /* diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h index deabaf9759b6..43dc55be524e 100644 --- a/arch/x86/include/asm/vdso.h +++ b/arch/x86/include/asm/vdso.h @@ -13,9 +13,6 @@ struct vdso_image { void *data; unsigned long size; /* Always a multiple of PAGE_SIZE */ - /* text_mapping.pages is big enough for data/size page pointers */ - struct vm_special_mapping text_mapping; - unsigned long alt, alt_len; long sym_vvar_start; /* Negative offset to the vvar area */ diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h index f556c4843aa1..e728699db774 100644 --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h @@ -37,6 +37,12 @@ struct vsyscall_gtod_data { }; extern struct vsyscall_gtod_data vsyscall_gtod_data; +extern int vclocks_used; +static inline bool vclock_was_used(int vclock) +{ + return READ_ONCE(vclocks_used) & (1 << vclock); +} + static inline unsigned gtod_read_begin(const struct vsyscall_gtod_data *s) { unsigned ret; diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index c80c02c6ec49..ab5c2c685a3c 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c @@ -30,7 +30,7 @@ static unsigned int numachip1_get_apic_id(unsigned long x) unsigned long value; unsigned int id = (x >> 24) & 0xff; - if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) { + if (static_cpu_has(X86_FEATURE_NODEID_MSR)) { rdmsrl(MSR_FAM10H_NODE_ID, value); id |= (value << 2) & 0xff00; } @@ -178,7 +178,7 @@ static void fixup_cpu_id(struct cpuinfo_x86 *c, int node) this_cpu_write(cpu_llc_id, node); /* Account for nodes per socket in multi-core-module processors */ - if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) { + if (static_cpu_has(X86_FEATURE_NODEID_MSR)) { rdmsrl(MSR_FAM10H_NODE_ID, val); nodes = ((val >> 3) & 7) + 1; } diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index f25321894ad2..fdb0fbfb1197 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2521,6 +2521,7 @@ void __init setup_ioapic_dest(void) { int pin, ioapic, irq, irq_entry; const struct cpumask *mask; + struct irq_desc *desc; struct irq_data *idata; struct irq_chip *chip; @@ -2536,7 +2537,9 @@ void __init setup_ioapic_dest(void) if (irq < 0 || !mp_init_irq_at_boot(ioapic, irq)) continue; - idata = irq_get_irq_data(irq); + desc = irq_to_desc(irq); + raw_spin_lock_irq(&desc->lock); + idata = irq_desc_get_irq_data(desc); /* * Honour affinities which have been set in early boot @@ -2550,6 +2553,7 @@ void __init setup_ioapic_dest(void) /* Might be lapic_chip for irq 0 */ if (chip->irq_set_affinity) chip->irq_set_affinity(idata, mask, false); + raw_spin_unlock_irq(&desc->lock); } } #endif diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index 908cb37da171..3b670df4ba7b 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -31,7 +31,7 @@ struct apic_chip_data { struct irq_domain *x86_vector_domain; EXPORT_SYMBOL_GPL(x86_vector_domain); static DEFINE_RAW_SPINLOCK(vector_lock); -static cpumask_var_t vector_cpumask; +static cpumask_var_t vector_cpumask, vector_searchmask, searched_cpumask; static struct irq_chip lapic_controller; #ifdef CONFIG_X86_IO_APIC static struct apic_chip_data *legacy_irq_data[NR_IRQS_LEGACY]; @@ -118,35 +118,47 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d, */ static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START; static int current_offset = VECTOR_OFFSET_START % 16; - int cpu, err; + int cpu, vector; - if (d->move_in_progress) + /* + * If there is still a move in progress or the previous move has not + * been cleaned up completely, tell the caller to come back later. + */ + if (d->move_in_progress || + cpumask_intersects(d->old_domain, cpu_online_mask)) return -EBUSY; /* Only try and allocate irqs on cpus that are present */ - err = -ENOSPC; cpumask_clear(d->old_domain); + cpumask_clear(searched_cpumask); cpu = cpumask_first_and(mask, cpu_online_mask); while (cpu < nr_cpu_ids) { - int new_cpu, vector, offset; + int new_cpu, offset; + /* Get the possible target cpus for @mask/@cpu from the apic */ apic->vector_allocation_domain(cpu, vector_cpumask, mask); + /* + * Clear the offline cpus from @vector_cpumask for searching + * and verify whether the result overlaps with @mask. If true, + * then the call to apic->cpu_mask_to_apicid_and() will + * succeed as well. If not, no point in trying to find a + * vector in this mask. + */ + cpumask_and(vector_searchmask, vector_cpumask, cpu_online_mask); + if (!cpumask_intersects(vector_searchmask, mask)) + goto next_cpu; + if (cpumask_subset(vector_cpumask, d->domain)) { - err = 0; if (cpumask_equal(vector_cpumask, d->domain)) - break; + goto success; /* - * New cpumask using the vector is a proper subset of - * the current in use mask. So cleanup the vector - * allocation for the members that are not used anymore. + * Mark the cpus which are not longer in the mask for + * cleanup. */ - cpumask_andnot(d->old_domain, d->domain, - vector_cpumask); - d->move_in_progress = - cpumask_intersects(d->old_domain, cpu_online_mask); - cpumask_and(d->domain, d->domain, vector_cpumask); - break; + cpumask_andnot(d->old_domain, d->domain, vector_cpumask); + vector = d->cfg.vector; + goto update; } vector = current_vector; @@ -158,45 +170,60 @@ next: vector = FIRST_EXTERNAL_VECTOR + offset; } - if (unlikely(current_vector == vector)) { - cpumask_or(d->old_domain, d->old_domain, - vector_cpumask); - cpumask_andnot(vector_cpumask, mask, d->old_domain); - cpu = cpumask_first_and(vector_cpumask, - cpu_online_mask); - continue; - } + /* If the search wrapped around, try the next cpu */ + if (unlikely(current_vector == vector)) + goto next_cpu; if (test_bit(vector, used_vectors)) goto next; - for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) { + for_each_cpu(new_cpu, vector_searchmask) { if (!IS_ERR_OR_NULL(per_cpu(vector_irq, new_cpu)[vector])) goto next; } /* Found one! */ current_vector = vector; current_offset = offset; - if (d->cfg.vector) { + /* Schedule the old vector for cleanup on all cpus */ + if (d->cfg.vector) cpumask_copy(d->old_domain, d->domain); - d->move_in_progress = - cpumask_intersects(d->old_domain, cpu_online_mask); - } - for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) + for_each_cpu(new_cpu, vector_searchmask) per_cpu(vector_irq, new_cpu)[vector] = irq_to_desc(irq); - d->cfg.vector = vector; - cpumask_copy(d->domain, vector_cpumask); - err = 0; - break; - } + goto update; - if (!err) { - /* cache destination APIC IDs into cfg->dest_apicid */ - err = apic->cpu_mask_to_apicid_and(mask, d->domain, - &d->cfg.dest_apicid); +next_cpu: + /* + * We exclude the current @vector_cpumask from the requested + * @mask and try again with the next online cpu in the + * result. We cannot modify @mask, so we use @vector_cpumask + * as a temporary buffer here as it will be reassigned when + * calling apic->vector_allocation_domain() above. + */ + cpumask_or(searched_cpumask, searched_cpumask, vector_cpumask); + cpumask_andnot(vector_cpumask, mask, searched_cpumask); + cpu = cpumask_first_and(vector_cpumask, cpu_online_mask); + continue; } + return -ENOSPC; - return err; +update: + /* + * Exclude offline cpus from the cleanup mask and set the + * move_in_progress flag when the result is not empty. + */ + cpumask_and(d->old_domain, d->old_domain, cpu_online_mask); + d->move_in_progress = !cpumask_empty(d->old_domain); + d->cfg.vector = vector; + cpumask_copy(d->domain, vector_cpumask); +success: + /* + * Cache destination APIC IDs into cfg->dest_apicid. This cannot fail + * as we already established, that mask & d->domain & cpu_online_mask + * is not empty. + */ + BUG_ON(apic->cpu_mask_to_apicid_and(mask, d->domain, + &d->cfg.dest_apicid)); + return 0; } static int assign_irq_vector(int irq, struct apic_chip_data *data, @@ -226,10 +253,8 @@ static int assign_irq_vector_policy(int irq, int node, static void clear_irq_vector(int irq, struct apic_chip_data *data) { struct irq_desc *desc; - unsigned long flags; int cpu, vector; - raw_spin_lock_irqsave(&vector_lock, flags); BUG_ON(!data->cfg.vector); vector = data->cfg.vector; @@ -239,10 +264,13 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data) data->cfg.vector = 0; cpumask_clear(data->domain); - if (likely(!data->move_in_progress)) { - raw_spin_unlock_irqrestore(&vector_lock, flags); + /* + * If move is in progress or the old_domain mask is not empty, + * i.e. the cleanup IPI has not been processed yet, we need to remove + * the old references to desc from all cpus vector tables. + */ + if (!data->move_in_progress && cpumask_empty(data->old_domain)) return; - } desc = irq_to_desc(irq); for_each_cpu_and(cpu, data->old_domain, cpu_online_mask) { @@ -255,7 +283,6 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data) } } data->move_in_progress = 0; - raw_spin_unlock_irqrestore(&vector_lock, flags); } void init_irq_alloc_info(struct irq_alloc_info *info, @@ -276,19 +303,24 @@ void copy_irq_alloc_info(struct irq_alloc_info *dst, struct irq_alloc_info *src) static void x86_vector_free_irqs(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs) { + struct apic_chip_data *apic_data; struct irq_data *irq_data; + unsigned long flags; int i; for (i = 0; i < nr_irqs; i++) { irq_data = irq_domain_get_irq_data(x86_vector_domain, virq + i); if (irq_data && irq_data->chip_data) { + raw_spin_lock_irqsave(&vector_lock, flags); clear_irq_vector(virq + i, irq_data->chip_data); - free_apic_chip_data(irq_data->chip_data); + apic_data = irq_data->chip_data; + irq_domain_reset_irq_data(irq_data); + raw_spin_unlock_irqrestore(&vector_lock, flags); + free_apic_chip_data(apic_data); #ifdef CONFIG_X86_IO_APIC if (virq + i < nr_legacy_irqs()) legacy_irq_data[virq + i] = NULL; #endif - irq_domain_reset_irq_data(irq_data); } } } @@ -406,6 +438,8 @@ int __init arch_early_irq_init(void) arch_init_htirq_domain(x86_vector_domain); BUG_ON(!alloc_cpumask_var(&vector_cpumask, GFP_KERNEL)); + BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL)); + BUG_ON(!alloc_cpumask_var(&searched_cpumask, GFP_KERNEL)); return arch_early_ioapic_init(); } @@ -494,14 +528,7 @@ static int apic_set_affinity(struct irq_data *irq_data, return -EINVAL; err = assign_irq_vector(irq, data, dest); - if (err) { - if (assign_irq_vector(irq, data, - irq_data_get_affinity_mask(irq_data))) - pr_err("Failed to recover vector for irq %d\n", irq); - return err; - } - - return IRQ_SET_MASK_OK; + return err ? err : IRQ_SET_MASK_OK; } static struct irq_chip lapic_controller = { @@ -513,20 +540,12 @@ static struct irq_chip lapic_controller = { #ifdef CONFIG_SMP static void __send_cleanup_vector(struct apic_chip_data *data) { - cpumask_var_t cleanup_mask; - - if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) { - unsigned int i; - - for_each_cpu_and(i, data->old_domain, cpu_online_mask) - apic->send_IPI_mask(cpumask_of(i), - IRQ_MOVE_CLEANUP_VECTOR); - } else { - cpumask_and(cleanup_mask, data->old_domain, cpu_online_mask); - apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); - free_cpumask_var(cleanup_mask); - } + raw_spin_lock(&vector_lock); + cpumask_and(data->old_domain, data->old_domain, cpu_online_mask); data->move_in_progress = 0; + if (!cpumask_empty(data->old_domain)) + apic->send_IPI_mask(data->old_domain, IRQ_MOVE_CLEANUP_VECTOR); + raw_spin_unlock(&vector_lock); } void send_cleanup_vector(struct irq_cfg *cfg) @@ -570,12 +589,25 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void) goto unlock; /* - * Check if the irq migration is in progress. If so, we - * haven't received the cleanup request yet for this irq. + * Nothing to cleanup if irq migration is in progress + * or this cpu is not set in the cleanup mask. */ - if (data->move_in_progress) + if (data->move_in_progress || + !cpumask_test_cpu(me, data->old_domain)) goto unlock; + /* + * We have two cases to handle here: + * 1) vector is unchanged but the target mask got reduced + * 2) vector and the target mask has changed + * + * #1 is obvious, but in #2 we have two vectors with the same + * irq descriptor: the old and the new vector. So we need to + * make sure that we only cleanup the old vector. The new + * vector has the current @vector number in the config and + * this cpu is part of the target mask. We better leave that + * one alone. + */ if (vector == data->cfg.vector && cpumask_test_cpu(me, data->domain)) goto unlock; @@ -593,6 +625,7 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void) goto unlock; } __this_cpu_write(vector_irq[vector], VECTOR_UNUSED); + cpumask_clear_cpu(me, data->old_domain); unlock: raw_spin_unlock(&desc->lock); } @@ -621,12 +654,48 @@ void irq_complete_move(struct irq_cfg *cfg) __irq_complete_move(cfg, ~get_irq_regs()->orig_ax); } -void irq_force_complete_move(int irq) +/* + * Called with @desc->lock held and interrupts disabled. + */ +void irq_force_complete_move(struct irq_desc *desc) { - struct irq_cfg *cfg = irq_cfg(irq); + struct irq_data *irqdata = irq_desc_get_irq_data(desc); + struct apic_chip_data *data = apic_chip_data(irqdata); + struct irq_cfg *cfg = data ? &data->cfg : NULL; - if (cfg) - __irq_complete_move(cfg, cfg->vector); + if (!cfg) + return; + + __irq_complete_move(cfg, cfg->vector); + + /* + * This is tricky. If the cleanup of @data->old_domain has not been + * done yet, then the following setaffinity call will fail with + * -EBUSY. This can leave the interrupt in a stale state. + * + * The cleanup cannot make progress because we hold @desc->lock. So in + * case @data->old_domain is not yet cleaned up, we need to drop the + * lock and acquire it again. @desc cannot go away, because the + * hotplug code holds the sparse irq lock. + */ + raw_spin_lock(&vector_lock); + /* Clean out all offline cpus (including ourself) first. */ + cpumask_and(data->old_domain, data->old_domain, cpu_online_mask); + while (!cpumask_empty(data->old_domain)) { + raw_spin_unlock(&vector_lock); + raw_spin_unlock(&desc->lock); + cpu_relax(); + raw_spin_lock(&desc->lock); + /* + * Reevaluate apic_chip_data. It might have been cleared after + * we dropped @desc->lock. + */ + data = apic_chip_data(irqdata); + if (!data) + return; + raw_spin_lock(&vector_lock); + } + raw_spin_unlock(&vector_lock); } #endif diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index d760c6bb37b5..624db00583f4 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -889,7 +889,10 @@ void __init uv_system_init(void) return; } pr_info("UV: Found %s hub\n", hub); - map_low_mmrs(); + + /* We now only need to map the MMRs on UV1 */ + if (is_uv1_hub()) + map_low_mmrs(); m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); m_val = m_n_config.s.m_skt; diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index 6ce39025f467..fdeb0ce07c16 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c @@ -7,7 +7,7 @@ #include #include "../../../drivers/lguest/lg.h" -#define __SYSCALL_I386(nr, sym, compat) [nr] = 1, +#define __SYSCALL_I386(nr, sym, qual) [nr] = 1, static char syscalls[] = { #include }; diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index f2edafb5f24e..d875f97d4e0b 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -4,17 +4,11 @@ #include -#define __SYSCALL_64(nr, sym, compat) [nr] = 1, -#define __SYSCALL_COMMON(nr, sym, compat) [nr] = 1, -#ifdef CONFIG_X86_X32_ABI -# define __SYSCALL_X32(nr, sym, compat) [nr] = 1, -#else -# define __SYSCALL_X32(nr, sym, compat) /* nothing */ -#endif +#define __SYSCALL_64(nr, sym, qual) [nr] = 1, static char syscalls_64[] = { #include }; -#define __SYSCALL_I386(nr, sym, compat) [nr] = 1, +#define __SYSCALL_I386(nr, sym, qual) [nr] = 1, static char syscalls_ia32[] = { #include }; diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 58031303e304..d8cf3338a035 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -30,13 +30,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_PERF_EVENTS) += perf_event.o - ifdef CONFIG_PERF_EVENTS -obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o perf_event_amd_uncore.o -ifdef CONFIG_AMD_IOMMU -obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd_iommu.o -endif obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_rapl.o perf_event_intel_cqm.o @@ -56,7 +50,7 @@ obj-$(CONFIG_X86_MCE) += mcheck/ obj-$(CONFIG_MTRR) += mtrr/ obj-$(CONFIG_MICROCODE) += microcode/ -obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o +obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o @@ -64,7 +58,7 @@ ifdef CONFIG_X86_FEATURE_NAMES quiet_cmd_mkcapflags = MKCAP $@ cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@ -cpufeature = $(src)/../../include/asm/cpufeature.h +cpufeature = $(src)/../../include/asm/cpufeatures.h targets += capflags.c $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index a07956a08936..97c59fd60702 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -117,7 +117,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c) void (*f_vide)(void); u64 d, d2; - printk(KERN_INFO "AMD K6 stepping B detected - "); + pr_info("AMD K6 stepping B detected - "); /* * It looks like AMD fixed the 2.6.2 bug and improved indirect @@ -133,10 +133,9 @@ static void init_amd_k6(struct cpuinfo_x86 *c) d = d2-d; if (d > 20*K6_BUG_LOOP) - printk(KERN_CONT - "system stability may be impaired when more than 32 MB are used.\n"); + pr_cont("system stability may be impaired when more than 32 MB are used.\n"); else - printk(KERN_CONT "probably OK (after B9730xxxx).\n"); + pr_cont("probably OK (after B9730xxxx).\n"); } /* K6 with old style WHCR */ @@ -154,7 +153,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c) wbinvd(); wrmsr(MSR_K6_WHCR, l, h); local_irq_restore(flags); - printk(KERN_INFO "Enabling old style K6 write allocation for %d Mb\n", + pr_info("Enabling old style K6 write allocation for %d Mb\n", mbytes); } return; @@ -175,7 +174,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c) wbinvd(); wrmsr(MSR_K6_WHCR, l, h); local_irq_restore(flags); - printk(KERN_INFO "Enabling new style K6 write allocation for %d Mb\n", + pr_info("Enabling new style K6 write allocation for %d Mb\n", mbytes); } @@ -202,7 +201,7 @@ static void init_amd_k7(struct cpuinfo_x86 *c) */ if (c->x86_model >= 6 && c->x86_model <= 10) { if (!cpu_has(c, X86_FEATURE_XMM)) { - printk(KERN_INFO "Enabling disabled K7/SSE Support.\n"); + pr_info("Enabling disabled K7/SSE Support.\n"); msr_clear_bit(MSR_K7_HWCR, 15); set_cpu_cap(c, X86_FEATURE_XMM); } @@ -216,9 +215,8 @@ static void init_amd_k7(struct cpuinfo_x86 *c) if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) { rdmsr(MSR_K7_CLK_CTL, l, h); if ((l & 0xfff00000) != 0x20000000) { - printk(KERN_INFO - "CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", - l, ((l & 0x000fffff)|0x20000000)); + pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", + l, ((l & 0x000fffff)|0x20000000)); wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h); } } @@ -485,7 +483,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) { unsigned long pfn = tseg >> PAGE_SHIFT; - printk(KERN_DEBUG "tseg: %010llx\n", tseg); + pr_debug("tseg: %010llx\n", tseg); if (pfn_range_is_mapped(pfn, pfn + 1)) set_memory_4k((unsigned long)__va(tseg), 1); } @@ -500,8 +498,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) rdmsrl(MSR_K7_HWCR, val); if (!(val & BIT(24))) - printk(KERN_WARNING FW_BUG "TSC doesn't count " - "with P0 frequency!\n"); + pr_warn(FW_BUG "TSC doesn't count with P0 frequency!\n"); } } diff --git a/arch/x86/kernel/cpu/bugs_64.c b/arch/x86/kernel/cpu/bugs_64.c index 04f0fe5af83e..a972ac4c7e7d 100644 --- a/arch/x86/kernel/cpu/bugs_64.c +++ b/arch/x86/kernel/cpu/bugs_64.c @@ -15,7 +15,7 @@ void __init check_bugs(void) { identify_boot_cpu(); #if !defined(CONFIG_SMP) - printk(KERN_INFO "CPU: "); + pr_info("CPU: "); print_cpu_info(&boot_cpu_data); #endif alternative_instructions(); diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index ae20be6e483c..1661d8ec9280 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include #include @@ -29,7 +29,7 @@ static void init_c3(struct cpuinfo_x86 *c) rdmsr(MSR_VIA_FCR, lo, hi); lo |= ACE_FCR; /* enable ACE unit */ wrmsr(MSR_VIA_FCR, lo, hi); - printk(KERN_INFO "CPU: Enabled ACE h/w crypto\n"); + pr_info("CPU: Enabled ACE h/w crypto\n"); } /* enable RNG unit, if present and disabled */ @@ -37,7 +37,7 @@ static void init_c3(struct cpuinfo_x86 *c) rdmsr(MSR_VIA_RNG, lo, hi); lo |= RNG_ENABLE; /* enable RNG unit */ wrmsr(MSR_VIA_RNG, lo, hi); - printk(KERN_INFO "CPU: Enabled h/w RNG\n"); + pr_info("CPU: Enabled h/w RNG\n"); } /* store Centaur Extended Feature Flags as @@ -130,7 +130,7 @@ static void init_centaur(struct cpuinfo_x86 *c) name = "C6"; fcr_set = ECX8|DSMC|EDCTLB|EMMX|ERETSTK; fcr_clr = DPDC; - printk(KERN_NOTICE "Disabling bugged TSC.\n"); + pr_notice("Disabling bugged TSC.\n"); clear_cpu_cap(c, X86_FEATURE_TSC); break; case 8: @@ -163,11 +163,11 @@ static void init_centaur(struct cpuinfo_x86 *c) newlo = (lo|fcr_set) & (~fcr_clr); if (newlo != lo) { - printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n", + pr_info("Centaur FCR was 0x%X now 0x%X\n", lo, newlo); wrmsr(MSR_IDT_FCR1, newlo, hi); } else { - printk(KERN_INFO "Centaur FCR is 0x%X\n", lo); + pr_info("Centaur FCR is 0x%X\n", lo); } /* Emulate MTRRs using Centaur's MCR. */ set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 37830de8f60a..b25c33dd10df 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -162,6 +162,22 @@ static int __init x86_mpx_setup(char *s) } __setup("nompx", x86_mpx_setup); +static int __init x86_noinvpcid_setup(char *s) +{ + /* noinvpcid 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_INVPCID)) + return 0; + + setup_clear_cpu_cap(X86_FEATURE_INVPCID); + pr_info("noinvpcid: INVPCID feature disabled\n"); + return 0; +} +early_param("noinvpcid", x86_noinvpcid_setup); + #ifdef CONFIG_X86_32 static int cachesize_override = -1; static int disable_x86_serial_nr = 1; @@ -228,7 +244,7 @@ static void squash_the_stupid_serial_number(struct cpuinfo_x86 *c) lo |= 0x200000; wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi); - printk(KERN_NOTICE "CPU serial number disabled.\n"); + pr_notice("CPU serial number disabled.\n"); clear_cpu_cap(c, X86_FEATURE_PN); /* Disabling the serial number may affect the cpuid level */ @@ -329,9 +345,8 @@ static void filter_cpuid_features(struct cpuinfo_x86 *c, bool warn) if (!warn) continue; - printk(KERN_WARNING - "CPU: CPU feature " X86_CAP_FMT " disabled, no CPUID level 0x%x\n", - x86_cap_flag(df->feature), df->level); + pr_warn("CPU: CPU feature " X86_CAP_FMT " disabled, no CPUID level 0x%x\n", + x86_cap_flag(df->feature), df->level); } } @@ -510,7 +525,7 @@ void detect_ht(struct cpuinfo_x86 *c) smp_num_siblings = (ebx & 0xff0000) >> 16; if (smp_num_siblings == 1) { - printk_once(KERN_INFO "CPU0: Hyper-Threading is disabled\n"); + pr_info_once("CPU0: Hyper-Threading is disabled\n"); goto out; } @@ -531,10 +546,10 @@ void detect_ht(struct cpuinfo_x86 *c) out: if (!printed && (c->x86_max_cores * smp_num_siblings) > 1) { - printk(KERN_INFO "CPU: Physical Processor ID: %d\n", - c->phys_proc_id); - printk(KERN_INFO "CPU: Processor Core ID: %d\n", - c->cpu_core_id); + pr_info("CPU: Physical Processor ID: %d\n", + c->phys_proc_id); + pr_info("CPU: Processor Core ID: %d\n", + c->cpu_core_id); printed = 1; } #endif @@ -559,9 +574,8 @@ static void get_cpu_vendor(struct cpuinfo_x86 *c) } } - printk_once(KERN_ERR - "CPU: vendor_id '%s' unknown, using generic init.\n" \ - "CPU: Your system may be unstable.\n", v); + pr_err_once("CPU: vendor_id '%s' unknown, using generic init.\n" \ + "CPU: Your system may be unstable.\n", v); c->x86_vendor = X86_VENDOR_UNKNOWN; this_cpu = &default_cpu; @@ -760,7 +774,7 @@ void __init early_cpu_init(void) int count = 0; #ifdef CONFIG_PROCESSOR_SELECT - printk(KERN_INFO "KERNEL supported cpus:\n"); + pr_info("KERNEL supported cpus:\n"); #endif for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) { @@ -778,7 +792,7 @@ void __init early_cpu_init(void) for (j = 0; j < 2; j++) { if (!cpudev->c_ident[j]) continue; - printk(KERN_INFO " %s %s\n", cpudev->c_vendor, + pr_info(" %s %s\n", cpudev->c_vendor, cpudev->c_ident[j]); } } @@ -1061,7 +1075,7 @@ static void __print_cpu_msr(void) for (index = index_min; index < index_max; index++) { if (rdmsrl_safe(index, &val)) continue; - printk(KERN_INFO " MSR%08x: %016llx\n", index, val); + pr_info(" MSR%08x: %016llx\n", index, val); } } } @@ -1100,19 +1114,19 @@ void print_cpu_info(struct cpuinfo_x86 *c) } if (vendor && !strstr(c->x86_model_id, vendor)) - printk(KERN_CONT "%s ", vendor); + pr_cont("%s ", vendor); if (c->x86_model_id[0]) - printk(KERN_CONT "%s", c->x86_model_id); + pr_cont("%s", c->x86_model_id); else - printk(KERN_CONT "%d86", c->x86); + pr_cont("%d86", c->x86); - printk(KERN_CONT " (family: 0x%x, model: 0x%x", c->x86, c->x86_model); + pr_cont(" (family: 0x%x, model: 0x%x", c->x86, c->x86_model); if (c->x86_mask || c->cpuid_level >= 0) - printk(KERN_CONT ", stepping: 0x%x)\n", c->x86_mask); + pr_cont(", stepping: 0x%x)\n", c->x86_mask); else - printk(KERN_CONT ")\n"); + pr_cont(")\n"); print_cpu_msr(c); } @@ -1438,7 +1452,7 @@ void cpu_init(void) show_ucode_info_early(); - printk(KERN_INFO "Initializing CPU#%d\n", cpu); + pr_info("Initializing CPU#%d\n", cpu); if (cpu_feature_enabled(X86_FEATURE_VME) || cpu_has_tsc || @@ -1475,20 +1489,6 @@ void cpu_init(void) } #endif -#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS -void warn_pre_alternatives(void) -{ - WARN(1, "You're using static_cpu_has before alternatives have run!\n"); -} -EXPORT_SYMBOL_GPL(warn_pre_alternatives); -#endif - -inline bool __static_cpu_has_safe(u16 bit) -{ - return boot_cpu_has(bit); -} -EXPORT_SYMBOL_GPL(__static_cpu_has_safe); - static void bsp_resume(void) { if (this_cpu->c_bsp_resume) diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c index aaf152e79637..6adef9cac23e 100644 --- a/arch/x86/kernel/cpu/cyrix.c +++ b/arch/x86/kernel/cpu/cyrix.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "cpu.h" @@ -103,7 +104,7 @@ static void check_cx686_slop(struct cpuinfo_x86 *c) local_irq_restore(flags); if (ccr5 & 2) { /* possible wrong calibration done */ - printk(KERN_INFO "Recalibrating delay loop with SLOP bit reset\n"); + pr_info("Recalibrating delay loop with SLOP bit reset\n"); calibrate_delay(); c->loops_per_jiffy = loops_per_jiffy; } @@ -115,7 +116,7 @@ static void set_cx86_reorder(void) { u8 ccr3; - printk(KERN_INFO "Enable Memory access reorder on Cyrix/NSC processor.\n"); + pr_info("Enable Memory access reorder on Cyrix/NSC processor.\n"); ccr3 = getCx86(CX86_CCR3); setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ @@ -128,7 +129,7 @@ static void set_cx86_reorder(void) static void set_cx86_memwb(void) { - printk(KERN_INFO "Enable Memory-Write-back mode on Cyrix/NSC processor.\n"); + pr_info("Enable Memory-Write-back mode on Cyrix/NSC processor.\n"); /* CCR2 bit 2: unlock NW bit */ setCx86_old(CX86_CCR2, getCx86_old(CX86_CCR2) & ~0x04); @@ -268,7 +269,7 @@ static void init_cyrix(struct cpuinfo_x86 *c) * VSA1 we work around however. */ - printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n"); + pr_info("Working around Cyrix MediaGX virtual DMA bugs.\n"); isa_dma_bridge_buggy = 2; /* We do this before the PCI layer is running. However we @@ -426,7 +427,7 @@ static void cyrix_identify(struct cpuinfo_x86 *c) if (dir0 == 5 || dir0 == 3) { unsigned char ccr3; unsigned long flags; - printk(KERN_INFO "Enabling CPUID on Cyrix processor.\n"); + pr_info("Enabling CPUID on Cyrix processor.\n"); local_irq_save(flags); ccr3 = getCx86(CX86_CCR3); /* enable MAPEN */ diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index d820d8eae96b..73d391ae452f 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c @@ -56,7 +56,7 @@ detect_hypervisor_vendor(void) } if (max_pri) - printk(KERN_INFO "Hypervisor detected: %s\n", x86_hyper->name); + pr_info("Hypervisor detected: %s\n", x86_hyper->name); } void init_hypervisor(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 565648bc1a0a..6040bd71679f 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include @@ -61,7 +61,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) */ if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2 && c->microcode < 0x20e) { - printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n"); + pr_warn("Atom PSE erratum detected, BIOS microcode update recommended\n"); clear_cpu_cap(c, X86_FEATURE_PSE); } @@ -140,7 +140,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) { rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable); if (!(misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING)) { - printk(KERN_INFO "Disabled fast string operations\n"); + pr_info("Disabled fast string operations\n"); setup_clear_cpu_cap(X86_FEATURE_REP_GOOD); setup_clear_cpu_cap(X86_FEATURE_ERMS); } @@ -176,7 +176,7 @@ int ppro_with_ram_bug(void) boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 1 && boot_cpu_data.x86_mask < 8) { - printk(KERN_INFO "Pentium Pro with Errata#50 detected. Taking evasive action.\n"); + pr_info("Pentium Pro with Errata#50 detected. Taking evasive action.\n"); return 1; } return 0; @@ -225,7 +225,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c) set_cpu_bug(c, X86_BUG_F00F); if (!f00f_workaround_enabled) { - printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n"); + pr_notice("Intel Pentium with F0 0F bug - workaround enabled.\n"); f00f_workaround_enabled = 1; } } @@ -244,7 +244,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c) * Forcefully enable PAE if kernel parameter "forcepae" is present. */ if (forcepae) { - printk(KERN_WARNING "PAE forced!\n"); + pr_warn("PAE forced!\n"); set_cpu_cap(c, X86_FEATURE_PAE); add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE); } diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 0b6c52388cf4..de6626c18e42 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include @@ -444,7 +444,7 @@ static ssize_t store_cache_disable(struct cacheinfo *this_leaf, err = amd_set_l3_disable_slot(nb, cpu, slot, val); if (err) { if (err == -EEXIST) - pr_warning("L3 slot %d in use/index already disabled!\n", + pr_warn("L3 slot %d in use/index already disabled!\n", slot); return err; } diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index afa9f0d487ea..fbb5e90557a5 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c index 4cfba4371a71..517619ea6498 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-inject.c +++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c @@ -115,7 +115,7 @@ static int raise_local(void) int cpu = m->extcpu; if (m->inject_flags & MCJ_EXCEPTION) { - printk(KERN_INFO "Triggering MCE exception on CPU %d\n", cpu); + pr_info("Triggering MCE exception on CPU %d\n", cpu); switch (context) { case MCJ_CTX_IRQ: /* @@ -128,15 +128,15 @@ static int raise_local(void) raise_exception(m, NULL); break; default: - printk(KERN_INFO "Invalid MCE context\n"); + pr_info("Invalid MCE context\n"); ret = -EINVAL; } - printk(KERN_INFO "MCE exception done on CPU %d\n", cpu); + pr_info("MCE exception done on CPU %d\n", cpu); } else if (m->status) { - printk(KERN_INFO "Starting machine check poll CPU %d\n", cpu); + pr_info("Starting machine check poll CPU %d\n", cpu); raise_poll(m); mce_notify_irq(); - printk(KERN_INFO "Machine check poll done on CPU %d\n", cpu); + pr_info("Machine check poll done on CPU %d\n", cpu); } else m->finished = 0; @@ -183,8 +183,7 @@ static void raise_mce(struct mce *m) start = jiffies; while (!cpumask_empty(mce_inject_cpumask)) { if (!time_before(jiffies, start + 2*HZ)) { - printk(KERN_ERR - "Timeout waiting for mce inject %lx\n", + pr_err("Timeout waiting for mce inject %lx\n", *cpumask_bits(mce_inject_cpumask)); break; } @@ -241,7 +240,7 @@ static int inject_init(void) { if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) return -ENOMEM; - printk(KERN_INFO "Machine check injector initialized\n"); + pr_info("Machine check injector initialized\n"); register_mce_write_callback(mce_write); register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, "mce_notify"); diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index a006f4cd792b..b7180801ea33 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1617,10 +1617,10 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c) case X86_VENDOR_AMD: { u32 ebx = cpuid_ebx(0x80000007); - mce_amd_feature_init(c); mce_flags.overflow_recov = !!(ebx & BIT(0)); mce_flags.succor = !!(ebx & BIT(1)); mce_flags.smca = !!(ebx & BIT(3)); + mce_amd_feature_init(c); break; } diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index e99b15077e94..88de27bd5797 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -28,7 +28,7 @@ #include #include -#define NR_BLOCKS 9 +#define NR_BLOCKS 5 #define THRESHOLD_MAX 0xFFF #define INT_TYPE_APIC 0x00020000 #define MASK_VALID_HI 0x80000000 @@ -49,6 +49,19 @@ #define DEF_LVT_OFF 0x2 #define DEF_INT_TYPE_APIC 0x2 +/* Scalable MCA: */ + +/* Threshold LVT offset is at MSR0xC0000410[15:12] */ +#define SMCA_THR_LVT_OFF 0xF000 + +/* + * OS is required to set the MCAX bit to acknowledge that it is now using the + * new MSR ranges and new registers under each bank. It also means that the OS + * will configure deferred errors in the new MCx_CONFIG register. If the bit is + * not set, uncorrectable errors will cause a system panic. + */ +#define SMCA_MCAX_EN_OFF 0x1 + static const char * const th_names[] = { "load_store", "insn_fetch", @@ -84,6 +97,13 @@ struct thresh_restart { static inline bool is_shared_bank(int bank) { + /* + * Scalable MCA provides for only one core to have access to the MSRs of + * a shared bank. + */ + if (mce_flags.smca) + return false; + /* Bank 4 is for northbridge reporting and is thus shared */ return (bank == 4); } @@ -135,6 +155,14 @@ static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi) } if (apic != msr) { + /* + * On SMCA CPUs, LVT offset is programmed at a different MSR, and + * the BIOS provides the value. The original field where LVT offset + * was set is reserved. Return early here: + */ + if (mce_flags.smca) + return 0; + pr_err(FW_BUG "cpu %d, invalid threshold interrupt offset %d " "for bank %d, block %d (MSR%08X=0x%x%08x)\n", b->cpu, apic, b->bank, b->block, b->address, hi, lo); @@ -247,14 +275,65 @@ static void deferred_error_interrupt_enable(struct cpuinfo_x86 *c) wrmsr(MSR_CU_DEF_ERR, low, high); } +static int +prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr, + int offset, u32 misc_high) +{ + unsigned int cpu = smp_processor_id(); + struct threshold_block b; + int new; + + if (!block) + per_cpu(bank_map, cpu) |= (1 << bank); + + memset(&b, 0, sizeof(b)); + b.cpu = cpu; + b.bank = bank; + b.block = block; + b.address = addr; + b.interrupt_capable = lvt_interrupt_supported(bank, misc_high); + + if (!b.interrupt_capable) + goto done; + + b.interrupt_enable = 1; + + if (mce_flags.smca) { + u32 smca_low, smca_high; + u32 smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(bank); + + if (!rdmsr_safe(smca_addr, &smca_low, &smca_high)) { + smca_high |= SMCA_MCAX_EN_OFF; + wrmsr(smca_addr, smca_low, smca_high); + } + + /* Gather LVT offset for thresholding: */ + if (rdmsr_safe(MSR_CU_DEF_ERR, &smca_low, &smca_high)) + goto out; + + new = (smca_low & SMCA_THR_LVT_OFF) >> 12; + } else { + new = (misc_high & MASK_LVTOFF_HI) >> 20; + } + + offset = setup_APIC_mce_threshold(offset, new); + + if ((offset == new) && (mce_threshold_vector != amd_threshold_interrupt)) + mce_threshold_vector = amd_threshold_interrupt; + +done: + mce_threshold_block_init(&b, offset); + +out: + return offset; +} + /* cpu init entry point, called from mce.c with preempt off */ void mce_amd_feature_init(struct cpuinfo_x86 *c) { - struct threshold_block b; - unsigned int cpu = smp_processor_id(); u32 low = 0, high = 0, address = 0; unsigned int bank, block; - int offset = -1, new; + int offset = -1; for (bank = 0; bank < mca_cfg.banks; ++bank) { for (block = 0; block < NR_BLOCKS; ++block) { @@ -279,29 +358,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) (high & MASK_LOCKED_HI)) continue; - if (!block) - per_cpu(bank_map, cpu) |= (1 << bank); - - memset(&b, 0, sizeof(b)); - b.cpu = cpu; - b.bank = bank; - b.block = block; - b.address = address; - b.interrupt_capable = lvt_interrupt_supported(bank, high); - - if (!b.interrupt_capable) - goto init; - - b.interrupt_enable = 1; - new = (high & MASK_LVTOFF_HI) >> 20; - offset = setup_APIC_mce_threshold(offset, new); - - if ((offset == new) && - (mce_threshold_vector != amd_threshold_interrupt)) - mce_threshold_vector = amd_threshold_interrupt; - -init: - mce_threshold_block_init(&b, offset); + offset = prepare_threshold_block(bank, block, address, offset, high); } } diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c index 12402e10aeff..2a0717bf8033 100644 --- a/arch/x86/kernel/cpu/mcheck/p5.c +++ b/arch/x86/kernel/cpu/mcheck/p5.c @@ -26,14 +26,12 @@ static void pentium_machine_check(struct pt_regs *regs, long error_code) rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi); rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi); - printk(KERN_EMERG - "CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n", - smp_processor_id(), loaddr, lotype); + pr_emerg("CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n", + smp_processor_id(), loaddr, lotype); if (lotype & (1<<5)) { - printk(KERN_EMERG - "CPU#%d: Possible thermal failure (CPU on fire ?).\n", - smp_processor_id()); + pr_emerg("CPU#%d: Possible thermal failure (CPU on fire ?).\n", + smp_processor_id()); } add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); @@ -61,12 +59,10 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c) /* Read registers before enabling: */ rdmsr(MSR_IA32_P5_MC_ADDR, l, h); rdmsr(MSR_IA32_P5_MC_TYPE, l, h); - printk(KERN_INFO - "Intel old style machine check architecture supported.\n"); + pr_info("Intel old style machine check architecture supported.\n"); /* Enable MCE: */ cr4_set_bits(X86_CR4_MCE); - printk(KERN_INFO - "Intel old style machine check reporting enabled on CPU#%d.\n", - smp_processor_id()); + pr_info("Intel old style machine check reporting enabled on CPU#%d.\n", + smp_processor_id()); } diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 2c5aaf8c2e2f..0b445c2ff735 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -190,7 +190,7 @@ static int therm_throt_process(bool new_event, int event, int level) /* if we just entered the thermal event */ if (new_event) { if (event == THERMAL_THROTTLING_EVENT) - printk(KERN_CRIT "CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n", + pr_crit("CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n", this_cpu, level == CORE_LEVEL ? "Core" : "Package", state->count); @@ -198,8 +198,7 @@ static int therm_throt_process(bool new_event, int event, int level) } if (old_event) { if (event == THERMAL_THROTTLING_EVENT) - printk(KERN_INFO "CPU%d: %s temperature/speed normal\n", - this_cpu, + pr_info("CPU%d: %s temperature/speed normal\n", this_cpu, level == CORE_LEVEL ? "Core" : "Package"); return 1; } @@ -417,8 +416,8 @@ static void intel_thermal_interrupt(void) static void unexpected_thermal_interrupt(void) { - printk(KERN_ERR "CPU%d: Unexpected LVT thermal interrupt!\n", - smp_processor_id()); + pr_err("CPU%d: Unexpected LVT thermal interrupt!\n", + smp_processor_id()); } static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt; @@ -499,7 +498,7 @@ void intel_init_thermal(struct cpuinfo_x86 *c) if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) { if (system_state == SYSTEM_BOOTING) - printk(KERN_DEBUG "CPU%d: Thermal monitoring handled by SMI\n", cpu); + pr_debug("CPU%d: Thermal monitoring handled by SMI\n", cpu); return; } @@ -557,8 +556,8 @@ void intel_init_thermal(struct cpuinfo_x86 *c) l = apic_read(APIC_LVTTHMR); apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); - printk_once(KERN_INFO "CPU0: Thermal monitoring enabled (%s)\n", - tm2 ? "TM2" : "TM1"); + pr_info_once("CPU0: Thermal monitoring enabled (%s)\n", + tm2 ? "TM2" : "TM1"); /* enable thermal throttle processing */ atomic_set(&therm_throt_en, 1); diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c index 7245980186ee..fcf9ae9384f4 100644 --- a/arch/x86/kernel/cpu/mcheck/threshold.c +++ b/arch/x86/kernel/cpu/mcheck/threshold.c @@ -12,8 +12,8 @@ static void default_threshold_interrupt(void) { - printk(KERN_ERR "Unexpected threshold interrupt at vector %x\n", - THRESHOLD_APIC_VECTOR); + pr_err("Unexpected threshold interrupt at vector %x\n", + THRESHOLD_APIC_VECTOR); } void (*mce_threshold_vector)(void) = default_threshold_interrupt; diff --git a/arch/x86/kernel/cpu/mcheck/winchip.c b/arch/x86/kernel/cpu/mcheck/winchip.c index 01dd8702880b..c6a722e1d011 100644 --- a/arch/x86/kernel/cpu/mcheck/winchip.c +++ b/arch/x86/kernel/cpu/mcheck/winchip.c @@ -17,7 +17,7 @@ static void winchip_machine_check(struct pt_regs *regs, long error_code) { ist_enter(regs); - printk(KERN_EMERG "CPU0: Machine Check Exception.\n"); + pr_emerg("CPU0: Machine Check Exception.\n"); add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); ist_exit(regs); @@ -39,6 +39,5 @@ void winchip_mcheck_init(struct cpuinfo_x86 *c) cr4_set_bits(X86_CR4_MCE); - printk(KERN_INFO - "Winchip machine check reporting enabled on CPU#0.\n"); + pr_info("Winchip machine check reporting enabled on CPU#0.\n"); } diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 2233f8a76615..5374d5d762e2 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -431,10 +431,6 @@ int __init save_microcode_in_initrd_amd(void) else container = cont_va; - if (ucode_new_rev) - pr_info("microcode: updated early to new patch_level=0x%08x\n", - ucode_new_rev); - eax = cpuid_eax(0x00000001); eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); @@ -469,8 +465,7 @@ void reload_ucode_amd(void) if (mc && rev < mc->hdr.patch_id) { if (!__apply_microcode_amd(mc)) { ucode_new_rev = mc->hdr.patch_id; - pr_info("microcode: reload patch_level=0x%08x\n", - ucode_new_rev); + pr_info("reload patch_level=0x%08x\n", ucode_new_rev); } } } @@ -953,10 +948,14 @@ struct microcode_ops * __init init_amd_microcode(void) struct cpuinfo_x86 *c = &boot_cpu_data; if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { - pr_warning("AMD CPU family 0x%x not supported\n", c->x86); + pr_warn("AMD CPU family 0x%x not supported\n", c->x86); return NULL; } + if (ucode_new_rev) + pr_info_once("microcode updated early to new patch_level=0x%08x\n", + ucode_new_rev); + return µcode_amd_ops; } diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index faec7120c508..cea8552e2b3a 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -43,16 +43,8 @@ #define MICROCODE_VERSION "2.01" static struct microcode_ops *microcode_ops; - static bool dis_ucode_ldr; -static int __init disable_loader(char *str) -{ - dis_ucode_ldr = true; - return 1; -} -__setup("dis_ucode_ldr", disable_loader); - /* * Synchronization. * @@ -81,15 +73,16 @@ struct cpu_info_ctx { static bool __init check_loader_disabled_bsp(void) { + static const char *__dis_opt_str = "dis_ucode_ldr"; + #ifdef CONFIG_X86_32 const char *cmdline = (const char *)__pa_nodebug(boot_command_line); - const char *opt = "dis_ucode_ldr"; - const char *option = (const char *)__pa_nodebug(opt); + const char *option = (const char *)__pa_nodebug(__dis_opt_str); bool *res = (bool *)__pa_nodebug(&dis_ucode_ldr); #else /* CONFIG_X86_64 */ const char *cmdline = boot_command_line; - const char *option = "dis_ucode_ldr"; + const char *option = __dis_opt_str; bool *res = &dis_ucode_ldr; #endif @@ -479,7 +472,7 @@ static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw) enum ucode_state ustate; struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - if (uci && uci->valid) + if (uci->valid) return UCODE_OK; if (collect_cpu_info(cpu)) diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index ee81c544ee0d..cb397947f688 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -39,9 +39,15 @@ #include #include -static unsigned long mc_saved_in_initrd[MAX_UCODE_COUNT]; +/* + * Temporary microcode blobs pointers storage. We note here the pointers to + * microcode blobs we've got from whatever storage (detached initrd, builtin). + * Later on, we put those into final storage mc_saved_data.mc_saved. + */ +static unsigned long mc_tmp_ptrs[MAX_UCODE_COUNT]; + static struct mc_saved_data { - unsigned int mc_saved_count; + unsigned int num_saved; struct microcode_intel **mc_saved; } mc_saved_data; @@ -78,53 +84,50 @@ load_microcode_early(struct microcode_intel **saved, } static inline void -copy_initrd_ptrs(struct microcode_intel **mc_saved, unsigned long *initrd, - unsigned long off, int num_saved) +copy_ptrs(struct microcode_intel **mc_saved, unsigned long *mc_ptrs, + unsigned long off, int num_saved) { int i; for (i = 0; i < num_saved; i++) - mc_saved[i] = (struct microcode_intel *)(initrd[i] + off); + mc_saved[i] = (struct microcode_intel *)(mc_ptrs[i] + off); } #ifdef CONFIG_X86_32 static void -microcode_phys(struct microcode_intel **mc_saved_tmp, - struct mc_saved_data *mc_saved_data) +microcode_phys(struct microcode_intel **mc_saved_tmp, struct mc_saved_data *mcs) { int i; struct microcode_intel ***mc_saved; - mc_saved = (struct microcode_intel ***) - __pa_nodebug(&mc_saved_data->mc_saved); - for (i = 0; i < mc_saved_data->mc_saved_count; i++) { + mc_saved = (struct microcode_intel ***)__pa_nodebug(&mcs->mc_saved); + + for (i = 0; i < mcs->num_saved; i++) { struct microcode_intel *p; - p = *(struct microcode_intel **) - __pa_nodebug(mc_saved_data->mc_saved + i); + p = *(struct microcode_intel **)__pa_nodebug(mcs->mc_saved + i); mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p); } } #endif static enum ucode_state -load_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd, - unsigned long initrd_start, struct ucode_cpu_info *uci) +load_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs, + unsigned long offset, struct ucode_cpu_info *uci) { struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; - unsigned int count = mc_saved_data->mc_saved_count; + unsigned int count = mcs->num_saved; - if (!mc_saved_data->mc_saved) { - copy_initrd_ptrs(mc_saved_tmp, initrd, initrd_start, count); + if (!mcs->mc_saved) { + copy_ptrs(mc_saved_tmp, mc_ptrs, offset, count); return load_microcode_early(mc_saved_tmp, count, uci); } else { #ifdef CONFIG_X86_32 - microcode_phys(mc_saved_tmp, mc_saved_data); + microcode_phys(mc_saved_tmp, mcs); return load_microcode_early(mc_saved_tmp, count, uci); #else - return load_microcode_early(mc_saved_data->mc_saved, - count, uci); + return load_microcode_early(mcs->mc_saved, count, uci); #endif } } @@ -175,25 +178,25 @@ matching_model_microcode(struct microcode_header_intel *mc_header, } static int -save_microcode(struct mc_saved_data *mc_saved_data, +save_microcode(struct mc_saved_data *mcs, struct microcode_intel **mc_saved_src, - unsigned int mc_saved_count) + unsigned int num_saved) { int i, j; struct microcode_intel **saved_ptr; int ret; - if (!mc_saved_count) + if (!num_saved) return -EINVAL; /* * Copy new microcode data. */ - saved_ptr = kcalloc(mc_saved_count, sizeof(struct microcode_intel *), GFP_KERNEL); + saved_ptr = kcalloc(num_saved, sizeof(struct microcode_intel *), GFP_KERNEL); if (!saved_ptr) return -ENOMEM; - for (i = 0; i < mc_saved_count; i++) { + for (i = 0; i < num_saved; i++) { struct microcode_header_intel *mc_hdr; struct microcode_intel *mc; unsigned long size; @@ -219,8 +222,8 @@ save_microcode(struct mc_saved_data *mc_saved_data, /* * Point to newly saved microcode. */ - mc_saved_data->mc_saved = saved_ptr; - mc_saved_data->mc_saved_count = mc_saved_count; + mcs->mc_saved = saved_ptr; + mcs->num_saved = num_saved; return 0; @@ -284,22 +287,20 @@ static unsigned int _save_mc(struct microcode_intel **mc_saved, * BSP can stay in the platform. */ static enum ucode_state __init -get_matching_model_microcode(int cpu, unsigned long start, - void *data, size_t size, - struct mc_saved_data *mc_saved_data, - unsigned long *mc_saved_in_initrd, +get_matching_model_microcode(unsigned long start, void *data, size_t size, + struct mc_saved_data *mcs, unsigned long *mc_ptrs, struct ucode_cpu_info *uci) { - u8 *ucode_ptr = data; - unsigned int leftover = size; + struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; + struct microcode_header_intel *mc_header; + unsigned int num_saved = mcs->num_saved; enum ucode_state state = UCODE_OK; + unsigned int leftover = size; + u8 *ucode_ptr = data; unsigned int mc_size; - struct microcode_header_intel *mc_header; - struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; - unsigned int mc_saved_count = mc_saved_data->mc_saved_count; int i; - while (leftover && mc_saved_count < ARRAY_SIZE(mc_saved_tmp)) { + while (leftover && num_saved < ARRAY_SIZE(mc_saved_tmp)) { if (leftover < sizeof(mc_header)) break; @@ -318,32 +319,31 @@ get_matching_model_microcode(int cpu, unsigned long start, * the platform, we need to find and save microcode patches * with the same family and model as the BSP. */ - if (matching_model_microcode(mc_header, uci->cpu_sig.sig) != - UCODE_OK) { + if (matching_model_microcode(mc_header, uci->cpu_sig.sig) != UCODE_OK) { ucode_ptr += mc_size; continue; } - mc_saved_count = _save_mc(mc_saved_tmp, ucode_ptr, mc_saved_count); + num_saved = _save_mc(mc_saved_tmp, ucode_ptr, num_saved); ucode_ptr += mc_size; } if (leftover) { state = UCODE_ERROR; - goto out; + return state; } - if (mc_saved_count == 0) { + if (!num_saved) { state = UCODE_NFOUND; - goto out; + return state; } - for (i = 0; i < mc_saved_count; i++) - mc_saved_in_initrd[i] = (unsigned long)mc_saved_tmp[i] - start; + for (i = 0; i < num_saved; i++) + mc_ptrs[i] = (unsigned long)mc_saved_tmp[i] - start; + + mcs->num_saved = num_saved; - mc_saved_data->mc_saved_count = mc_saved_count; -out: return state; } @@ -373,7 +373,7 @@ static int collect_cpu_info_early(struct ucode_cpu_info *uci) native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); csig.pf = 1 << ((val[1] >> 18) & 7); } - native_wrmsr(MSR_IA32_UCODE_REV, 0, 0); + native_wrmsrl(MSR_IA32_UCODE_REV, 0); /* As documented in the SDM: Do a CPUID 1 here */ sync_core(); @@ -396,11 +396,11 @@ static void show_saved_mc(void) unsigned int sig, pf, rev, total_size, data_size, date; struct ucode_cpu_info uci; - if (mc_saved_data.mc_saved_count == 0) { + if (!mc_saved_data.num_saved) { pr_debug("no microcode data saved.\n"); return; } - pr_debug("Total microcode saved: %d\n", mc_saved_data.mc_saved_count); + pr_debug("Total microcode saved: %d\n", mc_saved_data.num_saved); collect_cpu_info_early(&uci); @@ -409,7 +409,7 @@ static void show_saved_mc(void) rev = uci.cpu_sig.rev; pr_debug("CPU: sig=0x%x, pf=0x%x, rev=0x%x\n", sig, pf, rev); - for (i = 0; i < mc_saved_data.mc_saved_count; i++) { + for (i = 0; i < mc_saved_data.num_saved; i++) { struct microcode_header_intel *mc_saved_header; struct extended_sigtable *ext_header; int ext_sigcount; @@ -465,7 +465,7 @@ int save_mc_for_early(u8 *mc) { struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; unsigned int mc_saved_count_init; - unsigned int mc_saved_count; + unsigned int num_saved; struct microcode_intel **mc_saved; int ret = 0; int i; @@ -476,23 +476,23 @@ int save_mc_for_early(u8 *mc) */ mutex_lock(&x86_cpu_microcode_mutex); - mc_saved_count_init = mc_saved_data.mc_saved_count; - mc_saved_count = mc_saved_data.mc_saved_count; + mc_saved_count_init = mc_saved_data.num_saved; + num_saved = mc_saved_data.num_saved; mc_saved = mc_saved_data.mc_saved; - if (mc_saved && mc_saved_count) + if (mc_saved && num_saved) memcpy(mc_saved_tmp, mc_saved, - mc_saved_count * sizeof(struct microcode_intel *)); + num_saved * sizeof(struct microcode_intel *)); /* * Save the microcode patch mc in mc_save_tmp structure if it's a newer * version. */ - mc_saved_count = _save_mc(mc_saved_tmp, mc, mc_saved_count); + num_saved = _save_mc(mc_saved_tmp, mc, num_saved); /* * Save the mc_save_tmp in global mc_saved_data. */ - ret = save_microcode(&mc_saved_data, mc_saved_tmp, mc_saved_count); + ret = save_microcode(&mc_saved_data, mc_saved_tmp, num_saved); if (ret) { pr_err("Cannot save microcode patch.\n"); goto out; @@ -536,7 +536,7 @@ static bool __init load_builtin_intel_microcode(struct cpio_data *cp) static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin"; static __init enum ucode_state -scan_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd, +scan_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs, unsigned long start, unsigned long size, struct ucode_cpu_info *uci) { @@ -551,14 +551,18 @@ scan_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd, cd.data = NULL; cd.size = 0; - cd = find_cpio_data(p, (void *)start, size, &offset); - if (!cd.data) { + /* try built-in microcode if no initrd */ + if (!size) { if (!load_builtin_intel_microcode(&cd)) return UCODE_ERROR; + } else { + cd = find_cpio_data(p, (void *)start, size, &offset); + if (!cd.data) + return UCODE_ERROR; } - return get_matching_model_microcode(0, start, cd.data, cd.size, - mc_saved_data, initrd, uci); + return get_matching_model_microcode(start, cd.data, cd.size, + mcs, mc_ptrs, uci); } /* @@ -567,14 +571,11 @@ scan_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd, static void print_ucode_info(struct ucode_cpu_info *uci, unsigned int date) { - int cpu = smp_processor_id(); - - pr_info("CPU%d microcode updated early to revision 0x%x, date = %04x-%02x-%02x\n", - cpu, - uci->cpu_sig.rev, - date & 0xffff, - date >> 24, - (date >> 16) & 0xff); + pr_info_once("microcode updated early to revision 0x%x, date = %04x-%02x-%02x\n", + uci->cpu_sig.rev, + date & 0xffff, + date >> 24, + (date >> 16) & 0xff); } #ifdef CONFIG_X86_32 @@ -603,19 +604,19 @@ void show_ucode_info_early(void) */ static void print_ucode(struct ucode_cpu_info *uci) { - struct microcode_intel *mc_intel; + struct microcode_intel *mc; int *delay_ucode_info_p; int *current_mc_date_p; - mc_intel = uci->mc; - if (mc_intel == NULL) + mc = uci->mc; + if (!mc) return; delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info); current_mc_date_p = (int *)__pa_nodebug(¤t_mc_date); *delay_ucode_info_p = 1; - *current_mc_date_p = mc_intel->hdr.date; + *current_mc_date_p = mc->hdr.date; } #else @@ -630,37 +631,35 @@ static inline void flush_tlb_early(void) static inline void print_ucode(struct ucode_cpu_info *uci) { - struct microcode_intel *mc_intel; + struct microcode_intel *mc; - mc_intel = uci->mc; - if (mc_intel == NULL) + mc = uci->mc; + if (!mc) return; - print_ucode_info(uci, mc_intel->hdr.date); + print_ucode_info(uci, mc->hdr.date); } #endif static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) { - struct microcode_intel *mc_intel; + struct microcode_intel *mc; unsigned int val[2]; - mc_intel = uci->mc; - if (mc_intel == NULL) + mc = uci->mc; + if (!mc) return 0; /* write microcode via MSR 0x79 */ - native_wrmsr(MSR_IA32_UCODE_WRITE, - (unsigned long) mc_intel->bits, - (unsigned long) mc_intel->bits >> 16 >> 16); - native_wrmsr(MSR_IA32_UCODE_REV, 0, 0); + native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); + native_wrmsrl(MSR_IA32_UCODE_REV, 0); /* As documented in the SDM: Do a CPUID 1 here */ sync_core(); /* get the current revision from MSR 0x8B */ native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); - if (val[1] != mc_intel->hdr.rev) + if (val[1] != mc->hdr.rev) return -1; #ifdef CONFIG_X86_64 @@ -672,25 +671,26 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) if (early) print_ucode(uci); else - print_ucode_info(uci, mc_intel->hdr.date); + print_ucode_info(uci, mc->hdr.date); return 0; } /* * This function converts microcode patch offsets previously stored in - * mc_saved_in_initrd to pointers and stores the pointers in mc_saved_data. + * mc_tmp_ptrs to pointers and stores the pointers in mc_saved_data. */ int __init save_microcode_in_initrd_intel(void) { - unsigned int count = mc_saved_data.mc_saved_count; + unsigned int count = mc_saved_data.num_saved; struct microcode_intel *mc_saved[MAX_UCODE_COUNT]; int ret = 0; - if (count == 0) + if (!count) return ret; - copy_initrd_ptrs(mc_saved, mc_saved_in_initrd, initrd_start, count); + copy_ptrs(mc_saved, mc_tmp_ptrs, get_initrd_start(), count); + ret = save_microcode(&mc_saved_data, mc_saved, count); if (ret) pr_err("Cannot save microcode patches from initrd.\n"); @@ -701,8 +701,7 @@ int __init save_microcode_in_initrd_intel(void) } static void __init -_load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data, - unsigned long *initrd, +_load_ucode_intel_bsp(struct mc_saved_data *mcs, unsigned long *mc_ptrs, unsigned long start, unsigned long size) { struct ucode_cpu_info uci; @@ -710,11 +709,11 @@ _load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data, collect_cpu_info_early(&uci); - ret = scan_microcode(mc_saved_data, initrd, start, size, &uci); + ret = scan_microcode(mcs, mc_ptrs, start, size, &uci); if (ret != UCODE_OK) return; - ret = load_microcode(mc_saved_data, initrd, start, &uci); + ret = load_microcode(mcs, mc_ptrs, start, &uci); if (ret != UCODE_OK) return; @@ -728,53 +727,49 @@ void __init load_ucode_intel_bsp(void) struct boot_params *p; p = (struct boot_params *)__pa_nodebug(&boot_params); - start = p->hdr.ramdisk_image; size = p->hdr.ramdisk_size; - _load_ucode_intel_bsp( - (struct mc_saved_data *)__pa_nodebug(&mc_saved_data), - (unsigned long *)__pa_nodebug(&mc_saved_in_initrd), - start, size); + /* + * Set start only if we have an initrd image. We cannot use initrd_start + * because it is not set that early yet. + */ + start = (size ? p->hdr.ramdisk_image : 0); + + _load_ucode_intel_bsp((struct mc_saved_data *)__pa_nodebug(&mc_saved_data), + (unsigned long *)__pa_nodebug(&mc_tmp_ptrs), + start, size); #else - start = boot_params.hdr.ramdisk_image + PAGE_OFFSET; size = boot_params.hdr.ramdisk_size; + start = (size ? boot_params.hdr.ramdisk_image + PAGE_OFFSET : 0); - _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, start, size); + _load_ucode_intel_bsp(&mc_saved_data, mc_tmp_ptrs, start, size); #endif } void load_ucode_intel_ap(void) { - struct mc_saved_data *mc_saved_data_p; + unsigned long *mcs_tmp_p; + struct mc_saved_data *mcs_p; struct ucode_cpu_info uci; - unsigned long *mc_saved_in_initrd_p; - unsigned long initrd_start_addr; enum ucode_state ret; #ifdef CONFIG_X86_32 - unsigned long *initrd_start_p; - mc_saved_in_initrd_p = - (unsigned long *)__pa_nodebug(mc_saved_in_initrd); - mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data); - initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start); - initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p); + mcs_tmp_p = (unsigned long *)__pa_nodebug(mc_tmp_ptrs); + mcs_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data); #else - mc_saved_data_p = &mc_saved_data; - mc_saved_in_initrd_p = mc_saved_in_initrd; - initrd_start_addr = initrd_start; + mcs_tmp_p = mc_tmp_ptrs; + mcs_p = &mc_saved_data; #endif /* * If there is no valid ucode previously saved in memory, no need to * update ucode on this AP. */ - if (mc_saved_data_p->mc_saved_count == 0) + if (!mcs_p->num_saved) return; collect_cpu_info_early(&uci); - ret = load_microcode(mc_saved_data_p, mc_saved_in_initrd_p, - initrd_start_addr, &uci); - + ret = load_microcode(mcs_p, mcs_tmp_p, get_initrd_start_addr(), &uci); if (ret != UCODE_OK) return; @@ -786,13 +781,13 @@ void reload_ucode_intel(void) struct ucode_cpu_info uci; enum ucode_state ret; - if (!mc_saved_data.mc_saved_count) + if (!mc_saved_data.num_saved) return; collect_cpu_info_early(&uci); ret = load_microcode_early(mc_saved_data.mc_saved, - mc_saved_data.mc_saved_count, &uci); + mc_saved_data.num_saved, &uci); if (ret != UCODE_OK) return; @@ -825,7 +820,7 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) * return 0 - no update found * return 1 - found update */ -static int get_matching_mc(struct microcode_intel *mc_intel, int cpu) +static int get_matching_mc(struct microcode_intel *mc, int cpu) { struct cpu_signature cpu_sig; unsigned int csig, cpf, crev; @@ -836,39 +831,36 @@ static int get_matching_mc(struct microcode_intel *mc_intel, int cpu) cpf = cpu_sig.pf; crev = cpu_sig.rev; - return has_newer_microcode(mc_intel, csig, cpf, crev); + return has_newer_microcode(mc, csig, cpf, crev); } static int apply_microcode_intel(int cpu) { - struct microcode_intel *mc_intel; + struct microcode_intel *mc; struct ucode_cpu_info *uci; + struct cpuinfo_x86 *c; unsigned int val[2]; - int cpu_num = raw_smp_processor_id(); - struct cpuinfo_x86 *c = &cpu_data(cpu_num); - - uci = ucode_cpu_info + cpu; - mc_intel = uci->mc; /* We should bind the task to the CPU */ - BUG_ON(cpu_num != cpu); + if (WARN_ON(raw_smp_processor_id() != cpu)) + return -1; - if (mc_intel == NULL) + uci = ucode_cpu_info + cpu; + mc = uci->mc; + if (!mc) return 0; /* * Microcode on this CPU could be updated earlier. Only apply the - * microcode patch in mc_intel when it is newer than the one on this + * microcode patch in mc when it is newer than the one on this * CPU. */ - if (get_matching_mc(mc_intel, cpu) == 0) + if (!get_matching_mc(mc, cpu)) return 0; /* write microcode via MSR 0x79 */ - wrmsr(MSR_IA32_UCODE_WRITE, - (unsigned long) mc_intel->bits, - (unsigned long) mc_intel->bits >> 16 >> 16); - wrmsr(MSR_IA32_UCODE_REV, 0, 0); + wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); + wrmsrl(MSR_IA32_UCODE_REV, 0); /* As documented in the SDM: Do a CPUID 1 here */ sync_core(); @@ -876,16 +868,19 @@ static int apply_microcode_intel(int cpu) /* get the current revision from MSR 0x8B */ rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); - if (val[1] != mc_intel->hdr.rev) { + if (val[1] != mc->hdr.rev) { pr_err("CPU%d update to revision 0x%x failed\n", - cpu_num, mc_intel->hdr.rev); + cpu, mc->hdr.rev); return -1; } + pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x\n", - cpu_num, val[1], - mc_intel->hdr.date & 0xffff, - mc_intel->hdr.date >> 24, - (mc_intel->hdr.date >> 16) & 0xff); + cpu, val[1], + mc->hdr.date & 0xffff, + mc->hdr.date >> 24, + (mc->hdr.date >> 16) & 0xff); + + c = &cpu_data(cpu); uci->cpu_sig.rev = val[1]; c->microcode = val[1]; diff --git a/arch/x86/kernel/cpu/mkcapflags.sh b/arch/x86/kernel/cpu/mkcapflags.sh index 3f20710a5b23..6988c74409a8 100644 --- a/arch/x86/kernel/cpu/mkcapflags.sh +++ b/arch/x86/kernel/cpu/mkcapflags.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeature.h +# Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeatures.h # IN=$1 @@ -49,8 +49,8 @@ dump_array() trap 'rm "$OUT"' EXIT ( - echo "#ifndef _ASM_X86_CPUFEATURE_H" - echo "#include " + echo "#ifndef _ASM_X86_CPUFEATURES_H" + echo "#include " echo "#endif" echo "" diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 20e242ea1bc4..4e7c6933691c 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -161,8 +161,8 @@ 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); - printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n", - ms_hyperv.features, ms_hyperv.hints); + pr_info("HyperV: features 0x%x, hints 0x%x\n", + ms_hyperv.features, ms_hyperv.hints); #ifdef CONFIG_X86_LOCAL_APIC if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) { @@ -174,8 +174,8 @@ 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; - printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n", - lapic_timer_frequency); + pr_info("HyperV: LAPIC Timer Frequency: %#x\n", + lapic_timer_frequency); } #endif diff --git a/arch/x86/kernel/cpu/mtrr/centaur.c b/arch/x86/kernel/cpu/mtrr/centaur.c index 316fe3e60a97..3d689937fc1b 100644 --- a/arch/x86/kernel/cpu/mtrr/centaur.c +++ b/arch/x86/kernel/cpu/mtrr/centaur.c @@ -103,7 +103,7 @@ centaur_validate_add_page(unsigned long base, unsigned long size, unsigned int t */ if (type != MTRR_TYPE_WRCOMB && (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) { - pr_warning("mtrr: only write-combining%s supported\n", + pr_warn("mtrr: only write-combining%s supported\n", centaur_mcr_type ? " and uncacheable are" : " is"); return -EINVAL; } diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index 0d98503c2245..31e951ce6dff 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -57,9 +57,9 @@ static int __initdata nr_range; static struct var_mtrr_range_state __initdata range_state[RANGE_NUM]; static int __initdata debug_print; -#define Dprintk(x...) do { if (debug_print) printk(KERN_DEBUG x); } while (0) +#define Dprintk(x...) do { if (debug_print) pr_debug(x); } while (0) -#define BIOS_BUG_MSG KERN_WARNING \ +#define BIOS_BUG_MSG \ "WARNING: BIOS bug: VAR MTRR %d contains strange UC entry under 1M, check with your system vendor!\n" static int __init @@ -81,9 +81,9 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range, base, base + size); } if (debug_print) { - printk(KERN_DEBUG "After WB checking\n"); + pr_debug("After WB checking\n"); for (i = 0; i < nr_range; i++) - printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n", + pr_debug("MTRR MAP PFN: %016llx - %016llx\n", range[i].start, range[i].end); } @@ -101,7 +101,7 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range, (mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED) && (mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED)) { /* Var MTRR contains UC entry below 1M? Skip it: */ - printk(BIOS_BUG_MSG, i); + pr_warn(BIOS_BUG_MSG, i); if (base + size <= (1<<(20-PAGE_SHIFT))) continue; size -= (1<<(20-PAGE_SHIFT)) - base; @@ -114,11 +114,11 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range, extra_remove_base + extra_remove_size); if (debug_print) { - printk(KERN_DEBUG "After UC checking\n"); + pr_debug("After UC checking\n"); for (i = 0; i < RANGE_NUM; i++) { if (!range[i].end) continue; - printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n", + pr_debug("MTRR MAP PFN: %016llx - %016llx\n", range[i].start, range[i].end); } } @@ -126,9 +126,9 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range, /* sort the ranges */ nr_range = clean_sort_range(range, RANGE_NUM); if (debug_print) { - printk(KERN_DEBUG "After sorting\n"); + pr_debug("After sorting\n"); for (i = 0; i < nr_range; i++) - printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n", + pr_debug("MTRR MAP PFN: %016llx - %016llx\n", range[i].start, range[i].end); } @@ -544,7 +544,7 @@ static void __init print_out_mtrr_range_state(void) start_base = to_size_factor(start_base, &start_factor), type = range_state[i].type; - printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n", + pr_debug("reg %d, base: %ld%cB, range: %ld%cB, type %s\n", i, start_base, start_factor, size_base, size_factor, (type == MTRR_TYPE_UNCACHABLE) ? "UC" : @@ -713,7 +713,7 @@ int __init mtrr_cleanup(unsigned address_bits) return 0; /* Print original var MTRRs at first, for debugging: */ - printk(KERN_DEBUG "original variable MTRRs\n"); + pr_debug("original variable MTRRs\n"); print_out_mtrr_range_state(); memset(range, 0, sizeof(range)); @@ -733,7 +733,7 @@ int __init mtrr_cleanup(unsigned address_bits) x_remove_base, x_remove_size); range_sums = sum_ranges(range, nr_range); - printk(KERN_INFO "total RAM covered: %ldM\n", + pr_info("total RAM covered: %ldM\n", range_sums >> (20 - PAGE_SHIFT)); if (mtrr_chunk_size && mtrr_gran_size) { @@ -745,12 +745,11 @@ int __init mtrr_cleanup(unsigned address_bits) if (!result[i].bad) { set_var_mtrr_all(address_bits); - printk(KERN_DEBUG "New variable MTRRs\n"); + pr_debug("New variable MTRRs\n"); print_out_mtrr_range_state(); return 1; } - printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, " - "will find optimal one\n"); + pr_info("invalid mtrr_gran_size or mtrr_chunk_size, will find optimal one\n"); } i = 0; @@ -768,7 +767,7 @@ int __init mtrr_cleanup(unsigned address_bits) x_remove_base, x_remove_size, i); if (debug_print) { mtrr_print_out_one_result(i); - printk(KERN_INFO "\n"); + pr_info("\n"); } i++; @@ -779,7 +778,7 @@ int __init mtrr_cleanup(unsigned address_bits) index_good = mtrr_search_optimal_index(); if (index_good != -1) { - printk(KERN_INFO "Found optimal setting for mtrr clean up\n"); + pr_info("Found optimal setting for mtrr clean up\n"); i = index_good; mtrr_print_out_one_result(i); @@ -790,7 +789,7 @@ int __init mtrr_cleanup(unsigned address_bits) gran_size <<= 10; x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size); set_var_mtrr_all(address_bits); - printk(KERN_DEBUG "New variable MTRRs\n"); + pr_debug("New variable MTRRs\n"); print_out_mtrr_range_state(); return 1; } else { @@ -799,8 +798,8 @@ int __init mtrr_cleanup(unsigned address_bits) mtrr_print_out_one_result(i); } - printk(KERN_INFO "mtrr_cleanup: can not find optimal value\n"); - printk(KERN_INFO "please specify mtrr_gran_size/mtrr_chunk_size\n"); + pr_info("mtrr_cleanup: can not find optimal value\n"); + pr_info("please specify mtrr_gran_size/mtrr_chunk_size\n"); return 0; } @@ -918,7 +917,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) /* kvm/qemu doesn't have mtrr set right, don't trim them all: */ if (!highest_pfn) { - printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n"); + pr_info("CPU MTRRs all blank - virtualized system.\n"); return 0; } @@ -973,7 +972,8 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) end_pfn); if (total_trim_size) { - pr_warning("WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing %lluMB of RAM.\n", total_trim_size >> 20); + pr_warn("WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing %lluMB of RAM.\n", + total_trim_size >> 20); if (!changed_by_mtrr_cleanup) WARN_ON(1); diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index c870af161008..fcbcb2f678ca 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -55,7 +55,7 @@ static inline void k8_check_syscfg_dram_mod_en(void) rdmsr(MSR_K8_SYSCFG, lo, hi); if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) { - printk(KERN_ERR FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]" + pr_err(FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]" " not cleared by BIOS, clearing this bit\n", smp_processor_id()); lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY; @@ -501,14 +501,14 @@ void __init mtrr_state_warn(void) if (!mask) return; if (mask & MTRR_CHANGE_MASK_FIXED) - pr_warning("mtrr: your CPUs had inconsistent fixed MTRR settings\n"); + pr_warn("mtrr: your CPUs had inconsistent fixed MTRR settings\n"); if (mask & MTRR_CHANGE_MASK_VARIABLE) - pr_warning("mtrr: your CPUs had inconsistent variable MTRR settings\n"); + pr_warn("mtrr: your CPUs had inconsistent variable MTRR settings\n"); if (mask & MTRR_CHANGE_MASK_DEFTYPE) - pr_warning("mtrr: your CPUs had inconsistent MTRRdefType settings\n"); + pr_warn("mtrr: your CPUs had inconsistent MTRRdefType settings\n"); - printk(KERN_INFO "mtrr: probably your BIOS does not setup all CPUs.\n"); - printk(KERN_INFO "mtrr: corrected configuration.\n"); + pr_info("mtrr: probably your BIOS does not setup all CPUs.\n"); + pr_info("mtrr: corrected configuration.\n"); } /* @@ -519,8 +519,7 @@ void __init mtrr_state_warn(void) void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) { if (wrmsr_safe(msr, a, b) < 0) { - printk(KERN_ERR - "MTRR: CPU %u: Writing MSR %x to %x:%x failed\n", + pr_err("MTRR: CPU %u: Writing MSR %x to %x:%x failed\n", smp_processor_id(), msr, a, b); } } @@ -607,7 +606,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, tmp |= ~((1ULL<<(hi - 1)) - 1); if (tmp != mask) { - printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n"); + pr_warn("mtrr: your BIOS has configured an incorrect mask, fixing it.\n"); add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); mask = tmp; } @@ -858,13 +857,13 @@ int generic_validate_add_page(unsigned long base, unsigned long size, boot_cpu_data.x86_model == 1 && boot_cpu_data.x86_mask <= 7) { if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) { - pr_warning("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); + pr_warn("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); return -EINVAL; } if (!(base + size < 0x70000 || base > 0x7003F) && (type == MTRR_TYPE_WRCOMB || type == MTRR_TYPE_WRBACK)) { - pr_warning("mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n"); + pr_warn("mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n"); return -EINVAL; } } @@ -878,7 +877,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, lbase = lbase >> 1, last = last >> 1) ; if (lbase != last) { - pr_warning("mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", base, size); + pr_warn("mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", base, size); return -EINVAL; } return 0; diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 5c3d149ee91c..10f8d4796240 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -47,7 +47,7 @@ #include #include -#include +#include #include #include #include @@ -300,24 +300,24 @@ int mtrr_add_page(unsigned long base, unsigned long size, return error; if (type >= MTRR_NUM_TYPES) { - pr_warning("mtrr: type: %u invalid\n", type); + pr_warn("mtrr: type: %u invalid\n", type); return -EINVAL; } /* If the type is WC, check that this processor supports it */ if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) { - pr_warning("mtrr: your processor doesn't support write-combining\n"); + pr_warn("mtrr: your processor doesn't support write-combining\n"); return -ENOSYS; } if (!size) { - pr_warning("mtrr: zero sized request\n"); + pr_warn("mtrr: zero sized request\n"); return -EINVAL; } if ((base | (base + size - 1)) >> (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) { - pr_warning("mtrr: base or size exceeds the MTRR width\n"); + pr_warn("mtrr: base or size exceeds the MTRR width\n"); return -EINVAL; } @@ -348,7 +348,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, } else if (types_compatible(type, ltype)) continue; } - pr_warning("mtrr: 0x%lx000,0x%lx000 overlaps existing" + pr_warn("mtrr: 0x%lx000,0x%lx000 overlaps existing" " 0x%lx000,0x%lx000\n", base, size, lbase, lsize); goto out; @@ -357,7 +357,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, if (ltype != type) { if (types_compatible(type, ltype)) continue; - pr_warning("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n", + pr_warn("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n", base, size, mtrr_attrib_to_str(ltype), mtrr_attrib_to_str(type)); goto out; @@ -395,7 +395,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, static int mtrr_check(unsigned long base, unsigned long size) { if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { - pr_warning("mtrr: size and base must be multiples of 4 kiB\n"); + pr_warn("mtrr: size and base must be multiples of 4 kiB\n"); pr_debug("mtrr: size: 0x%lx base: 0x%lx\n", size, base); dump_stack(); return -1; @@ -493,16 +493,16 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) } } if (reg >= max) { - pr_warning("mtrr: register: %d too big\n", reg); + pr_warn("mtrr: register: %d too big\n", reg); goto out; } mtrr_if->get(reg, &lbase, &lsize, <ype); if (lsize < 1) { - pr_warning("mtrr: MTRR %d not used\n", reg); + pr_warn("mtrr: MTRR %d not used\n", reg); goto out; } if (mtrr_usage_table[reg] < 1) { - pr_warning("mtrr: reg: %d has count=0\n", reg); + pr_warn("mtrr: reg: %d has count=0\n", reg); goto out; } if (--mtrr_usage_table[reg] < 1) diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index a667078a5180..fed2ab1f1065 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1960,7 +1960,8 @@ intel_bts_constraints(struct perf_event *event) static int intel_alt_er(int idx, u64 config) { - int alt_idx; + int alt_idx = idx; + if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1)) return idx; @@ -2897,14 +2898,12 @@ static void intel_pmu_cpu_starting(int cpu) return; if (!(x86_pmu.flags & PMU_FL_NO_HT_SHARING)) { - void **onln = &cpuc->kfree_on_online[X86_PERF_KFREE_SHARED]; - for_each_cpu(i, topology_sibling_cpumask(cpu)) { struct intel_shared_regs *pc; pc = per_cpu(cpu_hw_events, i).shared_regs; if (pc && pc->core_id == core_id) { - *onln = cpuc->shared_regs; + cpuc->kfree_on_online[0] = cpuc->shared_regs; cpuc->shared_regs = pc; break; } diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 10602f0a438f..7c79261ed939 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -1325,13 +1325,13 @@ void __init intel_ds_init(void) switch (format) { case 0: - printk(KERN_CONT "PEBS fmt0%c, ", pebs_type); + pr_cont("PEBS fmt0%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_core); x86_pmu.drain_pebs = intel_pmu_drain_pebs_core; break; case 1: - printk(KERN_CONT "PEBS fmt1%c, ", pebs_type); + pr_cont("PEBS fmt1%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; break; @@ -1351,7 +1351,7 @@ void __init intel_ds_init(void) break; default: - printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type); + pr_cont("no PEBS fmt%d%c, ", format, pebs_type); x86_pmu.pebs = 0; } } diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index f97f8075bf04..3bf41d413775 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -995,6 +995,9 @@ static int __init uncore_pci_init(void) case 87: /* Knights Landing */ ret = knl_uncore_pci_init(); break; + case 94: /* SkyLake */ + ret = skl_uncore_pci_init(); + break; default: return 0; } diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 07aa2d6bd710..a7086b862156 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -336,6 +336,7 @@ int snb_uncore_pci_init(void); int ivb_uncore_pci_init(void); int hsw_uncore_pci_init(void); int bdw_uncore_pci_init(void); +int skl_uncore_pci_init(void); void snb_uncore_cpu_init(void); void nhm_uncore_cpu_init(void); int snb_pci2phy_map_init(int devid); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c index 0b934820fafd..2bd030ddd0db 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c @@ -8,6 +8,7 @@ #define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00 #define PCI_DEVICE_ID_INTEL_HSW_U_IMC 0x0a04 #define PCI_DEVICE_ID_INTEL_BDW_IMC 0x1604 +#define PCI_DEVICE_ID_INTEL_SKL_IMC 0x191f /* SNB event control */ #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff @@ -524,6 +525,14 @@ static const struct pci_device_id bdw_uncore_pci_ids[] = { { /* end: all zeroes */ }, }; +static const struct pci_device_id skl_uncore_pci_ids[] = { + { /* IMC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_IMC), + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), + }, + { /* end: all zeroes */ }, +}; + static struct pci_driver snb_uncore_pci_driver = { .name = "snb_uncore", .id_table = snb_uncore_pci_ids, @@ -544,6 +553,11 @@ static struct pci_driver bdw_uncore_pci_driver = { .id_table = bdw_uncore_pci_ids, }; +static struct pci_driver skl_uncore_pci_driver = { + .name = "skl_uncore", + .id_table = skl_uncore_pci_ids, +}; + struct imc_uncore_pci_dev { __u32 pci_id; struct pci_driver *driver; @@ -558,6 +572,7 @@ static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = { IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */ IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core ULT Mobile Processor */ IMC_DEV(BDW_IMC, &bdw_uncore_pci_driver), /* 5th Gen Core U */ + IMC_DEV(SKL_IMC, &skl_uncore_pci_driver), /* 6th Gen Core */ { /* end marker */ } }; @@ -610,6 +625,11 @@ int bdw_uncore_pci_init(void) return imc_uncore_pci_init(); } +int skl_uncore_pci_init(void) +{ + return imc_uncore_pci_init(); +} + /* end of Sandy Bridge uncore support */ /* Nehalem uncore support */ diff --git a/arch/x86/kernel/cpu/rdrand.c b/arch/x86/kernel/cpu/rdrand.c index 819d94982e07..f6f50c4ceaec 100644 --- a/arch/x86/kernel/cpu/rdrand.c +++ b/arch/x86/kernel/cpu/rdrand.c @@ -51,7 +51,7 @@ void x86_init_rdrand(struct cpuinfo_x86 *c) for (i = 0; i < SANITY_CHECK_LOOPS; i++) { if (!rdrand_long(&tmp)) { clear_cpu_cap(c, X86_FEATURE_RDRAND); - printk_once(KERN_WARNING "rdrand: disabled\n"); + pr_warn_once("rdrand: disabled\n"); return; } } diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index 4c60eaf0571c..cd531355e838 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -87,10 +87,10 @@ void detect_extended_topology(struct cpuinfo_x86 *c) c->x86_max_cores = (core_level_siblings / smp_num_siblings); if (!printed) { - printk(KERN_INFO "CPU: Physical Processor ID: %d\n", + pr_info("CPU: Physical Processor ID: %d\n", c->phys_proc_id); if (c->x86_max_cores > 1) - printk(KERN_INFO "CPU: Processor Core ID: %d\n", + pr_info("CPU: Processor Core ID: %d\n", c->cpu_core_id); printed = 1; } diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c index 252da7aceca6..34178564be2a 100644 --- a/arch/x86/kernel/cpu/transmeta.c +++ b/arch/x86/kernel/cpu/transmeta.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include "cpu.h" @@ -33,7 +33,7 @@ static void init_transmeta(struct cpuinfo_x86 *c) if (max >= 0x80860001) { cpuid(0x80860001, &dummy, &cpu_rev, &cpu_freq, &cpu_flags); if (cpu_rev != 0x02000000) { - printk(KERN_INFO "CPU: Processor revision %u.%u.%u.%u, %u MHz\n", + pr_info("CPU: Processor revision %u.%u.%u.%u, %u MHz\n", (cpu_rev >> 24) & 0xff, (cpu_rev >> 16) & 0xff, (cpu_rev >> 8) & 0xff, @@ -44,10 +44,10 @@ static void init_transmeta(struct cpuinfo_x86 *c) if (max >= 0x80860002) { cpuid(0x80860002, &new_cpu_rev, &cms_rev1, &cms_rev2, &dummy); if (cpu_rev == 0x02000000) { - printk(KERN_INFO "CPU: Processor revision %08X, %u MHz\n", + pr_info("CPU: Processor revision %08X, %u MHz\n", new_cpu_rev, cpu_freq); } - printk(KERN_INFO "CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n", + pr_info("CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n", (cms_rev1 >> 24) & 0xff, (cms_rev1 >> 16) & 0xff, (cms_rev1 >> 8) & 0xff, @@ -76,7 +76,7 @@ static void init_transmeta(struct cpuinfo_x86 *c) (void *)&cpu_info[56], (void *)&cpu_info[60]); cpu_info[64] = '\0'; - printk(KERN_INFO "CPU: %s\n", cpu_info); + pr_info("CPU: %s\n", cpu_info); } /* Unhide possibly hidden capability flags */ diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 628a059a9a06..364e58346897 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -62,7 +62,7 @@ static unsigned long vmware_get_tsc_khz(void) tsc_hz = eax | (((uint64_t)ebx) << 32); do_div(tsc_hz, 1000); BUG_ON(tsc_hz >> 32); - printk(KERN_INFO "TSC freq read from hypervisor : %lu.%03lu MHz\n", + pr_info("TSC freq read from hypervisor : %lu.%03lu MHz\n", (unsigned long) tsc_hz / 1000, (unsigned long) tsc_hz % 1000); @@ -84,8 +84,7 @@ static void __init vmware_platform_setup(void) if (ebx != UINT_MAX) x86_platform.calibrate_tsc = vmware_get_tsc_khz; else - printk(KERN_WARNING - "Failed to get TSC freq from the hypervisor\n"); + pr_warn("Failed to get TSC freq from the hypervisor\n"); } /* diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 58f34319b29a..9ef978d69c22 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -57,10 +57,9 @@ struct crash_elf_data { struct kimage *image; /* * Total number of ram ranges we have after various adjustments for - * GART, crash reserved region etc. + * crash reserved region, etc. */ unsigned int max_nr_ranges; - unsigned long gart_start, gart_end; /* Pointer to elf header */ void *ehdr; @@ -201,17 +200,6 @@ static int get_nr_ram_ranges_callback(u64 start, u64 end, void *arg) return 0; } -static int get_gart_ranges_callback(u64 start, u64 end, void *arg) -{ - struct crash_elf_data *ced = arg; - - ced->gart_start = start; - ced->gart_end = end; - - /* Not expecting more than 1 gart aperture */ - return 1; -} - /* Gather all the required information to prepare elf headers for ram regions */ static void fill_up_crash_elf_data(struct crash_elf_data *ced, @@ -226,22 +214,6 @@ static void fill_up_crash_elf_data(struct crash_elf_data *ced, ced->max_nr_ranges = nr_ranges; - /* - * We don't create ELF headers for GART aperture as an attempt - * to dump this memory in second kernel leads to hang/crash. - * If gart aperture is present, one needs to exclude that region - * and that could lead to need of extra phdr. - */ - walk_iomem_res("GART", IORESOURCE_MEM, 0, -1, - ced, get_gart_ranges_callback); - - /* - * If we have gart region, excluding that could potentially split - * a memory range, resulting in extra header. Account for that. - */ - if (ced->gart_end) - ced->max_nr_ranges++; - /* Exclusion of crash region could split memory ranges */ ced->max_nr_ranges++; @@ -350,13 +322,6 @@ static int elf_header_exclude_ranges(struct crash_elf_data *ced, return ret; } - /* Exclude GART region */ - if (ced->gart_end) { - ret = exclude_mem_range(cmem, ced->gart_start, ced->gart_end); - if (ret) - return ret; - } - return ret; } @@ -599,12 +564,12 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) /* Add ACPI tables */ cmd.type = E820_ACPI; flags = IORESOURCE_MEM | IORESOURCE_BUSY; - walk_iomem_res("ACPI Tables", flags, 0, -1, &cmd, + walk_iomem_res_desc(IORES_DESC_ACPI_TABLES, flags, 0, -1, &cmd, memmap_entry_callback); /* Add ACPI Non-volatile Storage */ cmd.type = E820_NVS; - walk_iomem_res("ACPI Non-volatile Storage", flags, 0, -1, &cmd, + walk_iomem_res_desc(IORES_DESC_ACPI_NV_STORAGE, flags, 0, -1, &cmd, memmap_entry_callback); /* Add crashk_low_res region */ diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 569c1e4f96fe..621b501f8935 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -24,6 +24,7 @@ #include #include #include +#include /* * The e820 map is the map that gets modified e.g. with command line parameters @@ -925,6 +926,41 @@ static const char *e820_type_to_string(int e820_type) } } +static unsigned long e820_type_to_iomem_type(int e820_type) +{ + switch (e820_type) { + case E820_RESERVED_KERN: + case E820_RAM: + return IORESOURCE_SYSTEM_RAM; + case E820_ACPI: + case E820_NVS: + case E820_UNUSABLE: + case E820_PRAM: + case E820_PMEM: + default: + return IORESOURCE_MEM; + } +} + +static unsigned long e820_type_to_iores_desc(int e820_type) +{ + switch (e820_type) { + case E820_ACPI: + return IORES_DESC_ACPI_TABLES; + case E820_NVS: + return IORES_DESC_ACPI_NV_STORAGE; + case E820_PMEM: + return IORES_DESC_PERSISTENT_MEMORY; + case E820_PRAM: + return IORES_DESC_PERSISTENT_MEMORY_LEGACY; + case E820_RESERVED_KERN: + case E820_RAM: + case E820_UNUSABLE: + default: + return IORES_DESC_NONE; + } +} + static bool do_mark_busy(u32 type, struct resource *res) { /* this is the legacy bios/dos rom-shadow + mmio region */ @@ -967,7 +1003,8 @@ void __init e820_reserve_resources(void) res->start = e820.map[i].addr; res->end = end; - res->flags = IORESOURCE_MEM; + res->flags = e820_type_to_iomem_type(e820.map[i].type); + res->desc = e820_type_to_iores_desc(e820.map[i].type); /* * don't register the region that could be conflicted with diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index d25097c3fc1d..299b58bb975b 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -114,6 +114,10 @@ void __kernel_fpu_begin(void) kernel_fpu_disable(); if (fpu->fpregs_active) { + /* + * Ignore return value -- we don't care if reg state + * is clobbered. + */ copy_fpregs_to_fpstate(fpu); } else { this_cpu_write(fpu_fpregs_owner_ctx, NULL); @@ -189,8 +193,12 @@ void fpu__save(struct fpu *fpu) preempt_disable(); if (fpu->fpregs_active) { - if (!copy_fpregs_to_fpstate(fpu)) - fpregs_deactivate(fpu); + if (!copy_fpregs_to_fpstate(fpu)) { + if (use_eager_fpu()) + copy_kernel_to_fpregs(&fpu->state); + else + fpregs_deactivate(fpu); + } } preempt_enable(); } @@ -223,14 +231,15 @@ void fpstate_init(union fpregs_state *state) } EXPORT_SYMBOL_GPL(fpstate_init); -/* - * Copy the current task's FPU state to a new task's FPU context. - * - * In both the 'eager' and the 'lazy' case we save hardware registers - * directly to the destination buffer. - */ -static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu) +int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) { + dst_fpu->counter = 0; + dst_fpu->fpregs_active = 0; + dst_fpu->last_cpu = -1; + + if (!src_fpu->fpstate_active || !cpu_has_fpu) + return 0; + WARN_ON_FPU(src_fpu != ¤t->thread.fpu); /* @@ -243,10 +252,9 @@ static void 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. - * - * If the FPU context got destroyed in the process (FNSAVE - * done on old CPUs) then copy it back into the source - * context and mark the current task for lazy restore. + * 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 @@ -259,19 +267,13 @@ static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu) preempt_disable(); if (!copy_fpregs_to_fpstate(dst_fpu)) { memcpy(&src_fpu->state, &dst_fpu->state, xstate_size); - fpregs_deactivate(src_fpu); + + if (use_eager_fpu()) + copy_kernel_to_fpregs(&src_fpu->state); + else + fpregs_deactivate(src_fpu); } preempt_enable(); -} - -int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) -{ - dst_fpu->counter = 0; - dst_fpu->fpregs_active = 0; - dst_fpu->last_cpu = -1; - - if (src_fpu->fpstate_active && cpu_has_fpu) - fpu_copy(dst_fpu, src_fpu); return 0; } @@ -423,7 +425,7 @@ void fpu__clear(struct fpu *fpu) { WARN_ON_FPU(fpu != ¤t->thread.fpu); /* Almost certainly an anomaly */ - if (!use_eager_fpu()) { + if (!use_eager_fpu() || !static_cpu_has(X86_FEATURE_FPU)) { /* FPU state will be reallocated lazily at the first use. */ fpu__drop(fpu); } else { diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index 6d9f0a7ef4c8..471fe277ff40 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -260,7 +260,10 @@ static void __init fpu__init_system_xstate_size_legacy(void) * not only saved the restores along the way, but we also have the * FPU ready to be used for the original task. * - * 'eager' switching is used on modern CPUs, there we switch the FPU + * 'lazy' is deprecated because it's almost never a performance win + * and it's much more complicated than 'eager'. + * + * 'eager' switching is by default on all CPUs, there we switch the FPU * state during every context switch, regardless of whether the task * has used FPU instructions in that time slice or not. This is done * because modern FPU context saving instructions are able to optimize @@ -271,7 +274,7 @@ static void __init fpu__init_system_xstate_size_legacy(void) * to use 'eager' restores, if we detect that a task is using the FPU * frequently. See the fpu->counter logic in fpu/internal.h for that. ] */ -static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO; +static enum { ENABLE, DISABLE } eagerfpu = ENABLE; /* * Find supported xfeatures based on cpu features and command-line input. @@ -348,15 +351,9 @@ static void __init fpu__init_system_ctx_switch(void) */ static void __init fpu__init_parse_early_param(void) { - /* - * No need to check "eagerfpu=auto" again, since it is the - * initial default. - */ if (cmdline_find_option_bool(boot_command_line, "eagerfpu=off")) { eagerfpu = DISABLE; fpu__clear_eager_fpu_features(); - } else if (cmdline_find_option_bool(boot_command_line, "eagerfpu=on")) { - eagerfpu = ENABLE; } if (cmdline_find_option_bool(boot_command_line, "no387")) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index f129a9af6357..1f4422d5c8d0 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -40,13 +40,8 @@ pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX); /* Wipe all early page tables except for the kernel symbol map */ static void __init reset_early_page_tables(void) { - unsigned long i; - - for (i = 0; i < PTRS_PER_PGD-1; i++) - early_level4_pgt[i].pgd = 0; - + memset(early_level4_pgt, 0, sizeof(pgd_t)*(PTRS_PER_PGD-1)); next_early_pgt = 0; - write_cr3(__pa_nodebug(early_level4_pgt)); } @@ -54,7 +49,6 @@ static void __init reset_early_page_tables(void) int __init early_make_pgtable(unsigned long address) { unsigned long physaddr = address - __PAGE_OFFSET; - unsigned long i; pgdval_t pgd, *pgd_p; pudval_t pud, *pud_p; pmdval_t pmd, *pmd_p; @@ -81,8 +75,7 @@ again: } pud_p = (pudval_t *)early_dynamic_pgts[next_early_pgt++]; - for (i = 0; i < PTRS_PER_PUD; i++) - pud_p[i] = 0; + memset(pud_p, 0, sizeof(*pud_p) * PTRS_PER_PUD); *pgd_p = (pgdval_t)pud_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE; } pud_p += pud_index(address); @@ -97,8 +90,7 @@ again: } pmd_p = (pmdval_t *)early_dynamic_pgts[next_early_pgt++]; - for (i = 0; i < PTRS_PER_PMD; i++) - pmd_p[i] = 0; + 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; @@ -192,5 +184,13 @@ void __init x86_64_start_reservations(char *real_mode_data) reserve_ebda_region(); + switch (boot_params.hdr.hardware_subarch) { + case X86_SUBARCH_INTEL_MID: + x86_intel_mid_early_setup(); + break; + default: + break; + } + start_kernel(); } diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 6bc9ae24b6d2..54cdbd2003fe 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -389,6 +389,12 @@ default_entry: /* Make changes effective */ wrmsr + /* + * And make sure that all the mappings we set up have NX set from + * the beginning. + */ + orl $(1 << (_PAGE_BIT_NX - 32)), pa(__supported_pte_mask + 4) + enable_paging: /* diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index ffdc0e860390..22fbf9df61bb 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -38,7 +38,6 @@ #define pud_index(x) (((x) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET) -L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET) L4_START_KERNEL = pgd_index(__START_KERNEL_map) L3_START_KERNEL = pud_index(__START_KERNEL_map) @@ -76,9 +75,7 @@ startup_64: subq $_text - __START_KERNEL_map, %rbp /* Is the address not 2M aligned? */ - movq %rbp, %rax - andl $~PMD_PAGE_MASK, %eax - testl %eax, %eax + testl $~PMD_PAGE_MASK, %ebp jnz bad_address /* diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index b8e6ff5cd5d0..be0ebbb6d1d1 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index f8062aaf5df9..61521dc19c10 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -462,7 +462,7 @@ void fixup_irqs(void) * non intr-remapping case, we can't wait till this interrupt * arrives at this cpu before completing the irq move. */ - irq_force_complete_move(irq); + irq_force_complete_move(desc); if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { break_affinity = 1; @@ -470,6 +470,15 @@ void fixup_irqs(void) } chip = irq_data_get_irq_chip(data); + /* + * The interrupt descriptor might have been cleaned up + * already, but it is not yet removed from the radix tree + */ + if (!chip) { + raw_spin_unlock(&desc->lock); + continue; + } + if (!irqd_can_move_in_process_context(data) && chip->irq_mask) chip->irq_mask(data); diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 30ca7607cbbb..97340f2c437c 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -408,7 +408,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) processor.cpuflag = CPU_ENABLED; processor.cpufeature = (boot_cpu_data.x86 << 8) | (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask; - processor.featureflag = boot_cpu_data.x86_capability[0]; + processor.featureflag = boot_cpu_data.x86_capability[CPUID_1_EDX]; processor.reserved[0] = 0; processor.reserved[1] = 0; for (i = 0; i < 2; i++) { diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 64f9616f93f1..7f3550acde1b 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -40,7 +40,7 @@ #include #include -#include +#include #include static struct class *msr_class; diff --git a/arch/x86/kernel/pmem.c b/arch/x86/kernel/pmem.c index 14415aff1813..92f70147a9a6 100644 --- a/arch/x86/kernel/pmem.c +++ b/arch/x86/kernel/pmem.c @@ -13,11 +13,11 @@ static int found(u64 start, u64 end, void *data) static __init int register_e820_pmem(void) { - char *pmem = "Persistent Memory (legacy)"; struct platform_device *pdev; int rc; - rc = walk_iomem_res(pmem, IORESOURCE_MEM, 0, -1, NULL, found); + rc = walk_iomem_res_desc(IORES_DESC_PERSISTENT_MEMORY_LEGACY, + IORESOURCE_MEM, 0, -1, NULL, found); if (rc <= 0) return 0; diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 9f7c21c22477..9decee2bfdbe 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -418,9 +418,9 @@ static void mwait_idle(void) if (!current_set_polling_and_test()) { trace_cpu_idle_rcuidle(1, smp_processor_id()); if (this_cpu_has(X86_BUG_CLFLUSH_MONITOR)) { - smp_mb(); /* quirk */ + mb(); /* quirk */ clflush((void *)¤t_thread_info()->flags); - smp_mb(); /* quirk */ + mb(); /* quirk */ } __monitor((void *)¤t_thread_info()->flags, 0, 0); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index d3d80e6d42a2..aa52c1009475 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -152,21 +152,21 @@ static struct resource data_resource = { .name = "Kernel data", .start = 0, .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; static struct resource code_resource = { .name = "Kernel code", .start = 0, .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; static struct resource bss_resource = { .name = "Kernel bss", .start = 0, .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM }; diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index cb6282c3638f..c07ff5ddbd47 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -692,12 +692,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs) static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs) { -#if defined(CONFIG_X86_32) || !defined(CONFIG_X86_64) +#ifdef CONFIG_X86_64 + if (is_ia32_task()) + return __NR_ia32_restart_syscall; +#endif +#ifdef CONFIG_X86_X32_ABI + return __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); +#else return __NR_restart_syscall; -#else /* !CONFIG_X86_32 && CONFIG_X86_64 */ - return test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : - __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); -#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */ +#endif } /* diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index ade185a46b1d..1e630d1b7ad9 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -83,30 +83,16 @@ gate_desc idt_table[NR_VECTORS] __page_aligned_bss; DECLARE_BITMAP(used_vectors, NR_VECTORS); EXPORT_SYMBOL_GPL(used_vectors); -static inline void conditional_sti(struct pt_regs *regs) +static inline void cond_local_irq_enable(struct pt_regs *regs) { if (regs->flags & X86_EFLAGS_IF) local_irq_enable(); } -static inline void preempt_conditional_sti(struct pt_regs *regs) -{ - preempt_count_inc(); - if (regs->flags & X86_EFLAGS_IF) - local_irq_enable(); -} - -static inline void conditional_cli(struct pt_regs *regs) -{ - if (regs->flags & X86_EFLAGS_IF) - local_irq_disable(); -} - -static inline void preempt_conditional_cli(struct pt_regs *regs) +static inline void cond_local_irq_disable(struct pt_regs *regs) { if (regs->flags & X86_EFLAGS_IF) local_irq_disable(); - preempt_count_dec(); } void ist_enter(struct pt_regs *regs) @@ -286,7 +272,7 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str, if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) != NOTIFY_STOP) { - conditional_sti(regs); + cond_local_irq_enable(regs); do_trap(trapnr, signr, str, regs, error_code, fill_trap_info(regs, signr, trapnr, &info)); } @@ -368,7 +354,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) if (notify_die(DIE_TRAP, "bounds", regs, error_code, X86_TRAP_BR, SIGSEGV) == NOTIFY_STOP) return; - conditional_sti(regs); + cond_local_irq_enable(regs); if (!user_mode(regs)) die("bounds", regs, error_code); @@ -443,7 +429,7 @@ do_general_protection(struct pt_regs *regs, long error_code) struct task_struct *tsk; RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); - conditional_sti(regs); + cond_local_irq_enable(regs); if (v8086_mode(regs)) { local_irq_enable(); @@ -517,9 +503,11 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code) * as we may switch to the interrupt stack. */ debug_stack_usage_inc(); - preempt_conditional_sti(regs); + preempt_disable(); + cond_local_irq_enable(regs); do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL); - preempt_conditional_cli(regs); + cond_local_irq_disable(regs); + preempt_enable_no_resched(); debug_stack_usage_dec(); exit: ist_exit(regs); @@ -648,12 +636,14 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) debug_stack_usage_inc(); /* It's safe to allow irq's after DR6 has been saved */ - preempt_conditional_sti(regs); + preempt_disable(); + cond_local_irq_enable(regs); if (v8086_mode(regs)) { handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, X86_TRAP_DB); - preempt_conditional_cli(regs); + cond_local_irq_disable(regs); + preempt_enable_no_resched(); debug_stack_usage_dec(); goto exit; } @@ -673,7 +663,8 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) si_code = get_si_code(tsk->thread.debugreg6); if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp) send_sigtrap(tsk, regs, error_code, si_code); - preempt_conditional_cli(regs); + cond_local_irq_disable(regs); + preempt_enable_no_resched(); debug_stack_usage_dec(); exit: @@ -696,7 +687,7 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr) if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP) return; - conditional_sti(regs); + cond_local_irq_enable(regs); if (!user_mode(regs)) { if (!fixup_exception(regs)) { @@ -743,20 +734,19 @@ do_simd_coprocessor_error(struct pt_regs *regs, long error_code) dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) { - conditional_sti(regs); + cond_local_irq_enable(regs); } dotraplinkage void do_device_not_available(struct pt_regs *regs, long error_code) { RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); - BUG_ON(use_eager_fpu()); #ifdef CONFIG_MATH_EMULATION - if (read_cr0() & X86_CR0_EM) { + if (!boot_cpu_has(X86_FEATURE_FPU) && (read_cr0() & X86_CR0_EM)) { struct math_emu_info info = { }; - conditional_sti(regs); + cond_local_irq_enable(regs); info.regs = regs; math_emulate(&info); @@ -765,7 +755,7 @@ do_device_not_available(struct pt_regs *regs, long error_code) #endif fpu__restore(¤t->thread.fpu); /* interrupts still off */ #ifdef CONFIG_X86_32 - conditional_sti(regs); + cond_local_irq_enable(regs); #endif } NOKPROBE_SYMBOL(do_device_not_available); diff --git a/arch/x86/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu.S index 07efb35ee4bc..014ea59aa153 100644 --- a/arch/x86/kernel/verify_cpu.S +++ b/arch/x86/kernel/verify_cpu.S @@ -30,7 +30,7 @@ * appropriately. Either display a message or halt. */ -#include +#include #include verify_cpu: diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index e574b8546518..3dce1ca0a653 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -362,7 +362,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus) /* make room for real-mode segments */ tsk->thread.sp0 += 16; - if (static_cpu_has_safe(X86_FEATURE_SEP)) + if (static_cpu_has(X86_FEATURE_SEP)) tsk->thread.sysenter_cs = 0; load_sp0(tss, &tsk->thread); diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 74e4bf11f562..04afe9b7e52a 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -195,6 +195,17 @@ SECTIONS :init #endif + /* + * Section for code used exclusively before alternatives are run. All + * references to such code must be patched out by alternatives, normally + * by using X86_FEATURE_ALWAYS CPU feature bit. + * + * See static_cpu_has() for an example. + */ + .altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) { + *(.altinstr_aux) + } + INIT_DATA_SECTION(16) .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) { @@ -325,6 +336,7 @@ SECTIONS __brk_limit = .; } + . = ALIGN(PAGE_SIZE); _end = .; STABS_DEBUG diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 4ba229ac3f4f..fd57d3ae7e16 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -1520,12 +1520,6 @@ __init void lguest_init(void) */ reserve_top_address(lguest_data.reserve_mem); - /* - * If we don't initialize the lock dependency checker now, it crashes - * atomic_notifier_chain_register, then paravirt_disable_iospace. - */ - lockdep_init(); - /* Hook in our special panic hypercall code. */ atomic_notifier_chain_register(&panic_notifier_list, &paniced); @@ -1535,7 +1529,7 @@ __init void lguest_init(void) */ cpu_detect(&new_cpu_data); /* head.S usually sets up the first capability word, so do it here. */ - new_cpu_data.x86_capability[0] = cpuid_edx(1); + new_cpu_data.x86_capability[CPUID_1_EDX] = cpuid_edx(1); /* Math is always hard! */ set_cpu_cap(&new_cpu_data, X86_FEATURE_FPU); diff --git a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S index a2fe51b00cce..65be7cfaf947 100644 --- a/arch/x86/lib/clear_page_64.S +++ b/arch/x86/lib/clear_page_64.S @@ -1,5 +1,5 @@ #include -#include +#include #include /* diff --git a/arch/x86/lib/cmdline.c b/arch/x86/lib/cmdline.c index 422db000d727..5cc78bf57232 100644 --- a/arch/x86/lib/cmdline.c +++ b/arch/x86/lib/cmdline.c @@ -21,12 +21,16 @@ static inline int myisspace(u8 c) * @option: option string to look for * * Returns the position of that @option (starts counting with 1) - * or 0 on not found. + * or 0 on not found. @option will only be found if it is found + * as an entire word in @cmdline. For instance, if @option="car" + * then a cmdline which contains "cart" will not match. */ -int cmdline_find_option_bool(const char *cmdline, const char *option) +static int +__cmdline_find_option_bool(const char *cmdline, int max_cmdline_size, + const char *option) { char c; - int len, pos = 0, wstart = 0; + int pos = 0, wstart = 0; const char *opptr = NULL; enum { st_wordstart = 0, /* Start of word/after whitespace */ @@ -37,11 +41,11 @@ int cmdline_find_option_bool(const char *cmdline, const char *option) if (!cmdline) return -1; /* No command line */ - len = min_t(int, strlen(cmdline), COMMAND_LINE_SIZE); - if (!len) - return 0; - - while (len--) { + /* + * This 'pos' check ensures we do not overrun + * a non-NULL-terminated 'cmdline' + */ + while (pos < max_cmdline_size) { c = *(char *)cmdline++; pos++; @@ -58,18 +62,35 @@ int cmdline_find_option_bool(const char *cmdline, const char *option) /* fall through */ case st_wordcmp: - if (!*opptr) + if (!*opptr) { + /* + * We matched all the way to the end of the + * option we were looking for. If the + * command-line has a space _or_ ends, then + * we matched! + */ if (!c || myisspace(c)) return wstart; - else - state = st_wordskip; - else if (!c) + /* + * We hit the end of the option, but _not_ + * the end of a word on the cmdline. Not + * a match. + */ + } else if (!c) { + /* + * Hit the NULL terminator on the end of + * cmdline. + */ return 0; - else if (c != *opptr++) - state = st_wordskip; - else if (!len) /* last word and is matching */ - return wstart; - break; + } else if (c == *opptr++) { + /* + * We are currently matching, so continue + * to the next character on the cmdline. + */ + break; + } + state = st_wordskip; + /* fall through */ case st_wordskip: if (!c) @@ -82,3 +103,8 @@ int cmdline_find_option_bool(const char *cmdline, const char *option) return 0; /* Buffer overrun */ } + +int cmdline_find_option_bool(const char *cmdline, const char *option) +{ + return __cmdline_find_option_bool(cmdline, COMMAND_LINE_SIZE, option); +} diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S index 009f98216b7e..24ef1c2104d4 100644 --- a/arch/x86/lib/copy_page_64.S +++ b/arch/x86/lib/copy_page_64.S @@ -1,7 +1,7 @@ /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */ #include -#include +#include #include /* diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index 982ce34f4a9b..fba343062055 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S index 16698bba87de..a0de849435ad 100644 --- a/arch/x86/lib/memcpy_64.S +++ b/arch/x86/lib/memcpy_64.S @@ -1,7 +1,7 @@ /* Copyright 2002 Andi Kleen */ #include -#include +#include #include /* diff --git a/arch/x86/lib/memmove_64.S b/arch/x86/lib/memmove_64.S index ca2afdd6d98e..90ce01bee00c 100644 --- a/arch/x86/lib/memmove_64.S +++ b/arch/x86/lib/memmove_64.S @@ -6,7 +6,7 @@ * - Copyright 2011 Fenghua Yu */ #include -#include +#include #include #undef memmove diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S index 2661fad05827..c9c81227ea37 100644 --- a/arch/x86/lib/memset_64.S +++ b/arch/x86/lib/memset_64.S @@ -1,7 +1,7 @@ /* Copyright 2002 Andi Kleen, SuSE Labs */ #include -#include +#include #include .weak memset diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c index 42982b26e32b..740d7ac03a55 100644 --- a/arch/x86/mm/hugetlbpage.c +++ b/arch/x86/mm/hugetlbpage.c @@ -173,10 +173,10 @@ static __init int setup_hugepagesz(char *opt) } __setup("hugepagesz=", setup_hugepagesz); -#ifdef CONFIG_CMA +#if (defined(CONFIG_MEMORY_ISOLATION) && defined(CONFIG_COMPACTION)) || defined(CONFIG_CMA) static __init int gigantic_pages_init(void) { - /* With CMA we can allocate gigantic pages at runtime */ + /* With compaction or CMA we can allocate gigantic pages at runtime */ if (cpu_has_gbpages && !size_to_hstate(1UL << PUD_SHIFT)) hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); return 0; diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index cb4ef3de61f9..a4bb1c7ab65e 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -388,7 +388,6 @@ repeat: } pte_t *kmap_pte; -pgprot_t kmap_prot; static inline pte_t *kmap_get_fixmap_pte(unsigned long vaddr) { @@ -405,8 +404,6 @@ static void __init kmap_init(void) */ kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); kmap_pte = kmap_get_fixmap_pte(kmap_vstart); - - kmap_prot = PAGE_KERNEL; } #ifdef CONFIG_HIGHMEM diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 5488d21123bd..9686535edfb5 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include "mm_internal.h" @@ -1206,26 +1207,13 @@ int kern_addr_valid(unsigned long addr) static unsigned long probe_memory_block_size(void) { - /* start from 2g */ - unsigned long bz = 1UL<<31; + unsigned long bz = MIN_MEMORY_BLOCK_SIZE; - if (totalram_pages >= (64ULL << (30 - PAGE_SHIFT))) { - pr_info("Using 2GB memory block size for large-memory system\n"); - return 2UL * 1024 * 1024 * 1024; - } - - /* less than 64g installed */ - if ((max_pfn << PAGE_SHIFT) < (16UL << 32)) - return MIN_MEMORY_BLOCK_SIZE; - - /* get the tail size */ - while (bz > MIN_MEMORY_BLOCK_SIZE) { - if (!((max_pfn << PAGE_SHIFT) & (bz - 1))) - break; - bz >>= 1; - } + /* if system is UV or has 64GB of RAM or more, use large blocks */ + if (is_uv_system() || ((max_pfn << PAGE_SHIFT) >= (64UL << 30))) + bz = 2UL << 30; /* 2GB */ - printk(KERN_DEBUG "memory block size : %ldMB\n", bz >> 20); + pr_info("x86/mm: Memory block size: %ldMB\n", bz >> 20); return bz; } diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c index d470cf219a2d..1b1110fa0057 100644 --- a/arch/x86/mm/kasan_init_64.c +++ b/arch/x86/mm/kasan_init_64.c @@ -120,11 +120,22 @@ void __init kasan_init(void) kasan_populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END), (void *)KASAN_SHADOW_END); - memset(kasan_zero_page, 0, PAGE_SIZE); - load_cr3(init_level4_pgt); __flush_tlb_all(); - init_task.kasan_depth = 0; + /* + * kasan_zero_page has been used as early shadow memory, thus it may + * contain some garbage. Now we can clear and write protect it, since + * after the TLB flush no one should write to it. + */ + memset(kasan_zero_page, 0, PAGE_SIZE); + for (i = 0; i < PTRS_PER_PTE; i++) { + pte_t pte = __pte(__pa(kasan_zero_page) | __PAGE_KERNEL_RO); + set_pte(&kasan_zero_pte[i], pte); + } + /* Flush TLBs again to be sure that write protection applied. */ + __flush_tlb_all(); + + init_task.kasan_depth = 0; pr_info("KernelAddressSanitizer initialized\n"); } diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index c3b3f653ed0c..f70c1ff46125 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c @@ -465,46 +465,67 @@ static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi) return true; } +/* + * Mark all currently memblock-reserved physical memory (which covers the + * kernel's own memory ranges) as hot-unswappable. + */ static void __init numa_clear_kernel_node_hotplug(void) { - int i, nid; - nodemask_t numa_kernel_nodes = NODE_MASK_NONE; - unsigned long start, end; - struct memblock_region *r; + nodemask_t reserved_nodemask = NODE_MASK_NONE; + struct memblock_region *mb_region; + int i; /* + * We have to do some preprocessing of memblock regions, to + * make them suitable for reservation. + * * At this time, all memory regions reserved by memblock are - * used by the kernel. Set the nid in memblock.reserved will - * mark out all the nodes the kernel resides in. + * used by the kernel, but those regions are not split up + * along node boundaries yet, and don't necessarily have their + * node ID set yet either. + * + * So iterate over all memory known to the x86 architecture, + * and use those ranges to set the nid in memblock.reserved. + * This will split up the memblock regions along node + * boundaries and will set the node IDs as well. */ for (i = 0; i < numa_meminfo.nr_blks; i++) { - struct numa_memblk *mb = &numa_meminfo.blk[i]; + struct numa_memblk *mb = numa_meminfo.blk + i; + int ret; - memblock_set_node(mb->start, mb->end - mb->start, - &memblock.reserved, mb->nid); + ret = memblock_set_node(mb->start, mb->end - mb->start, &memblock.reserved, mb->nid); + WARN_ON_ONCE(ret); } /* - * Mark all kernel nodes. + * Now go over all reserved memblock regions, to construct a + * node mask of all kernel reserved memory areas. * - * When booting with mem=nn[kMG] or in a kdump kernel, numa_meminfo - * may not include all the memblock.reserved memory ranges because - * trim_snb_memory() reserves specific pages for Sandy Bridge graphics. + * [ Note, when booting with mem=nn[kMG] or in a kdump kernel, + * numa_meminfo might not include all memblock.reserved + * memory ranges, because quirks such as trim_snb_memory() + * reserve specific pages for Sandy Bridge graphics. ] */ - for_each_memblock(reserved, r) - if (r->nid != MAX_NUMNODES) - node_set(r->nid, numa_kernel_nodes); + for_each_memblock(reserved, mb_region) { + if (mb_region->nid != MAX_NUMNODES) + node_set(mb_region->nid, reserved_nodemask); + } - /* Clear MEMBLOCK_HOTPLUG flag for memory in kernel nodes. */ + /* + * Finally, clear the MEMBLOCK_HOTPLUG flag for all memory + * belonging to the reserved node mask. + * + * Note that this will include memory regions that reside + * on nodes that contain kernel memory - entire nodes + * become hot-unpluggable: + */ for (i = 0; i < numa_meminfo.nr_blks; i++) { - nid = numa_meminfo.blk[i].nid; - if (!node_isset(nid, numa_kernel_nodes)) - continue; + struct numa_memblk *mb = numa_meminfo.blk + i; - start = numa_meminfo.blk[i].start; - end = numa_meminfo.blk[i].end; + if (!node_isset(mb->nid, reserved_nodemask)) + continue; - memblock_clear_hotplug(start, end - start); + memblock_clear_hotplug(mb->start, mb->end - mb->start); } } diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index fc6a4c8f6e2a..632d34d20237 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -33,7 +33,7 @@ struct cpa_data { pgd_t *pgd; pgprot_t mask_set; pgprot_t mask_clr; - int numpages; + unsigned long numpages; int flags; unsigned long pfn; unsigned force_split : 1; @@ -910,15 +910,10 @@ static void populate_pte(struct cpa_data *cpa, pte = pte_offset_kernel(pmd, start); while (num_pages-- && start < end) { - - /* deal with the NX bit */ - if (!(pgprot_val(pgprot) & _PAGE_NX)) - cpa->pfn &= ~_PAGE_NX; - - set_pte(pte, pfn_pte(cpa->pfn >> PAGE_SHIFT, pgprot)); + set_pte(pte, pfn_pte(cpa->pfn, pgprot)); start += PAGE_SIZE; - cpa->pfn += PAGE_SIZE; + cpa->pfn++; pte++; } } @@ -974,11 +969,11 @@ static int populate_pmd(struct cpa_data *cpa, pmd = pmd_offset(pud, start); - set_pmd(pmd, __pmd(cpa->pfn | _PAGE_PSE | + set_pmd(pmd, __pmd(cpa->pfn << PAGE_SHIFT | _PAGE_PSE | massage_pgprot(pmd_pgprot))); start += PMD_SIZE; - cpa->pfn += PMD_SIZE; + cpa->pfn += PMD_SIZE >> PAGE_SHIFT; cur_pages += PMD_SIZE >> PAGE_SHIFT; } @@ -1047,11 +1042,11 @@ static int populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd, * Map everything starting from the Gb boundary, possibly with 1G pages */ while (end - start >= PUD_SIZE) { - set_pud(pud, __pud(cpa->pfn | _PAGE_PSE | + set_pud(pud, __pud(cpa->pfn << PAGE_SHIFT | _PAGE_PSE | massage_pgprot(pud_pgprot))); start += PUD_SIZE; - cpa->pfn += PUD_SIZE; + cpa->pfn += PUD_SIZE >> PAGE_SHIFT; cur_pages += PUD_SIZE >> PAGE_SHIFT; pud++; } @@ -1350,7 +1345,7 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) * CPA operation. Either a large page has been * preserved or a single page update happened. */ - BUG_ON(cpa->numpages > numpages); + BUG_ON(cpa->numpages > numpages || !cpa->numpages); numpages -= cpa->numpages; if (cpa->flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) cpa->curpage++; diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index f4ae536b0914..04e2e7144bee 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -943,7 +943,7 @@ int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot, return -EINVAL; } - *prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) | + *prot = __pgprot((pgprot_val(*prot) & (~_PAGE_CACHE_MASK)) | cachemode2protval(pcm)); return 0; @@ -959,7 +959,7 @@ int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot, /* Set prot based on lookup */ pcm = lookup_memtype(pfn_t_to_phys(pfn)); - *prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) | + *prot = __pgprot((pgprot_val(*prot) & (~_PAGE_CACHE_MASK)) | cachemode2protval(pcm)); return 0; diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c index 92e2eacb3321..8bea84724a7d 100644 --- a/arch/x86/mm/setup_nx.c +++ b/arch/x86/mm/setup_nx.c @@ -4,6 +4,7 @@ #include #include +#include static int disable_nx; @@ -31,9 +32,8 @@ early_param("noexec", noexec_setup); void x86_configure_nx(void) { - if (boot_cpu_has(X86_FEATURE_NX) && !disable_nx) - __supported_pte_mask |= _PAGE_NX; - else + /* If disable_nx is set, clear NX on all new mappings going forward. */ + if (disable_nx) __supported_pte_mask &= ~_PAGE_NX; } diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 50d86c0e9ba4..660a83c8287b 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "op_x86_model.h" #include "op_counter.h" diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 2879efc73a96..b4a9f23d77d9 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c index ea48449b2e63..a2433817c987 100644 --- a/arch/x86/platform/efi/efi-bgrt.c +++ b/arch/x86/platform/efi/efi-bgrt.c @@ -10,6 +10,9 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -28,8 +31,7 @@ struct bmp_header { void __init efi_bgrt_init(void) { acpi_status status; - void __iomem *image; - bool ioremapped = false; + void *image; struct bmp_header bmp_header; if (acpi_disabled) @@ -55,11 +57,6 @@ void __init efi_bgrt_init(void) bgrt_tab->status); return; } - if (bgrt_tab->status != 1) { - pr_debug("Ignoring BGRT: invalid status %u (expected 1)\n", - bgrt_tab->status); - return; - } if (bgrt_tab->image_type != 0) { pr_err("Ignoring BGRT: invalid image type %u (expected 0)\n", bgrt_tab->image_type); @@ -70,20 +67,19 @@ void __init efi_bgrt_init(void) return; } - image = efi_lookup_mapped_addr(bgrt_tab->image_address); + image = memremap(bgrt_tab->image_address, sizeof(bmp_header), MEMREMAP_WB); if (!image) { - image = early_ioremap(bgrt_tab->image_address, - sizeof(bmp_header)); - ioremapped = true; - if (!image) { - pr_err("Ignoring BGRT: failed to map image header memory\n"); - return; - } + pr_err("Ignoring BGRT: failed to map image header memory\n"); + return; } - memcpy_fromio(&bmp_header, image, sizeof(bmp_header)); - if (ioremapped) - early_iounmap(image, sizeof(bmp_header)); + memcpy(&bmp_header, image, sizeof(bmp_header)); + memunmap(image); + if (bmp_header.id != 0x4d42) { + pr_err("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n", + bmp_header.id); + return; + } bgrt_image_size = bmp_header.size; bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN); @@ -93,18 +89,14 @@ void __init efi_bgrt_init(void) return; } - if (ioremapped) { - image = early_ioremap(bgrt_tab->image_address, - bmp_header.size); - if (!image) { - pr_err("Ignoring BGRT: failed to map image memory\n"); - kfree(bgrt_image); - bgrt_image = NULL; - return; - } + image = memremap(bgrt_tab->image_address, bmp_header.size, MEMREMAP_WB); + if (!image) { + pr_err("Ignoring BGRT: failed to map image memory\n"); + kfree(bgrt_image); + bgrt_image = NULL; + return; } - memcpy_fromio(bgrt_image, image, bgrt_image_size); - if (ioremapped) - early_iounmap(image, bmp_header.size); + memcpy(bgrt_image, image, bgrt_image_size); + memunmap(image); } diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index ad285404ea7f..e80826e6f3a9 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -235,10 +235,10 @@ void __init efi_print_memmap(void) char buf[64]; md = p; - pr_info("mem%02u: %s range=[0x%016llx-0x%016llx) (%lluMB)\n", + pr_info("mem%02u: %s range=[0x%016llx-0x%016llx] (%lluMB)\n", i, efi_md_typeattr_format(buf, sizeof(buf), md), md->phys_addr, - md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), + md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1, (md->num_pages >> (20 - EFI_PAGE_SHIFT))); } #endif /* EFI_DEBUG */ @@ -815,6 +815,7 @@ static void __init kexec_enter_virtual_mode(void) { #ifdef CONFIG_KEXEC_CORE efi_memory_desc_t *md; + unsigned int num_pages; void *p; efi.systab = NULL; @@ -829,6 +830,12 @@ static void __init kexec_enter_virtual_mode(void) return; } + if (efi_alloc_page_tables()) { + pr_err("Failed to allocate EFI page tables\n"); + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return; + } + /* * Map efi regions which were passed via setup_data. The virt_addr is a * fixed addr which was used in first kernel of a kexec boot. @@ -843,6 +850,14 @@ static void __init kexec_enter_virtual_mode(void) BUG_ON(!efi.systab); + num_pages = ALIGN(memmap.nr_map * memmap.desc_size, PAGE_SIZE); + num_pages >>= PAGE_SHIFT; + + if (efi_setup_page_tables(memmap.phys_map, num_pages)) { + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return; + } + efi_sync_low_kernel_mappings(); /* @@ -869,7 +884,7 @@ static void __init kexec_enter_virtual_mode(void) * This function will switch the EFI runtime services to virtual mode. * Essentially, we look through the EFI memmap and map every region that * has the runtime attribute bit set in its memory descriptor into the - * ->trampoline_pgd page table using a top-down VA allocation scheme. + * efi_pgd page table. * * The old method which used to update that memory descriptor with the * virtual address obtained from ioremap() is still supported when the @@ -879,8 +894,8 @@ static void __init kexec_enter_virtual_mode(void) * * The new method does a pagetable switch in a preemption-safe manner * so that we're in a different address space when calling a runtime - * function. For function arguments passing we do copy the PGDs of the - * kernel page table into ->trampoline_pgd prior to each call. + * function. For function arguments passing we do copy the PUDs of the + * kernel page table into efi_pgd prior to each call. * * Specially for kexec boot, efi runtime maps in previous kernel should * be passed in via setup_data. In that case runtime ranges will be mapped @@ -895,6 +910,12 @@ static void __init __efi_enter_virtual_mode(void) efi.systab = NULL; + if (efi_alloc_page_tables()) { + pr_err("Failed to allocate EFI page tables\n"); + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return; + } + efi_merge_regions(); new_memmap = efi_map_regions(&count, &pg_shift); if (!new_memmap) { @@ -954,28 +975,11 @@ static void __init __efi_enter_virtual_mode(void) efi_runtime_mkexec(); /* - * We mapped the descriptor array into the EFI pagetable above but we're - * not unmapping it here. Here's why: - * - * We're copying select PGDs from the kernel page table to the EFI page - * table and when we do so and make changes to those PGDs like unmapping - * stuff from them, those changes appear in the kernel page table and we - * go boom. - * - * From setup_real_mode(): - * - * ... - * trampoline_pgd[0] = init_level4_pgt[pgd_index(__PAGE_OFFSET)].pgd; - * - * In this particular case, our allocation is in PGD 0 of the EFI page - * table but we've copied that PGD from PGD[272] of the EFI page table: - * - * pgd_index(__PAGE_OFFSET = 0xffff880000000000) = 272 - * - * where the direct memory mapping in kernel space is. - * - * new_memmap's VA comes from that direct mapping and thus clearing it, - * it would get cleared in the kernel page table too. + * We mapped the descriptor array into the EFI pagetable above + * but we're not unmapping it here because if we're running in + * EFI mixed mode we need all of memory to be accessible when + * we pass parameters to the EFI runtime services in the + * thunking code. * * efi_cleanup_page_tables(__pa(new_memmap), 1 << pg_shift); */ diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index ed5b67338294..58d669bc8250 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -38,6 +38,11 @@ * say 0 - 3G. */ +int __init efi_alloc_page_tables(void) +{ + return 0; +} + void efi_sync_low_kernel_mappings(void) {} void __init efi_dump_pagetable(void) {} int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index a0ac0f9c307f..b492521503fe 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -15,6 +15,8 @@ * */ +#define pr_fmt(fmt) "efi: " fmt + #include #include #include @@ -40,6 +42,7 @@ #include #include #include +#include /* * We allocate runtime services regions bottom-up, starting from -4G, i.e. @@ -47,16 +50,7 @@ */ static u64 efi_va = EFI_VA_START; -/* - * Scratch space used for switching the pagetable in the EFI stub - */ -struct efi_scratch { - u64 r15; - u64 prev_cr3; - pgd_t *efi_pgt; - bool use_pgd; - u64 phys_stack; -} __packed; +struct efi_scratch efi_scratch; static void __init early_code_mapping_set_exec(int executable) { @@ -83,8 +77,11 @@ pgd_t * __init efi_call_phys_prolog(void) int pgd; int n_pgds; - if (!efi_enabled(EFI_OLD_MEMMAP)) - return NULL; + if (!efi_enabled(EFI_OLD_MEMMAP)) { + save_pgd = (pgd_t *)read_cr3(); + write_cr3((unsigned long)efi_scratch.efi_pgt); + goto out; + } early_code_mapping_set_exec(1); @@ -96,6 +93,7 @@ pgd_t * __init efi_call_phys_prolog(void) vaddress = (unsigned long)__va(pgd * PGDIR_SIZE); set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress)); } +out: __flush_tlb_all(); return save_pgd; @@ -109,8 +107,11 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) int pgd_idx; int nr_pgds; - if (!save_pgd) + if (!efi_enabled(EFI_OLD_MEMMAP)) { + write_cr3((unsigned long)save_pgd); + __flush_tlb_all(); return; + } nr_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE); @@ -123,27 +124,98 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) early_code_mapping_set_exec(0); } +static pgd_t *efi_pgd; + +/* + * We need our own copy of the higher levels of the page tables + * because we want to avoid inserting EFI region mappings (EFI_VA_END + * to EFI_VA_START) into the standard kernel page tables. Everything + * else can be shared, see efi_sync_low_kernel_mappings(). + */ +int __init efi_alloc_page_tables(void) +{ + pgd_t *pgd; + pud_t *pud; + gfp_t gfp_mask; + + if (efi_enabled(EFI_OLD_MEMMAP)) + return 0; + + gfp_mask = GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO; + efi_pgd = (pgd_t *)__get_free_page(gfp_mask); + if (!efi_pgd) + return -ENOMEM; + + pgd = efi_pgd + pgd_index(EFI_VA_END); + + pud = pud_alloc_one(NULL, 0); + if (!pud) { + free_page((unsigned long)efi_pgd); + return -ENOMEM; + } + + pgd_populate(NULL, pgd, pud); + + return 0; +} + /* * Add low kernel mappings for passing arguments to EFI functions. */ void efi_sync_low_kernel_mappings(void) { - unsigned num_pgds; - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); + unsigned num_entries; + pgd_t *pgd_k, *pgd_efi; + pud_t *pud_k, *pud_efi; if (efi_enabled(EFI_OLD_MEMMAP)) return; - num_pgds = pgd_index(MODULES_END - 1) - pgd_index(PAGE_OFFSET); + /* + * We can share all PGD entries apart from the one entry that + * covers the EFI runtime mapping space. + * + * Make sure the EFI runtime region mappings are guaranteed to + * only span a single PGD entry and that the entry also maps + * other important kernel regions. + */ + BUILD_BUG_ON(pgd_index(EFI_VA_END) != pgd_index(MODULES_END)); + BUILD_BUG_ON((EFI_VA_START & PGDIR_MASK) != + (EFI_VA_END & PGDIR_MASK)); + + pgd_efi = efi_pgd + pgd_index(PAGE_OFFSET); + pgd_k = pgd_offset_k(PAGE_OFFSET); + + num_entries = pgd_index(EFI_VA_END) - pgd_index(PAGE_OFFSET); + memcpy(pgd_efi, pgd_k, sizeof(pgd_t) * num_entries); + + /* + * We share all the PUD entries apart from those that map the + * EFI regions. Copy around them. + */ + BUILD_BUG_ON((EFI_VA_START & ~PUD_MASK) != 0); + BUILD_BUG_ON((EFI_VA_END & ~PUD_MASK) != 0); + + pgd_efi = efi_pgd + pgd_index(EFI_VA_END); + pud_efi = pud_offset(pgd_efi, 0); - memcpy(pgd + pgd_index(PAGE_OFFSET), - init_mm.pgd + pgd_index(PAGE_OFFSET), - sizeof(pgd_t) * num_pgds); + pgd_k = pgd_offset_k(EFI_VA_END); + pud_k = pud_offset(pgd_k, 0); + + num_entries = pud_index(EFI_VA_END); + memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); + + pud_efi = pud_offset(pgd_efi, EFI_VA_START); + pud_k = pud_offset(pgd_k, EFI_VA_START); + + num_entries = PTRS_PER_PUD - pud_index(EFI_VA_START); + memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); } int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) { - unsigned long text; + unsigned long pfn, text; + efi_memory_desc_t *md; struct page *page; unsigned npages; pgd_t *pgd; @@ -151,8 +223,8 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) if (efi_enabled(EFI_OLD_MEMMAP)) return 0; - efi_scratch.efi_pgt = (pgd_t *)(unsigned long)real_mode_header->trampoline_pgd; - pgd = __va(efi_scratch.efi_pgt); + efi_scratch.efi_pgt = (pgd_t *)__pa(efi_pgd); + pgd = efi_pgd; /* * It can happen that the physical address of new_memmap lands in memory @@ -160,7 +232,8 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) * and ident-map those pages containing the map before calling * phys_efi_set_virtual_address_map(). */ - if (kernel_map_pages_in_pgd(pgd, pa_memmap, pa_memmap, num_pages, _PAGE_NX)) { + pfn = pa_memmap >> PAGE_SHIFT; + if (kernel_map_pages_in_pgd(pgd, pfn, pa_memmap, num_pages, _PAGE_NX)) { pr_err("Error ident-mapping new memmap (0x%lx)!\n", pa_memmap); return 1; } @@ -176,6 +249,25 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) if (!IS_ENABLED(CONFIG_EFI_MIXED)) return 0; + /* + * Map all of RAM so that we can access arguments in the 1:1 + * mapping when making EFI runtime calls. + */ + for_each_efi_memory_desc(&memmap, md) { + if (md->type != EFI_CONVENTIONAL_MEMORY && + md->type != EFI_LOADER_DATA && + md->type != EFI_LOADER_CODE) + continue; + + pfn = md->phys_addr >> PAGE_SHIFT; + npages = md->num_pages; + + if (kernel_map_pages_in_pgd(pgd, pfn, md->phys_addr, npages, 0)) { + pr_err("Failed to map 1:1 memory\n"); + return 1; + } + } + page = alloc_page(GFP_KERNEL|__GFP_DMA32); if (!page) panic("Unable to allocate EFI runtime stack < 4GB\n"); @@ -185,8 +277,9 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) npages = (_end - _text) >> PAGE_SHIFT; text = __pa(_text); + pfn = text >> PAGE_SHIFT; - if (kernel_map_pages_in_pgd(pgd, text >> PAGE_SHIFT, text, npages, 0)) { + if (kernel_map_pages_in_pgd(pgd, pfn, text, npages, 0)) { pr_err("Failed to map kernel text 1:1\n"); return 1; } @@ -196,20 +289,20 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) { - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); - - kernel_unmap_pages_in_pgd(pgd, pa_memmap, num_pages); + kernel_unmap_pages_in_pgd(efi_pgd, pa_memmap, num_pages); } static void __init __map_region(efi_memory_desc_t *md, u64 va) { - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); - unsigned long pf = 0; + unsigned long flags = 0; + unsigned long pfn; + pgd_t *pgd = efi_pgd; if (!(md->attribute & EFI_MEMORY_WB)) - pf |= _PAGE_PCD; + flags |= _PAGE_PCD; - if (kernel_map_pages_in_pgd(pgd, md->phys_addr, va, md->num_pages, pf)) + pfn = md->phys_addr >> PAGE_SHIFT; + if (kernel_map_pages_in_pgd(pgd, pfn, va, md->num_pages, flags)) pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n", md->phys_addr, va); } @@ -312,9 +405,7 @@ void __init efi_runtime_mkexec(void) void __init efi_dump_pagetable(void) { #ifdef CONFIG_EFI_PGT_DUMP - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); - - ptdump_walk_pgd_level(NULL, pgd); + ptdump_walk_pgd_level(NULL, efi_pgd); #endif } diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S index 86d0f9e08dd9..32020cb8bb08 100644 --- a/arch/x86/platform/efi/efi_stub_64.S +++ b/arch/x86/platform/efi/efi_stub_64.S @@ -38,41 +38,6 @@ mov %rsi, %cr0; \ mov (%rsp), %rsp - /* stolen from gcc */ - .macro FLUSH_TLB_ALL - movq %r15, efi_scratch(%rip) - movq %r14, efi_scratch+8(%rip) - movq %cr4, %r15 - movq %r15, %r14 - andb $0x7f, %r14b - movq %r14, %cr4 - movq %r15, %cr4 - movq efi_scratch+8(%rip), %r14 - movq efi_scratch(%rip), %r15 - .endm - - .macro SWITCH_PGT - cmpb $0, efi_scratch+24(%rip) - je 1f - movq %r15, efi_scratch(%rip) # r15 - # save previous CR3 - movq %cr3, %r15 - movq %r15, efi_scratch+8(%rip) # prev_cr3 - movq efi_scratch+16(%rip), %r15 # EFI pgt - movq %r15, %cr3 - 1: - .endm - - .macro RESTORE_PGT - cmpb $0, efi_scratch+24(%rip) - je 2f - movq efi_scratch+8(%rip), %r15 - movq %r15, %cr3 - movq efi_scratch(%rip), %r15 - FLUSH_TLB_ALL - 2: - .endm - ENTRY(efi_call) SAVE_XMM mov (%rsp), %rax @@ -83,16 +48,8 @@ ENTRY(efi_call) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx - SWITCH_PGT call *%rdi - RESTORE_PGT addq $48, %rsp RESTORE_XMM ret ENDPROC(efi_call) - - .data -ENTRY(efi_scratch) - .fill 3,8,0 - .byte 0 - .quad 0 diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 1c7380da65ff..2326bf51978f 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -1,3 +1,5 @@ +#define pr_fmt(fmt) "efi: " fmt + #include #include #include @@ -8,6 +10,7 @@ #include #include #include +#include #include #include @@ -53,6 +56,33 @@ void efi_delete_dummy_variable(void) 0, NULL); } +/* + * In the nonblocking case we do not attempt to perform garbage + * collection if we do not have enough free space. Rather, we do the + * bare minimum check and give up immediately if the available space + * is below EFI_MIN_RESERVE. + * + * This function is intended to be small and simple because it is + * invoked from crash handler paths. + */ +static efi_status_t +query_variable_store_nonblocking(u32 attributes, unsigned long size) +{ + efi_status_t status; + u64 storage_size, remaining_size, max_size; + + status = efi.query_variable_info_nonblocking(attributes, &storage_size, + &remaining_size, + &max_size); + if (status != EFI_SUCCESS) + return status; + + if (remaining_size - size < EFI_MIN_RESERVE) + return EFI_OUT_OF_RESOURCES; + + return EFI_SUCCESS; +} + /* * Some firmware implementations refuse to boot if there's insufficient space * in the variable store. Ensure that we never use more than a safe limit. @@ -60,7 +90,8 @@ void efi_delete_dummy_variable(void) * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable * store. */ -efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) +efi_status_t efi_query_variable_store(u32 attributes, unsigned long size, + bool nonblocking) { efi_status_t status; u64 storage_size, remaining_size, max_size; @@ -68,6 +99,9 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) return 0; + if (nonblocking) + return query_variable_store_nonblocking(attributes, size); + status = efi.query_variable_info(attributes, &storage_size, &remaining_size, &max_size); if (status != EFI_SUCCESS) @@ -248,6 +282,16 @@ out: return ret; } +static const struct dmi_system_id sgi_uv1_dmi[] = { + { NULL, "SGI UV1", + { DMI_MATCH(DMI_PRODUCT_NAME, "Stoutland Platform"), + DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), + DMI_MATCH(DMI_BIOS_VENDOR, "SGI.COM"), + } + }, + { } /* NULL entry stops DMI scanning */ +}; + void __init efi_apply_memmap_quirks(void) { /* @@ -256,14 +300,12 @@ void __init efi_apply_memmap_quirks(void) * services. */ if (!efi_runtime_supported()) { - pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); + pr_info("Setup done, disabling due to 32/64-bit mismatch\n"); efi_unmap_memmap(); } - /* - * UV doesn't support the new EFI pagetable mapping yet. - */ - if (is_uv_system()) + /* UV2+ BIOS has a fix for this issue. UV1 still needs the quirk. */ + if (dmi_check_system(sgi_uv1_dmi)) set_bit(EFI_OLD_MEMMAP, &efi.flags); } diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c index 1bbc21e2e4ae..90bb997ed0a2 100644 --- a/arch/x86/platform/intel-mid/intel-mid.c +++ b/arch/x86/platform/intel-mid/intel-mid.c @@ -138,7 +138,7 @@ static void intel_mid_arch_setup(void) intel_mid_ops = get_intel_mid_ops[__intel_mid_cpu_chip](); else { intel_mid_ops = get_intel_mid_ops[INTEL_MID_CPU_CHIP_PENWELL](); - pr_info("ARCH: Unknown SoC, assuming PENWELL!\n"); + pr_info("ARCH: Unknown SoC, assuming Penwell!\n"); } out: @@ -214,12 +214,10 @@ static inline int __init setup_x86_intel_mid_timer(char *arg) else if (strcmp("lapic_and_apbt", arg) == 0) intel_mid_timer_options = INTEL_MID_TIMER_LAPIC_APBT; else { - pr_warn("X86 INTEL_MID timer option %s not recognised" - " use x86_intel_mid_timer=apbt_only or lapic_and_apbt\n", - arg); + pr_warn("X86 INTEL_MID timer option %s not recognised use x86_intel_mid_timer=apbt_only or lapic_and_apbt\n", + arg); return -EINVAL; } return 0; } __setup("x86_intel_mid_timer=", setup_x86_intel_mid_timer); - diff --git a/arch/x86/platform/intel-quark/imr.c b/arch/x86/platform/intel-quark/imr.c index c1bdafaac3ca..c61b6c332e97 100644 --- a/arch/x86/platform/intel-quark/imr.c +++ b/arch/x86/platform/intel-quark/imr.c @@ -220,11 +220,12 @@ static int imr_dbgfs_state_show(struct seq_file *s, void *unused) if (imr_is_enabled(&imr)) { base = imr_to_phys(imr.addr_lo); end = imr_to_phys(imr.addr_hi) + IMR_MASK; + size = end - base + 1; } else { base = 0; end = 0; + size = 0; } - size = end - base; seq_printf(s, "imr%02i: base=%pa, end=%pa, size=0x%08zx " "rmask=0x%08x, wmask=0x%08x, %s, %s\n", i, &base, &end, size, imr.rmask, imr.wmask, @@ -579,6 +580,7 @@ static void __init imr_fixup_memmap(struct imr_device *idev) { phys_addr_t base = virt_to_phys(&_text); size_t size = virt_to_phys(&__end_rodata) - base; + unsigned long start, end; int i; int ret; @@ -586,18 +588,24 @@ static void __init imr_fixup_memmap(struct imr_device *idev) for (i = 0; i < idev->max_imr; i++) imr_clear(i); + start = (unsigned long)_text; + end = (unsigned long)__end_rodata - 1; + /* * Setup a locked IMR around the physical extent of the kernel * from the beginning of the .text secton to the end of the * .rodata section as one physically contiguous block. + * + * We don't round up @size since it is already PAGE_SIZE aligned. + * See vmlinux.lds.S for details. */ ret = imr_add_range(base, size, IMR_CPU, IMR_CPU, true); if (ret < 0) { - pr_err("unable to setup IMR for kernel: (%p - %p)\n", - &_text, &__end_rodata); + pr_err("unable to setup IMR for kernel: %zu KiB (%lx - %lx)\n", + size / 1024, start, end); } else { - pr_info("protecting kernel .text - .rodata: %zu KiB (%p - %p)\n", - size / 1024, &_text, &__end_rodata); + pr_info("protecting kernel .text - .rodata: %zu KiB (%lx - %lx)\n", + size / 1024, start, end); } } diff --git a/arch/x86/um/asm/barrier.h b/arch/x86/um/asm/barrier.h index 174781a404ff..00c319048d52 100644 --- a/arch/x86/um/asm/barrier.h +++ b/arch/x86/um/asm/barrier.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/arch/x86/um/os-Linux/task_size.c b/arch/x86/um/os-Linux/task_size.c index 8502ad30e61b..5adb6a2fd117 100644 --- a/arch/x86/um/os-Linux/task_size.c +++ b/arch/x86/um/os-Linux/task_size.c @@ -109,7 +109,7 @@ unsigned long os_get_top_address(void) exit(1); } - printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT); + printf("0x%lx\n", bottom << UM_KERN_PAGE_SHIFT); printf("Locating the top of the address space ... "); fflush(stdout); @@ -134,7 +134,7 @@ out: exit(1); } top <<= UM_KERN_PAGE_SHIFT; - printf("0x%x\n", top); + printf("0x%lx\n", top); return top; } diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c index 439c0994b696..bfce503dffae 100644 --- a/arch/x86/um/sys_call_table_32.c +++ b/arch/x86/um/sys_call_table_32.c @@ -25,11 +25,11 @@ #define old_mmap sys_old_mmap -#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; +#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; #include #undef __SYSCALL_I386 -#define __SYSCALL_I386(nr, sym, compat) [ nr ] = sym, +#define __SYSCALL_I386(nr, sym, qual) [ nr ] = sym, extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c index b74ea6c2c0e7..f306413d3eb6 100644 --- a/arch/x86/um/sys_call_table_64.c +++ b/arch/x86/um/sys_call_table_64.c @@ -35,14 +35,11 @@ #define stub_execveat sys_execveat #define stub_rt_sigreturn sys_rt_sigreturn -#define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat) -#define __SYSCALL_X32(nr, sym, compat) /* Not supported */ - -#define __SYSCALL_64(nr, sym, compat) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; +#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; #include #undef __SYSCALL_64 -#define __SYSCALL_64(nr, sym, compat) [ nr ] = sym, +#define __SYSCALL_64(nr, sym, qual) [ nr ] = sym, extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c index ce7e3607a870..470564bbd08e 100644 --- a/arch/x86/um/user-offsets.c +++ b/arch/x86/um/user-offsets.c @@ -9,14 +9,12 @@ #include #ifdef __i386__ -#define __SYSCALL_I386(nr, sym, compat) [nr] = 1, +#define __SYSCALL_I386(nr, sym, qual) [nr] = 1, static char syscalls[] = { #include }; #else -#define __SYSCALL_64(nr, sym, compat) [nr] = 1, -#define __SYSCALL_COMMON(nr, sym, compat) [nr] = 1, -#define __SYSCALL_X32(nr, sym, compat) /* Not supported */ +#define __SYSCALL_64(nr, sym, qual) [nr] = 1, static char syscalls[] = { #include }; diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index d09e4c9d7cc5..2c261082eadf 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1654,7 +1654,7 @@ asmlinkage __visible void __init xen_start_kernel(void) cpu_detect(&new_cpu_data); set_cpu_cap(&new_cpu_data, X86_FEATURE_FPU); new_cpu_data.wp_works_ok = 1; - new_cpu_data.x86_capability[0] = cpuid_edx(1); + new_cpu_data.x86_capability[CPUID_1_EDX] = cpuid_edx(1); #endif if (xen_start_info->mod_start) { diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index e9df1567d778..a3b4e907c5bf 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -138,6 +138,22 @@ config XTENSA_VARIANT_HAVE_PERF_EVENTS If unsure, say N. +config XTENSA_FAKE_NMI + bool "Treat PMM IRQ as NMI" + depends on XTENSA_VARIANT_HAVE_PERF_EVENTS + default n + help + If PMM IRQ is the only IRQ at EXCM level it is safe to + treat it as NMI, which improves accuracy of profiling. + + If there are other interrupts at or above PMM IRQ priority level + but not above the EXCM level, PMM IRQ still may be treated as NMI, + but only if these IRQs are not used. There will be a build warning + saying that this is not safe, and a bugcheck if one of these IRQs + actually fire. + + If unsure, say N. + config XTENSA_UNALIGNED_USER bool "Unaligned memory access in use space" help diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index 74fed0b4e2c2..c38e5a732d86 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h @@ -25,9 +25,12 @@ #ifdef CONFIG_MMU +void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size); +void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size); +void xtensa_iounmap(volatile void __iomem *addr); + /* * Return the virtual address for the specified bus memory. - * Note that we currently don't support any address outside the KIO segment. */ static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long size) @@ -36,7 +39,7 @@ static inline void __iomem *ioremap_nocache(unsigned long offset, && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE) return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR); else - BUG(); + return xtensa_ioremap_nocache(offset, size); } static inline void __iomem *ioremap_cache(unsigned long offset, @@ -46,7 +49,7 @@ static inline void __iomem *ioremap_cache(unsigned long offset, && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE) return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR); else - BUG(); + return xtensa_ioremap_cache(offset, size); } #define ioremap_cache ioremap_cache @@ -60,6 +63,13 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) static inline void iounmap(volatile void __iomem *addr) { + unsigned long va = (unsigned long) addr; + + if (!(va >= XCHAL_KIO_CACHED_VADDR && + va - XCHAL_KIO_CACHED_VADDR < XCHAL_KIO_SIZE) && + !(va >= XCHAL_KIO_BYPASS_VADDR && + va - XCHAL_KIO_BYPASS_VADDR < XCHAL_KIO_SIZE)) + xtensa_iounmap(addr); } #define virt_to_bus virt_to_phys diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 83e2e4bc01ba..744ecf0dc3a4 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -78,22 +78,20 @@ #define XTENSA_INTLEVEL_MASK(level) _XTENSA_INTLEVEL_MASK(level) #define _XTENSA_INTLEVEL_MASK(level) (XCHAL_INTLEVEL##level##_MASK) -#define IS_POW2(v) (((v) & ((v) - 1)) == 0) +#define XTENSA_INTLEVEL_ANDBELOW_MASK(l) _XTENSA_INTLEVEL_ANDBELOW_MASK(l) +#define _XTENSA_INTLEVEL_ANDBELOW_MASK(l) (XCHAL_INTLEVEL##l##_ANDBELOW_MASK) #define PROFILING_INTLEVEL XTENSA_INT_LEVEL(XCHAL_PROFILING_INTERRUPT) /* LOCKLEVEL defines the interrupt level that masks all * general-purpose interrupts. */ -#if defined(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) && \ - defined(XCHAL_PROFILING_INTERRUPT) && \ - PROFILING_INTLEVEL == XCHAL_EXCM_LEVEL && \ - XCHAL_EXCM_LEVEL > 1 && \ - IS_POW2(XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL)) -#define LOCKLEVEL (XCHAL_EXCM_LEVEL - 1) +#if defined(CONFIG_XTENSA_FAKE_NMI) && defined(XCHAL_PROFILING_INTERRUPT) +#define LOCKLEVEL (PROFILING_INTLEVEL - 1) #else #define LOCKLEVEL XCHAL_EXCM_LEVEL #endif + #define TOPLEVEL XCHAL_EXCM_LEVEL #define XTENSA_FAKE_NMI (LOCKLEVEL < TOPLEVEL) diff --git a/arch/xtensa/include/asm/timex.h b/arch/xtensa/include/asm/timex.h index ca929e6a38b5..f9b389d4e973 100644 --- a/arch/xtensa/include/asm/timex.h +++ b/arch/xtensa/include/asm/timex.h @@ -12,19 +12,16 @@ #include #include -#define _INTLEVEL(x) XCHAL_INT ## x ## _LEVEL -#define INTLEVEL(x) _INTLEVEL(x) - #if XCHAL_NUM_TIMERS > 0 && \ - INTLEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL + XTENSA_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL # define LINUX_TIMER 0 # define LINUX_TIMER_INT XCHAL_TIMER0_INTERRUPT #elif XCHAL_NUM_TIMERS > 1 && \ - INTLEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL + XTENSA_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL # define LINUX_TIMER 1 # define LINUX_TIMER_INT XCHAL_TIMER1_INTERRUPT #elif XCHAL_NUM_TIMERS > 2 && \ - INTLEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL + XTENSA_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL # define LINUX_TIMER 2 # define LINUX_TIMER_INT XCHAL_TIMER2_INTERRUPT #else diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 42d441f7898b..be0cae8082c7 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -205,6 +205,32 @@ extern void do_IRQ(int, struct pt_regs *); #if XTENSA_FAKE_NMI +#define IS_POW2(v) (((v) & ((v) - 1)) == 0) + +#if !(PROFILING_INTLEVEL == XCHAL_EXCM_LEVEL && \ + IS_POW2(XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL))) +#warning "Fake NMI is requested for PMM, but there are other IRQs at or above its level." +#warning "Fake NMI will be used, but there will be a bugcheck if one of those IRQs fire." + +static inline void check_valid_nmi(void) +{ + unsigned intread = get_sr(interrupt); + unsigned intenable = get_sr(intenable); + + BUG_ON(intread & intenable & + ~(XTENSA_INTLEVEL_ANDBELOW_MASK(PROFILING_INTLEVEL) ^ + XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL) ^ + BIT(XCHAL_PROFILING_INTERRUPT))); +} + +#else + +static inline void check_valid_nmi(void) +{ +} + +#endif + irqreturn_t xtensa_pmu_irq_handler(int irq, void *dev_id); DEFINE_PER_CPU(unsigned long, nmi_count); @@ -219,6 +245,7 @@ void do_nmi(struct pt_regs *regs) old_regs = set_irq_regs(regs); nmi_enter(); ++*this_cpu_ptr(&nmi_count); + check_valid_nmi(); xtensa_pmu_irq_handler(0, NULL); nmi_exit(); set_irq_regs(old_regs); diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile index e601e2fbe8e6..0b3d296a016a 100644 --- a/arch/xtensa/mm/Makefile +++ b/arch/xtensa/mm/Makefile @@ -3,5 +3,5 @@ # obj-y := init.o misc.o -obj-$(CONFIG_MMU) += cache.o fault.o mmu.o tlb.o +obj-$(CONFIG_MMU) += cache.o fault.o ioremap.o mmu.o tlb.o obj-$(CONFIG_HIGHMEM) += highmem.o diff --git a/arch/xtensa/mm/ioremap.c b/arch/xtensa/mm/ioremap.c new file mode 100644 index 000000000000..d89c3c5fd962 --- /dev/null +++ b/arch/xtensa/mm/ioremap.c @@ -0,0 +1,68 @@ +/* + * ioremap implementation. + * + * Copyright (C) 2015 Cadence Design Systems Inc. + * + * 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 + +static void __iomem *xtensa_ioremap(unsigned long paddr, unsigned long size, + pgprot_t prot) +{ + unsigned long offset = paddr & ~PAGE_MASK; + unsigned long pfn = __phys_to_pfn(paddr); + struct vm_struct *area; + unsigned long vaddr; + int err; + + paddr &= PAGE_MASK; + + WARN_ON(pfn_valid(pfn)); + + size = PAGE_ALIGN(offset + size); + + area = get_vm_area(size, VM_IOREMAP); + if (!area) + return NULL; + + vaddr = (unsigned long)area->addr; + area->phys_addr = paddr; + + err = ioremap_page_range(vaddr, vaddr + size, paddr, prot); + + if (err) { + vunmap((void *)vaddr); + return NULL; + } + + flush_cache_vmap(vaddr, vaddr + size); + return (void __iomem *)(offset + vaddr); +} + +void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size) +{ + return xtensa_ioremap(addr, size, pgprot_noncached(PAGE_KERNEL)); +} +EXPORT_SYMBOL(xtensa_ioremap_nocache); + +void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size) +{ + return xtensa_ioremap(addr, size, PAGE_KERNEL); +} +EXPORT_SYMBOL(xtensa_ioremap_cache); + +void xtensa_iounmap(volatile void __iomem *io_addr) +{ + void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr); + + vunmap(addr); +} +EXPORT_SYMBOL(xtensa_iounmap); diff --git a/block/blk-core.c b/block/blk-core.c index ab51685988c2..c60e233eb08b 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2198,7 +2198,7 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq) if (q->mq_ops) { if (blk_queue_io_stat(q)) blk_account_io_start(rq, true); - blk_mq_insert_request(rq, false, true, true); + blk_mq_insert_request(rq, false, true, false); return 0; } diff --git a/block/blk-merge.c b/block/blk-merge.c index 1699df5b0493..888a7fec81f7 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -70,6 +70,18 @@ static struct bio *blk_bio_write_same_split(struct request_queue *q, return bio_split(bio, q->limits.max_write_same_sectors, GFP_NOIO, bs); } +static inline unsigned get_max_io_size(struct request_queue *q, + struct bio *bio) +{ + unsigned sectors = blk_max_size_offset(q, bio->bi_iter.bi_sector); + unsigned mask = queue_logical_block_size(q) - 1; + + /* aligned to logical block size */ + sectors &= ~(mask >> 9); + + return sectors; +} + static struct bio *blk_bio_segment_split(struct request_queue *q, struct bio *bio, struct bio_set *bs, @@ -81,6 +93,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, unsigned front_seg_size = bio->bi_seg_front_size; bool do_split = true; struct bio *new = NULL; + const unsigned max_sectors = get_max_io_size(q, bio); bio_for_each_segment(bv, bio, iter) { /* @@ -90,20 +103,19 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset)) goto split; - if (sectors + (bv.bv_len >> 9) > - blk_max_size_offset(q, bio->bi_iter.bi_sector)) { + if (sectors + (bv.bv_len >> 9) > max_sectors) { /* * Consider this a new segment if we're splitting in * the middle of this vector. */ if (nsegs < queue_max_segments(q) && - sectors < blk_max_size_offset(q, - bio->bi_iter.bi_sector)) { + sectors < max_sectors) { nsegs++; - sectors = blk_max_size_offset(q, - bio->bi_iter.bi_sector); + sectors = max_sectors; } - goto split; + if (sectors) + goto split; + /* Make this single bvec as the 1st segment */ } if (bvprvp && blk_queue_cluster(q)) { diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c index 1cf18784c5cf..431fdda21737 100644 --- a/block/blk-mq-sysfs.c +++ b/block/blk-mq-sysfs.c @@ -408,17 +408,18 @@ void blk_mq_unregister_disk(struct gendisk *disk) blk_mq_enable_hotplug(); } +void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx) +{ + kobject_init(&hctx->kobj, &blk_mq_hw_ktype); +} + static void blk_mq_sysfs_init(struct request_queue *q) { - struct blk_mq_hw_ctx *hctx; struct blk_mq_ctx *ctx; int i; kobject_init(&q->mq_kobj, &blk_mq_ktype); - queue_for_each_hw_ctx(q, hctx, i) - kobject_init(&hctx->kobj, &blk_mq_hw_ktype); - queue_for_each_ctx(q, ctx, i) kobject_init(&ctx->kobj, &blk_mq_ctx_ktype); } diff --git a/block/blk-mq.c b/block/blk-mq.c index 4c0622fae413..645eb9e716d0 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1742,31 +1742,6 @@ static int blk_mq_init_hctx(struct request_queue *q, return -1; } -static int blk_mq_init_hw_queues(struct request_queue *q, - struct blk_mq_tag_set *set) -{ - struct blk_mq_hw_ctx *hctx; - unsigned int i; - - /* - * Initialize hardware queues - */ - queue_for_each_hw_ctx(q, hctx, i) { - if (blk_mq_init_hctx(q, set, hctx, i)) - break; - } - - if (i == q->nr_hw_queues) - return 0; - - /* - * Init failed - */ - blk_mq_exit_hw_queues(q, set, i); - - return 1; -} - static void blk_mq_init_cpu_queues(struct request_queue *q, unsigned int nr_hw_queues) { @@ -1824,6 +1799,7 @@ static void blk_mq_map_swqueue(struct request_queue *q, continue; hctx = q->mq_ops->map_queue(q, i); + cpumask_set_cpu(i, hctx->cpumask); ctx->index_hw = hctx->nr_ctx; hctx->ctxs[hctx->nr_ctx++] = ctx; @@ -1972,54 +1948,89 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set) } EXPORT_SYMBOL(blk_mq_init_queue); -struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, - struct request_queue *q) +static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set, + struct request_queue *q) { - struct blk_mq_hw_ctx **hctxs; - struct blk_mq_ctx __percpu *ctx; - unsigned int *map; - int i; - - ctx = alloc_percpu(struct blk_mq_ctx); - if (!ctx) - return ERR_PTR(-ENOMEM); - - hctxs = kmalloc_node(set->nr_hw_queues * sizeof(*hctxs), GFP_KERNEL, - set->numa_node); - - if (!hctxs) - goto err_percpu; - - map = blk_mq_make_queue_map(set); - if (!map) - goto err_map; + int i, j; + struct blk_mq_hw_ctx **hctxs = q->queue_hw_ctx; + blk_mq_sysfs_unregister(q); for (i = 0; i < set->nr_hw_queues; i++) { - int node = blk_mq_hw_queue_to_node(map, i); + int node; + if (hctxs[i]) + continue; + + node = blk_mq_hw_queue_to_node(q->mq_map, i); hctxs[i] = kzalloc_node(sizeof(struct blk_mq_hw_ctx), GFP_KERNEL, node); if (!hctxs[i]) - goto err_hctxs; + break; if (!zalloc_cpumask_var_node(&hctxs[i]->cpumask, GFP_KERNEL, - node)) - goto err_hctxs; + node)) { + kfree(hctxs[i]); + hctxs[i] = NULL; + break; + } atomic_set(&hctxs[i]->nr_active, 0); hctxs[i]->numa_node = node; hctxs[i]->queue_num = i; + + if (blk_mq_init_hctx(q, set, hctxs[i], i)) { + free_cpumask_var(hctxs[i]->cpumask); + kfree(hctxs[i]); + hctxs[i] = NULL; + break; + } + blk_mq_hctx_kobj_init(hctxs[i]); } + for (j = i; j < q->nr_hw_queues; j++) { + struct blk_mq_hw_ctx *hctx = hctxs[j]; + + if (hctx) { + if (hctx->tags) { + blk_mq_free_rq_map(set, hctx->tags, j); + set->tags[j] = NULL; + } + blk_mq_exit_hctx(q, set, hctx, j); + free_cpumask_var(hctx->cpumask); + kobject_put(&hctx->kobj); + kfree(hctx->ctxs); + kfree(hctx); + hctxs[j] = NULL; + + } + } + q->nr_hw_queues = i; + blk_mq_sysfs_register(q); +} + +struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, + struct request_queue *q) +{ + q->queue_ctx = alloc_percpu(struct blk_mq_ctx); + if (!q->queue_ctx) + return ERR_PTR(-ENOMEM); + + q->queue_hw_ctx = kzalloc_node(nr_cpu_ids * sizeof(*(q->queue_hw_ctx)), + GFP_KERNEL, set->numa_node); + if (!q->queue_hw_ctx) + goto err_percpu; + + q->mq_map = blk_mq_make_queue_map(set); + if (!q->mq_map) + goto err_map; + + blk_mq_realloc_hw_ctxs(set, q); + if (!q->nr_hw_queues) + goto err_hctxs; INIT_WORK(&q->timeout_work, blk_mq_timeout_work); blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ); q->nr_queues = nr_cpu_ids; - q->nr_hw_queues = set->nr_hw_queues; - q->mq_map = map; - - q->queue_ctx = ctx; - q->queue_hw_ctx = hctxs; q->mq_ops = set->ops; q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; @@ -2048,9 +2059,6 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, blk_mq_init_cpu_queues(q, set->nr_hw_queues); - if (blk_mq_init_hw_queues(q, set)) - goto err_hctxs; - get_online_cpus(); mutex_lock(&all_q_mutex); @@ -2064,17 +2072,11 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, return q; err_hctxs: - kfree(map); - for (i = 0; i < set->nr_hw_queues; i++) { - if (!hctxs[i]) - break; - free_cpumask_var(hctxs[i]->cpumask); - kfree(hctxs[i]); - } + kfree(q->mq_map); err_map: - kfree(hctxs); + kfree(q->queue_hw_ctx); err_percpu: - free_percpu(ctx); + free_percpu(q->queue_ctx); return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL(blk_mq_init_allocated_queue); @@ -2282,9 +2284,13 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set) set->nr_hw_queues = 1; set->queue_depth = min(64U, set->queue_depth); } + /* + * There is no use for more h/w queues than cpus. + */ + if (set->nr_hw_queues > nr_cpu_ids) + set->nr_hw_queues = nr_cpu_ids; - set->tags = kmalloc_node(set->nr_hw_queues * - sizeof(struct blk_mq_tags *), + set->tags = kzalloc_node(nr_cpu_ids * sizeof(struct blk_mq_tags *), GFP_KERNEL, set->numa_node); if (!set->tags) return -ENOMEM; @@ -2307,7 +2313,7 @@ void blk_mq_free_tag_set(struct blk_mq_tag_set *set) { int i; - for (i = 0; i < set->nr_hw_queues; i++) { + for (i = 0; i < nr_cpu_ids; i++) { if (set->tags[i]) blk_mq_free_rq_map(set, set->tags[i], i); } @@ -2339,6 +2345,35 @@ int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr) return ret; } +void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues) +{ + struct request_queue *q; + + if (nr_hw_queues > nr_cpu_ids) + nr_hw_queues = nr_cpu_ids; + if (nr_hw_queues < 1 || nr_hw_queues == set->nr_hw_queues) + return; + + list_for_each_entry(q, &set->tag_list, tag_set_list) + blk_mq_freeze_queue(q); + + set->nr_hw_queues = nr_hw_queues; + list_for_each_entry(q, &set->tag_list, tag_set_list) { + blk_mq_realloc_hw_ctxs(set, q); + + if (q->nr_hw_queues > 1) + blk_queue_make_request(q, blk_mq_make_request); + else + blk_queue_make_request(q, blk_sq_make_request); + + blk_mq_queue_reinit(q, cpu_online_mask); + } + + list_for_each_entry(q, &set->tag_list, tag_set_list) + blk_mq_unfreeze_queue(q); +} +EXPORT_SYMBOL_GPL(blk_mq_update_nr_hw_queues); + void blk_mq_disable_hotplug(void) { mutex_lock(&all_q_mutex); diff --git a/block/blk-mq.h b/block/blk-mq.h index eaede8e45c9c..9087b11037b7 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h @@ -57,6 +57,7 @@ extern int blk_mq_hw_queue_to_node(unsigned int *map, unsigned int); */ extern int blk_mq_sysfs_register(struct request_queue *q); extern void blk_mq_sysfs_unregister(struct request_queue *q); +extern void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx); extern void blk_mq_rq_timed_out(struct request *req, bool reserved); diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 1f9093e901da..e3c591dd8f19 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -632,6 +632,13 @@ static inline struct cfq_group *cfqg_parent(struct cfq_group *cfqg) return pblkg ? blkg_to_cfqg(pblkg) : NULL; } +static inline bool cfqg_is_descendant(struct cfq_group *cfqg, + struct cfq_group *ancestor) +{ + return cgroup_is_descendant(cfqg_to_blkg(cfqg)->blkcg->css.cgroup, + cfqg_to_blkg(ancestor)->blkcg->css.cgroup); +} + static inline void cfqg_get(struct cfq_group *cfqg) { return blkg_get(cfqg_to_blkg(cfqg)); @@ -758,6 +765,11 @@ static void cfqg_stats_xfer_dead(struct cfq_group *cfqg) #else /* CONFIG_CFQ_GROUP_IOSCHED */ static inline struct cfq_group *cfqg_parent(struct cfq_group *cfqg) { return NULL; } +static inline bool cfqg_is_descendant(struct cfq_group *cfqg, + struct cfq_group *ancestor) +{ + return true; +} static inline void cfqg_get(struct cfq_group *cfqg) { } static inline void cfqg_put(struct cfq_group *cfqg) { } @@ -2897,6 +2909,7 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq) static void cfq_arm_slice_timer(struct cfq_data *cfqd) { struct cfq_queue *cfqq = cfqd->active_queue; + struct cfq_rb_root *st = cfqq->service_tree; struct cfq_io_cq *cic; unsigned long sl, group_idle = 0; @@ -2947,8 +2960,13 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) return; } - /* There are other queues in the group, don't do group idle */ - if (group_idle && cfqq->cfqg->nr_cfqq > 1) + /* + * There are other queues in the group or this is the only group and + * it has too big thinktime, don't do group idle. + */ + if (group_idle && + (cfqq->cfqg->nr_cfqq > 1 || + cfq_io_thinktime_big(cfqd, &st->ttime, true))) return; cfq_mark_cfqq_wait_request(cfqq); @@ -3947,16 +3965,27 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq)) return true; - if (new_cfqq->cfqg != cfqq->cfqg) + /* + * Treat ancestors of current cgroup the same way as current cgroup. + * For anybody else we disallow preemption to guarantee service + * fairness among cgroups. + */ + if (!cfqg_is_descendant(cfqq->cfqg, new_cfqq->cfqg)) return false; if (cfq_slice_used(cfqq)) return true; + /* + * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. + */ + if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) + return true; + + WARN_ON_ONCE(cfqq->ioprio_class != new_cfqq->ioprio_class); /* Allow preemption only if we are idling on sync-noidle tree */ if (cfqd->serving_wl_type == SYNC_NOIDLE_WORKLOAD && cfqq_type(new_cfqq) == SYNC_NOIDLE_WORKLOAD && - new_cfqq->service_tree->count == 2 && RB_EMPTY_ROOT(&cfqq->sort_list)) return true; @@ -3967,12 +3996,6 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, if ((rq->cmd_flags & REQ_PRIO) && !cfqq->prio_pending) return true; - /* - * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. - */ - if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) - return true; - /* An idle queue should not be idle now for some reason */ if (RB_EMPTY_ROOT(&cfqq->sort_list) && !cfq_should_idle(cfqd, cfqq)) return true; diff --git a/block/ioctl.c b/block/ioctl.c index 77f5d17779d6..d8996bbd7f12 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -434,42 +434,6 @@ bool blkdev_dax_capable(struct block_device *bdev) return true; } - -static int blkdev_daxset(struct block_device *bdev, unsigned long argp) -{ - unsigned long arg; - int rc = 0; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - if (get_user(arg, (int __user *)(argp))) - return -EFAULT; - arg = !!arg; - if (arg == !!(bdev->bd_inode->i_flags & S_DAX)) - return 0; - - if (arg) - arg = S_DAX; - - if (arg && !blkdev_dax_capable(bdev)) - return -ENOTTY; - - inode_lock(bdev->bd_inode); - if (bdev->bd_map_count == 0) - inode_set_flags(bdev->bd_inode, arg, S_DAX); - else - rc = -EBUSY; - inode_unlock(bdev->bd_inode); - return rc; -} -#else -static int blkdev_daxset(struct block_device *bdev, int arg) -{ - if (arg) - return -ENOTTY; - return 0; -} #endif static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode, @@ -634,8 +598,6 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, case BLKTRACESETUP: case BLKTRACETEARDOWN: return blk_trace_ioctl(bdev, cmd, argp); - case BLKDAXSET: - return blkdev_daxset(bdev, arg); case BLKDAXGET: return put_int(arg, !!(bdev->bd_inode->i_flags & S_DAX)); break; diff --git a/block/partition-generic.c b/block/partition-generic.c index 746935a5973c..fefd01b496a0 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "partitions/check.h" @@ -550,13 +551,24 @@ int invalidate_partitions(struct gendisk *disk, struct block_device *bdev) return 0; } -unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) +static struct page *read_pagecache_sector(struct block_device *bdev, sector_t n) { struct address_space *mapping = bdev->bd_inode->i_mapping; + + return read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)), + NULL); +} + +unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) +{ struct page *page; - page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)), - NULL); + /* don't populate page cache for dax capable devices */ + if (IS_DAX(bdev->bd_inode)) + page = read_dax_sector(bdev, n); + else + page = read_pagecache_sector(bdev, n); + if (!IS_ERR(page)) { if (PageError(page)) goto fail; diff --git a/crypto/Kconfig b/crypto/Kconfig index 7240821137fd..93a1fdc1feee 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -84,15 +84,6 @@ config CRYPTO_RNG_DEFAULT tristate select CRYPTO_DRBG_MENU -config CRYPTO_PCOMP - tristate - select CRYPTO_PCOMP2 - select CRYPTO_ALGAPI - -config CRYPTO_PCOMP2 - tristate - select CRYPTO_ALGAPI2 - config CRYPTO_AKCIPHER2 tristate select CRYPTO_ALGAPI2 @@ -122,7 +113,6 @@ config CRYPTO_MANAGER2 select CRYPTO_AEAD2 select CRYPTO_HASH2 select CRYPTO_BLKCIPHER2 - select CRYPTO_PCOMP2 select CRYPTO_AKCIPHER2 config CRYPTO_USER @@ -227,6 +217,9 @@ config CRYPTO_GLUE_HELPER_X86 depends on X86 select CRYPTO_ALGAPI +config CRYPTO_ENGINE + tristate + comment "Authenticated Encryption with Associated Data" config CRYPTO_CCM @@ -472,11 +465,13 @@ config CRYPTO_CRCT10DIF_PCLMUL config CRYPTO_GHASH tristate "GHASH digest algorithm" select CRYPTO_GF128MUL + select CRYPTO_HASH help GHASH is message digest algorithm for GCM (Galois/Counter Mode). config CRYPTO_POLY1305 tristate "Poly1305 authenticator algorithm" + select CRYPTO_HASH help Poly1305 authenticator algorithm, RFC7539. @@ -1504,15 +1499,6 @@ config CRYPTO_DEFLATE You will most probably want this if using IPSec. -config CRYPTO_ZLIB - tristate "Zlib compression algorithm" - select CRYPTO_PCOMP - select ZLIB_INFLATE - select ZLIB_DEFLATE - select NLATTR - help - This is the zlib algorithm. - config CRYPTO_LZO tristate "LZO compression algorithm" select CRYPTO_ALGAPI @@ -1593,6 +1579,7 @@ endif # if CRYPTO_DRBG_MENU config CRYPTO_JITTERENTROPY tristate "Jitterentropy Non-Deterministic Random Number Generator" + select CRYPTO_RNG help The Jitterentropy RNG is a noise that is intended to provide seed to another RNG. The RNG does not diff --git a/crypto/Makefile b/crypto/Makefile index 2acdbbd30475..4f4ef7eaae3f 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -7,6 +7,7 @@ crypto-y := api.o cipher.o compress.o memneq.o obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o +obj-$(CONFIG_CRYPTO_ENGINE) += crypto_engine.o obj-$(CONFIG_CRYPTO_FIPS) += fips.o crypto_algapi-$(CONFIG_PROC_FS) += proc.o @@ -28,7 +29,6 @@ crypto_hash-y += ahash.o crypto_hash-y += shash.o obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o -obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h @@ -99,10 +99,9 @@ obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o obj-$(CONFIG_CRYPTO_CHACHA20) += chacha20_generic.o obj-$(CONFIG_CRYPTO_POLY1305) += poly1305_generic.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o -obj-$(CONFIG_CRYPTO_ZLIB) += zlib.o obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o -obj-$(CONFIG_CRYPTO_CRC32) += crc32.o +obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o obj-$(CONFIG_CRYPTO_LZO) += lzo.o diff --git a/crypto/ahash.c b/crypto/ahash.c index d19b52324cf5..5fc1f172963d 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -166,24 +166,6 @@ int crypto_ahash_walk_first(struct ahash_request *req, } EXPORT_SYMBOL_GPL(crypto_ahash_walk_first); -int crypto_hash_walk_first_compat(struct hash_desc *hdesc, - struct crypto_hash_walk *walk, - struct scatterlist *sg, unsigned int len) -{ - walk->total = len; - - if (!walk->total) { - walk->entrylen = 0; - return 0; - } - - walk->alignmask = crypto_hash_alignmask(hdesc->tfm); - walk->sg = sg; - walk->flags = hdesc->flags & CRYPTO_TFM_REQ_MASK; - - return hash_walk_new_entry(walk); -} - static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen) { @@ -542,6 +524,12 @@ struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, u32 type, } EXPORT_SYMBOL_GPL(crypto_alloc_ahash); +int crypto_has_ahash(const char *alg_name, u32 type, u32 mask) +{ + return crypto_type_has_alg(alg_name, &crypto_ahash_type, type, mask); +} +EXPORT_SYMBOL_GPL(crypto_has_ahash); + static int ahash_prepare_alg(struct ahash_alg *alg) { struct crypto_alg *base = &alg->halg.base; diff --git a/crypto/algapi.c b/crypto/algapi.c index 7be76aa31579..731255a6104f 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -987,6 +987,21 @@ unsigned int crypto_alg_extsize(struct crypto_alg *alg) } EXPORT_SYMBOL_GPL(crypto_alg_extsize); +int crypto_type_has_alg(const char *name, const struct crypto_type *frontend, + u32 type, u32 mask) +{ + int ret = 0; + struct crypto_alg *alg = crypto_find_alg(name, frontend, type, mask); + + if (!IS_ERR(alg)) { + crypto_mod_put(alg); + ret = 1; + } + + return ret; +} +EXPORT_SYMBOL_GPL(crypto_type_has_alg); + static int __init crypto_algapi_init(void) { crypto_init_proc(); diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 608a7562839d..68a5ceaa04c8 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -54,7 +54,8 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg, lock_sock(sk); if (!ctx->more) { - err = crypto_ahash_init(&ctx->req); + err = af_alg_wait_for_completion(crypto_ahash_init(&ctx->req), + &ctx->completion); if (err) goto unlock; } @@ -125,6 +126,7 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page, } else { if (!ctx->more) { err = crypto_ahash_init(&ctx->req); + err = af_alg_wait_for_completion(err, &ctx->completion); if (err) goto unlock; } diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 38c1aa89d3a0..28556fce4267 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -65,18 +65,10 @@ struct skcipher_async_req { struct skcipher_async_rsgl first_sgl; struct list_head list; struct scatterlist *tsg; - char iv[]; + atomic_t *inflight; + struct skcipher_request req; }; -#define GET_SREQ(areq, ctx) (struct skcipher_async_req *)((char *)areq + \ - crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req))) - -#define GET_REQ_SIZE(ctx) \ - crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req)) - -#define GET_IV_SIZE(ctx) \ - crypto_skcipher_ivsize(crypto_skcipher_reqtfm(&ctx->req)) - #define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \ sizeof(struct scatterlist) - 1) @@ -102,15 +94,12 @@ static void skcipher_free_async_sgls(struct skcipher_async_req *sreq) static void skcipher_async_cb(struct crypto_async_request *req, int err) { - struct sock *sk = req->data; - struct alg_sock *ask = alg_sk(sk); - struct skcipher_ctx *ctx = ask->private; - struct skcipher_async_req *sreq = GET_SREQ(req, ctx); + struct skcipher_async_req *sreq = req->data; struct kiocb *iocb = sreq->iocb; - atomic_dec(&ctx->inflight); + atomic_dec(sreq->inflight); skcipher_free_async_sgls(sreq); - kfree(req); + kzfree(sreq); iocb->ki_complete(iocb, err, err); } @@ -306,8 +295,11 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg, { struct sock *sk = sock->sk; struct alg_sock *ask = alg_sk(sk); + struct sock *psk = ask->parent; + struct alg_sock *pask = alg_sk(psk); struct skcipher_ctx *ctx = ask->private; - struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(&ctx->req); + struct skcipher_tfm *skc = pask->private; + struct crypto_skcipher *tfm = skc->skcipher; unsigned ivsize = crypto_skcipher_ivsize(tfm); struct skcipher_sg_list *sgl; struct af_alg_control con = {}; @@ -509,37 +501,43 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg, { struct sock *sk = sock->sk; struct alg_sock *ask = alg_sk(sk); + struct sock *psk = ask->parent; + struct alg_sock *pask = alg_sk(psk); struct skcipher_ctx *ctx = ask->private; + struct skcipher_tfm *skc = pask->private; + struct crypto_skcipher *tfm = skc->skcipher; struct skcipher_sg_list *sgl; struct scatterlist *sg; struct skcipher_async_req *sreq; struct skcipher_request *req; struct skcipher_async_rsgl *last_rsgl = NULL; - unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx); - unsigned int reqlen = sizeof(struct skcipher_async_req) + - GET_REQ_SIZE(ctx) + GET_IV_SIZE(ctx); + unsigned int txbufs = 0, len = 0, tx_nents; + unsigned int reqsize = crypto_skcipher_reqsize(tfm); + unsigned int ivsize = crypto_skcipher_ivsize(tfm); int err = -ENOMEM; bool mark = false; + char *iv; - lock_sock(sk); - req = kmalloc(reqlen, GFP_KERNEL); - if (unlikely(!req)) - goto unlock; + sreq = kzalloc(sizeof(*sreq) + reqsize + ivsize, GFP_KERNEL); + if (unlikely(!sreq)) + goto out; - sreq = GET_SREQ(req, ctx); + req = &sreq->req; + iv = (char *)(req + 1) + reqsize; sreq->iocb = msg->msg_iocb; - memset(&sreq->first_sgl, '\0', sizeof(struct skcipher_async_rsgl)); INIT_LIST_HEAD(&sreq->list); + sreq->inflight = &ctx->inflight; + + lock_sock(sk); + tx_nents = skcipher_all_sg_nents(ctx); sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL); - if (unlikely(!sreq->tsg)) { - kfree(req); + if (unlikely(!sreq->tsg)) goto unlock; - } sg_init_table(sreq->tsg, tx_nents); - memcpy(sreq->iv, ctx->iv, GET_IV_SIZE(ctx)); - skcipher_request_set_tfm(req, crypto_skcipher_reqtfm(&ctx->req)); - skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - skcipher_async_cb, sk); + memcpy(iv, ctx->iv, ivsize); + skcipher_request_set_tfm(req, tfm); + skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, + skcipher_async_cb, sreq); while (iov_iter_count(&msg->msg_iter)) { struct skcipher_async_rsgl *rsgl; @@ -615,20 +613,22 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg, sg_mark_end(sreq->tsg + txbufs - 1); skcipher_request_set_crypt(req, sreq->tsg, sreq->first_sgl.sgl.sg, - len, sreq->iv); + len, iv); err = ctx->enc ? crypto_skcipher_encrypt(req) : crypto_skcipher_decrypt(req); if (err == -EINPROGRESS) { atomic_inc(&ctx->inflight); err = -EIOCBQUEUED; + sreq = NULL; goto unlock; } free: skcipher_free_async_sgls(sreq); - kfree(req); unlock: skcipher_wmem_wakeup(sk); release_sock(sk); + kzfree(sreq); +out: return err; } @@ -637,9 +637,12 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg, { struct sock *sk = sock->sk; struct alg_sock *ask = alg_sk(sk); + struct sock *psk = ask->parent; + struct alg_sock *pask = alg_sk(psk); struct skcipher_ctx *ctx = ask->private; - unsigned bs = crypto_skcipher_blocksize(crypto_skcipher_reqtfm( - &ctx->req)); + struct skcipher_tfm *skc = pask->private; + struct crypto_skcipher *tfm = skc->skcipher; + unsigned bs = crypto_skcipher_blocksize(tfm); struct skcipher_sg_list *sgl; struct scatterlist *sg; int err = -EAGAIN; @@ -947,7 +950,8 @@ static int skcipher_accept_parent_nokey(void *private, struct sock *sk) ask->private = ctx; skcipher_request_set_tfm(&ctx->req, skcipher); - skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, + skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_SLEEP | + CRYPTO_TFM_REQ_MAY_BACKLOG, af_alg_complete, &ctx->completion); sk->sk_destruct = skcipher_sock_destruct; diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 758acabf2d81..8f3056cd0399 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -547,9 +547,7 @@ int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen, struct pkcs7_signed_info *sinfo = ctx->sinfo; if (!test_bit(sinfo_has_content_type, &sinfo->aa_set) || - !test_bit(sinfo_has_message_digest, &sinfo->aa_set) || - (ctx->msg->data_type == OID_msIndirectData && - !test_bit(sinfo_has_ms_opus_info, &sinfo->aa_set))) { + !test_bit(sinfo_has_message_digest, &sinfo->aa_set)) { pr_warn("Missing required AuthAttr\n"); return -EBADMSG; } diff --git a/crypto/crc32.c b/crypto/crc32_generic.c similarity index 98% rename from crypto/crc32.c rename to crypto/crc32_generic.c index 187ded28cb0b..aa2a25fc7482 100644 --- a/crypto/crc32.c +++ b/crypto/crc32_generic.c @@ -131,7 +131,7 @@ static struct shash_alg alg = { .digestsize = CHKSUM_DIGEST_SIZE, .base = { .cra_name = "crc32", - .cra_driver_name = "crc32-table", + .cra_driver_name = "crc32-generic", .cra_priority = 100, .cra_blocksize = CHKSUM_BLOCK_SIZE, .cra_ctxsize = sizeof(u32), @@ -157,3 +157,4 @@ MODULE_AUTHOR("Alexander Boyko "); MODULE_DESCRIPTION("CRC32 calculations wrapper for lib/crc32"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CRYPTO("crc32"); +MODULE_ALIAS_CRYPTO("crc32-generic"); diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c new file mode 100644 index 000000000000..a55c82dd48ef --- /dev/null +++ b/crypto/crypto_engine.c @@ -0,0 +1,355 @@ +/* + * Handle async block request by crypto hardware engine. + * + * Copyright (C) 2016 Linaro, Inc. + * + * Author: Baolin Wang + * + * 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 "internal.h" + +#define CRYPTO_ENGINE_MAX_QLEN 10 + +void crypto_finalize_request(struct crypto_engine *engine, + struct ablkcipher_request *req, int err); + +/** + * crypto_pump_requests - dequeue one request from engine queue to process + * @engine: the hardware engine + * @in_kthread: true if we are in the context of the request pump thread + * + * This function checks if there is any request in the engine queue that + * needs processing and if so call out to the driver to initialize hardware + * and handle each request. + */ +static void crypto_pump_requests(struct crypto_engine *engine, + bool in_kthread) +{ + struct crypto_async_request *async_req, *backlog; + struct ablkcipher_request *req; + unsigned long flags; + bool was_busy = false; + int ret; + + spin_lock_irqsave(&engine->queue_lock, flags); + + /* Make sure we are not already running a request */ + if (engine->cur_req) + goto out; + + /* If another context is idling then defer */ + if (engine->idling) { + queue_kthread_work(&engine->kworker, &engine->pump_requests); + goto out; + } + + /* Check if the engine queue is idle */ + if (!crypto_queue_len(&engine->queue) || !engine->running) { + if (!engine->busy) + goto out; + + /* Only do teardown in the thread */ + if (!in_kthread) { + queue_kthread_work(&engine->kworker, + &engine->pump_requests); + goto out; + } + + engine->busy = false; + engine->idling = true; + spin_unlock_irqrestore(&engine->queue_lock, flags); + + if (engine->unprepare_crypt_hardware && + engine->unprepare_crypt_hardware(engine)) + pr_err("failed to unprepare crypt hardware\n"); + + spin_lock_irqsave(&engine->queue_lock, flags); + engine->idling = false; + goto out; + } + + /* Get the fist request from the engine queue to handle */ + backlog = crypto_get_backlog(&engine->queue); + async_req = crypto_dequeue_request(&engine->queue); + if (!async_req) + goto out; + + req = ablkcipher_request_cast(async_req); + + engine->cur_req = req; + if (backlog) + backlog->complete(backlog, -EINPROGRESS); + + if (engine->busy) + was_busy = true; + else + engine->busy = true; + + spin_unlock_irqrestore(&engine->queue_lock, flags); + + /* Until here we get the request need to be encrypted successfully */ + if (!was_busy && engine->prepare_crypt_hardware) { + ret = engine->prepare_crypt_hardware(engine); + if (ret) { + pr_err("failed to prepare crypt hardware\n"); + goto req_err; + } + } + + if (engine->prepare_request) { + ret = engine->prepare_request(engine, engine->cur_req); + if (ret) { + pr_err("failed to prepare request: %d\n", ret); + goto req_err; + } + engine->cur_req_prepared = true; + } + + ret = engine->crypt_one_request(engine, engine->cur_req); + if (ret) { + pr_err("failed to crypt one request from queue\n"); + goto req_err; + } + return; + +req_err: + crypto_finalize_request(engine, engine->cur_req, ret); + return; + +out: + spin_unlock_irqrestore(&engine->queue_lock, flags); +} + +static void crypto_pump_work(struct kthread_work *work) +{ + struct crypto_engine *engine = + container_of(work, struct crypto_engine, pump_requests); + + crypto_pump_requests(engine, true); +} + +/** + * crypto_transfer_request - transfer the new request into the engine queue + * @engine: the hardware engine + * @req: the request need to be listed into the engine queue + */ +int crypto_transfer_request(struct crypto_engine *engine, + struct ablkcipher_request *req, bool need_pump) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&engine->queue_lock, flags); + + if (!engine->running) { + spin_unlock_irqrestore(&engine->queue_lock, flags); + return -ESHUTDOWN; + } + + ret = ablkcipher_enqueue_request(&engine->queue, req); + + if (!engine->busy && need_pump) + queue_kthread_work(&engine->kworker, &engine->pump_requests); + + spin_unlock_irqrestore(&engine->queue_lock, flags); + return ret; +} +EXPORT_SYMBOL_GPL(crypto_transfer_request); + +/** + * crypto_transfer_request_to_engine - transfer one request to list into the + * engine queue + * @engine: the hardware engine + * @req: the request need to be listed into the engine queue + */ +int crypto_transfer_request_to_engine(struct crypto_engine *engine, + struct ablkcipher_request *req) +{ + return crypto_transfer_request(engine, req, true); +} +EXPORT_SYMBOL_GPL(crypto_transfer_request_to_engine); + +/** + * crypto_finalize_request - finalize one request if the request is done + * @engine: the hardware engine + * @req: the request need to be finalized + * @err: error number + */ +void crypto_finalize_request(struct crypto_engine *engine, + struct ablkcipher_request *req, int err) +{ + unsigned long flags; + bool finalize_cur_req = false; + int ret; + + spin_lock_irqsave(&engine->queue_lock, flags); + if (engine->cur_req == req) + finalize_cur_req = true; + spin_unlock_irqrestore(&engine->queue_lock, flags); + + if (finalize_cur_req) { + if (engine->cur_req_prepared && engine->unprepare_request) { + ret = engine->unprepare_request(engine, req); + if (ret) + pr_err("failed to unprepare request\n"); + } + + spin_lock_irqsave(&engine->queue_lock, flags); + engine->cur_req = NULL; + engine->cur_req_prepared = false; + spin_unlock_irqrestore(&engine->queue_lock, flags); + } + + req->base.complete(&req->base, err); + + queue_kthread_work(&engine->kworker, &engine->pump_requests); +} +EXPORT_SYMBOL_GPL(crypto_finalize_request); + +/** + * crypto_engine_start - start the hardware engine + * @engine: the hardware engine need to be started + * + * Return 0 on success, else on fail. + */ +int crypto_engine_start(struct crypto_engine *engine) +{ + unsigned long flags; + + spin_lock_irqsave(&engine->queue_lock, flags); + + if (engine->running || engine->busy) { + spin_unlock_irqrestore(&engine->queue_lock, flags); + return -EBUSY; + } + + engine->running = true; + spin_unlock_irqrestore(&engine->queue_lock, flags); + + queue_kthread_work(&engine->kworker, &engine->pump_requests); + + return 0; +} +EXPORT_SYMBOL_GPL(crypto_engine_start); + +/** + * crypto_engine_stop - stop the hardware engine + * @engine: the hardware engine need to be stopped + * + * Return 0 on success, else on fail. + */ +int crypto_engine_stop(struct crypto_engine *engine) +{ + unsigned long flags; + unsigned limit = 500; + int ret = 0; + + spin_lock_irqsave(&engine->queue_lock, flags); + + /* + * If the engine queue is not empty or the engine is on busy state, + * we need to wait for a while to pump the requests of engine queue. + */ + while ((crypto_queue_len(&engine->queue) || engine->busy) && limit--) { + spin_unlock_irqrestore(&engine->queue_lock, flags); + msleep(20); + spin_lock_irqsave(&engine->queue_lock, flags); + } + + if (crypto_queue_len(&engine->queue) || engine->busy) + ret = -EBUSY; + else + engine->running = false; + + spin_unlock_irqrestore(&engine->queue_lock, flags); + + if (ret) + pr_warn("could not stop engine\n"); + + return ret; +} +EXPORT_SYMBOL_GPL(crypto_engine_stop); + +/** + * crypto_engine_alloc_init - allocate crypto hardware engine structure and + * initialize it. + * @dev: the device attached with one hardware engine + * @rt: whether this queue is set to run as a realtime task + * + * This must be called from context that can sleep. + * Return: the crypto engine structure on success, else NULL. + */ +struct crypto_engine *crypto_engine_alloc_init(struct device *dev, bool rt) +{ + struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; + struct crypto_engine *engine; + + if (!dev) + return NULL; + + engine = devm_kzalloc(dev, sizeof(*engine), GFP_KERNEL); + if (!engine) + return NULL; + + engine->rt = rt; + engine->running = false; + engine->busy = false; + engine->idling = false; + engine->cur_req_prepared = false; + engine->priv_data = dev; + snprintf(engine->name, sizeof(engine->name), + "%s-engine", dev_name(dev)); + + crypto_init_queue(&engine->queue, CRYPTO_ENGINE_MAX_QLEN); + spin_lock_init(&engine->queue_lock); + + init_kthread_worker(&engine->kworker); + engine->kworker_task = kthread_run(kthread_worker_fn, + &engine->kworker, "%s", + engine->name); + if (IS_ERR(engine->kworker_task)) { + dev_err(dev, "failed to create crypto request pump task\n"); + return NULL; + } + init_kthread_work(&engine->pump_requests, crypto_pump_work); + + if (engine->rt) { + dev_info(dev, "will run requests pump with realtime priority\n"); + sched_setscheduler(engine->kworker_task, SCHED_FIFO, ¶m); + } + + return engine; +} +EXPORT_SYMBOL_GPL(crypto_engine_alloc_init); + +/** + * crypto_engine_exit - free the resources of hardware engine when exit + * @engine: the hardware engine need to be freed + * + * Return 0 for success. + */ +int crypto_engine_exit(struct crypto_engine *engine) +{ + int ret; + + ret = crypto_engine_stop(engine); + if (ret) + return ret; + + flush_kthread_worker(&engine->kworker); + kthread_stop(engine->kworker_task); + + return 0; +} +EXPORT_SYMBOL_GPL(crypto_engine_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Crypto hardware engine framework"); diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index 237f3795cfaa..43fe85f20d57 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -499,6 +499,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (link->dump == NULL) return -EINVAL; + down_read(&crypto_alg_sem); list_for_each_entry(alg, &crypto_alg_list, cra_list) dump_alloc += CRYPTO_REPORT_MAXSIZE; @@ -508,8 +509,11 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) .done = link->done, .min_dump_alloc = dump_alloc, }; - return netlink_dump_start(crypto_nlsk, skb, nlh, &c); + err = netlink_dump_start(crypto_nlsk, skb, nlh, &c); } + up_read(&crypto_alg_sem); + + return err; } err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX, diff --git a/crypto/drbg.c b/crypto/drbg.c index ab6ef1d08568..1b86310db7b1 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -219,48 +219,6 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t flags) } } -/* - * FIPS 140-2 continuous self test - * The test is performed on the result of one round of the output - * function. Thus, the function implicitly knows the size of the - * buffer. - * - * @drbg DRBG handle - * @buf output buffer of random data to be checked - * - * return: - * true on success - * false on error - */ -static bool drbg_fips_continuous_test(struct drbg_state *drbg, - const unsigned char *buf) -{ -#ifdef CONFIG_CRYPTO_FIPS - int ret = 0; - /* skip test if we test the overall system */ - if (list_empty(&drbg->test_data.list)) - return true; - /* only perform test in FIPS mode */ - if (0 == fips_enabled) - return true; - if (!drbg->fips_primed) { - /* Priming of FIPS test */ - memcpy(drbg->prev, buf, drbg_blocklen(drbg)); - drbg->fips_primed = true; - /* return false due to priming, i.e. another round is needed */ - return false; - } - ret = memcmp(drbg->prev, buf, drbg_blocklen(drbg)); - if (!ret) - panic("DRBG continuous self test failed\n"); - memcpy(drbg->prev, buf, drbg_blocklen(drbg)); - /* the test shall pass when the two compared values are not equal */ - return ret != 0; -#else - return true; -#endif /* CONFIG_CRYPTO_FIPS */ -} - /* * Convert an integer into a byte representation of this integer. * The byte representation is big-endian @@ -603,11 +561,6 @@ static int drbg_ctr_generate(struct drbg_state *drbg, } outlen = (drbg_blocklen(drbg) < (buflen - len)) ? drbg_blocklen(drbg) : (buflen - len); - if (!drbg_fips_continuous_test(drbg, drbg->scratchpad)) { - /* 10.2.1.5.2 step 6 */ - crypto_inc(drbg->V, drbg_blocklen(drbg)); - continue; - } /* 10.2.1.5.2 step 4.3 */ memcpy(buf + len, drbg->scratchpad, outlen); len += outlen; @@ -733,8 +686,6 @@ static int drbg_hmac_generate(struct drbg_state *drbg, return ret; outlen = (drbg_blocklen(drbg) < (buflen - len)) ? drbg_blocklen(drbg) : (buflen - len); - if (!drbg_fips_continuous_test(drbg, drbg->V)) - continue; /* 10.1.2.5 step 4.2 */ memcpy(buf + len, drbg->V, outlen); @@ -963,10 +914,6 @@ static int drbg_hash_hashgen(struct drbg_state *drbg, } outlen = (drbg_blocklen(drbg) < (buflen - len)) ? drbg_blocklen(drbg) : (buflen - len); - if (!drbg_fips_continuous_test(drbg, dst)) { - crypto_inc(src, drbg_statelen(drbg)); - continue; - } /* 10.1.1.4 step hashgen 4.2 */ memcpy(buf + len, dst, outlen); len += outlen; @@ -1201,11 +1148,6 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg) drbg->reseed_ctr = 0; drbg->d_ops = NULL; drbg->core = NULL; -#ifdef CONFIG_CRYPTO_FIPS - kzfree(drbg->prev); - drbg->prev = NULL; - drbg->fips_primed = false; -#endif } /* @@ -1244,12 +1186,6 @@ static inline int drbg_alloc_state(struct drbg_state *drbg) drbg->C = kmalloc(drbg_statelen(drbg), GFP_KERNEL); if (!drbg->C) goto err; -#ifdef CONFIG_CRYPTO_FIPS - drbg->prev = kmalloc(drbg_blocklen(drbg), GFP_KERNEL); - if (!drbg->prev) - goto err; - drbg->fips_primed = false; -#endif /* scratchpad is only generated for CTR and Hash */ if (drbg->core->flags & DRBG_HMAC) sb_size = 0; diff --git a/crypto/internal.h b/crypto/internal.h index 00e42a3ed814..7eefcdb00227 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -104,6 +104,9 @@ int crypto_probing_notify(unsigned long val, void *v); unsigned int crypto_alg_extsize(struct crypto_alg *alg); +int crypto_type_has_alg(const char *name, const struct crypto_type *frontend, + u32 type, u32 mask); + static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg) { atomic_inc(&alg->cra_refcnt); diff --git a/crypto/keywrap.c b/crypto/keywrap.c index b1d106ce55f3..72014f963ba7 100644 --- a/crypto/keywrap.c +++ b/crypto/keywrap.c @@ -212,7 +212,7 @@ static int crypto_kw_decrypt(struct blkcipher_desc *desc, SEMIBSIZE)) ret = -EBADMSG; - memzero_explicit(&block, sizeof(struct crypto_kw_block)); + memzero_explicit(block, sizeof(struct crypto_kw_block)); return ret; } @@ -297,7 +297,7 @@ static int crypto_kw_encrypt(struct blkcipher_desc *desc, /* establish the IV for the caller to pick up */ memcpy(desc->info, block->A, SEMIBSIZE); - memzero_explicit(&block, sizeof(struct crypto_kw_block)); + memzero_explicit(block, sizeof(struct crypto_kw_block)); return 0; } diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c index f78d4fc4e38a..c4eb9da49d4f 100644 --- a/crypto/mcryptd.c +++ b/crypto/mcryptd.c @@ -522,6 +522,7 @@ static int mcryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, inst->alg.halg.base.cra_flags = type; inst->alg.halg.digestsize = salg->digestsize; + inst->alg.halg.statesize = salg->statesize; inst->alg.halg.base.cra_ctxsize = sizeof(struct mcryptd_hash_ctx); inst->alg.halg.base.cra_init = mcryptd_hash_init_tfm; diff --git a/crypto/pcompress.c b/crypto/pcompress.c deleted file mode 100644 index 7a13b4088857..000000000000 --- a/crypto/pcompress.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Cryptographic API. - * - * Partial (de)compression operations. - * - * Copyright 2008 Sony 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; 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. - * - * 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 -#include - -#include "internal.h" - - -static int crypto_pcomp_init(struct crypto_tfm *tfm, u32 type, u32 mask) -{ - return 0; -} - -static int crypto_pcomp_init_tfm(struct crypto_tfm *tfm) -{ - return 0; -} - -#ifdef CONFIG_NET -static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg) -{ - struct crypto_report_comp rpcomp; - - strncpy(rpcomp.type, "pcomp", sizeof(rpcomp.type)); - if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS, - sizeof(struct crypto_report_comp), &rpcomp)) - goto nla_put_failure; - return 0; - -nla_put_failure: - return -EMSGSIZE; -} -#else -static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg) -{ - return -ENOSYS; -} -#endif - -static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg) - __attribute__ ((unused)); -static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg) -{ - seq_printf(m, "type : pcomp\n"); -} - -static const struct crypto_type crypto_pcomp_type = { - .extsize = crypto_alg_extsize, - .init = crypto_pcomp_init, - .init_tfm = crypto_pcomp_init_tfm, -#ifdef CONFIG_PROC_FS - .show = crypto_pcomp_show, -#endif - .report = crypto_pcomp_report, - .maskclear = ~CRYPTO_ALG_TYPE_MASK, - .maskset = CRYPTO_ALG_TYPE_MASK, - .type = CRYPTO_ALG_TYPE_PCOMPRESS, - .tfmsize = offsetof(struct crypto_pcomp, base), -}; - -struct crypto_pcomp *crypto_alloc_pcomp(const char *alg_name, u32 type, - u32 mask) -{ - return crypto_alloc_tfm(alg_name, &crypto_pcomp_type, type, mask); -} -EXPORT_SYMBOL_GPL(crypto_alloc_pcomp); - -int crypto_register_pcomp(struct pcomp_alg *alg) -{ - struct crypto_alg *base = &alg->base; - - base->cra_type = &crypto_pcomp_type; - base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; - base->cra_flags |= CRYPTO_ALG_TYPE_PCOMPRESS; - - return crypto_register_alg(base); -} -EXPORT_SYMBOL_GPL(crypto_register_pcomp); - -int crypto_unregister_pcomp(struct pcomp_alg *alg) -{ - return crypto_unregister_alg(&alg->base); -} -EXPORT_SYMBOL_GPL(crypto_unregister_pcomp); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Partial (de)compression type"); -MODULE_AUTHOR("Sony Corporation"); diff --git a/crypto/shash.c b/crypto/shash.c index 88a27de79848..a051541a4a17 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -354,11 +354,10 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm) crt->final = shash_async_final; crt->finup = shash_async_finup; crt->digest = shash_async_digest; + crt->setkey = shash_async_setkey; + + crt->has_setkey = alg->setkey != shash_no_setkey; - if (alg->setkey) { - crt->setkey = shash_async_setkey; - crt->has_setkey = true; - } if (alg->export) crt->export = shash_async_export; if (alg->import) @@ -369,151 +368,6 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm) return 0; } -static int shash_compat_setkey(struct crypto_hash *tfm, const u8 *key, - unsigned int keylen) -{ - struct shash_desc **descp = crypto_hash_ctx(tfm); - struct shash_desc *desc = *descp; - - return crypto_shash_setkey(desc->tfm, key, keylen); -} - -static int shash_compat_init(struct hash_desc *hdesc) -{ - struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm); - struct shash_desc *desc = *descp; - - desc->flags = hdesc->flags; - - return crypto_shash_init(desc); -} - -static int shash_compat_update(struct hash_desc *hdesc, struct scatterlist *sg, - unsigned int len) -{ - struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm); - struct shash_desc *desc = *descp; - struct crypto_hash_walk walk; - int nbytes; - - for (nbytes = crypto_hash_walk_first_compat(hdesc, &walk, sg, len); - nbytes > 0; nbytes = crypto_hash_walk_done(&walk, nbytes)) - nbytes = crypto_shash_update(desc, walk.data, nbytes); - - return nbytes; -} - -static int shash_compat_final(struct hash_desc *hdesc, u8 *out) -{ - struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm); - - return crypto_shash_final(*descp, out); -} - -static int shash_compat_digest(struct hash_desc *hdesc, struct scatterlist *sg, - unsigned int nbytes, u8 *out) -{ - unsigned int offset = sg->offset; - int err; - - if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) { - struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm); - struct shash_desc *desc = *descp; - void *data; - - desc->flags = hdesc->flags; - - data = kmap_atomic(sg_page(sg)); - err = crypto_shash_digest(desc, data + offset, nbytes, out); - kunmap_atomic(data); - crypto_yield(desc->flags); - goto out; - } - - err = shash_compat_init(hdesc); - if (err) - goto out; - - err = shash_compat_update(hdesc, sg, nbytes); - if (err) - goto out; - - err = shash_compat_final(hdesc, out); - -out: - return err; -} - -static void crypto_exit_shash_ops_compat(struct crypto_tfm *tfm) -{ - struct shash_desc **descp = crypto_tfm_ctx(tfm); - struct shash_desc *desc = *descp; - - crypto_free_shash(desc->tfm); - kzfree(desc); -} - -static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm) -{ - struct hash_tfm *crt = &tfm->crt_hash; - struct crypto_alg *calg = tfm->__crt_alg; - struct shash_alg *alg = __crypto_shash_alg(calg); - struct shash_desc **descp = crypto_tfm_ctx(tfm); - struct crypto_shash *shash; - struct shash_desc *desc; - - if (!crypto_mod_get(calg)) - return -EAGAIN; - - shash = crypto_create_tfm(calg, &crypto_shash_type); - if (IS_ERR(shash)) { - crypto_mod_put(calg); - return PTR_ERR(shash); - } - - desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(shash), - GFP_KERNEL); - if (!desc) { - crypto_free_shash(shash); - return -ENOMEM; - } - - *descp = desc; - desc->tfm = shash; - tfm->exit = crypto_exit_shash_ops_compat; - - crt->init = shash_compat_init; - crt->update = shash_compat_update; - crt->final = shash_compat_final; - crt->digest = shash_compat_digest; - crt->setkey = shash_compat_setkey; - - crt->digestsize = alg->digestsize; - - return 0; -} - -static int crypto_init_shash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) -{ - switch (mask & CRYPTO_ALG_TYPE_MASK) { - case CRYPTO_ALG_TYPE_HASH_MASK: - return crypto_init_shash_ops_compat(tfm); - } - - return -EINVAL; -} - -static unsigned int crypto_shash_ctxsize(struct crypto_alg *alg, u32 type, - u32 mask) -{ - switch (mask & CRYPTO_ALG_TYPE_MASK) { - case CRYPTO_ALG_TYPE_HASH_MASK: - return sizeof(struct shash_desc *); - } - - return 0; -} - static int crypto_shash_init_tfm(struct crypto_tfm *tfm) { struct crypto_shash *hash = __crypto_shash_cast(tfm); @@ -560,9 +414,7 @@ static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) } static const struct crypto_type crypto_shash_type = { - .ctxsize = crypto_shash_ctxsize, .extsize = crypto_alg_extsize, - .init = crypto_init_shash_ops, .init_tfm = crypto_shash_init_tfm, #ifdef CONFIG_PROC_FS .show = crypto_shash_show, diff --git a/crypto/skcipher.c b/crypto/skcipher.c index d199c0b1751c..69230e9d4ac9 100644 --- a/crypto/skcipher.c +++ b/crypto/skcipher.c @@ -118,7 +118,7 @@ static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm) skcipher->decrypt = skcipher_decrypt_blkcipher; skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher); - skcipher->has_setkey = calg->cra_blkcipher.max_keysize; + skcipher->keysize = calg->cra_blkcipher.max_keysize; return 0; } @@ -211,7 +211,7 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm) skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher); skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) + sizeof(struct ablkcipher_request); - skcipher->has_setkey = calg->cra_ablkcipher.max_keysize; + skcipher->keysize = calg->cra_ablkcipher.max_keysize; return 0; } diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 270bc4b82bd9..579dce071463 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -554,164 +554,6 @@ out: crypto_free_blkcipher(tfm); } -static int test_hash_jiffies_digest(struct hash_desc *desc, - struct scatterlist *sg, int blen, - char *out, int secs) -{ - unsigned long start, end; - int bcount; - int ret; - - for (start = jiffies, end = start + secs * HZ, bcount = 0; - time_before(jiffies, end); bcount++) { - ret = crypto_hash_digest(desc, sg, blen, out); - if (ret) - return ret; - } - - printk("%6u opers/sec, %9lu bytes/sec\n", - bcount / secs, ((long)bcount * blen) / secs); - - return 0; -} - -static int test_hash_jiffies(struct hash_desc *desc, struct scatterlist *sg, - int blen, int plen, char *out, int secs) -{ - unsigned long start, end; - int bcount, pcount; - int ret; - - if (plen == blen) - return test_hash_jiffies_digest(desc, sg, blen, out, secs); - - for (start = jiffies, end = start + secs * HZ, bcount = 0; - time_before(jiffies, end); bcount++) { - ret = crypto_hash_init(desc); - if (ret) - return ret; - for (pcount = 0; pcount < blen; pcount += plen) { - ret = crypto_hash_update(desc, sg, plen); - if (ret) - return ret; - } - /* we assume there is enough space in 'out' for the result */ - ret = crypto_hash_final(desc, out); - if (ret) - return ret; - } - - printk("%6u opers/sec, %9lu bytes/sec\n", - bcount / secs, ((long)bcount * blen) / secs); - - return 0; -} - -static int test_hash_cycles_digest(struct hash_desc *desc, - struct scatterlist *sg, int blen, char *out) -{ - unsigned long cycles = 0; - int i; - int ret; - - local_irq_disable(); - - /* Warm-up run. */ - for (i = 0; i < 4; i++) { - ret = crypto_hash_digest(desc, sg, blen, out); - if (ret) - goto out; - } - - /* The real thing. */ - for (i = 0; i < 8; i++) { - cycles_t start, end; - - start = get_cycles(); - - ret = crypto_hash_digest(desc, sg, blen, out); - if (ret) - goto out; - - end = get_cycles(); - - cycles += end - start; - } - -out: - local_irq_enable(); - - if (ret) - return ret; - - printk("%6lu cycles/operation, %4lu cycles/byte\n", - cycles / 8, cycles / (8 * blen)); - - return 0; -} - -static int test_hash_cycles(struct hash_desc *desc, struct scatterlist *sg, - int blen, int plen, char *out) -{ - unsigned long cycles = 0; - int i, pcount; - int ret; - - if (plen == blen) - return test_hash_cycles_digest(desc, sg, blen, out); - - local_irq_disable(); - - /* Warm-up run. */ - for (i = 0; i < 4; i++) { - ret = crypto_hash_init(desc); - if (ret) - goto out; - for (pcount = 0; pcount < blen; pcount += plen) { - ret = crypto_hash_update(desc, sg, plen); - if (ret) - goto out; - } - ret = crypto_hash_final(desc, out); - if (ret) - goto out; - } - - /* The real thing. */ - for (i = 0; i < 8; i++) { - cycles_t start, end; - - start = get_cycles(); - - ret = crypto_hash_init(desc); - if (ret) - goto out; - for (pcount = 0; pcount < blen; pcount += plen) { - ret = crypto_hash_update(desc, sg, plen); - if (ret) - goto out; - } - ret = crypto_hash_final(desc, out); - if (ret) - goto out; - - end = get_cycles(); - - cycles += end - start; - } - -out: - local_irq_enable(); - - if (ret) - return ret; - - printk("%6lu cycles/operation, %4lu cycles/byte\n", - cycles / 8, cycles / (8 * blen)); - - return 0; -} - static void test_hash_sg_init(struct scatterlist *sg) { int i; @@ -723,69 +565,6 @@ static void test_hash_sg_init(struct scatterlist *sg) } } -static void test_hash_speed(const char *algo, unsigned int secs, - struct hash_speed *speed) -{ - struct scatterlist sg[TVMEMSIZE]; - struct crypto_hash *tfm; - struct hash_desc desc; - static char output[1024]; - int i; - int ret; - - tfm = crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC); - - if (IS_ERR(tfm)) { - printk(KERN_ERR "failed to load transform for %s: %ld\n", algo, - PTR_ERR(tfm)); - return; - } - - printk(KERN_INFO "\ntesting speed of %s (%s)\n", algo, - get_driver_name(crypto_hash, tfm)); - - desc.tfm = tfm; - desc.flags = 0; - - if (crypto_hash_digestsize(tfm) > sizeof(output)) { - printk(KERN_ERR "digestsize(%u) > outputbuffer(%zu)\n", - crypto_hash_digestsize(tfm), sizeof(output)); - goto out; - } - - test_hash_sg_init(sg); - for (i = 0; speed[i].blen != 0; i++) { - if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) { - printk(KERN_ERR - "template (%u) too big for tvmem (%lu)\n", - speed[i].blen, TVMEMSIZE * PAGE_SIZE); - goto out; - } - - if (speed[i].klen) - crypto_hash_setkey(tfm, tvmem[0], speed[i].klen); - - printk(KERN_INFO "test%3u " - "(%5u byte blocks,%5u bytes per update,%4u updates): ", - i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen); - - if (secs) - ret = test_hash_jiffies(&desc, sg, speed[i].blen, - speed[i].plen, output, secs); - else - ret = test_hash_cycles(&desc, sg, speed[i].blen, - speed[i].plen, output); - - if (ret) { - printk(KERN_ERR "hashing failed ret=%d\n", ret); - break; - } - } - -out: - crypto_free_hash(tfm); -} - static inline int do_one_ahash_op(struct ahash_request *req, int ret) { if (ret == -EINPROGRESS || ret == -EBUSY) { @@ -945,8 +724,8 @@ out: return 0; } -static void test_ahash_speed(const char *algo, unsigned int secs, - struct hash_speed *speed) +static void test_ahash_speed_common(const char *algo, unsigned int secs, + struct hash_speed *speed, unsigned mask) { struct scatterlist sg[TVMEMSIZE]; struct tcrypt_result tresult; @@ -955,7 +734,7 @@ static void test_ahash_speed(const char *algo, unsigned int secs, char *output; int i, ret; - tfm = crypto_alloc_ahash(algo, 0, 0); + tfm = crypto_alloc_ahash(algo, 0, mask); if (IS_ERR(tfm)) { pr_err("failed to load transform for %s: %ld\n", algo, PTR_ERR(tfm)); @@ -1021,6 +800,18 @@ out: crypto_free_ahash(tfm); } +static void test_ahash_speed(const char *algo, unsigned int secs, + struct hash_speed *speed) +{ + return test_ahash_speed_common(algo, secs, speed, 0); +} + +static void test_hash_speed(const char *algo, unsigned int secs, + struct hash_speed *speed) +{ + return test_ahash_speed_common(algo, secs, speed, CRYPTO_ALG_ASYNC); +} + static inline int do_one_acipher_op(struct ablkcipher_request *req, int ret) { if (ret == -EINPROGRESS || ret == -EBUSY) { diff --git a/crypto/testmgr.c b/crypto/testmgr.c index ae8c57fd8bc7..93f3527962ec 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -96,13 +96,6 @@ struct comp_test_suite { } comp, decomp; }; -struct pcomp_test_suite { - struct { - struct pcomp_testvec *vecs; - unsigned int count; - } comp, decomp; -}; - struct hash_test_suite { struct hash_testvec *vecs; unsigned int count; @@ -133,7 +126,6 @@ struct alg_test_desc { struct aead_test_suite aead; struct cipher_test_suite cipher; struct comp_test_suite comp; - struct pcomp_test_suite pcomp; struct hash_test_suite hash; struct cprng_test_suite cprng; struct drbg_test_suite drbg; @@ -198,6 +190,61 @@ static int wait_async_op(struct tcrypt_result *tr, int ret) return ret; } +static int ahash_partial_update(struct ahash_request **preq, + struct crypto_ahash *tfm, struct hash_testvec *template, + void *hash_buff, int k, int temp, struct scatterlist *sg, + const char *algo, char *result, struct tcrypt_result *tresult) +{ + char *state; + struct ahash_request *req; + int statesize, ret = -EINVAL; + + req = *preq; + statesize = crypto_ahash_statesize( + crypto_ahash_reqtfm(req)); + state = kmalloc(statesize, GFP_KERNEL); + if (!state) { + pr_err("alt: hash: Failed to alloc state for %s\n", algo); + goto out_nostate; + } + ret = crypto_ahash_export(req, state); + if (ret) { + pr_err("alt: hash: Failed to export() for %s\n", algo); + goto out; + } + ahash_request_free(req); + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) { + pr_err("alg: hash: Failed to alloc request for %s\n", algo); + goto out_noreq; + } + ahash_request_set_callback(req, + CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, tresult); + + memcpy(hash_buff, template->plaintext + temp, + template->tap[k]); + sg_init_one(&sg[0], hash_buff, template->tap[k]); + ahash_request_set_crypt(req, sg, result, template->tap[k]); + ret = crypto_ahash_import(req, state); + if (ret) { + pr_err("alg: hash: Failed to import() for %s\n", algo); + goto out; + } + ret = wait_async_op(tresult, crypto_ahash_update(req)); + if (ret) + goto out; + *preq = req; + ret = 0; + goto out_noreq; +out: + ahash_request_free(req); +out_noreq: + kfree(state); +out_nostate: + return ret; +} + static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, unsigned int tcount, bool use_digest, const int align_offset) @@ -385,6 +432,84 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, } } + /* partial update exercise */ + j = 0; + for (i = 0; i < tcount; i++) { + /* alignment tests are only done with continuous buffers */ + if (align_offset != 0) + break; + + if (template[i].np < 2) + continue; + + j++; + memset(result, 0, MAX_DIGEST_SIZE); + + ret = -EINVAL; + hash_buff = xbuf[0]; + memcpy(hash_buff, template[i].plaintext, + template[i].tap[0]); + sg_init_one(&sg[0], hash_buff, template[i].tap[0]); + + if (template[i].ksize) { + crypto_ahash_clear_flags(tfm, ~0); + if (template[i].ksize > MAX_KEYLEN) { + pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n", + j, algo, template[i].ksize, MAX_KEYLEN); + ret = -EINVAL; + goto out; + } + memcpy(key, template[i].key, template[i].ksize); + ret = crypto_ahash_setkey(tfm, key, template[i].ksize); + if (ret) { + pr_err("alg: hash: setkey failed on test %d for %s: ret=%d\n", + j, algo, -ret); + goto out; + } + } + + ahash_request_set_crypt(req, sg, result, template[i].tap[0]); + ret = wait_async_op(&tresult, crypto_ahash_init(req)); + if (ret) { + pr_err("alt: hash: init failed on test %d for %s: ret=%d\n", + j, algo, -ret); + goto out; + } + ret = wait_async_op(&tresult, crypto_ahash_update(req)); + if (ret) { + pr_err("alt: hash: update failed on test %d for %s: ret=%d\n", + j, algo, -ret); + goto out; + } + + temp = template[i].tap[0]; + for (k = 1; k < template[i].np; k++) { + ret = ahash_partial_update(&req, tfm, &template[i], + hash_buff, k, temp, &sg[0], algo, result, + &tresult); + if (ret) { + pr_err("hash: partial update failed on test %d for %s: ret=%d\n", + j, algo, -ret); + goto out_noreq; + } + temp += template[i].tap[k]; + } + ret = wait_async_op(&tresult, crypto_ahash_final(req)); + if (ret) { + pr_err("alt: hash: final failed on test %d for %s: ret=%d\n", + j, algo, -ret); + goto out; + } + if (memcmp(result, template[i].digest, + crypto_ahash_digestsize(tfm))) { + pr_err("alg: hash: Partial Test %d failed for %s\n", + j, algo); + hexdump(result, crypto_ahash_digestsize(tfm)); + ret = -EINVAL; + goto out; + } + } + ret = 0; out: @@ -488,6 +613,8 @@ static int __test_aead(struct crypto_aead *tfm, int enc, aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, tcrypt_complete, &result); + iv_len = crypto_aead_ivsize(tfm); + for (i = 0, j = 0; i < tcount; i++) { if (template[i].np) continue; @@ -508,7 +635,6 @@ static int __test_aead(struct crypto_aead *tfm, int enc, memcpy(input, template[i].input, template[i].ilen); memcpy(assoc, template[i].assoc, template[i].alen); - iv_len = crypto_aead_ivsize(tfm); if (template[i].iv) memcpy(iv, template[i].iv, iv_len); else @@ -617,7 +743,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc, j++; if (template[i].iv) - memcpy(iv, template[i].iv, MAX_IVLEN); + memcpy(iv, template[i].iv, iv_len); else memset(iv, 0, MAX_IVLEN); @@ -1293,183 +1419,6 @@ out: return ret; } -static int test_pcomp(struct crypto_pcomp *tfm, - struct pcomp_testvec *ctemplate, - struct pcomp_testvec *dtemplate, int ctcount, - int dtcount) -{ - const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm)); - unsigned int i; - char result[COMP_BUF_SIZE]; - int res; - - for (i = 0; i < ctcount; i++) { - struct comp_request req; - unsigned int produced = 0; - - res = crypto_compress_setup(tfm, ctemplate[i].params, - ctemplate[i].paramsize); - if (res) { - pr_err("alg: pcomp: compression setup failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - - res = crypto_compress_init(tfm); - if (res) { - pr_err("alg: pcomp: compression init failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - - memset(result, 0, sizeof(result)); - - req.next_in = ctemplate[i].input; - req.avail_in = ctemplate[i].inlen / 2; - req.next_out = result; - req.avail_out = ctemplate[i].outlen / 2; - - res = crypto_compress_update(tfm, &req); - if (res < 0 && (res != -EAGAIN || req.avail_in)) { - pr_err("alg: pcomp: compression update failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - if (res > 0) - produced += res; - - /* Add remaining input data */ - req.avail_in += (ctemplate[i].inlen + 1) / 2; - - res = crypto_compress_update(tfm, &req); - if (res < 0 && (res != -EAGAIN || req.avail_in)) { - pr_err("alg: pcomp: compression update failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - if (res > 0) - produced += res; - - /* Provide remaining output space */ - req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2; - - res = crypto_compress_final(tfm, &req); - if (res < 0) { - pr_err("alg: pcomp: compression final failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - produced += res; - - if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) { - pr_err("alg: comp: Compression test %d failed for %s: " - "output len = %d (expected %d)\n", i + 1, algo, - COMP_BUF_SIZE - req.avail_out, - ctemplate[i].outlen); - return -EINVAL; - } - - if (produced != ctemplate[i].outlen) { - pr_err("alg: comp: Compression test %d failed for %s: " - "returned len = %u (expected %d)\n", i + 1, - algo, produced, ctemplate[i].outlen); - return -EINVAL; - } - - if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) { - pr_err("alg: pcomp: Compression test %d failed for " - "%s\n", i + 1, algo); - hexdump(result, ctemplate[i].outlen); - return -EINVAL; - } - } - - for (i = 0; i < dtcount; i++) { - struct comp_request req; - unsigned int produced = 0; - - res = crypto_decompress_setup(tfm, dtemplate[i].params, - dtemplate[i].paramsize); - if (res) { - pr_err("alg: pcomp: decompression setup failed on " - "test %d for %s: error=%d\n", i + 1, algo, res); - return res; - } - - res = crypto_decompress_init(tfm); - if (res) { - pr_err("alg: pcomp: decompression init failed on test " - "%d for %s: error=%d\n", i + 1, algo, res); - return res; - } - - memset(result, 0, sizeof(result)); - - req.next_in = dtemplate[i].input; - req.avail_in = dtemplate[i].inlen / 2; - req.next_out = result; - req.avail_out = dtemplate[i].outlen / 2; - - res = crypto_decompress_update(tfm, &req); - if (res < 0 && (res != -EAGAIN || req.avail_in)) { - pr_err("alg: pcomp: decompression update failed on " - "test %d for %s: error=%d\n", i + 1, algo, res); - return res; - } - if (res > 0) - produced += res; - - /* Add remaining input data */ - req.avail_in += (dtemplate[i].inlen + 1) / 2; - - res = crypto_decompress_update(tfm, &req); - if (res < 0 && (res != -EAGAIN || req.avail_in)) { - pr_err("alg: pcomp: decompression update failed on " - "test %d for %s: error=%d\n", i + 1, algo, res); - return res; - } - if (res > 0) - produced += res; - - /* Provide remaining output space */ - req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2; - - res = crypto_decompress_final(tfm, &req); - if (res < 0 && (res != -EAGAIN || req.avail_in)) { - pr_err("alg: pcomp: decompression final failed on " - "test %d for %s: error=%d\n", i + 1, algo, res); - return res; - } - if (res > 0) - produced += res; - - if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) { - pr_err("alg: comp: Decompression test %d failed for " - "%s: output len = %d (expected %d)\n", i + 1, - algo, COMP_BUF_SIZE - req.avail_out, - dtemplate[i].outlen); - return -EINVAL; - } - - if (produced != dtemplate[i].outlen) { - pr_err("alg: comp: Decompression test %d failed for " - "%s: returned len = %u (expected %d)\n", i + 1, - algo, produced, dtemplate[i].outlen); - return -EINVAL; - } - - if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) { - pr_err("alg: pcomp: Decompression test %d failed for " - "%s\n", i + 1, algo); - hexdump(result, dtemplate[i].outlen); - return -EINVAL; - } - } - - return 0; -} - - static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template, unsigned int tcount) { @@ -1640,28 +1589,6 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, return err; } -static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver, - u32 type, u32 mask) -{ - struct crypto_pcomp *tfm; - int err; - - tfm = crypto_alloc_pcomp(driver, type, mask); - if (IS_ERR(tfm)) { - pr_err("alg: pcomp: Failed to load transform for %s: %ld\n", - driver, PTR_ERR(tfm)); - return PTR_ERR(tfm); - } - - err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs, - desc->suite.pcomp.decomp.vecs, - desc->suite.pcomp.comp.count, - desc->suite.pcomp.decomp.count); - - crypto_free_pcomp(tfm); - return err; -} - static int alg_test_hash(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask) { @@ -2081,7 +2008,6 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "ansi_cprng", .test = alg_test_cprng, - .fips_allowed = 1, .suite = { .cprng = { .vecs = ansi_cprng_aes_tv_template, @@ -2132,6 +2058,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha1),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2177,6 +2104,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha224),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2190,6 +2118,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha256),cbc(aes))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2216,6 +2145,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha256),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2242,6 +2172,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha384),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -2254,6 +2185,7 @@ static const struct alg_test_desc alg_test_descs[] = { } }, { .alg = "authenc(hmac(sha512),cbc(aes))", + .fips_allowed = 1, .test = alg_test_aead, .suite = { .aead = { @@ -2281,6 +2213,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha512),cbc(des3_ede))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { @@ -3840,22 +3773,6 @@ static const struct alg_test_desc alg_test_descs[] = { } } } - }, { - .alg = "zlib", - .test = alg_test_pcomp, - .fips_allowed = 1, - .suite = { - .pcomp = { - .comp = { - .vecs = zlib_comp_tv_template, - .count = ZLIB_COMP_TEST_VECTORS - }, - .decomp = { - .vecs = zlib_decomp_tv_template, - .count = ZLIB_DECOMP_TEST_VECTORS - } - } - } } }; diff --git a/crypto/testmgr.h b/crypto/testmgr.h index da0a8fd765f4..487ec880e889 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -25,9 +25,6 @@ #define _CRYPTO_TESTMGR_H #include -#include - -#include #define MAX_DIGEST_SIZE 64 #define MAX_TAP 8 @@ -32268,14 +32265,6 @@ struct comp_testvec { char output[COMP_BUF_SIZE]; }; -struct pcomp_testvec { - const void *params; - unsigned int paramsize; - int inlen, outlen; - char input[COMP_BUF_SIZE]; - char output[COMP_BUF_SIZE]; -}; - /* * Deflate test vectors (null-terminated strings). * Params: winbits=-11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL. @@ -32356,139 +32345,6 @@ static struct comp_testvec deflate_decomp_tv_template[] = { }, }; -#define ZLIB_COMP_TEST_VECTORS 2 -#define ZLIB_DECOMP_TEST_VECTORS 2 - -static const struct { - struct nlattr nla; - int val; -} deflate_comp_params[] = { - { - .nla = { - .nla_len = NLA_HDRLEN + sizeof(int), - .nla_type = ZLIB_COMP_LEVEL, - }, - .val = Z_DEFAULT_COMPRESSION, - }, { - .nla = { - .nla_len = NLA_HDRLEN + sizeof(int), - .nla_type = ZLIB_COMP_METHOD, - }, - .val = Z_DEFLATED, - }, { - .nla = { - .nla_len = NLA_HDRLEN + sizeof(int), - .nla_type = ZLIB_COMP_WINDOWBITS, - }, - .val = -11, - }, { - .nla = { - .nla_len = NLA_HDRLEN + sizeof(int), - .nla_type = ZLIB_COMP_MEMLEVEL, - }, - .val = MAX_MEM_LEVEL, - }, { - .nla = { - .nla_len = NLA_HDRLEN + sizeof(int), - .nla_type = ZLIB_COMP_STRATEGY, - }, - .val = Z_DEFAULT_STRATEGY, - } -}; - -static const struct { - struct nlattr nla; - int val; -} deflate_decomp_params[] = { - { - .nla = { - .nla_len = NLA_HDRLEN + sizeof(int), - .nla_type = ZLIB_DECOMP_WINDOWBITS, - }, - .val = -11, - } -}; - -static struct pcomp_testvec zlib_comp_tv_template[] = { - { - .params = &deflate_comp_params, - .paramsize = sizeof(deflate_comp_params), - .inlen = 70, - .outlen = 38, - .input = "Join us now and share the software " - "Join us now and share the software ", - .output = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56" - "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51" - "\x28\xce\x48\x2c\x4a\x55\x28\xc9" - "\x48\x55\x28\xce\x4f\x2b\x29\x07" - "\x71\xbc\x08\x2b\x01\x00", - }, { - .params = &deflate_comp_params, - .paramsize = sizeof(deflate_comp_params), - .inlen = 191, - .outlen = 122, - .input = "This document describes a compression method based on the DEFLATE" - "compression algorithm. This document defines the application of " - "the DEFLATE algorithm to the IP Payload Compression Protocol.", - .output = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04" - "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09" - "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8" - "\x24\xdb\x67\xd9\x47\xc1\xef\x49" - "\x68\x12\x51\xae\x76\x67\xd6\x27" - "\x19\x88\x1a\xde\x85\xab\x21\xf2" - "\x08\x5d\x16\x1e\x20\x04\x2d\xad" - "\xf3\x18\xa2\x15\x85\x2d\x69\xc4" - "\x42\x83\x23\xb6\x6c\x89\x71\x9b" - "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f" - "\xed\x62\xa9\x4c\x80\xff\x13\xaf" - "\x52\x37\xed\x0e\x52\x6b\x59\x02" - "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98" - "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a" - "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79" - "\xfa\x02", - }, -}; - -static struct pcomp_testvec zlib_decomp_tv_template[] = { - { - .params = &deflate_decomp_params, - .paramsize = sizeof(deflate_decomp_params), - .inlen = 122, - .outlen = 191, - .input = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04" - "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09" - "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8" - "\x24\xdb\x67\xd9\x47\xc1\xef\x49" - "\x68\x12\x51\xae\x76\x67\xd6\x27" - "\x19\x88\x1a\xde\x85\xab\x21\xf2" - "\x08\x5d\x16\x1e\x20\x04\x2d\xad" - "\xf3\x18\xa2\x15\x85\x2d\x69\xc4" - "\x42\x83\x23\xb6\x6c\x89\x71\x9b" - "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f" - "\xed\x62\xa9\x4c\x80\xff\x13\xaf" - "\x52\x37\xed\x0e\x52\x6b\x59\x02" - "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98" - "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a" - "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79" - "\xfa\x02", - .output = "This document describes a compression method based on the DEFLATE" - "compression algorithm. This document defines the application of " - "the DEFLATE algorithm to the IP Payload Compression Protocol.", - }, { - .params = &deflate_decomp_params, - .paramsize = sizeof(deflate_decomp_params), - .inlen = 38, - .outlen = 70, - .input = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56" - "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51" - "\x28\xce\x48\x2c\x4a\x55\x28\xc9" - "\x48\x55\x28\xce\x4f\x2b\x29\x07" - "\x71\xbc\x08\x2b\x01\x00", - .output = "Join us now and share the software " - "Join us now and share the software ", - }, -}; - /* * LZO test vectors (null-terminated strings). */ diff --git a/crypto/zlib.c b/crypto/zlib.c deleted file mode 100644 index d51a30a29e42..000000000000 --- a/crypto/zlib.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Cryptographic API. - * - * Zlib algorithm - * - * Copyright 2008 Sony Corporation - * - * Based on deflate.c, which is - * Copyright (c) 2003 James Morris - * - * 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. - * - * FIXME: deflate transforms will require up to a total of about 436k of kernel - * memory on i386 (390k for compression, the rest for decompression), as the - * current zlib kernel code uses a worst case pre-allocation system by default. - * This needs to be fixed so that the amount of memory required is properly - * related to the winbits and memlevel parameters. - */ - -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - - -struct zlib_ctx { - struct z_stream_s comp_stream; - struct z_stream_s decomp_stream; - int decomp_windowBits; -}; - - -static void zlib_comp_exit(struct zlib_ctx *ctx) -{ - struct z_stream_s *stream = &ctx->comp_stream; - - if (stream->workspace) { - zlib_deflateEnd(stream); - vfree(stream->workspace); - stream->workspace = NULL; - } -} - -static void zlib_decomp_exit(struct zlib_ctx *ctx) -{ - struct z_stream_s *stream = &ctx->decomp_stream; - - if (stream->workspace) { - zlib_inflateEnd(stream); - vfree(stream->workspace); - stream->workspace = NULL; - } -} - -static int zlib_init(struct crypto_tfm *tfm) -{ - return 0; -} - -static void zlib_exit(struct crypto_tfm *tfm) -{ - struct zlib_ctx *ctx = crypto_tfm_ctx(tfm); - - zlib_comp_exit(ctx); - zlib_decomp_exit(ctx); -} - - -static int zlib_compress_setup(struct crypto_pcomp *tfm, const void *params, - unsigned int len) -{ - struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); - struct z_stream_s *stream = &ctx->comp_stream; - struct nlattr *tb[ZLIB_COMP_MAX + 1]; - int window_bits, mem_level; - size_t workspacesize; - int ret; - - ret = nla_parse(tb, ZLIB_COMP_MAX, params, len, NULL); - if (ret) - return ret; - - zlib_comp_exit(ctx); - - window_bits = tb[ZLIB_COMP_WINDOWBITS] - ? nla_get_u32(tb[ZLIB_COMP_WINDOWBITS]) - : MAX_WBITS; - mem_level = tb[ZLIB_COMP_MEMLEVEL] - ? nla_get_u32(tb[ZLIB_COMP_MEMLEVEL]) - : DEF_MEM_LEVEL; - - workspacesize = zlib_deflate_workspacesize(window_bits, mem_level); - stream->workspace = vzalloc(workspacesize); - if (!stream->workspace) - return -ENOMEM; - - ret = zlib_deflateInit2(stream, - tb[ZLIB_COMP_LEVEL] - ? nla_get_u32(tb[ZLIB_COMP_LEVEL]) - : Z_DEFAULT_COMPRESSION, - tb[ZLIB_COMP_METHOD] - ? nla_get_u32(tb[ZLIB_COMP_METHOD]) - : Z_DEFLATED, - window_bits, - mem_level, - tb[ZLIB_COMP_STRATEGY] - ? nla_get_u32(tb[ZLIB_COMP_STRATEGY]) - : Z_DEFAULT_STRATEGY); - if (ret != Z_OK) { - vfree(stream->workspace); - stream->workspace = NULL; - return -EINVAL; - } - - return 0; -} - -static int zlib_compress_init(struct crypto_pcomp *tfm) -{ - int ret; - struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); - struct z_stream_s *stream = &dctx->comp_stream; - - ret = zlib_deflateReset(stream); - if (ret != Z_OK) - return -EINVAL; - - return 0; -} - -static int zlib_compress_update(struct crypto_pcomp *tfm, - struct comp_request *req) -{ - int ret; - struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); - struct z_stream_s *stream = &dctx->comp_stream; - - pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out); - stream->next_in = req->next_in; - stream->avail_in = req->avail_in; - stream->next_out = req->next_out; - stream->avail_out = req->avail_out; - - ret = zlib_deflate(stream, Z_NO_FLUSH); - switch (ret) { - case Z_OK: - break; - - case Z_BUF_ERROR: - pr_debug("zlib_deflate could not make progress\n"); - return -EAGAIN; - - default: - pr_debug("zlib_deflate failed %d\n", ret); - return -EINVAL; - } - - ret = req->avail_out - stream->avail_out; - pr_debug("avail_in %lu, avail_out %lu (consumed %lu, produced %u)\n", - stream->avail_in, stream->avail_out, - req->avail_in - stream->avail_in, ret); - req->next_in = stream->next_in; - req->avail_in = stream->avail_in; - req->next_out = stream->next_out; - req->avail_out = stream->avail_out; - return ret; -} - -static int zlib_compress_final(struct crypto_pcomp *tfm, - struct comp_request *req) -{ - int ret; - struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); - struct z_stream_s *stream = &dctx->comp_stream; - - pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out); - stream->next_in = req->next_in; - stream->avail_in = req->avail_in; - stream->next_out = req->next_out; - stream->avail_out = req->avail_out; - - ret = zlib_deflate(stream, Z_FINISH); - if (ret != Z_STREAM_END) { - pr_debug("zlib_deflate failed %d\n", ret); - return -EINVAL; - } - - ret = req->avail_out - stream->avail_out; - pr_debug("avail_in %lu, avail_out %lu (consumed %lu, produced %u)\n", - stream->avail_in, stream->avail_out, - req->avail_in - stream->avail_in, ret); - req->next_in = stream->next_in; - req->avail_in = stream->avail_in; - req->next_out = stream->next_out; - req->avail_out = stream->avail_out; - return ret; -} - - -static int zlib_decompress_setup(struct crypto_pcomp *tfm, const void *params, - unsigned int len) -{ - struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); - struct z_stream_s *stream = &ctx->decomp_stream; - struct nlattr *tb[ZLIB_DECOMP_MAX + 1]; - int ret = 0; - - ret = nla_parse(tb, ZLIB_DECOMP_MAX, params, len, NULL); - if (ret) - return ret; - - zlib_decomp_exit(ctx); - - ctx->decomp_windowBits = tb[ZLIB_DECOMP_WINDOWBITS] - ? nla_get_u32(tb[ZLIB_DECOMP_WINDOWBITS]) - : DEF_WBITS; - - stream->workspace = vzalloc(zlib_inflate_workspacesize()); - if (!stream->workspace) - return -ENOMEM; - - ret = zlib_inflateInit2(stream, ctx->decomp_windowBits); - if (ret != Z_OK) { - vfree(stream->workspace); - stream->workspace = NULL; - return -EINVAL; - } - - return 0; -} - -static int zlib_decompress_init(struct crypto_pcomp *tfm) -{ - int ret; - struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); - struct z_stream_s *stream = &dctx->decomp_stream; - - ret = zlib_inflateReset(stream); - if (ret != Z_OK) - return -EINVAL; - - return 0; -} - -static int zlib_decompress_update(struct crypto_pcomp *tfm, - struct comp_request *req) -{ - int ret; - struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); - struct z_stream_s *stream = &dctx->decomp_stream; - - pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out); - stream->next_in = req->next_in; - stream->avail_in = req->avail_in; - stream->next_out = req->next_out; - stream->avail_out = req->avail_out; - - ret = zlib_inflate(stream, Z_SYNC_FLUSH); - switch (ret) { - case Z_OK: - case Z_STREAM_END: - break; - - case Z_BUF_ERROR: - pr_debug("zlib_inflate could not make progress\n"); - return -EAGAIN; - - default: - pr_debug("zlib_inflate failed %d\n", ret); - return -EINVAL; - } - - ret = req->avail_out - stream->avail_out; - pr_debug("avail_in %lu, avail_out %lu (consumed %lu, produced %u)\n", - stream->avail_in, stream->avail_out, - req->avail_in - stream->avail_in, ret); - req->next_in = stream->next_in; - req->avail_in = stream->avail_in; - req->next_out = stream->next_out; - req->avail_out = stream->avail_out; - return ret; -} - -static int zlib_decompress_final(struct crypto_pcomp *tfm, - struct comp_request *req) -{ - int ret; - struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); - struct z_stream_s *stream = &dctx->decomp_stream; - - pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out); - stream->next_in = req->next_in; - stream->avail_in = req->avail_in; - stream->next_out = req->next_out; - stream->avail_out = req->avail_out; - - if (dctx->decomp_windowBits < 0) { - ret = zlib_inflate(stream, Z_SYNC_FLUSH); - /* - * Work around a bug in zlib, which sometimes wants to taste an - * extra byte when being used in the (undocumented) raw deflate - * mode. (From USAGI). - */ - if (ret == Z_OK && !stream->avail_in && stream->avail_out) { - const void *saved_next_in = stream->next_in; - u8 zerostuff = 0; - - stream->next_in = &zerostuff; - stream->avail_in = 1; - ret = zlib_inflate(stream, Z_FINISH); - stream->next_in = saved_next_in; - stream->avail_in = 0; - } - } else - ret = zlib_inflate(stream, Z_FINISH); - if (ret != Z_STREAM_END) { - pr_debug("zlib_inflate failed %d\n", ret); - return -EINVAL; - } - - ret = req->avail_out - stream->avail_out; - pr_debug("avail_in %lu, avail_out %lu (consumed %lu, produced %u)\n", - stream->avail_in, stream->avail_out, - req->avail_in - stream->avail_in, ret); - req->next_in = stream->next_in; - req->avail_in = stream->avail_in; - req->next_out = stream->next_out; - req->avail_out = stream->avail_out; - return ret; -} - - -static struct pcomp_alg zlib_alg = { - .compress_setup = zlib_compress_setup, - .compress_init = zlib_compress_init, - .compress_update = zlib_compress_update, - .compress_final = zlib_compress_final, - .decompress_setup = zlib_decompress_setup, - .decompress_init = zlib_decompress_init, - .decompress_update = zlib_decompress_update, - .decompress_final = zlib_decompress_final, - - .base = { - .cra_name = "zlib", - .cra_flags = CRYPTO_ALG_TYPE_PCOMPRESS, - .cra_ctxsize = sizeof(struct zlib_ctx), - .cra_module = THIS_MODULE, - .cra_init = zlib_init, - .cra_exit = zlib_exit, - } -}; - -static int __init zlib_mod_init(void) -{ - return crypto_register_pcomp(&zlib_alg); -} - -static void __exit zlib_mod_fini(void) -{ - crypto_unregister_pcomp(&zlib_alg); -} - -module_init(zlib_mod_init); -module_exit(zlib_mod_fini); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Zlib Compression Algorithm"); -MODULE_AUTHOR("Sony Corporation"); -MODULE_ALIAS_CRYPTO("zlib"); diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index c570b1d9f094..0872d5fecb82 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -880,7 +880,7 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb, break; case BUS_NOTIFY_DRIVER_NOT_BOUND: case BUS_NOTIFY_UNBOUND_DRIVER: - pdev->dev.pm_domain = NULL; + dev_pm_domain_set(&pdev->dev, NULL); break; case BUS_NOTIFY_ADD_DEVICE: dev_pm_domain_set(&pdev->dev, &acpi_lpss_pm_domain); diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 296b7a14893a..b6f7fa3a1d40 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -62,7 +62,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) if (count < 0) { return NULL; } else if (count > 0) { - resources = kmalloc(count * sizeof(struct resource), + resources = kzalloc(count * sizeof(struct resource), GFP_KERNEL); if (!resources) { dev_err(&adev->dev, "No memory for resources\n"); diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 0431883653be..559c1173de1c 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -519,7 +519,7 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, u64 param3, u64 param4) { int rc; - unsigned long pfn; + u64 base_addr, size; /* If user manually set "flags", make sure it is legal */ if (flags && (flags & @@ -545,10 +545,17 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, /* * Disallow crazy address masks that give BIOS leeway to pick * injection address almost anywhere. Insist on page or - * better granularity and that target address is normal RAM. + * better granularity and that target address is normal RAM or + * NVDIMM. */ - pfn = PFN_DOWN(param1 & param2); - if (!page_is_ram(pfn) || ((param2 & PAGE_MASK) != PAGE_MASK)) + base_addr = param1 & param2; + size = ~param2 + 1; + + if (((param2 & PAGE_MASK) != PAGE_MASK) || + ((region_intersects(base_addr, size, IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE) + != REGION_INTERSECTS) && + (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY) + != REGION_INTERSECTS))) return -EINVAL; inject: diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 90e2d54be526..1316ddd92fac 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -135,14 +135,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), }, }, - { - .callback = video_detect_force_vendor, - .ident = "Dell Inspiron 5737", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5737"), - }, - }, /* * These models have a working acpi_video backlight control, and using diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 594fcabd22cd..546a3692774f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -264,6 +264,26 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ + { PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19b2), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19b3), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19b4), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19b5), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19b6), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19b7), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19bE), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19bF), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19c0), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19c1), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19c2), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19c3), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19c4), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19c5), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19c6), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19c7), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */ { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */ { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index a4faa438889c..167ba7e3b92e 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -240,8 +240,7 @@ enum { error-handling stage) */ AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */ AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */ - AHCI_HFLAG_EDGE_IRQ = (1 << 19), /* HOST_IRQ_STAT behaves as - Edge Triggered */ + #ifdef CONFIG_PCI_MSI AHCI_HFLAG_MULTI_MSI = (1 << 20), /* multiple PCI MSIs */ AHCI_HFLAG_MULTI_MSIX = (1 << 21), /* per-port MSI-X */ @@ -250,6 +249,7 @@ enum { AHCI_HFLAG_MULTI_MSI = 0, AHCI_HFLAG_MULTI_MSIX = 0, #endif + AHCI_HFLAG_WAKE_BEFORE_STOP = (1 << 22), /* wake before DMA stop */ /* ap->flags bits */ @@ -360,6 +360,7 @@ struct ahci_host_priv { * be overridden anytime before the host is activated. */ void (*start_engine)(struct ata_port *ap); + irqreturn_t (*irq_handler)(int irq, void *dev_instance); }; #ifdef CONFIG_PCI_MSI @@ -423,6 +424,7 @@ int ahci_reset_em(struct ata_host *host); void ahci_print_info(struct ata_host *host, const char *scc_s); int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht); void ahci_error_handler(struct ata_port *ap); +u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked); static inline void __iomem *__ahci_port_base(struct ata_host *host, unsigned int port_no) diff --git a/drivers/ata/ahci_brcmstb.c b/drivers/ata/ahci_brcmstb.c index b36cae2fd04b..e87bcec0fd7c 100644 --- a/drivers/ata/ahci_brcmstb.c +++ b/drivers/ata/ahci_brcmstb.c @@ -317,6 +317,7 @@ static int brcm_ahci_probe(struct platform_device *pdev) if (IS_ERR(hpriv)) return PTR_ERR(hpriv); hpriv->plat_data = priv; + hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP; brcm_sata_alpm_init(hpriv); diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index e2c6d9e0c5ac..8e3f7faf00d3 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -548,6 +548,88 @@ softreset_retry: return rc; } +/** + * xgene_ahci_handle_broken_edge_irq - Handle the broken irq. + * @ata_host: Host that recieved the irq + * @irq_masked: HOST_IRQ_STAT value + * + * For hardware with broken edge trigger latch + * the HOST_IRQ_STAT register misses the edge interrupt + * when clearing of HOST_IRQ_STAT register and hardware + * reporting the PORT_IRQ_STAT register at the + * same clock cycle. + * As such, the algorithm below outlines the workaround. + * + * 1. Read HOST_IRQ_STAT register and save the state. + * 2. Clear the HOST_IRQ_STAT register. + * 3. Read back the HOST_IRQ_STAT register. + * 4. If HOST_IRQ_STAT register equals to zero, then + * traverse the rest of port's PORT_IRQ_STAT register + * to check if an interrupt is triggered at that point else + * go to step 6. + * 5. If PORT_IRQ_STAT register of rest ports is not equal to zero + * then update the state of HOST_IRQ_STAT saved in step 1. + * 6. Handle port interrupts. + * 7. Exit + */ +static int xgene_ahci_handle_broken_edge_irq(struct ata_host *host, + u32 irq_masked) +{ + struct ahci_host_priv *hpriv = host->private_data; + void __iomem *port_mmio; + int i; + + if (!readl(hpriv->mmio + HOST_IRQ_STAT)) { + for (i = 0; i < host->n_ports; i++) { + if (irq_masked & (1 << i)) + continue; + + port_mmio = ahci_port_base(host->ports[i]); + if (readl(port_mmio + PORT_IRQ_STAT)) + irq_masked |= (1 << i); + } + } + + return ahci_handle_port_intr(host, irq_masked); +} + +static irqreturn_t xgene_ahci_irq_intr(int irq, void *dev_instance) +{ + struct ata_host *host = dev_instance; + struct ahci_host_priv *hpriv; + unsigned int rc = 0; + void __iomem *mmio; + u32 irq_stat, irq_masked; + + VPRINTK("ENTER\n"); + + hpriv = host->private_data; + mmio = hpriv->mmio; + + /* sigh. 0xffffffff is a valid return from h/w */ + irq_stat = readl(mmio + HOST_IRQ_STAT); + if (!irq_stat) + return IRQ_NONE; + + irq_masked = irq_stat & hpriv->port_map; + + spin_lock(&host->lock); + + /* + * HOST_IRQ_STAT behaves as edge triggered latch meaning that + * it should be cleared before all the port events are cleared. + */ + writel(irq_stat, mmio + HOST_IRQ_STAT); + + rc = xgene_ahci_handle_broken_edge_irq(host, irq_masked); + + spin_unlock(&host->lock); + + VPRINTK("EXIT\n"); + + return IRQ_RETVAL(rc); +} + static struct ata_port_operations xgene_ahci_v1_ops = { .inherits = &ahci_ops, .host_stop = xgene_ahci_host_stop, @@ -779,7 +861,8 @@ skip_clk_phy: hpriv->flags = AHCI_HFLAG_NO_NCQ; break; case XGENE_AHCI_V2: - hpriv->flags |= AHCI_HFLAG_YES_FBS | AHCI_HFLAG_EDGE_IRQ; + hpriv->flags |= AHCI_HFLAG_YES_FBS; + hpriv->irq_handler = xgene_ahci_irq_intr; break; default: break; diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index d61740e78d6d..513b3fa74d78 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -113,6 +113,7 @@ static ssize_t ahci_store_em_buffer(struct device *dev, const char *buf, size_t size); static ssize_t ahci_show_em_supported(struct device *dev, struct device_attribute *attr, char *buf); +static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance); static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); @@ -496,8 +497,8 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) } } - /* fabricate port_map from cap.nr_ports */ - if (!port_map) { + /* fabricate port_map from cap.nr_ports for < AHCI 1.3 */ + if (!port_map && vers < 0x10300) { port_map = (1 << ahci_nr_ports(cap)) - 1; dev_warn(dev, "forcing PORTS_IMPL to 0x%x\n", port_map); @@ -512,6 +513,9 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) if (!hpriv->start_engine) hpriv->start_engine = ahci_start_engine; + + if (!hpriv->irq_handler) + hpriv->irq_handler = ahci_single_level_irq_intr; } EXPORT_SYMBOL_GPL(ahci_save_initial_config); @@ -593,8 +597,22 @@ EXPORT_SYMBOL_GPL(ahci_start_engine); int ahci_stop_engine(struct ata_port *ap) { void __iomem *port_mmio = ahci_port_base(ap); + struct ahci_host_priv *hpriv = ap->host->private_data; u32 tmp; + /* + * On some controllers, stopping a port's DMA engine while the port + * is in ALPM state (partial or slumber) results in failures on + * subsequent DMA engine starts. For those controllers, put the + * port back in active state before stopping its DMA engine. + */ + if ((hpriv->flags & AHCI_HFLAG_WAKE_BEFORE_STOP) && + (ap->link.lpm_policy > ATA_LPM_MAX_POWER) && + ahci_set_lpm(&ap->link, ATA_LPM_MAX_POWER, ATA_LPM_WAKE_ONLY)) { + dev_err(ap->host->dev, "Failed to wake up port before engine stop\n"); + return -EIO; + } + tmp = readl(port_mmio + PORT_CMD); /* check if the HBA is idle */ @@ -689,6 +707,9 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, void __iomem *port_mmio = ahci_port_base(ap); if (policy != ATA_LPM_MAX_POWER) { + /* wakeup flag only applies to the max power policy */ + hints &= ~ATA_LPM_WAKE_ONLY; + /* * Disable interrupts on Phy Ready. This keeps us from * getting woken up due to spurious phy ready @@ -704,7 +725,8 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, u32 cmd = readl(port_mmio + PORT_CMD); if (policy == ATA_LPM_MAX_POWER || !(hints & ATA_LPM_HIPM)) { - cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE); + if (!(hints & ATA_LPM_WAKE_ONLY)) + cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE); cmd |= PORT_CMD_ICC_ACTIVE; writel(cmd, port_mmio + PORT_CMD); @@ -712,6 +734,9 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, /* wait 10ms to be sure we've come out of LPM state */ ata_msleep(ap, 10); + + if (hints & ATA_LPM_WAKE_ONLY) + return 0; } else { cmd |= PORT_CMD_ALPE; if (policy == ATA_LPM_MIN_POWER) @@ -1825,7 +1850,7 @@ static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance) return IRQ_HANDLED; } -static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked) +u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked) { unsigned int i, handled = 0; @@ -1851,43 +1876,7 @@ static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked) return handled; } - -static irqreturn_t ahci_single_edge_irq_intr(int irq, void *dev_instance) -{ - struct ata_host *host = dev_instance; - struct ahci_host_priv *hpriv; - unsigned int rc = 0; - void __iomem *mmio; - u32 irq_stat, irq_masked; - - VPRINTK("ENTER\n"); - - hpriv = host->private_data; - mmio = hpriv->mmio; - - /* sigh. 0xffffffff is a valid return from h/w */ - irq_stat = readl(mmio + HOST_IRQ_STAT); - if (!irq_stat) - return IRQ_NONE; - - irq_masked = irq_stat & hpriv->port_map; - - spin_lock(&host->lock); - - /* - * HOST_IRQ_STAT behaves as edge triggered latch meaning that - * it should be cleared before all the port events are cleared. - */ - writel(irq_stat, mmio + HOST_IRQ_STAT); - - rc = ahci_handle_port_intr(host, irq_masked); - - spin_unlock(&host->lock); - - VPRINTK("EXIT\n"); - - return IRQ_RETVAL(rc); -} +EXPORT_SYMBOL_GPL(ahci_handle_port_intr); static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance) { @@ -2514,14 +2503,18 @@ int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht) int irq = hpriv->irq; int rc; - if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX)) + if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX)) { + if (hpriv->irq_handler) + dev_warn(host->dev, "both AHCI_HFLAG_MULTI_MSI flag set \ + and custom irq handler implemented\n"); + rc = ahci_host_activate_multi_irqs(host, sht); - else if (hpriv->flags & AHCI_HFLAG_EDGE_IRQ) - rc = ata_host_activate(host, irq, ahci_single_edge_irq_intr, - IRQF_SHARED, sht); - else - rc = ata_host_activate(host, irq, ahci_single_level_irq_intr, + } else { + rc = ata_host_activate(host, irq, hpriv->irq_handler, IRQF_SHARED, sht); + } + + return rc; } EXPORT_SYMBOL_GPL(ahci_host_activate); diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index cbb74719d2c1..55e257c268dd 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4125,6 +4125,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, { " 2GB ATA Flash Disk", "ADMA428M", ATA_HORKAGE_NODMA }, + { "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA }, /* Odd clown on sil3726/4726 PMPs */ { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index cdf6215a9a22..051b6158d1b7 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -997,12 +997,9 @@ static inline int ata_hsm_ok_in_wq(struct ata_port *ap, static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq) { struct ata_port *ap = qc->ap; - unsigned long flags; if (ap->ops->error_handler) { if (in_wq) { - spin_lock_irqsave(ap->lock, flags); - /* EH might have kicked in while host lock is * released. */ @@ -1014,8 +1011,6 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq) } else ata_port_freeze(ap); } - - spin_unlock_irqrestore(ap->lock, flags); } else { if (likely(!(qc->err_mask & AC_ERR_HSM))) ata_qc_complete(qc); @@ -1024,10 +1019,8 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq) } } else { if (in_wq) { - spin_lock_irqsave(ap->lock, flags); ata_sff_irq_on(ap); ata_qc_complete(qc); - spin_unlock_irqrestore(ap->lock, flags); } else ata_qc_complete(qc); } @@ -1048,9 +1041,10 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, { struct ata_link *link = qc->dev->link; struct ata_eh_info *ehi = &link->eh_info; - unsigned long flags = 0; int poll_next; + lockdep_assert_held(ap->lock); + WARN_ON_ONCE((qc->flags & ATA_QCFLAG_ACTIVE) == 0); /* Make sure ata_sff_qc_issue() does not throw things @@ -1112,14 +1106,6 @@ fsm_start: } } - /* Send the CDB (atapi) or the first data block (ata pio out). - * During the state transition, interrupt handler shouldn't - * be invoked before the data transfer is complete and - * hsm_task_state is changed. Hence, the following locking. - */ - if (in_wq) - spin_lock_irqsave(ap->lock, flags); - if (qc->tf.protocol == ATA_PROT_PIO) { /* PIO data out protocol. * send first data block. @@ -1135,9 +1121,6 @@ fsm_start: /* send CDB */ atapi_send_cdb(ap, qc); - if (in_wq) - spin_unlock_irqrestore(ap->lock, flags); - /* if polling, ata_sff_pio_task() handles the rest. * otherwise, interrupt handler takes over from here. */ @@ -1296,7 +1279,8 @@ fsm_start: break; default: poll_next = 0; - BUG(); + WARN(true, "ata%d: SFF host state machine in invalid state %d", + ap->print_id, ap->hsm_task_state); } return poll_next; @@ -1361,12 +1345,14 @@ static void ata_sff_pio_task(struct work_struct *work) u8 status; int poll_next; + spin_lock_irq(ap->lock); + BUG_ON(ap->sff_pio_task_link == NULL); /* qc can be NULL if timeout occurred */ qc = ata_qc_from_tag(ap, link->active_tag); if (!qc) { ap->sff_pio_task_link = NULL; - return; + goto out_unlock; } fsm_start: @@ -1381,11 +1367,14 @@ fsm_start: */ status = ata_sff_busy_wait(ap, ATA_BUSY, 5); if (status & ATA_BUSY) { + spin_unlock_irq(ap->lock); ata_msleep(ap, 2); + spin_lock_irq(ap->lock); + status = ata_sff_busy_wait(ap, ATA_BUSY, 10); if (status & ATA_BUSY) { ata_sff_queue_pio_task(link, ATA_SHORT_PAUSE); - return; + goto out_unlock; } } @@ -1402,6 +1391,8 @@ fsm_start: */ if (poll_next) goto fsm_start; +out_unlock: + spin_unlock_irq(ap->lock); } /** diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index e3d4b059fcd1..e347e7acd8ed 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -30,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 82f2ae0d7cc4..a969a7e443be 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -168,7 +168,7 @@ static char *res_strings[] = { "reserved 14", "Unrecognized cell", "reserved 16", - "reassemby abort: AAL5 abort", + "reassembly abort: AAL5 abort", "packet purged", "packet ageing timeout", "channel ageing timeout", diff --git a/drivers/base/component.c b/drivers/base/component.c index 89f5cf68d80a..2738039aae9e 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -206,6 +206,8 @@ static void component_match_release(struct device *master, if (mc->release) mc->release(master, mc->data); } + + kfree(match->compare); } static void devm_component_match_release(struct device *dev, void *res) @@ -221,14 +223,14 @@ static int component_match_realloc(struct device *dev, if (match->alloc == num) return 0; - new = devm_kmalloc_array(dev, num, sizeof(*new), GFP_KERNEL); + new = kmalloc_array(num, sizeof(*new), GFP_KERNEL); if (!new) return -ENOMEM; if (match->compare) { memcpy(new, match->compare, sizeof(*new) * min(match->num, num)); - devm_kfree(dev, match->compare); + kfree(match->compare); } match->compare = new; match->alloc = num; @@ -283,6 +285,24 @@ void component_match_add_release(struct device *master, } EXPORT_SYMBOL(component_match_add_release); +static void free_master(struct master *master) +{ + struct component_match *match = master->match; + int i; + + list_del(&master->node); + + if (match) { + for (i = 0; i < match->num; i++) { + struct component *c = match->compare[i].component; + if (c) + c->master = NULL; + } + } + + kfree(master); +} + int component_master_add_with_match(struct device *dev, const struct component_master_ops *ops, struct component_match *match) @@ -309,11 +329,9 @@ int component_master_add_with_match(struct device *dev, ret = try_to_bring_up_master(master, NULL); - if (ret < 0) { - /* Delete off the list if we weren't successful */ - list_del(&master->node); - kfree(master); - } + if (ret < 0) + free_master(master); + mutex_unlock(&component_mutex); return ret < 0 ? ret : 0; @@ -324,25 +342,12 @@ void component_master_del(struct device *dev, const struct component_master_ops *ops) { struct master *master; - int i; mutex_lock(&component_mutex); master = __master_find(dev, ops); if (master) { - struct component_match *match = master->match; - take_down_master(master); - - list_del(&master->node); - - if (match) { - for (i = 0; i < match->num; i++) { - struct component *c = match->compare[i].component; - if (c) - c->master = NULL; - } - } - kfree(master); + free_master(master); } mutex_unlock(&component_mutex); } diff --git a/drivers/base/core.c b/drivers/base/core.c index 0a8bdade53f2..b405b773adec 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2155,7 +2155,7 @@ create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) return pos; overflow: - dev_WARN(dev, "device/subsystem name too long"); + dev_WARN(dev, true, "device/subsystem name too long"); return 0; } diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 47c43386786b..279e53989374 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -284,6 +284,7 @@ out_free_priv_data: return err; } +EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs); /** * platform_msi_domain_free_irqs - Free MSI interrupts for @dev @@ -301,6 +302,7 @@ void platform_msi_domain_free_irqs(struct device *dev) msi_domain_free_irqs(dev->msi_domain, dev); platform_msi_free_descs(dev, 0, MAX_DEV_MSIS); } +EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs); /** * platform_msi_get_host_data - Query the private data associated with diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 73d6e5d39e33..f437afa17f2b 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -558,10 +558,15 @@ static int platform_drv_probe(struct device *_dev) return ret; ret = dev_pm_domain_attach(_dev, true); - if (ret != -EPROBE_DEFER && drv->probe) { - ret = drv->probe(dev); - if (ret) - dev_pm_domain_detach(_dev, true); + if (ret != -EPROBE_DEFER) { + if (drv->probe) { + ret = drv->probe(dev); + if (ret) + dev_pm_domain_detach(_dev, true); + } else { + /* don't fail if just dev_pm_domain_attach failed */ + ret = 0; + } } if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) { diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c index 93ed14cc2252..f6a9ad52cbbf 100644 --- a/drivers/base/power/common.c +++ b/drivers/base/power/common.c @@ -146,7 +146,7 @@ void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd) if (dev->pm_domain == pd) return; - WARN(device_is_bound(dev), + WARN(pd && device_is_bound(dev), "PM domains can only be changed for unbound devices\n"); dev->pm_domain = pd; device_pm_check_callbacks(dev); diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 6ac9a7f33b64..301b785f9f56 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -162,7 +162,7 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool timed) /** * genpd_queue_power_off_work - Queue up the execution of genpd_poweroff(). - * @genpd: PM domait to power off. + * @genpd: PM domain to power off. * * Queue up the execution of genpd_poweroff() unless it's already been done * before. @@ -172,16 +172,15 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) queue_work(pm_wq, &genpd->power_off_work); } -static int genpd_poweron(struct generic_pm_domain *genpd); - /** - * __genpd_poweron - Restore power to a given PM domain and its masters. + * genpd_poweron - Restore power to a given PM domain and its masters. * @genpd: PM domain to power up. + * @depth: nesting count for lockdep. * * Restore power to @genpd and all of its masters so that it is possible to * resume a device belonging to it. */ -static int __genpd_poweron(struct generic_pm_domain *genpd) +static int genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth) { struct gpd_link *link; int ret = 0; @@ -196,11 +195,16 @@ static int __genpd_poweron(struct generic_pm_domain *genpd) * with it. */ list_for_each_entry(link, &genpd->slave_links, slave_node) { - genpd_sd_counter_inc(link->master); + struct generic_pm_domain *master = link->master; + + genpd_sd_counter_inc(master); + + mutex_lock_nested(&master->lock, depth + 1); + ret = genpd_poweron(master, depth + 1); + mutex_unlock(&master->lock); - ret = genpd_poweron(link->master); if (ret) { - genpd_sd_counter_dec(link->master); + genpd_sd_counter_dec(master); goto err; } } @@ -223,20 +227,6 @@ static int __genpd_poweron(struct generic_pm_domain *genpd) return ret; } -/** - * genpd_poweron - Restore power to a given PM domain and its masters. - * @genpd: PM domain to power up. - */ -static int genpd_poweron(struct generic_pm_domain *genpd) -{ - int ret; - - mutex_lock(&genpd->lock); - ret = __genpd_poweron(genpd); - mutex_unlock(&genpd->lock); - return ret; -} - static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) { return GENPD_DEV_CALLBACK(genpd, int, save_state, dev); @@ -484,7 +474,7 @@ static int pm_genpd_runtime_resume(struct device *dev) } mutex_lock(&genpd->lock); - ret = __genpd_poweron(genpd); + ret = genpd_poweron(genpd, 0); mutex_unlock(&genpd->lock); if (ret) @@ -1339,8 +1329,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, if (!link) return -ENOMEM; - mutex_lock(&genpd->lock); - mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING); + mutex_lock(&subdomain->lock); + mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING); if (genpd->status == GPD_STATE_POWER_OFF && subdomain->status != GPD_STATE_POWER_OFF) { @@ -1363,8 +1353,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, genpd_sd_counter_inc(genpd); out: - mutex_unlock(&subdomain->lock); mutex_unlock(&genpd->lock); + mutex_unlock(&subdomain->lock); if (ret) kfree(link); return ret; @@ -1385,7 +1375,8 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) return -EINVAL; - mutex_lock(&genpd->lock); + mutex_lock(&subdomain->lock); + mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING); if (!list_empty(&subdomain->slave_links) || subdomain->device_count) { pr_warn("%s: unable to remove subdomain %s\n", genpd->name, @@ -1398,22 +1389,19 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, if (link->slave != subdomain) continue; - mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING); - list_del(&link->master_node); list_del(&link->slave_node); kfree(link); if (subdomain->status != GPD_STATE_POWER_OFF) genpd_sd_counter_dec(genpd); - mutex_unlock(&subdomain->lock); - ret = 0; break; } out: mutex_unlock(&genpd->lock); + mutex_unlock(&subdomain->lock); return ret; } @@ -1818,8 +1806,10 @@ int genpd_dev_pm_attach(struct device *dev) dev->pm_domain->detach = genpd_dev_pm_detach; dev->pm_domain->sync = genpd_dev_pm_sync; - ret = genpd_poweron(pd); + mutex_lock(&pd->lock); + ret = genpd_poweron(pd, 0); + mutex_unlock(&pd->lock); out: return ret ? -EPROBE_DEFER : 0; } diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index cf351d3dab1c..ab711c2c3e00 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -13,12 +13,14 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include #include #include #include +#include #include "opp.h" @@ -229,6 +231,82 @@ unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev) } EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_clock_latency); +/** + * dev_pm_opp_get_max_volt_latency() - Get max voltage latency in nanoseconds + * @dev: device for which we do this operation + * + * Return: This function returns the max voltage latency in nanoseconds. + * + * Locking: This function takes rcu_read_lock(). + */ +unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) +{ + struct device_opp *dev_opp; + struct dev_pm_opp *opp; + struct regulator *reg; + unsigned long latency_ns = 0; + unsigned long min_uV = ~0, max_uV = 0; + int ret; + + rcu_read_lock(); + + dev_opp = _find_device_opp(dev); + if (IS_ERR(dev_opp)) { + rcu_read_unlock(); + return 0; + } + + reg = dev_opp->regulator; + if (IS_ERR_OR_NULL(reg)) { + /* Regulator may not be required for device */ + if (reg) + dev_err(dev, "%s: Invalid regulator (%ld)\n", __func__, + PTR_ERR(reg)); + rcu_read_unlock(); + return 0; + } + + list_for_each_entry_rcu(opp, &dev_opp->opp_list, node) { + if (!opp->available) + continue; + + if (opp->u_volt_min < min_uV) + min_uV = opp->u_volt_min; + if (opp->u_volt_max > max_uV) + max_uV = opp->u_volt_max; + } + + rcu_read_unlock(); + + /* + * The caller needs to ensure that dev_opp (and hence the regulator) + * isn't freed, while we are executing this routine. + */ + ret = regulator_set_voltage_time(reg, min_uV, max_uV); + if (ret > 0) + latency_ns = ret * 1000; + + return latency_ns; +} +EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_volt_latency); + +/** + * dev_pm_opp_get_max_transition_latency() - Get max transition latency in + * nanoseconds + * @dev: device for which we do this operation + * + * Return: This function returns the max transition latency, in nanoseconds, to + * switch from one OPP to other. + * + * Locking: This function takes rcu_read_lock(). + */ +unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev) +{ + return dev_pm_opp_get_max_volt_latency(dev) + + dev_pm_opp_get_max_clock_latency(dev); +} +EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_transition_latency); + /** * dev_pm_opp_get_suspend_opp() - Get suspend opp * @dev: device for which we do this operation @@ -451,6 +529,182 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); +/* + * The caller needs to ensure that device_opp (and hence the clk) isn't freed, + * while clk returned here is used. + */ +static struct clk *_get_opp_clk(struct device *dev) +{ + struct device_opp *dev_opp; + struct clk *clk; + + rcu_read_lock(); + + dev_opp = _find_device_opp(dev); + if (IS_ERR(dev_opp)) { + dev_err(dev, "%s: device opp doesn't exist\n", __func__); + clk = ERR_CAST(dev_opp); + goto unlock; + } + + clk = dev_opp->clk; + if (IS_ERR(clk)) + dev_err(dev, "%s: No clock available for the device\n", + __func__); + +unlock: + rcu_read_unlock(); + return clk; +} + +static int _set_opp_voltage(struct device *dev, struct regulator *reg, + unsigned long u_volt, unsigned long u_volt_min, + unsigned long u_volt_max) +{ + int ret; + + /* Regulator not available for device */ + if (IS_ERR(reg)) { + dev_dbg(dev, "%s: regulator not available: %ld\n", __func__, + PTR_ERR(reg)); + return 0; + } + + dev_dbg(dev, "%s: voltages (mV): %lu %lu %lu\n", __func__, u_volt_min, + u_volt, u_volt_max); + + ret = regulator_set_voltage_triplet(reg, u_volt_min, u_volt, + u_volt_max); + if (ret) + dev_err(dev, "%s: failed to set voltage (%lu %lu %lu mV): %d\n", + __func__, u_volt_min, u_volt, u_volt_max, ret); + + return ret; +} + +/** + * dev_pm_opp_set_rate() - Configure new OPP based on frequency + * @dev: device for which we do this operation + * @target_freq: frequency to achieve + * + * This configures the power-supplies and clock source to the levels specified + * by the OPP corresponding to the target_freq. + * + * Locking: This function takes rcu_read_lock(). + */ +int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) +{ + struct device_opp *dev_opp; + struct dev_pm_opp *old_opp, *opp; + struct regulator *reg; + struct clk *clk; + unsigned long freq, old_freq; + unsigned long u_volt, u_volt_min, u_volt_max; + unsigned long ou_volt, ou_volt_min, ou_volt_max; + int ret; + + if (unlikely(!target_freq)) { + dev_err(dev, "%s: Invalid target frequency %lu\n", __func__, + target_freq); + return -EINVAL; + } + + clk = _get_opp_clk(dev); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + freq = clk_round_rate(clk, target_freq); + if ((long)freq <= 0) + freq = target_freq; + + old_freq = clk_get_rate(clk); + + /* Return early if nothing to do */ + if (old_freq == freq) { + dev_dbg(dev, "%s: old/new frequencies (%lu Hz) are same, nothing to do\n", + __func__, freq); + return 0; + } + + rcu_read_lock(); + + dev_opp = _find_device_opp(dev); + if (IS_ERR(dev_opp)) { + dev_err(dev, "%s: device opp doesn't exist\n", __func__); + rcu_read_unlock(); + return PTR_ERR(dev_opp); + } + + old_opp = dev_pm_opp_find_freq_ceil(dev, &old_freq); + if (!IS_ERR(old_opp)) { + ou_volt = old_opp->u_volt; + ou_volt_min = old_opp->u_volt_min; + ou_volt_max = old_opp->u_volt_max; + } else { + dev_err(dev, "%s: failed to find current OPP for freq %lu (%ld)\n", + __func__, old_freq, PTR_ERR(old_opp)); + } + + opp = dev_pm_opp_find_freq_ceil(dev, &freq); + if (IS_ERR(opp)) { + ret = PTR_ERR(opp); + dev_err(dev, "%s: failed to find OPP for freq %lu (%d)\n", + __func__, freq, ret); + rcu_read_unlock(); + return ret; + } + + u_volt = opp->u_volt; + u_volt_min = opp->u_volt_min; + u_volt_max = opp->u_volt_max; + + reg = dev_opp->regulator; + + rcu_read_unlock(); + + /* Scaling up? Scale voltage before frequency */ + if (freq > old_freq) { + ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min, + u_volt_max); + if (ret) + goto restore_voltage; + } + + /* Change frequency */ + + dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n", + __func__, old_freq, freq); + + ret = clk_set_rate(clk, freq); + if (ret) { + dev_err(dev, "%s: failed to set clock rate: %d\n", __func__, + ret); + goto restore_voltage; + } + + /* Scaling down? Scale voltage after frequency */ + if (freq < old_freq) { + ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min, + u_volt_max); + if (ret) + goto restore_freq; + } + + return 0; + +restore_freq: + if (clk_set_rate(clk, old_freq)) + dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", + __func__, old_freq); +restore_voltage: + /* This shouldn't harm even if the voltages weren't updated earlier */ + if (!IS_ERR(old_opp)) + _set_opp_voltage(dev, reg, ou_volt, ou_volt_min, ou_volt_max); + + return ret; +} +EXPORT_SYMBOL_GPL(dev_pm_opp_set_rate); + /* List-dev Helpers */ static void _kfree_list_dev_rcu(struct rcu_head *head) { @@ -505,6 +759,8 @@ static struct device_opp *_add_device_opp(struct device *dev) { struct device_opp *dev_opp; struct device_list_opp *list_dev; + struct device_node *np; + int ret; /* Check for existing list for 'dev' first */ dev_opp = _find_device_opp(dev); @@ -527,6 +783,30 @@ static struct device_opp *_add_device_opp(struct device *dev) return NULL; } + /* + * Only required for backward compatibility with v1 bindings, but isn't + * harmful for other cases. And so we do it unconditionally. + */ + np = of_node_get(dev->of_node); + if (np) { + u32 val; + + if (!of_property_read_u32(np, "clock-latency", &val)) + dev_opp->clock_latency_ns_max = val; + of_property_read_u32(np, "voltage-tolerance", + &dev_opp->voltage_tolerance_v1); + of_node_put(np); + } + + /* Find clk for the device */ + dev_opp->clk = clk_get(dev, NULL); + if (IS_ERR(dev_opp->clk)) { + ret = PTR_ERR(dev_opp->clk); + if (ret != -EPROBE_DEFER) + dev_dbg(dev, "%s: Couldn't find clock: %d\n", __func__, + ret); + } + srcu_init_notifier_head(&dev_opp->srcu_head); INIT_LIST_HEAD(&dev_opp->opp_list); @@ -565,6 +845,13 @@ static void _remove_device_opp(struct device_opp *dev_opp) if (dev_opp->prop_name) return; + if (!IS_ERR_OR_NULL(dev_opp->regulator)) + return; + + /* Release clk */ + if (!IS_ERR(dev_opp->clk)) + clk_put(dev_opp->clk); + list_dev = list_first_entry(&dev_opp->dev_list, struct device_list_opp, node); @@ -683,6 +970,22 @@ static struct dev_pm_opp *_allocate_opp(struct device *dev, return opp; } +static bool _opp_supported_by_regulators(struct dev_pm_opp *opp, + struct device_opp *dev_opp) +{ + struct regulator *reg = dev_opp->regulator; + + if (!IS_ERR(reg) && + !regulator_is_supported_voltage(reg, opp->u_volt_min, + opp->u_volt_max)) { + pr_warn("%s: OPP minuV: %lu maxuV: %lu, not supported by regulator\n", + __func__, opp->u_volt_min, opp->u_volt_max); + return false; + } + + return true; +} + static int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct device_opp *dev_opp) { @@ -724,6 +1027,12 @@ static int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, dev_err(dev, "%s: Failed to register opp to debugfs (%d)\n", __func__, ret); + if (!_opp_supported_by_regulators(new_opp, dev_opp)) { + new_opp->available = false; + dev_warn(dev, "%s: OPP not supported by regulators (%lu)\n", + __func__, new_opp->rate); + } + return 0; } @@ -759,6 +1068,7 @@ static int _opp_add_v1(struct device *dev, unsigned long freq, long u_volt, { struct device_opp *dev_opp; struct dev_pm_opp *new_opp; + unsigned long tol; int ret; /* Hold our list modification lock here */ @@ -772,7 +1082,10 @@ static int _opp_add_v1(struct device *dev, unsigned long freq, long u_volt, /* populate the opp table */ new_opp->rate = freq; + tol = u_volt * dev_opp->voltage_tolerance_v1 / 100; new_opp->u_volt = u_volt; + new_opp->u_volt_min = u_volt - tol; + new_opp->u_volt_max = u_volt + tol; new_opp->available = true; new_opp->dynamic = dynamic; @@ -1085,6 +1398,113 @@ unlock: } EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name); +/** + * dev_pm_opp_set_regulator() - Set regulator name for the device + * @dev: Device for which regulator name is being set. + * @name: Name of the regulator. + * + * In order to support OPP switching, OPP layer needs to know the name of the + * device's regulator, as the core would be required to switch voltages as well. + * + * This must be called before any OPPs are initialized for the device. + * + * Locking: The internal device_opp and opp structures are RCU protected. + * Hence this function internally uses RCU updater strategy with mutex locks + * to keep the integrity of the internal data structures. Callers should ensure + * that this function is *NOT* called under RCU protection or in contexts where + * mutex cannot be locked. + */ +int dev_pm_opp_set_regulator(struct device *dev, const char *name) +{ + struct device_opp *dev_opp; + struct regulator *reg; + int ret; + + mutex_lock(&dev_opp_list_lock); + + dev_opp = _add_device_opp(dev); + if (!dev_opp) { + ret = -ENOMEM; + goto unlock; + } + + /* This should be called before OPPs are initialized */ + if (WARN_ON(!list_empty(&dev_opp->opp_list))) { + ret = -EBUSY; + goto err; + } + + /* Already have a regulator set */ + if (WARN_ON(!IS_ERR_OR_NULL(dev_opp->regulator))) { + ret = -EBUSY; + goto err; + } + /* Allocate the regulator */ + reg = regulator_get_optional(dev, name); + if (IS_ERR(reg)) { + ret = PTR_ERR(reg); + if (ret != -EPROBE_DEFER) + dev_err(dev, "%s: no regulator (%s) found: %d\n", + __func__, name, ret); + goto err; + } + + dev_opp->regulator = reg; + + mutex_unlock(&dev_opp_list_lock); + return 0; + +err: + _remove_device_opp(dev_opp); +unlock: + mutex_unlock(&dev_opp_list_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulator); + +/** + * dev_pm_opp_put_regulator() - Releases resources blocked for regulator + * @dev: Device for which regulator was set. + * + * Locking: The internal device_opp and opp structures are RCU protected. + * Hence this function internally uses RCU updater strategy with mutex locks + * to keep the integrity of the internal data structures. Callers should ensure + * that this function is *NOT* called under RCU protection or in contexts where + * mutex cannot be locked. + */ +void dev_pm_opp_put_regulator(struct device *dev) +{ + struct device_opp *dev_opp; + + mutex_lock(&dev_opp_list_lock); + + /* Check for existing list for 'dev' first */ + dev_opp = _find_device_opp(dev); + if (IS_ERR(dev_opp)) { + dev_err(dev, "Failed to find dev_opp: %ld\n", PTR_ERR(dev_opp)); + goto unlock; + } + + if (IS_ERR_OR_NULL(dev_opp->regulator)) { + dev_err(dev, "%s: Doesn't have regulator set\n", __func__); + goto unlock; + } + + /* Make sure there are no concurrent readers while updating dev_opp */ + WARN_ON(!list_empty(&dev_opp->opp_list)); + + regulator_put(dev_opp->regulator); + dev_opp->regulator = ERR_PTR(-EINVAL); + + /* Try freeing device_opp if this was the last blocking resource */ + _remove_device_opp(dev_opp); + +unlock: + mutex_unlock(&dev_opp_list_lock); +} +EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulator); + static bool _opp_is_supported(struct device *dev, struct device_opp *dev_opp, struct device_node *np) { diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h index 690638ef36ee..4f1bdfc7da03 100644 --- a/drivers/base/power/opp/opp.h +++ b/drivers/base/power/opp/opp.h @@ -22,6 +22,9 @@ #include #include +struct clk; +struct regulator; + /* Lock to allow exclusive modification to the device and opp lists */ extern struct mutex dev_opp_list_lock; @@ -132,9 +135,13 @@ struct device_list_opp { * @supported_hw: Array of version number to support. * @supported_hw_count: Number of elements in supported_hw array. * @prop_name: A name to postfix to many DT properties, while parsing them. + * @clk: Device's clock handle + * @regulator: Supply regulator * @dentry: debugfs dentry pointer of the real device directory (not links). * @dentry_name: Name of the real dentry. * + * @voltage_tolerance_v1: In percentage, for v1 bindings only. + * * This is an internal data structure maintaining the link to opps attached to * a device. This structure is not meant to be shared to users as it is * meant for book keeping and private to OPP library. @@ -153,12 +160,18 @@ struct device_opp { struct device_node *np; unsigned long clock_latency_ns_max; + + /* For backward compatibility with v1 bindings */ + unsigned int voltage_tolerance_v1; + bool shared_opp; struct dev_pm_opp *suspend_opp; unsigned int *supported_hw; unsigned int supported_hw_count; const char *prop_name; + struct clk *clk; + struct regulator *regulator; #ifdef CONFIG_DEBUG_FS struct dentry *dentry; diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c index 8812bfb9e3b8..eea51569f0eb 100644 --- a/drivers/base/regmap/regmap-mmio.c +++ b/drivers/base/regmap/regmap-mmio.c @@ -133,17 +133,17 @@ static int regmap_mmio_gather_write(void *context, while (val_size) { switch (ctx->val_bytes) { case 1: - __raw_writeb(*(u8 *)val, ctx->regs + offset); + writeb(*(u8 *)val, ctx->regs + offset); break; case 2: - __raw_writew(*(u16 *)val, ctx->regs + offset); + writew(*(u16 *)val, ctx->regs + offset); break; case 4: - __raw_writel(*(u32 *)val, ctx->regs + offset); + writel(*(u32 *)val, ctx->regs + offset); break; #ifdef CONFIG_64BIT case 8: - __raw_writeq(*(u64 *)val, ctx->regs + offset); + writeq(*(u64 *)val, ctx->regs + offset); break; #endif default: @@ -193,17 +193,17 @@ static int regmap_mmio_read(void *context, while (val_size) { switch (ctx->val_bytes) { case 1: - *(u8 *)val = __raw_readb(ctx->regs + offset); + *(u8 *)val = readb(ctx->regs + offset); break; case 2: - *(u16 *)val = __raw_readw(ctx->regs + offset); + *(u16 *)val = readw(ctx->regs + offset); break; case 4: - *(u32 *)val = __raw_readl(ctx->regs + offset); + *(u32 *)val = readl(ctx->regs + offset); break; #ifdef CONFIG_64BIT case 8: - *(u64 *)val = __raw_readq(ctx->regs + offset); + *(u64 *)val = readq(ctx->regs + offset); break; #endif default: diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 38f156745d53..7e4ddfb076d3 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h @@ -48,7 +48,6 @@ void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc); void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); #ifdef CONFIG_BCMA_DRIVER_MIPS -void bcma_chipco_serial_init(struct bcma_drv_cc *cc); extern struct platform_device bcma_pflash_dev; #endif /* CONFIG_BCMA_DRIVER_MIPS */ diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c index b7c8a8d4e6d1..b0f44a2937b9 100644 --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c @@ -15,6 +15,8 @@ #include #include +static void bcma_chipco_serial_init(struct bcma_drv_cc *cc); + static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, u32 mask, u32 value) { @@ -115,6 +117,8 @@ int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc) void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) { + struct bcma_bus *bus = cc->core->bus; + if (cc->early_setup_done) return; @@ -129,6 +133,9 @@ void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) if (cc->capabilities & BCMA_CC_CAP_PMU) bcma_pmu_early_init(cc); + if (IS_BUILTIN(CONFIG_BCM47XX) && bus->hosttype == BCMA_HOSTTYPE_SOC) + bcma_chipco_serial_init(cc); + cc->early_setup_done = true; } @@ -185,11 +192,12 @@ u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) ticks = 2; else if (ticks > maxt) ticks = maxt; - bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks); + bcma_pmu_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks); } else { struct bcma_bus *bus = cc->core->bus; if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4707 && + bus->chipinfo.id != BCMA_CHIP_ID_BCM47094 && bus->chipinfo.id != BCMA_CHIP_ID_BCM53018) bcma_core_set_clockmode(cc->core, ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC); @@ -314,9 +322,9 @@ u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value) return res; } -#ifdef CONFIG_BCMA_DRIVER_MIPS -void bcma_chipco_serial_init(struct bcma_drv_cc *cc) +static void bcma_chipco_serial_init(struct bcma_drv_cc *cc) { +#if IS_BUILTIN(CONFIG_BCM47XX) unsigned int irq; u32 baud_base; u32 i; @@ -358,5 +366,5 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc) ports[i].baud_base = baud_base; ports[i].reg_shift = 0; } +#endif /* CONFIG_BCM47XX */ } -#endif /* CONFIG_BCMA_DRIVER_MIPS */ diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index fe0d48cb1778..f1eb4d3e1d57 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c @@ -15,44 +15,44 @@ u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset) { - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); - bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); - return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); + bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR); + return bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA); } EXPORT_SYMBOL_GPL(bcma_chipco_pll_read); void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) { - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); - bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); - bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); + bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, value); } EXPORT_SYMBOL_GPL(bcma_chipco_pll_write); void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, u32 set) { - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); - bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); - bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); + bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR); + bcma_pmu_maskset32(cc, BCMA_CC_PMU_PLLCTL_DATA, mask, set); } EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset); void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, u32 set) { - bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset); - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR); - bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set); + bcma_pmu_write32(cc, BCMA_CC_PMU_CHIPCTL_ADDR, offset); + bcma_pmu_read32(cc, BCMA_CC_PMU_CHIPCTL_ADDR); + bcma_pmu_maskset32(cc, BCMA_CC_PMU_CHIPCTL_DATA, mask, set); } EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset); void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, u32 set) { - bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset); - bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR); - bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set); + bcma_pmu_write32(cc, BCMA_CC_PMU_REGCTL_ADDR, offset); + bcma_pmu_read32(cc, BCMA_CC_PMU_REGCTL_ADDR); + bcma_pmu_maskset32(cc, BCMA_CC_PMU_REGCTL_DATA, mask, set); } EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); @@ -60,18 +60,18 @@ static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc) { u32 ilp_ctl, alp_hz; - if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) & + if (!(bcma_pmu_read32(cc, BCMA_CC_PMU_STAT) & BCMA_CC_PMU_STAT_EXT_LPO_AVAIL)) return 0; - bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, - BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); + bcma_pmu_write32(cc, BCMA_CC_PMU_XTAL_FREQ, + BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); usleep_range(1000, 2000); - ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ); + ilp_ctl = bcma_pmu_read32(cc, BCMA_CC_PMU_XTAL_FREQ); ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK; - bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); + bcma_pmu_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); alp_hz = ilp_ctl * 32768 / 4; return (alp_hz + 50000) / 100000 * 100; @@ -127,8 +127,8 @@ static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq) mask = (u32)~(BCMA_RES_4314_HT_AVAIL | BCMA_RES_4314_MACPHY_CLK_AVAIL); - bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); - bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); + bcma_pmu_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); + bcma_pmu_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); bcma_wait_value(cc->core, BCMA_CLKCTLST, BCMA_CLKCTLST_HAVEHT, 0, 20000); break; @@ -140,7 +140,7 @@ static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq) /* Flush */ if (cc->pmu.rev >= 2) - bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); + bcma_pmu_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); /* TODO: Do we need to update OTP? */ } @@ -195,9 +195,9 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) /* Set the resource masks. */ if (min_msk) - bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk); + bcma_pmu_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk); if (max_msk) - bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); + bcma_pmu_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); /* * Add some delay; allow resources to come up and settle. @@ -269,23 +269,33 @@ static void bcma_pmu_workarounds(struct bcma_drv_cc *cc) void bcma_pmu_early_init(struct bcma_drv_cc *cc) { + struct bcma_bus *bus = cc->core->bus; u32 pmucap; - pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP); + if (cc->core->id.rev >= 35 && + cc->capabilities_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) { + cc->pmu.core = bcma_find_core(bus, BCMA_CORE_PMU); + if (!cc->pmu.core) + bcma_warn(bus, "Couldn't find expected PMU core"); + } + if (!cc->pmu.core) + cc->pmu.core = cc->core; + + pmucap = bcma_pmu_read32(cc, BCMA_CC_PMU_CAP); cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION); - bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n", - cc->pmu.rev, pmucap); + bcma_debug(bus, "Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev, + pmucap); } void bcma_pmu_init(struct bcma_drv_cc *cc) { if (cc->pmu.rev == 1) - bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, - ~BCMA_CC_PMU_CTL_NOILPONW); + bcma_pmu_mask32(cc, BCMA_CC_PMU_CTL, + ~BCMA_CC_PMU_CTL_NOILPONW); else - bcma_cc_set32(cc, BCMA_CC_PMU_CTL, - BCMA_CC_PMU_CTL_NOILPONW); + bcma_pmu_set32(cc, BCMA_CC_PMU_CTL, + BCMA_CC_PMU_CTL_NOILPONW); bcma_pmu_pll_init(cc); bcma_pmu_resources_init(cc); @@ -472,8 +482,8 @@ u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc) static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) { - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); - bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, value); } void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid) @@ -497,20 +507,20 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid) bus->chipinfo.id == BCMA_CHIP_ID_BCM53572) ? 6 : 0; /* RMW only the P1 divider */ - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, BCMA_CC_PMU_PLL_CTL0 + phypll_offset); - tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); + tmp = bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA); tmp &= (~(BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK)); tmp |= (bcm5357_bcm43236_p1div[spuravoid] << BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT); - bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, tmp); /* RMW only the int feedback divider */ - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, BCMA_CC_PMU_PLL_CTL2 + phypll_offset); - tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); + tmp = bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA); tmp &= ~(BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK); tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT; - bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, tmp); tmp = BCMA_CC_PMU_CTL_PLL_UPD; break; @@ -646,7 +656,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid) break; } - tmp |= bcma_cc_read32(cc, BCMA_CC_PMU_CTL); - bcma_cc_write32(cc, BCMA_CC_PMU_CTL, tmp); + tmp |= bcma_pmu_read32(cc, BCMA_CC_PMU_CTL); + bcma_pmu_write32(cc, BCMA_CC_PMU_CTL, tmp); } EXPORT_SYMBOL_GPL(bcma_pmu_spuravoid_pllupdate); diff --git a/drivers/bcma/driver_chipcommon_sflash.c b/drivers/bcma/driver_chipcommon_sflash.c index 7e11ef4cb7db..04d706ca5f43 100644 --- a/drivers/bcma/driver_chipcommon_sflash.c +++ b/drivers/bcma/driver_chipcommon_sflash.c @@ -38,6 +38,7 @@ static const struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { { "M25P32", 0x15, 0x10000, 64, }, { "M25P64", 0x16, 0x10000, 128, }, { "M25FL128", 0x17, 0x10000, 256, }, + { "MX25L25635F", 0x18, 0x10000, 512, }, { NULL }, }; diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 98067f757fb0..771a2a253440 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c @@ -192,6 +192,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) case BCMA_CHIP_ID_BCM4707: case BCMA_CHIP_ID_BCM5357: case BCMA_CHIP_ID_BCM53572: + case BCMA_CHIP_ID_BCM47094: chip->ngpio = 32; break; default: diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index 24424f3fef96..a40a203314db 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c @@ -337,12 +337,9 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { - struct bcma_bus *bus = mcore->core->bus; - if (mcore->early_setup_done) return; - bcma_chipco_serial_init(&bus->drv_cc); bcma_core_mips_flash_detect(mcore); mcore->early_setup_done = true; diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 0856189c065f..cae5385cf499 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -294,7 +294,7 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_DELL, 0x0016) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index df806b9c5490..4a2d1b235fb5 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c @@ -98,6 +98,9 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = { { BCMA_CORE_SHIM, "SHIM" }, { BCMA_CORE_PCIE2, "PCIe Gen2" }, { BCMA_CORE_ARM_CR4, "ARM CR4" }, + { BCMA_CORE_GCI, "GCI" }, + { BCMA_CORE_CMEM, "CNDS DDR2/3 memory controller" }, + { BCMA_CORE_ARM_CA7, "ARM CA7" }, { BCMA_CORE_DEFAULT, "Default" }, }; @@ -315,6 +318,8 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, switch (core->id.id) { case BCMA_CORE_4706_MAC_GBIT_COMMON: case BCMA_CORE_NS_CHIPCOMMON_B: + case BCMA_CORE_PMU: + case BCMA_CORE_GCI: /* Not used yet: case BCMA_CORE_OOB_ROUTER: */ break; default: diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c index 99e773cb70d0..3d31761c0ed0 100644 --- a/drivers/block/cryptoloop.c +++ b/drivers/block/cryptoloop.c @@ -21,9 +21,9 @@ #include +#include #include #include -#include #include #include #include @@ -46,7 +46,7 @@ cryptoloop_init(struct loop_device *lo, const struct loop_info64 *info) char *cipher; char *mode; char *cmsp = cms; /* c-m string pointer */ - struct crypto_blkcipher *tfm; + struct crypto_skcipher *tfm; /* encryption breaks for non sector aligned offsets */ @@ -82,12 +82,12 @@ cryptoloop_init(struct loop_device *lo, const struct loop_info64 *info) *cmsp++ = ')'; *cmsp = 0; - tfm = crypto_alloc_blkcipher(cms, 0, CRYPTO_ALG_ASYNC); + tfm = crypto_alloc_skcipher(cms, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) return PTR_ERR(tfm); - err = crypto_blkcipher_setkey(tfm, info->lo_encrypt_key, - info->lo_encrypt_key_size); + err = crypto_skcipher_setkey(tfm, info->lo_encrypt_key, + info->lo_encrypt_key_size); if (err != 0) goto out_free_tfm; @@ -96,17 +96,14 @@ cryptoloop_init(struct loop_device *lo, const struct loop_info64 *info) return 0; out_free_tfm: - crypto_free_blkcipher(tfm); + crypto_free_skcipher(tfm); out: return err; } -typedef int (*encdec_cbc_t)(struct blkcipher_desc *desc, - struct scatterlist *sg_out, - struct scatterlist *sg_in, - unsigned int nsg); +typedef int (*encdec_cbc_t)(struct skcipher_request *req); static int cryptoloop_transfer(struct loop_device *lo, int cmd, @@ -114,11 +111,8 @@ cryptoloop_transfer(struct loop_device *lo, int cmd, struct page *loop_page, unsigned loop_off, int size, sector_t IV) { - struct crypto_blkcipher *tfm = lo->key_data; - struct blkcipher_desc desc = { - .tfm = tfm, - .flags = CRYPTO_TFM_REQ_MAY_SLEEP, - }; + struct crypto_skcipher *tfm = lo->key_data; + SKCIPHER_REQUEST_ON_STACK(req, tfm); struct scatterlist sg_out; struct scatterlist sg_in; @@ -127,6 +121,10 @@ cryptoloop_transfer(struct loop_device *lo, int cmd, unsigned in_offs, out_offs; int err; + skcipher_request_set_tfm(req, tfm); + skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); + sg_init_table(&sg_out, 1); sg_init_table(&sg_in, 1); @@ -135,13 +133,13 @@ cryptoloop_transfer(struct loop_device *lo, int cmd, in_offs = raw_off; out_page = loop_page; out_offs = loop_off; - encdecfunc = crypto_blkcipher_crt(tfm)->decrypt; + encdecfunc = crypto_skcipher_decrypt; } else { in_page = loop_page; in_offs = loop_off; out_page = raw_page; out_offs = raw_off; - encdecfunc = crypto_blkcipher_crt(tfm)->encrypt; + encdecfunc = crypto_skcipher_encrypt; } while (size > 0) { @@ -152,10 +150,10 @@ cryptoloop_transfer(struct loop_device *lo, int cmd, sg_set_page(&sg_in, in_page, sz, in_offs); sg_set_page(&sg_out, out_page, sz, out_offs); - desc.info = iv; - err = encdecfunc(&desc, &sg_out, &sg_in, sz); + skcipher_request_set_crypt(req, &sg_in, &sg_out, sz, iv); + err = encdecfunc(req); if (err) - return err; + goto out; IV++; size -= sz; @@ -163,7 +161,11 @@ cryptoloop_transfer(struct loop_device *lo, int cmd, out_offs += sz; } - return 0; + err = 0; + +out: + skcipher_request_zero(req); + return err; } static int @@ -175,9 +177,9 @@ cryptoloop_ioctl(struct loop_device *lo, int cmd, unsigned long arg) static int cryptoloop_release(struct loop_device *lo) { - struct crypto_blkcipher *tfm = lo->key_data; + struct crypto_skcipher *tfm = lo->key_data; if (tfm != NULL) { - crypto_free_blkcipher(tfm); + crypto_free_skcipher(tfm); lo->key_data = NULL; return 0; } diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 34bc84efc29e..c227fd4cad75 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -26,13 +26,13 @@ #ifndef _DRBD_INT_H #define _DRBD_INT_H +#include #include #include #include #include #include #include -#include #include #include #include @@ -724,11 +724,11 @@ struct drbd_connection { struct list_head transfer_log; /* all requests not yet fully processed */ - struct crypto_hash *cram_hmac_tfm; - struct crypto_hash *integrity_tfm; /* checksums we compute, updates protected by connection->data->mutex */ - struct crypto_hash *peer_integrity_tfm; /* checksums we verify, only accessed from receiver thread */ - struct crypto_hash *csums_tfm; - struct crypto_hash *verify_tfm; + struct crypto_shash *cram_hmac_tfm; + struct crypto_ahash *integrity_tfm; /* checksums we compute, updates protected by connection->data->mutex */ + struct crypto_ahash *peer_integrity_tfm; /* checksums we verify, only accessed from receiver thread */ + struct crypto_ahash *csums_tfm; + struct crypto_ahash *verify_tfm; void *int_dig_in; void *int_dig_vv; @@ -1524,8 +1524,8 @@ static inline void ov_out_of_sync_print(struct drbd_device *device) } -extern void drbd_csum_bio(struct crypto_hash *, struct bio *, void *); -extern void drbd_csum_ee(struct crypto_hash *, struct drbd_peer_request *, void *); +extern void drbd_csum_bio(struct crypto_ahash *, struct bio *, void *); +extern void drbd_csum_ee(struct crypto_ahash *, struct drbd_peer_request *, void *); /* worker callbacks */ extern int w_e_end_data_req(struct drbd_work *, int); extern int w_e_end_rsdata_req(struct drbd_work *, int); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 5b43dfb79819..fa209773d494 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1340,7 +1340,7 @@ void drbd_send_ack_dp(struct drbd_peer_device *peer_device, enum drbd_packet cmd struct p_data *dp, int data_size) { if (peer_device->connection->peer_integrity_tfm) - data_size -= crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm); + data_size -= crypto_ahash_digestsize(peer_device->connection->peer_integrity_tfm); _drbd_send_ack(peer_device, cmd, dp->sector, cpu_to_be32(data_size), dp->block_id); } @@ -1629,7 +1629,7 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request * sock = &peer_device->connection->data; p = drbd_prepare_command(peer_device, sock); digest_size = peer_device->connection->integrity_tfm ? - crypto_hash_digestsize(peer_device->connection->integrity_tfm) : 0; + crypto_ahash_digestsize(peer_device->connection->integrity_tfm) : 0; if (!p) return -EIO; @@ -1718,7 +1718,7 @@ int drbd_send_block(struct drbd_peer_device *peer_device, enum drbd_packet cmd, p = drbd_prepare_command(peer_device, sock); digest_size = peer_device->connection->integrity_tfm ? - crypto_hash_digestsize(peer_device->connection->integrity_tfm) : 0; + crypto_ahash_digestsize(peer_device->connection->integrity_tfm) : 0; if (!p) return -EIO; @@ -2498,11 +2498,11 @@ void conn_free_crypto(struct drbd_connection *connection) { drbd_free_sock(connection); - crypto_free_hash(connection->csums_tfm); - crypto_free_hash(connection->verify_tfm); - crypto_free_hash(connection->cram_hmac_tfm); - crypto_free_hash(connection->integrity_tfm); - crypto_free_hash(connection->peer_integrity_tfm); + crypto_free_ahash(connection->csums_tfm); + crypto_free_ahash(connection->verify_tfm); + crypto_free_shash(connection->cram_hmac_tfm); + crypto_free_ahash(connection->integrity_tfm); + crypto_free_ahash(connection->peer_integrity_tfm); kfree(connection->int_dig_in); kfree(connection->int_dig_vv); diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index c055c5e12f24..226eb0c9f0fb 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -2160,19 +2160,34 @@ check_net_options(struct drbd_connection *connection, struct net_conf *new_net_c } struct crypto { - struct crypto_hash *verify_tfm; - struct crypto_hash *csums_tfm; - struct crypto_hash *cram_hmac_tfm; - struct crypto_hash *integrity_tfm; + struct crypto_ahash *verify_tfm; + struct crypto_ahash *csums_tfm; + struct crypto_shash *cram_hmac_tfm; + struct crypto_ahash *integrity_tfm; }; static int -alloc_hash(struct crypto_hash **tfm, char *tfm_name, int err_alg) +alloc_shash(struct crypto_shash **tfm, char *tfm_name, int err_alg) { if (!tfm_name[0]) return NO_ERROR; - *tfm = crypto_alloc_hash(tfm_name, 0, CRYPTO_ALG_ASYNC); + *tfm = crypto_alloc_shash(tfm_name, 0, 0); + if (IS_ERR(*tfm)) { + *tfm = NULL; + return err_alg; + } + + return NO_ERROR; +} + +static int +alloc_ahash(struct crypto_ahash **tfm, char *tfm_name, int err_alg) +{ + if (!tfm_name[0]) + return NO_ERROR; + + *tfm = crypto_alloc_ahash(tfm_name, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(*tfm)) { *tfm = NULL; return err_alg; @@ -2187,24 +2202,24 @@ alloc_crypto(struct crypto *crypto, struct net_conf *new_net_conf) char hmac_name[CRYPTO_MAX_ALG_NAME]; enum drbd_ret_code rv; - rv = alloc_hash(&crypto->csums_tfm, new_net_conf->csums_alg, - ERR_CSUMS_ALG); + rv = alloc_ahash(&crypto->csums_tfm, new_net_conf->csums_alg, + ERR_CSUMS_ALG); if (rv != NO_ERROR) return rv; - rv = alloc_hash(&crypto->verify_tfm, new_net_conf->verify_alg, - ERR_VERIFY_ALG); + rv = alloc_ahash(&crypto->verify_tfm, new_net_conf->verify_alg, + ERR_VERIFY_ALG); if (rv != NO_ERROR) return rv; - rv = alloc_hash(&crypto->integrity_tfm, new_net_conf->integrity_alg, - ERR_INTEGRITY_ALG); + rv = alloc_ahash(&crypto->integrity_tfm, new_net_conf->integrity_alg, + ERR_INTEGRITY_ALG); if (rv != NO_ERROR) return rv; if (new_net_conf->cram_hmac_alg[0] != 0) { snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)", new_net_conf->cram_hmac_alg); - rv = alloc_hash(&crypto->cram_hmac_tfm, hmac_name, - ERR_AUTH_ALG); + rv = alloc_shash(&crypto->cram_hmac_tfm, hmac_name, + ERR_AUTH_ALG); } return rv; @@ -2212,10 +2227,10 @@ alloc_crypto(struct crypto *crypto, struct net_conf *new_net_conf) static void free_crypto(struct crypto *crypto) { - crypto_free_hash(crypto->cram_hmac_tfm); - crypto_free_hash(crypto->integrity_tfm); - crypto_free_hash(crypto->csums_tfm); - crypto_free_hash(crypto->verify_tfm); + crypto_free_shash(crypto->cram_hmac_tfm); + crypto_free_ahash(crypto->integrity_tfm); + crypto_free_ahash(crypto->csums_tfm); + crypto_free_ahash(crypto->verify_tfm); } int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) @@ -2292,23 +2307,23 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) rcu_assign_pointer(connection->net_conf, new_net_conf); if (!rsr) { - crypto_free_hash(connection->csums_tfm); + crypto_free_ahash(connection->csums_tfm); connection->csums_tfm = crypto.csums_tfm; crypto.csums_tfm = NULL; } if (!ovr) { - crypto_free_hash(connection->verify_tfm); + crypto_free_ahash(connection->verify_tfm); connection->verify_tfm = crypto.verify_tfm; crypto.verify_tfm = NULL; } - crypto_free_hash(connection->integrity_tfm); + crypto_free_ahash(connection->integrity_tfm); connection->integrity_tfm = crypto.integrity_tfm; if (connection->cstate >= C_WF_REPORT_PARAMS && connection->agreed_pro_version >= 100) /* Do this without trying to take connection->data.mutex again. */ __drbd_send_protocol(connection, P_PROTOCOL_UPDATE); - crypto_free_hash(connection->cram_hmac_tfm); + crypto_free_shash(connection->cram_hmac_tfm); connection->cram_hmac_tfm = crypto.cram_hmac_tfm; mutex_unlock(&connection->resource->conf_update); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 1957fe8601dc..050aaa1c0350 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1627,7 +1627,7 @@ read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector, digest_size = 0; if (!trim && peer_device->connection->peer_integrity_tfm) { - digest_size = crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm); + digest_size = crypto_ahash_digestsize(peer_device->connection->peer_integrity_tfm); /* * FIXME: Receive the incoming digest into the receive buffer * here, together with its struct p_data? @@ -1741,7 +1741,7 @@ static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_req digest_size = 0; if (peer_device->connection->peer_integrity_tfm) { - digest_size = crypto_hash_digestsize(peer_device->connection->peer_integrity_tfm); + digest_size = crypto_ahash_digestsize(peer_device->connection->peer_integrity_tfm); err = drbd_recv_all_warn(peer_device->connection, dig_in, digest_size); if (err) return err; @@ -3321,7 +3321,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in int p_proto, p_discard_my_data, p_two_primaries, cf; struct net_conf *nc, *old_net_conf, *new_net_conf = NULL; char integrity_alg[SHARED_SECRET_MAX] = ""; - struct crypto_hash *peer_integrity_tfm = NULL; + struct crypto_ahash *peer_integrity_tfm = NULL; void *int_dig_in = NULL, *int_dig_vv = NULL; p_proto = be32_to_cpu(p->protocol); @@ -3402,14 +3402,14 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in * change. */ - peer_integrity_tfm = crypto_alloc_hash(integrity_alg, 0, CRYPTO_ALG_ASYNC); + peer_integrity_tfm = crypto_alloc_ahash(integrity_alg, 0, CRYPTO_ALG_ASYNC); if (!peer_integrity_tfm) { drbd_err(connection, "peer data-integrity-alg %s not supported\n", integrity_alg); goto disconnect; } - hash_size = crypto_hash_digestsize(peer_integrity_tfm); + hash_size = crypto_ahash_digestsize(peer_integrity_tfm); int_dig_in = kmalloc(hash_size, GFP_KERNEL); int_dig_vv = kmalloc(hash_size, GFP_KERNEL); if (!(int_dig_in && int_dig_vv)) { @@ -3439,7 +3439,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in mutex_unlock(&connection->resource->conf_update); mutex_unlock(&connection->data.mutex); - crypto_free_hash(connection->peer_integrity_tfm); + crypto_free_ahash(connection->peer_integrity_tfm); kfree(connection->int_dig_in); kfree(connection->int_dig_vv); connection->peer_integrity_tfm = peer_integrity_tfm; @@ -3457,7 +3457,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in disconnect_rcu_unlock: rcu_read_unlock(); disconnect: - crypto_free_hash(peer_integrity_tfm); + crypto_free_ahash(peer_integrity_tfm); kfree(int_dig_in); kfree(int_dig_vv); conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD); @@ -3469,15 +3469,15 @@ disconnect: * return: NULL (alg name was "") * ERR_PTR(error) if something goes wrong * or the crypto hash ptr, if it worked out ok. */ -static struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_device *device, +static struct crypto_ahash *drbd_crypto_alloc_digest_safe(const struct drbd_device *device, const char *alg, const char *name) { - struct crypto_hash *tfm; + struct crypto_ahash *tfm; if (!alg[0]) return NULL; - tfm = crypto_alloc_hash(alg, 0, CRYPTO_ALG_ASYNC); + tfm = crypto_alloc_ahash(alg, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { drbd_err(device, "Can not allocate \"%s\" as %s (reason: %ld)\n", alg, name, PTR_ERR(tfm)); @@ -3530,8 +3530,8 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i struct drbd_device *device; struct p_rs_param_95 *p; unsigned int header_size, data_size, exp_max_sz; - struct crypto_hash *verify_tfm = NULL; - struct crypto_hash *csums_tfm = NULL; + struct crypto_ahash *verify_tfm = NULL; + struct crypto_ahash *csums_tfm = NULL; struct net_conf *old_net_conf, *new_net_conf = NULL; struct disk_conf *old_disk_conf = NULL, *new_disk_conf = NULL; const int apv = connection->agreed_pro_version; @@ -3678,14 +3678,14 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i if (verify_tfm) { strcpy(new_net_conf->verify_alg, p->verify_alg); new_net_conf->verify_alg_len = strlen(p->verify_alg) + 1; - crypto_free_hash(peer_device->connection->verify_tfm); + crypto_free_ahash(peer_device->connection->verify_tfm); peer_device->connection->verify_tfm = verify_tfm; drbd_info(device, "using verify-alg: \"%s\"\n", p->verify_alg); } if (csums_tfm) { strcpy(new_net_conf->csums_alg, p->csums_alg); new_net_conf->csums_alg_len = strlen(p->csums_alg) + 1; - crypto_free_hash(peer_device->connection->csums_tfm); + crypto_free_ahash(peer_device->connection->csums_tfm); peer_device->connection->csums_tfm = csums_tfm; drbd_info(device, "using csums-alg: \"%s\"\n", p->csums_alg); } @@ -3729,9 +3729,9 @@ disconnect: mutex_unlock(&connection->resource->conf_update); /* just for completeness: actually not needed, * as this is not reached if csums_tfm was ok. */ - crypto_free_hash(csums_tfm); + crypto_free_ahash(csums_tfm); /* but free the verify_tfm again, if csums_tfm did not work out */ - crypto_free_hash(verify_tfm); + crypto_free_ahash(verify_tfm); conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD); return -EIO; } @@ -4925,14 +4925,13 @@ static int drbd_do_auth(struct drbd_connection *connection) { struct drbd_socket *sock; char my_challenge[CHALLENGE_LEN]; /* 64 Bytes... */ - struct scatterlist sg; char *response = NULL; char *right_response = NULL; char *peers_ch = NULL; unsigned int key_len; char secret[SHARED_SECRET_MAX]; /* 64 byte */ unsigned int resp_size; - struct hash_desc desc; + SHASH_DESC_ON_STACK(desc, connection->cram_hmac_tfm); struct packet_info pi; struct net_conf *nc; int err, rv; @@ -4945,12 +4944,12 @@ static int drbd_do_auth(struct drbd_connection *connection) memcpy(secret, nc->shared_secret, key_len); rcu_read_unlock(); - desc.tfm = connection->cram_hmac_tfm; - desc.flags = 0; + desc->tfm = connection->cram_hmac_tfm; + desc->flags = 0; - rv = crypto_hash_setkey(connection->cram_hmac_tfm, (u8 *)secret, key_len); + rv = crypto_shash_setkey(connection->cram_hmac_tfm, (u8 *)secret, key_len); if (rv) { - drbd_err(connection, "crypto_hash_setkey() failed with %d\n", rv); + drbd_err(connection, "crypto_shash_setkey() failed with %d\n", rv); rv = -1; goto fail; } @@ -5011,7 +5010,7 @@ static int drbd_do_auth(struct drbd_connection *connection) goto fail; } - resp_size = crypto_hash_digestsize(connection->cram_hmac_tfm); + resp_size = crypto_shash_digestsize(connection->cram_hmac_tfm); response = kmalloc(resp_size, GFP_NOIO); if (response == NULL) { drbd_err(connection, "kmalloc of response failed\n"); @@ -5019,10 +5018,7 @@ static int drbd_do_auth(struct drbd_connection *connection) goto fail; } - sg_init_table(&sg, 1); - sg_set_buf(&sg, peers_ch, pi.size); - - rv = crypto_hash_digest(&desc, &sg, sg.length, response); + rv = crypto_shash_digest(desc, peers_ch, pi.size, response); if (rv) { drbd_err(connection, "crypto_hash_digest() failed with %d\n", rv); rv = -1; @@ -5070,9 +5066,8 @@ static int drbd_do_auth(struct drbd_connection *connection) goto fail; } - sg_set_buf(&sg, my_challenge, CHALLENGE_LEN); - - rv = crypto_hash_digest(&desc, &sg, sg.length, right_response); + rv = crypto_shash_digest(desc, my_challenge, CHALLENGE_LEN, + right_response); if (rv) { drbd_err(connection, "crypto_hash_digest() failed with %d\n", rv); rv = -1; @@ -5091,6 +5086,7 @@ static int drbd_do_auth(struct drbd_connection *connection) kfree(peers_ch); kfree(response); kfree(right_response); + shash_desc_zero(desc); return rv; } diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index eff716c27b1f..4d87499f0d54 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -274,51 +274,56 @@ void drbd_request_endio(struct bio *bio) complete_master_bio(device, &m); } -void drbd_csum_ee(struct crypto_hash *tfm, struct drbd_peer_request *peer_req, void *digest) +void drbd_csum_ee(struct crypto_ahash *tfm, struct drbd_peer_request *peer_req, void *digest) { - struct hash_desc desc; + AHASH_REQUEST_ON_STACK(req, tfm); struct scatterlist sg; struct page *page = peer_req->pages; struct page *tmp; unsigned len; - desc.tfm = tfm; - desc.flags = 0; + ahash_request_set_tfm(req, tfm); + ahash_request_set_callback(req, 0, NULL, NULL); sg_init_table(&sg, 1); - crypto_hash_init(&desc); + crypto_ahash_init(req); while ((tmp = page_chain_next(page))) { /* all but the last page will be fully used */ sg_set_page(&sg, page, PAGE_SIZE, 0); - crypto_hash_update(&desc, &sg, sg.length); + ahash_request_set_crypt(req, &sg, NULL, sg.length); + crypto_ahash_update(req); page = tmp; } /* and now the last, possibly only partially used page */ len = peer_req->i.size & (PAGE_SIZE - 1); sg_set_page(&sg, page, len ?: PAGE_SIZE, 0); - crypto_hash_update(&desc, &sg, sg.length); - crypto_hash_final(&desc, digest); + ahash_request_set_crypt(req, &sg, digest, sg.length); + crypto_ahash_finup(req); + ahash_request_zero(req); } -void drbd_csum_bio(struct crypto_hash *tfm, struct bio *bio, void *digest) +void drbd_csum_bio(struct crypto_ahash *tfm, struct bio *bio, void *digest) { - struct hash_desc desc; + AHASH_REQUEST_ON_STACK(req, tfm); struct scatterlist sg; struct bio_vec bvec; struct bvec_iter iter; - desc.tfm = tfm; - desc.flags = 0; + ahash_request_set_tfm(req, tfm); + ahash_request_set_callback(req, 0, NULL, NULL); sg_init_table(&sg, 1); - crypto_hash_init(&desc); + crypto_ahash_init(req); bio_for_each_segment(bvec, bio, iter) { sg_set_page(&sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset); - crypto_hash_update(&desc, &sg, sg.length); + ahash_request_set_crypt(req, &sg, NULL, sg.length); + crypto_ahash_update(req); } - crypto_hash_final(&desc, digest); + ahash_request_set_crypt(req, NULL, digest, 0); + crypto_ahash_final(req); + ahash_request_zero(req); } /* MAYBE merge common code with w_e_end_ov_req */ @@ -337,7 +342,7 @@ static int w_e_send_csum(struct drbd_work *w, int cancel) if (unlikely((peer_req->flags & EE_WAS_ERROR) != 0)) goto out; - digest_size = crypto_hash_digestsize(peer_device->connection->csums_tfm); + digest_size = crypto_ahash_digestsize(peer_device->connection->csums_tfm); digest = kmalloc(digest_size, GFP_NOIO); if (digest) { sector_t sector = peer_req->i.sector; @@ -1113,7 +1118,7 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel) * a real fix would be much more involved, * introducing more locking mechanisms */ if (peer_device->connection->csums_tfm) { - digest_size = crypto_hash_digestsize(peer_device->connection->csums_tfm); + digest_size = crypto_ahash_digestsize(peer_device->connection->csums_tfm); D_ASSERT(device, digest_size == di->digest_size); digest = kmalloc(digest_size, GFP_NOIO); } @@ -1163,7 +1168,7 @@ int w_e_end_ov_req(struct drbd_work *w, int cancel) if (unlikely(cancel)) goto out; - digest_size = crypto_hash_digestsize(peer_device->connection->verify_tfm); + digest_size = crypto_ahash_digestsize(peer_device->connection->verify_tfm); digest = kmalloc(digest_size, GFP_NOIO); if (!digest) { err = 1; /* terminate the connection in case the allocation failed */ @@ -1235,7 +1240,7 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel) di = peer_req->digest; if (likely((peer_req->flags & EE_WAS_ERROR) == 0)) { - digest_size = crypto_hash_digestsize(peer_device->connection->verify_tfm); + digest_size = crypto_ahash_digestsize(peer_device->connection->verify_tfm); digest = kmalloc(digest_size, GFP_NOIO); if (digest) { drbd_csum_ee(peer_device->connection->verify_tfm, peer_req, digest); diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index fa893c3ec408..ebd641b85396 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -497,6 +497,7 @@ static int ath3k_probe(struct usb_interface *intf, /* match device ID in ath3k blacklist table */ if (!id->driver_info) { const struct usb_device_id *match; + match = usb_match_id(intf, ath3k_blist_tbl); if (match) id = match; diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 129d47bcc5fc..9a92c072a485 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -132,7 +132,7 @@ config SUNXI_RSB and AC100/AC200 ICs. config UNIPHIER_SYSTEM_BUS - bool "UniPhier System Bus driver" + tristate "UniPhier System Bus driver" depends on ARCH_UNIPHIER && OF default y help diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 25996e256110..795c9d9c96a6 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -330,7 +330,7 @@ static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, cmd = RSB_CMD_RD32; break; default: - dev_err(rsb->dev, "Invalid access width: %d\n", len); + dev_err(rsb->dev, "Invalid access width: %zd\n", len); return -EINVAL; } @@ -372,7 +372,7 @@ static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, cmd = RSB_CMD_WR32; break; default: - dev_err(rsb->dev, "Invalid access width: %d\n", len); + dev_err(rsb->dev, "Invalid access width: %zd\n", len); return -EINVAL; } diff --git a/drivers/bus/vexpress-config.c b/drivers/bus/vexpress-config.c index 6575c0fe6a4e..c3cb76b363c6 100644 --- a/drivers/bus/vexpress-config.c +++ b/drivers/bus/vexpress-config.c @@ -192,8 +192,10 @@ static int __init vexpress_config_init(void) /* Need the config devices early, before the "normal" devices... */ for_each_compatible_node(node, NULL, "arm,vexpress,config-bus") { err = vexpress_config_populate(node); - if (err) + if (err) { + of_node_put(node); break; + } } return err; diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 1341a94cc779..e657f989745e 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -555,8 +555,10 @@ static unsigned int intel_gtt_mappable_entries(void) static void intel_gtt_teardown_scratch_page(void) { set_pages_wb(intel_private.scratch_page, 1); - pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + if (intel_private.needs_dmar) + pci_unmap_page(intel_private.pcidev, + intel_private.scratch_page_dma, + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); __free_page(intel_private.scratch_page); } @@ -1430,6 +1432,8 @@ void intel_gmch_remove(void) if (--intel_private.refcount) return; + if (intel_private.scratch_page) + intel_gtt_teardown_scratch_page(); if (intel_private.pcidev) pci_dev_put(intel_private.pcidev); if (intel_private.bridge_dev) diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 05755441250c..fdced547ad59 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include "agp.h" diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index dbf22719462f..f7d89387bd62 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -77,7 +77,7 @@ config HW_RANDOM_ATMEL config HW_RANDOM_BCM63XX tristate "Broadcom BCM63xx Random Number Generator support" - depends on BCM63XX + depends on BCM63XX || BMIPS_GENERIC default HW_RANDOM ---help--- This driver provides kernel-side support for the Random Number @@ -372,6 +372,7 @@ config HW_RANDOM_XGENE config HW_RANDOM_STM32 tristate "STMicroelectronics STM32 random number generator" depends on HW_RANDOM && (ARCH_STM32 || COMPILE_TEST) + depends on HAS_IOMEM help This driver provides kernel-side support for the Random Number Generator hardware found on STM32 microcontrollers. diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c index 4b31f1387f37..38553f0500c9 100644 --- a/drivers/char/hw_random/bcm63xx-rng.c +++ b/drivers/char/hw_random/bcm63xx-rng.c @@ -79,10 +79,8 @@ static int bcm63xx_rng_data_read(struct hwrng *rng, u32 *data) static int bcm63xx_rng_probe(struct platform_device *pdev) { struct resource *r; - struct clk *clk; int ret; struct bcm63xx_rng_priv *priv; - struct hwrng *rng; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { @@ -132,10 +130,17 @@ static int bcm63xx_rng_probe(struct platform_device *pdev) return 0; } +static const struct of_device_id bcm63xx_rng_of_match[] = { + { .compatible = "brcm,bcm6368-rng", }, + {}, +}; +MODULE_DEVICE_TABLE(of, bcm63xx_rng_of_match); + static struct platform_driver bcm63xx_rng_driver = { .probe = bcm63xx_rng_probe, .driver = { .name = "bcm63xx-rng", + .of_match_table = bcm63xx_rng_of_match, }, }; diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 843d6f6aee7a..3b06c1d6cfb2 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -743,6 +743,16 @@ static const struct of_device_id n2rng_match[] = { .compatible = "SUNW,kt-rng", .data = (void *) 1, }, + { + .name = "random-number-generator", + .compatible = "ORCL,m4-rng", + .data = (void *) 1, + }, + { + .name = "random-number-generator", + .compatible = "ORCL,m7-rng", + .data = (void *) 1, + }, {}, }; MODULE_DEVICE_TABLE(of, n2rng_match); diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 9fda22e3387e..7fddd8696211 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -68,6 +68,7 @@ #include #include #include +#include #ifdef CONFIG_PARISC #include /* for register_parisc_driver() stuff */ @@ -2054,8 +2055,6 @@ static int hardcode_find_bmc(void) #ifdef CONFIG_ACPI -#include - /* * Once we get an ACPI failure, we don't try any more, because we go * through the tables sequentially. Once we don't find a table, there diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index ebce98033fbb..5759d75780cf 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -177,6 +177,8 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(0, "gpll_armclk", "gpll", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(0), 6, GFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + /* * Clock-Architecture Diagram 2 */ @@ -187,6 +189,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 8, GFLAGS), COMPOSITE_NOGATE(0, "ddrphy2x", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), + FACTOR(0, "ddrphy", "ddrphy2x", 0, 1, 2), COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, @@ -263,6 +266,8 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { COMPOSITE(0, "aclk_vcodec", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), + FACTOR_GATE(HCLK_VCODEC, "hclk_vcodec", "aclk_vcodec", 0, 1, 4, + RK2928_CLKGATE_CON(3), 12, GFLAGS), COMPOSITE(0, "aclk_hvec", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(20), 0, 2, MFLAGS, 2, 5, DFLAGS, @@ -351,6 +356,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { COMPOSITE_NOMUX(SCLK_MAC, "mac_clk", "mac_clk_ref", 0, RK2928_CLKSEL_CON(21), 9, 5, DFLAGS, RK2928_CLKGATE_CON(2), 6, GFLAGS), + FACTOR(0, "sclk_macref_out", "hclk_peri_src", 0, 1, 2), MUX(SCLK_HDMI, "dclk_hdmi", mux_dclk_p, 0, RK2928_CLKSEL_CON(31), 0, 1, MFLAGS), @@ -376,11 +382,9 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(ACLK_VIO, "aclk_vio", "aclk_disp1_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 13, GFLAGS), GATE(ACLK_LCDC, "aclk_lcdc", "aclk_disp1_pre", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), - GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS), + GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 12, GFLAGS), GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), - /* hclk_video gates */ - GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), /* xin24m gates */ GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK2928_CLKGATE_CON(10), 0, GFLAGS), @@ -444,34 +448,11 @@ static void __init rk3036_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); if (IS_ERR(clk)) pr_warn("%s: could not register clock usb480m: %ld\n", __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "ddrphy", "ddrphy2x", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock ddrphy: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", - "aclk_vcodec", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "sclk_macref_out", - "hclk_peri_src", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock sclk_macref_out: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_plls(rk3036_pll_clks, ARRAY_SIZE(rk3036_pll_clks), RK3036_GRF_SOC_STATUS0); diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 7f7444cbf6fc..40bab3901491 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -339,13 +339,15 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { INVERTER(0, "pclk_cif0", "pclkin_cif0", RK2928_CLKSEL_CON(30), 8, IFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + /* * the 480m are generated inside the usb block from these clocks, * but they are also a source for the hsicphy clock. */ - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 5, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 6, GFLAGS), COMPOSITE(0, "mac_src", mux_mac_p, 0, @@ -605,7 +607,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { GATE(SCLK_TIMER2, "timer2", "xin24m", 0, RK2928_CLKGATE_CON(3), 2, GFLAGS), - COMPOSITE_NOMUX(0, "sclk_tsadc", "xin24m", 0, + COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0, RK2928_CLKSEL_CON(34), 0, 16, DFLAGS, RK2928_CLKGATE_CON(2), 15, GFLAGS), @@ -662,11 +664,11 @@ static struct clk_div_table div_rk3188_aclk_core_t[] = { { /* sentinel */ }, }; -PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1", +PNAME(mux_hsicphy_p) = { "sclk_otgphy0_480m", "sclk_otgphy1_480m", "gpll", "cpll" }; static struct rockchip_clk_branch rk3188_i2s0_fracmux __initdata = - MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, + MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(3), 8, 2, MFLAGS); static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { @@ -722,7 +724,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0, RK2928_CLKSEL_CON(3), 0, 7, DFLAGS, RK2928_CLKGATE_CON(0), 9, GFLAGS), - COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", 0, + COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(7), 0, RK2928_CLKGATE_CON(0), 10, GFLAGS, &rk3188_i2s0_fracmux), @@ -748,12 +750,12 @@ static const char *const rk3188_critical_clocks[] __initconst = { "hclk_peri", "pclk_cpu", "pclk_peri", + "hclk_cpubus" }; static void __init rk3188_common_clk_init(struct device_node *np) { void __iomem *reg_base; - struct clk *clk; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -763,17 +765,6 @@ static void __init rk3188_common_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock usb480m: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_branches(common_clk_branches, ARRAY_SIZE(common_clk_branches)); diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index 981a50205339..c515915850a1 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -187,7 +187,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(7), 1, GFLAGS), GATE(0, "ddrc", "ddrphy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 5, GFLAGS), - GATE(0, "ddrphy", "ddrphy_pre", CLK_IGNORE_UNUSED, + FACTOR_GATE(0, "ddrphy", "ddrphy4x", CLK_IGNORE_UNUSED, 1, 4, RK2928_CLKGATE_CON(7), 0, GFLAGS), /* PD_CORE */ @@ -240,13 +240,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(32), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), - GATE(0, "hclk_vpu_src", "aclk_vpu_pre", 0, + FACTOR_GATE(0, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 4, GFLAGS), COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 2, GFLAGS), - GATE(0, "hclk_rkvdec_src", "aclk_rkvdec_pre", 0, + FACTOR_GATE(0, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 5, GFLAGS), COMPOSITE(0, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0, @@ -371,6 +371,8 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { MUX(0, "dclk_vop", mux_dclk_vop_p, 0, RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + COMPOSITE(0, "i2s0_src", mux_pll_src_2plls_p, 0, RK2928_CLKSEL_CON(9), 15, 1, MFLAGS, 0, 7, DFLAGS, RK2928_CLKGATE_CON(0), 3, GFLAGS), @@ -605,13 +607,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { /* PD_MMC */ MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), - MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 1), + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 0), MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK3228_SDIO_CON0, 1), - MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 1), + MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 0), MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3228_EMMC_CON0, 1), - MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 1), + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0), }; static const char *const rk3228_critical_clocks[] __initconst = { @@ -624,7 +626,6 @@ static const char *const rk3228_critical_clocks[] __initconst = { static void __init rk3228_clk_init(struct device_node *np) { void __iomem *reg_base; - struct clk *clk; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -634,29 +635,6 @@ static void __init rk3228_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "ddrphy_pre", "ddrphy4x", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock ddrphy_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vpu_pre", - "hclk_vpu_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vpu_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_rkvdec_pre", - "hclk_rkvdec_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_rkvdec_pre: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_plls(rk3228_pll_clks, ARRAY_SIZE(rk3228_pll_clks), RK3228_GRF_SOC_STATUS0); diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 984fc187d12e..3cb72163a512 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -195,8 +195,8 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" }; PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; -PNAME(mux_usbphy480m_p) = { "sclk_otgphy1", "sclk_otgphy2", - "sclk_otgphy0" }; +PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m", + "sclk_otgphy0_480m" }; PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; @@ -333,6 +333,8 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 7, GFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, RK3288_CLKSEL_CON(4), 15, 1, MFLAGS, 0, 7, DFLAGS, RK3288_CLKGATE_CON(4), 1, GFLAGS), @@ -399,12 +401,10 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { */ GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vdpu", 0, RK3288_CLKGATE_CON(9), 0, GFLAGS), - /* - * We introduce a virtul node of hclk_vodec_pre_v to split one clock - * struct with a gate and a fix divider into two node in software. - */ - GATE(0, "hclk_vcodec_pre_v", "aclk_vdpu", 0, + + FACTOR_GATE(0, "hclk_vcodec_pre", "aclk_vdpu", 0, 1, 4, RK3288_CLKGATE_CON(3), 10, GFLAGS), + GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK3288_CLKGATE_CON(9), 1, GFLAGS), @@ -537,11 +537,11 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(4), 10, GFLAGS), - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 4, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 5, GFLAGS), - GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY2, "sclk_otgphy2", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 6, GFLAGS), GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 7, GFLAGS), @@ -888,24 +888,6 @@ static void __init rk3288_clk_init(struct device_node *np) rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock usb480m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", - "hclk_vcodec_pre_v", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); if (IS_ERR(clk)) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index be0ede522269..31facd8426f7 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -121,7 +121,7 @@ PNAME(mux_i2s_2ch_p) = { "i2s_2ch_src", "i2s_2ch_frac", "dummy", "xin12m" }; PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "ext_i2s", "xin12m" }; -PNAME(mux_edp_24m_p) = { "dummy", "xin24m" }; +PNAME(mux_edp_24m_p) = { "xin24m", "dummy" }; PNAME(mux_vip_out_p) = { "vip_src", "xin24m" }; PNAME(mux_usbphy480m_p) = { "usbotg_out", "xin24m" }; PNAME(mux_hsic_usbphy480m_p) = { "usbotg_out", "dummy" }; @@ -165,7 +165,7 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkb_data = { .core_reg = RK3368_CLKSEL_CON(0), .div_core_shift = 0, .div_core_mask = 0x1f, - .mux_core_shift = 15, + .mux_core_shift = 7, }; static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { @@ -218,29 +218,29 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { } static struct rockchip_cpuclk_rate_table rk3368_cpuclkb_rates[] __initdata = { - RK3368_CPUCLKB_RATE(1512000000, 2, 6, 6), - RK3368_CPUCLKB_RATE(1488000000, 2, 5, 5), - RK3368_CPUCLKB_RATE(1416000000, 2, 5, 5), - RK3368_CPUCLKB_RATE(1200000000, 2, 4, 4), - RK3368_CPUCLKB_RATE(1008000000, 2, 4, 4), - RK3368_CPUCLKB_RATE( 816000000, 2, 3, 3), - RK3368_CPUCLKB_RATE( 696000000, 2, 3, 3), - RK3368_CPUCLKB_RATE( 600000000, 2, 2, 2), - RK3368_CPUCLKB_RATE( 408000000, 2, 2, 2), - RK3368_CPUCLKB_RATE( 312000000, 2, 2, 2), + RK3368_CPUCLKB_RATE(1512000000, 1, 5, 5), + RK3368_CPUCLKB_RATE(1488000000, 1, 4, 4), + RK3368_CPUCLKB_RATE(1416000000, 1, 4, 4), + RK3368_CPUCLKB_RATE(1200000000, 1, 3, 3), + RK3368_CPUCLKB_RATE(1008000000, 1, 3, 3), + RK3368_CPUCLKB_RATE( 816000000, 1, 2, 2), + RK3368_CPUCLKB_RATE( 696000000, 1, 2, 2), + RK3368_CPUCLKB_RATE( 600000000, 1, 1, 1), + RK3368_CPUCLKB_RATE( 408000000, 1, 1, 1), + RK3368_CPUCLKB_RATE( 312000000, 1, 1, 1), }; static struct rockchip_cpuclk_rate_table rk3368_cpuclkl_rates[] __initdata = { - RK3368_CPUCLKL_RATE(1512000000, 2, 7, 7), - RK3368_CPUCLKL_RATE(1488000000, 2, 6, 6), - RK3368_CPUCLKL_RATE(1416000000, 2, 6, 6), - RK3368_CPUCLKL_RATE(1200000000, 2, 5, 5), - RK3368_CPUCLKL_RATE(1008000000, 2, 5, 5), - RK3368_CPUCLKL_RATE( 816000000, 2, 4, 4), - RK3368_CPUCLKL_RATE( 696000000, 2, 3, 3), - RK3368_CPUCLKL_RATE( 600000000, 2, 3, 3), - RK3368_CPUCLKL_RATE( 408000000, 2, 2, 2), - RK3368_CPUCLKL_RATE( 312000000, 2, 2, 2), + RK3368_CPUCLKL_RATE(1512000000, 1, 6, 6), + RK3368_CPUCLKL_RATE(1488000000, 1, 5, 5), + RK3368_CPUCLKL_RATE(1416000000, 1, 5, 5), + RK3368_CPUCLKL_RATE(1200000000, 1, 4, 4), + RK3368_CPUCLKL_RATE(1008000000, 1, 4, 4), + RK3368_CPUCLKL_RATE( 816000000, 1, 3, 3), + RK3368_CPUCLKL_RATE( 696000000, 1, 2, 2), + RK3368_CPUCLKL_RATE( 600000000, 1, 2, 2), + RK3368_CPUCLKL_RATE( 408000000, 1, 1, 1), + RK3368_CPUCLKL_RATE( 312000000, 1, 1, 1), }; static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { @@ -248,6 +248,8 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { * Clock-Architecture Diagram 2 */ + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + MUX(SCLK_USBPHY480M, "usbphy_480m", mux_usbphy480m_p, CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(13), 8, 1, MFLAGS), @@ -299,7 +301,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE_NOGATE_DIVTBL(0, "ddrphy_src", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK3368_CLKSEL_CON(13), 4, 1, MFLAGS, 0, 2, DFLAGS, div_ddrphy_t), - GATE(0, "sclk_ddr", "ddrphy_div4", CLK_IGNORE_UNUSED, + FACTOR_GATE(0, "sclk_ddr", "ddrphy_src", CLK_IGNORE_UNUSED, 1, 4, RK3368_CLKGATE_CON(6), 14, GFLAGS), GATE(0, "sclk_ddr4x", "ddrphy_src", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(6), 15, GFLAGS), @@ -353,7 +355,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(32), 0, RK3368_CLKGATE_CON(6), 5, GFLAGS), - COMPOSITE_NODIV(SCLK_SPDIF_8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0, + COMPOSITE_NODIV(SCLK_SPDIF_8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(31), 8, 2, MFLAGS, RK3368_CLKGATE_CON(6), 6, GFLAGS), COMPOSITE(0, "i2s_2ch_src", mux_pll_src_cpll_gpll_p, 0, @@ -362,7 +364,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE_FRAC(0, "i2s_2ch_frac", "i2s_2ch_src", CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(54), 0, RK3368_CLKGATE_CON(5), 14, GFLAGS), - COMPOSITE_NODIV(SCLK_I2S_2CH, "sclk_i2s_2ch", mux_i2s_2ch_p, 0, + COMPOSITE_NODIV(SCLK_I2S_2CH, "sclk_i2s_2ch", mux_i2s_2ch_p, CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(53), 8, 2, MFLAGS, RK3368_CLKGATE_CON(5), 15, GFLAGS), @@ -384,18 +386,18 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { * Clock-Architecture Diagram 3 */ - COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_usb_p, 0, + COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_npll_usb_p, 0, RK3368_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3368_CLKGATE_CON(4), 6, GFLAGS), - COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb_p, 0, + COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_npll_usb_p, 0, RK3368_CLKSEL_CON(15), 14, 2, MFLAGS, 8, 5, DFLAGS, RK3368_CLKGATE_CON(4), 7, GFLAGS), /* - * We introduce a virtual node of hclk_vodec_pre_v to split one clock - * struct with a gate and a fix divider into two node in software. + * We use aclk_vdpu by default ---GRF_SOC_CON0[7] setting in system, + * so we ignore the mux and make clocks nodes as following, */ - GATE(0, "hclk_video_pre_v", "aclk_vdpu", 0, + FACTOR_GATE(0, "hclk_video_pre", "aclk_vdpu", 0, 1, 4, RK3368_CLKGATE_CON(4), 8, GFLAGS), COMPOSITE(0, "sclk_hevc_cabac_src", mux_pll_src_cpll_gpll_npll_usb_p, 0, @@ -442,7 +444,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0, RK3368_CLKGATE_CON(4), 13, GFLAGS), GATE(SCLK_HDMI_CEC, "sclk_hdmi_cec", "xin32k", 0, - RK3368_CLKGATE_CON(5), 12, GFLAGS), + RK3368_CLKGATE_CON(4), 12, GFLAGS), COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0, RK3368_CLKSEL_CON(21), 15, 1, MFLAGS, @@ -842,24 +844,6 @@ static void __init rk3368_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by a cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - /* ddrphy_div4 is created by a cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "ddrphy_div4", "ddrphy_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_video_pre", - "hclk_video_pre_v", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */ clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); if (IS_ERR(clk)) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index d9a0b5d4d47f..ab5052478870 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -70,7 +70,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, if (gate_offset >= 0) { gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate) - return ERR_PTR(-ENOMEM); + goto err_gate; gate->flags = gate_flags; gate->reg = base + gate_offset; @@ -82,7 +82,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, if (div_width > 0) { div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) - return ERR_PTR(-ENOMEM); + goto err_div; div->flags = div_flags; div->reg = base + muxdiv_offset; @@ -100,6 +100,11 @@ static struct clk *rockchip_clk_register_branch(const char *name, flags); return clk; +err_div: + kfree(gate); +err_gate: + kfree(mux); + return ERR_PTR(-ENOMEM); } struct rockchip_clk_frac { @@ -260,6 +265,53 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name, return clk; } +static struct clk *rockchip_clk_register_factor_branch(const char *name, + const char *const *parent_names, u8 num_parents, + void __iomem *base, unsigned int mult, unsigned int div, + int gate_offset, u8 gate_shift, u8 gate_flags, + unsigned long flags, spinlock_t *lock) +{ + struct clk *clk; + struct clk_gate *gate = NULL; + struct clk_fixed_factor *fix = NULL; + + /* without gate, register a simple factor clock */ + if (gate_offset == 0) { + return clk_register_fixed_factor(NULL, name, + parent_names[0], flags, mult, + div); + } + + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + gate->flags = gate_flags; + gate->reg = base + gate_offset; + gate->bit_idx = gate_shift; + gate->lock = lock; + + fix = kzalloc(sizeof(*fix), GFP_KERNEL); + if (!fix) { + kfree(gate); + return ERR_PTR(-ENOMEM); + } + + fix->mult = mult; + fix->div = div; + + clk = clk_register_composite(NULL, name, parent_names, num_parents, + NULL, NULL, + &fix->hw, &clk_fixed_factor_ops, + &gate->hw, &clk_gate_ops, flags); + if (IS_ERR(clk)) { + kfree(fix); + kfree(gate); + } + + return clk; +} + static DEFINE_SPINLOCK(clk_lock); static struct clk **clk_table; static void __iomem *reg_base; @@ -395,6 +447,14 @@ void __init rockchip_clk_register_branches( reg_base + list->muxdiv_offset, list->div_shift, list->div_flags, &clk_lock); break; + case branch_factor: + clk = rockchip_clk_register_factor_branch( + list->name, list->parent_names, + list->num_parents, reg_base, + list->div_shift, list->div_width, + list->gate_offset, list->gate_shift, + list->gate_flags, flags, &clk_lock); + break; } /* none of the cases above matched */ diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index ff8bd23a93ec..39c198bbcbee 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -254,6 +254,7 @@ enum rockchip_clk_branch_type { branch_gate, branch_mmc, branch_inverter, + branch_factor, }; struct rockchip_clk_branch { @@ -508,6 +509,33 @@ struct rockchip_clk_branch { .div_flags = if, \ } +#define FACTOR(_id, cname, pname, f, fm, fd) \ + { \ + .id = _id, \ + .branch_type = branch_factor, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .div_shift = fm, \ + .div_width = fd, \ + } + +#define FACTOR_GATE(_id, cname, pname, f, fm, fd, go, gb, gf) \ + { \ + .id = _id, \ + .branch_type = branch_factor, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .div_shift = fm, \ + .div_width = fd, \ + .gate_offset = go, \ + .gate_shift = gb, \ + .gate_flags = gf, \ + } + void rockchip_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks); struct regmap *rockchip_clk_get_grf(void); diff --git a/drivers/clk/sunxi/clk-a10-hosc.c b/drivers/clk/sunxi/clk-a10-hosc.c index 0481d5d673d6..6b598c6a0213 100644 --- a/drivers/clk/sunxi/clk-a10-hosc.c +++ b/drivers/clk/sunxi/clk-a10-hosc.c @@ -15,9 +15,9 @@ */ #include -#include #include #include +#include #define SUNXI_OSC24M_GATE 0 @@ -61,7 +61,6 @@ static void __init sun4i_osc_clk_setup(struct device_node *node) goto err_free_gate; of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); return; diff --git a/drivers/clk/sunxi/clk-a20-gmac.c b/drivers/clk/sunxi/clk-a20-gmac.c index 1611b036421c..3437f734c9bf 100644 --- a/drivers/clk/sunxi/clk-a20-gmac.c +++ b/drivers/clk/sunxi/clk-a20-gmac.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include @@ -107,7 +106,6 @@ static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) goto iounmap_reg; of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); return; diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 59428dbd607a..ddefe9668863 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -48,7 +48,7 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, u32 reg; unsigned long rate; struct clk_factors *factors = to_clk_factors(hw); - struct clk_factors_config *config = factors->config; + const struct clk_factors_config *config = factors->config; /* Fetch the register value */ reg = readl(factors->reg); @@ -63,18 +63,28 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE) p = FACTOR_GET(config->pshift, config->pwidth, reg); - /* Calculate the rate */ - rate = (parent_rate * (n + config->n_start) * (k + 1) >> p) / (m + 1); + if (factors->recalc) { + struct factors_request factors_req = { + .parent_rate = parent_rate, + .n = n, + .k = k, + .m = m, + .p = p, + }; - return rate; -} + /* get mux details from mux clk structure */ + if (factors->mux) + factors_req.parent_index = + (reg >> factors->mux->shift) & + factors->mux->mask; -static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - struct clk_factors *factors = to_clk_factors(hw); - factors->get_factors((u32 *)&rate, (u32)*parent_rate, - NULL, NULL, NULL, NULL); + factors->recalc(&factors_req); + + return factors_req.rate; + } + + /* Calculate the rate */ + rate = (parent_rate * (n + config->n_start) * (k + 1) >> p) / (m + 1); return rate; } @@ -82,6 +92,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, static int clk_factors_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { + struct clk_factors *factors = to_clk_factors(hw); struct clk_hw *parent, *best_parent = NULL; int i, num_parents; unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; @@ -89,6 +100,10 @@ static int clk_factors_determine_rate(struct clk_hw *hw, /* find the parent that can help provide the fastest rate <= rate */ num_parents = clk_hw_get_num_parents(hw); for (i = 0; i < num_parents; i++) { + struct factors_request factors_req = { + .rate = req->rate, + .parent_index = i, + }; parent = clk_hw_get_parent_by_index(hw, i); if (!parent) continue; @@ -97,8 +112,9 @@ static int clk_factors_determine_rate(struct clk_hw *hw, else parent_rate = clk_hw_get_rate(parent); - child_rate = clk_factors_round_rate(hw, req->rate, - &parent_rate); + factors_req.parent_rate = parent_rate; + factors->get_factors(&factors_req); + child_rate = factors_req.rate; if (child_rate <= req->rate && child_rate > best_child_rate) { best_parent = parent; @@ -120,13 +136,16 @@ static int clk_factors_determine_rate(struct clk_hw *hw, static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - u8 n = 0, k = 0, m = 0, p = 0; + struct factors_request req = { + .rate = rate, + .parent_rate = parent_rate, + }; u32 reg; struct clk_factors *factors = to_clk_factors(hw); - struct clk_factors_config *config = factors->config; + const struct clk_factors_config *config = factors->config; unsigned long flags = 0; - factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p); + factors->get_factors(&req); if (factors->lock) spin_lock_irqsave(factors->lock, flags); @@ -135,10 +154,10 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, reg = readl(factors->reg); /* Set up the new factors - macros do not do anything if width is 0 */ - reg = FACTOR_SET(config->nshift, config->nwidth, reg, n); - reg = FACTOR_SET(config->kshift, config->kwidth, reg, k); - reg = FACTOR_SET(config->mshift, config->mwidth, reg, m); - reg = FACTOR_SET(config->pshift, config->pwidth, reg, p); + reg = FACTOR_SET(config->nshift, config->nwidth, reg, req.n); + reg = FACTOR_SET(config->kshift, config->kwidth, reg, req.k); + reg = FACTOR_SET(config->mshift, config->mwidth, reg, req.m); + reg = FACTOR_SET(config->pshift, config->pwidth, reg, req.p); /* Apply them now */ writel(reg, factors->reg); @@ -155,7 +174,6 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_factors_ops = { .determine_rate = clk_factors_determine_rate, .recalc_rate = clk_factors_recalc_rate, - .round_rate = clk_factors_round_rate, .set_rate = clk_factors_set_rate, }; @@ -172,7 +190,7 @@ struct clk *sunxi_factors_register(struct device_node *node, struct clk_hw *mux_hw = NULL; const char *clk_name = node->name; const char *parents[FACTORS_MAX_PARENTS]; - int i = 0; + int ret, i = 0; /* if we have a mux, we will have >1 parents */ i = of_clk_parent_fill(node, parents, FACTORS_MAX_PARENTS); @@ -188,21 +206,22 @@ struct clk *sunxi_factors_register(struct device_node *node, factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); if (!factors) - return NULL; + goto err_factors; /* set up factors properties */ factors->reg = reg; factors->config = data->table; factors->get_factors = data->getter; + factors->recalc = data->recalc; factors->lock = lock; /* Add a gate if this factor clock can be gated */ if (data->enable) { gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); - if (!gate) { - kfree(factors); - return NULL; - } + if (!gate) + goto err_gate; + + factors->gate = gate; /* set up gate properties */ gate->reg = reg; @@ -214,11 +233,10 @@ struct clk *sunxi_factors_register(struct device_node *node, /* Add a mux if this factor clock can be muxed */ if (data->mux) { mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); - if (!mux) { - kfree(factors); - kfree(gate); - return NULL; - } + if (!mux) + goto err_mux; + + factors->mux = mux; /* set up gate properties */ mux->reg = reg; @@ -233,11 +251,44 @@ struct clk *sunxi_factors_register(struct device_node *node, mux_hw, &clk_mux_ops, &factors->hw, &clk_factors_ops, gate_hw, &clk_gate_ops, 0); + if (IS_ERR(clk)) + goto err_register; - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } + ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (ret) + goto err_provider; return clk; + +err_provider: + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); +err_register: + kfree(mux); +err_mux: + kfree(gate); +err_gate: + kfree(factors); +err_factors: + return NULL; +} + +void sunxi_factors_unregister(struct device_node *node, struct clk *clk) +{ + struct clk_hw *hw = __clk_get_hw(clk); + struct clk_factors *factors; + const char *name; + + if (!hw) + return; + + factors = to_clk_factors(hw); + name = clk_hw_get_name(hw); + + of_clk_del_provider(node); + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); + kfree(factors->mux); + kfree(factors->gate); + kfree(factors); } diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 171085ab5513..1e63c5b2d5f4 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -2,7 +2,6 @@ #define __MACH_SUNXI_CLK_FACTORS_H #include -#include #include #define SUNXI_FACTORS_NOT_APPLICABLE (0) @@ -19,21 +18,36 @@ struct clk_factors_config { u8 n_start; }; +struct factors_request { + unsigned long rate; + unsigned long parent_rate; + u8 parent_index; + u8 n; + u8 k; + u8 m; + u8 p; +}; + struct factors_data { int enable; int mux; int muxmask; - struct clk_factors_config *table; - void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); + const struct clk_factors_config *table; + void (*getter)(struct factors_request *req); + void (*recalc)(struct factors_request *req); const char *name; }; struct clk_factors { struct clk_hw hw; void __iomem *reg; - struct clk_factors_config *config; - void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); + const struct clk_factors_config *config; + void (*get_factors)(struct factors_request *req); + void (*recalc)(struct factors_request *req); spinlock_t *lock; + /* for cleanup */ + struct clk_mux *mux; + struct clk_gate *gate; }; struct clk *sunxi_factors_register(struct device_node *node, @@ -41,4 +55,6 @@ struct clk *sunxi_factors_register(struct device_node *node, spinlock_t *lock, void __iomem *reg); +void sunxi_factors_unregister(struct device_node *node, struct clk *clk); + #endif diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index d167e1efb927..b38d71cec74c 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -28,17 +29,16 @@ * rate = (parent_rate >> p) / (m + 1); */ -static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_a10_get_mod0_factors(struct factors_request *req) { u8 div, calcm, calcp; /* These clocks can only divide, so we will never be able to achieve * frequencies higher than the parent frequency */ - if (*freq > parent_rate) - *freq = parent_rate; + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); if (div < 16) calcp = 0; @@ -51,18 +51,13 @@ static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, calcm = DIV_ROUND_UP(div, 1 << calcp); - *freq = (parent_rate >> calcp) / calcm; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm - 1; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / calcm; + req->m = calcm - 1; + req->p = calcp; } /* user manual says "n" but it's really "p" */ -static struct clk_factors_config sun4i_a10_mod0_config = { +static const struct clk_factors_config sun4i_a10_mod0_config = { .mshift = 0, .mwidth = 4, .pshift = 16, diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c index f4da52b5ca0e..2cfc5a8a5534 100644 --- a/drivers/clk/sunxi/clk-simple-gates.c +++ b/drivers/clk/sunxi/clk-simple-gates.c @@ -130,6 +130,8 @@ CLK_OF_DECLARE(sun8i_a23_apb2, "allwinner,sun8i-a23-apb2-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun8i_a33_ahb1, "allwinner,sun8i-a33-ahb1-gates-clk", sunxi_simple_gates_init); +CLK_OF_DECLARE(sun8i_a83t_apb0, "allwinner,sun8i-a83t-apb0-gates-clk", + sunxi_simple_gates_init); CLK_OF_DECLARE(sun9i_a80_ahb0, "allwinner,sun9i-a80-ahb0-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun9i_a80_ahb1, "allwinner,sun9i-a80-ahb1-gates-clk", diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c index 23d042aabb4f..68021fa5ecd9 100644 --- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c +++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c @@ -9,7 +9,6 @@ */ #include -#include #include #include #include @@ -87,7 +86,6 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) clk_parent, 0, reg, i, 0, NULL); WARN_ON(IS_ERR(clk_data->clks[i])); - clk_register_clkdev(clk_data->clks[i], clk_name, NULL); j++; } diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c index 20887686bdbe..84a187e55360 100644 --- a/drivers/clk/sunxi/clk-sun6i-ar100.c +++ b/drivers/clk/sunxi/clk-sun6i-ar100.c @@ -8,211 +8,97 @@ * */ +#include #include #include #include #include +#include -#define SUN6I_AR100_MAX_PARENTS 4 -#define SUN6I_AR100_SHIFT_MASK 0x3 -#define SUN6I_AR100_SHIFT_MAX SUN6I_AR100_SHIFT_MASK -#define SUN6I_AR100_SHIFT_SHIFT 4 -#define SUN6I_AR100_DIV_MASK 0x1f -#define SUN6I_AR100_DIV_MAX (SUN6I_AR100_DIV_MASK + 1) -#define SUN6I_AR100_DIV_SHIFT 8 -#define SUN6I_AR100_MUX_MASK 0x3 -#define SUN6I_AR100_MUX_SHIFT 16 - -struct ar100_clk { - struct clk_hw hw; - void __iomem *reg; -}; - -static inline struct ar100_clk *to_ar100_clk(struct clk_hw *hw) -{ - return container_of(hw, struct ar100_clk, hw); -} - -static unsigned long ar100_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); - int shift = (val >> SUN6I_AR100_SHIFT_SHIFT) & SUN6I_AR100_SHIFT_MASK; - int div = (val >> SUN6I_AR100_DIV_SHIFT) & SUN6I_AR100_DIV_MASK; - - return (parent_rate >> shift) / (div + 1); -} - -static int ar100_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - int nparents = clk_hw_get_num_parents(hw); - long best_rate = -EINVAL; - int i; - - req->best_parent_hw = NULL; - - for (i = 0; i < nparents; i++) { - unsigned long parent_rate; - unsigned long tmp_rate; - struct clk_hw *parent; - unsigned long div; - int shift; - - parent = clk_hw_get_parent_by_index(hw, i); - parent_rate = clk_hw_get_rate(parent); - div = DIV_ROUND_UP(parent_rate, req->rate); - - /* - * The AR100 clk contains 2 divisors: - * - one power of 2 divisor - * - one regular divisor - * - * First check if we can safely shift (or divide by a power - * of 2) without losing precision on the requested rate. - */ - shift = ffs(div) - 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - shift = SUN6I_AR100_SHIFT_MAX; - - div >>= shift; - - /* - * Then if the divisor is still bigger than what the HW - * actually supports, use a bigger shift (or power of 2 - * divider) value and accept to lose some precision. - */ - while (div > SUN6I_AR100_DIV_MAX) { - shift++; - div >>= 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - break; - } - - /* - * If the shift value (or power of 2 divider) is bigger - * than what the HW actually support, skip this parent. - */ - if (shift > SUN6I_AR100_SHIFT_MAX) - continue; - - tmp_rate = (parent_rate >> shift) / div; - if (!req->best_parent_hw || tmp_rate > best_rate) { - req->best_parent_hw = parent; - req->best_parent_rate = parent_rate; - best_rate = tmp_rate; - } - } - - if (best_rate < 0) - return best_rate; - - req->rate = best_rate; - - return 0; -} - -static int ar100_set_parent(struct clk_hw *hw, u8 index) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); - - if (index >= SUN6I_AR100_MAX_PARENTS) - return -EINVAL; - - val &= ~(SUN6I_AR100_MUX_MASK << SUN6I_AR100_MUX_SHIFT); - val |= (index << SUN6I_AR100_MUX_SHIFT); - writel(val, clk->reg); - - return 0; -} +#include "clk-factors.h" -static u8 ar100_get_parent(struct clk_hw *hw) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - return (readl(clk->reg) >> SUN6I_AR100_MUX_SHIFT) & - SUN6I_AR100_MUX_MASK; -} - -static int ar100_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) +/** + * sun6i_get_ar100_factors - Calculates factors p, m for AR100 + * + * AR100 rate is calculated as follows + * rate = (parent_rate >> p) / (m + 1); + */ +static void sun6i_get_ar100_factors(struct factors_request *req) { - unsigned long div = parent_rate / rate; - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); + unsigned long div; int shift; - if (parent_rate % rate) - return -EINVAL; + /* clock only divides */ + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - shift = ffs(div) - 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - shift = SUN6I_AR100_SHIFT_MAX; + div = DIV_ROUND_UP(req->parent_rate, req->rate); - div >>= shift; + if (div < 32) + shift = 0; + else if (div >> 1 < 32) + shift = 1; + else if (div >> 2 < 32) + shift = 2; + else + shift = 3; - if (div > SUN6I_AR100_DIV_MAX) - return -EINVAL; + div >>= shift; - val &= ~((SUN6I_AR100_SHIFT_MASK << SUN6I_AR100_SHIFT_SHIFT) | - (SUN6I_AR100_DIV_MASK << SUN6I_AR100_DIV_SHIFT)); - val |= (shift << SUN6I_AR100_SHIFT_SHIFT) | - (div << SUN6I_AR100_DIV_SHIFT); - writel(val, clk->reg); + if (div > 32) + div = 32; - return 0; + req->rate = (req->parent_rate >> shift) / div; + req->m = div - 1; + req->p = shift; } -static struct clk_ops ar100_ops = { - .recalc_rate = ar100_recalc_rate, - .determine_rate = ar100_determine_rate, - .set_parent = ar100_set_parent, - .get_parent = ar100_get_parent, - .set_rate = ar100_set_rate, +static const struct clk_factors_config sun6i_ar100_config = { + .mwidth = 5, + .mshift = 8, + .pwidth = 2, + .pshift = 4, }; +static const struct factors_data sun6i_ar100_data = { + .mux = 16, + .muxmask = GENMASK(1, 0), + .table = &sun6i_ar100_config, + .getter = sun6i_get_ar100_factors, +}; + +static DEFINE_SPINLOCK(sun6i_ar100_lock); + static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev) { - const char *parents[SUN6I_AR100_MAX_PARENTS]; struct device_node *np = pdev->dev.of_node; - const char *clk_name = np->name; - struct clk_init_data init; - struct ar100_clk *ar100; struct resource *r; + void __iomem *reg; struct clk *clk; - int nparents; - - ar100 = devm_kzalloc(&pdev->dev, sizeof(*ar100), GFP_KERNEL); - if (!ar100) - return -ENOMEM; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ar100->reg = devm_ioremap_resource(&pdev->dev, r); - if (IS_ERR(ar100->reg)) - return PTR_ERR(ar100->reg); + reg = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(reg)) + return PTR_ERR(reg); - nparents = of_clk_get_parent_count(np); - if (nparents > SUN6I_AR100_MAX_PARENTS) - nparents = SUN6I_AR100_MAX_PARENTS; - - of_clk_parent_fill(np, parents, nparents); + clk = sunxi_factors_register(np, &sun6i_ar100_data, &sun6i_ar100_lock, + reg); + if (!clk) + return -ENOMEM; - of_property_read_string(np, "clock-output-names", &clk_name); + platform_set_drvdata(pdev, clk); - init.name = clk_name; - init.ops = &ar100_ops; - init.parent_names = parents; - init.num_parents = nparents; - init.flags = 0; + return 0; +} - ar100->hw.init = &init; +static int sun6i_a31_ar100_clk_remove(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct clk *clk = platform_get_drvdata(pdev); - clk = clk_register(&pdev->dev, &ar100->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + sunxi_factors_unregister(np, clk); - return of_clk_add_provider(np, of_clk_src_simple_get, clk); + return 0; } static const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = { @@ -227,6 +113,7 @@ static struct platform_driver sun6i_a31_ar100_clk_driver = { .of_match_table = sun6i_a31_ar100_clk_dt_ids, }, .probe = sun6i_a31_ar100_clk_probe, + .remove = sun6i_a31_ar100_clk_remove, }; module_platform_driver(sun6i_a31_ar100_clk_driver); diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c index e32d18ba252b..63fdb790df29 100644 --- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c +++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c @@ -17,7 +17,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -110,3 +109,5 @@ err_unmap: CLK_OF_DECLARE(sun8i_h3_bus_gates, "allwinner,sun8i-h3-bus-gates-clk", sun8i_h3_bus_gates_init); +CLK_OF_DECLARE(sun8i_a83t_bus_gates, "allwinner,sun8i-a83t-bus-gates-clk", + sun8i_h3_bus_gates_init); diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index bf117a636d23..3aaa9cbef791 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c @@ -15,74 +15,99 @@ */ #include +#include #include +#include +#include #include -#include "clk-factors.h" +#define SUN8I_MBUS_ENABLE 31 +#define SUN8I_MBUS_MUX_SHIFT 24 +#define SUN8I_MBUS_MUX_MASK 0x3 +#define SUN8I_MBUS_DIV_SHIFT 0 +#define SUN8I_MBUS_DIV_WIDTH 3 +#define SUN8I_MBUS_MAX_PARENTS 4 -/** - * sun8i_a23_get_mbus_factors() - calculates m factor for MBUS clocks - * MBUS rate is calculated as follows - * rate = parent_rate / (m + 1); - */ +static DEFINE_SPINLOCK(sun8i_a23_mbus_lock); -static void sun8i_a23_get_mbus_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void __init sun8i_a23_mbus_setup(struct device_node *node) { - u8 div; - - /* - * These clocks can only divide, so we will never be able to - * achieve frequencies higher than the parent frequency - */ - if (*freq > parent_rate) - *freq = parent_rate; - - div = DIV_ROUND_UP(parent_rate, *freq); + int num_parents = of_clk_get_parent_count(node); + const char *parents[num_parents]; + const char *clk_name = node->name; + struct resource res; + struct clk_divider *div; + struct clk_gate *gate; + struct clk_mux *mux; + struct clk *clk; + void __iomem *reg; + int err; - if (div > 8) - div = 8; + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (!reg) { + pr_err("Could not get registers for sun8i-mbus-clk\n"); + return; + } - *freq = parent_rate / div; + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + goto err_unmap; - /* we were called to round the frequency, we can now return */ - if (m == NULL) - return; + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + goto err_free_div; - *m = div - 1; -} + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + goto err_free_mux; -static struct clk_factors_config sun8i_a23_mbus_config = { - .mshift = 0, - .mwidth = 3, -}; + of_property_read_string(node, "clock-output-names", &clk_name); + of_clk_parent_fill(node, parents, num_parents); -static const struct factors_data sun8i_a23_mbus_data __initconst = { - .enable = 31, - .mux = 24, - .muxmask = BIT(1) | BIT(0), - .table = &sun8i_a23_mbus_config, - .getter = sun8i_a23_get_mbus_factors, -}; + gate->reg = reg; + gate->bit_idx = SUN8I_MBUS_ENABLE; + gate->lock = &sun8i_a23_mbus_lock; -static DEFINE_SPINLOCK(sun8i_a23_mbus_lock); + div->reg = reg; + div->shift = SUN8I_MBUS_DIV_SHIFT; + div->width = SUN8I_MBUS_DIV_WIDTH; + div->lock = &sun8i_a23_mbus_lock; -static void __init sun8i_a23_mbus_setup(struct device_node *node) -{ - struct clk *mbus; - void __iomem *reg; + mux->reg = reg; + mux->shift = SUN8I_MBUS_MUX_SHIFT; + mux->mask = SUN8I_MBUS_MUX_MASK; + mux->lock = &sun8i_a23_mbus_lock; - reg = of_iomap(node, 0); - if (!reg) { - pr_err("Could not get registers for a23-mbus-clk\n"); - return; - } + clk = clk_register_composite(NULL, clk_name, parents, num_parents, + &mux->hw, &clk_mux_ops, + &div->hw, &clk_divider_ops, + &gate->hw, &clk_gate_ops, + 0); + if (IS_ERR(clk)) + goto err_free_gate; - mbus = sunxi_factors_register(node, &sun8i_a23_mbus_data, - &sun8i_a23_mbus_lock, reg); + err = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (err) + goto err_unregister_clk; /* The MBUS clocks needs to be always enabled */ - __clk_get(mbus); - clk_prepare_enable(mbus); + __clk_get(clk); + clk_prepare_enable(clk); + + return; + +err_unregister_clk: + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); +err_free_gate: + kfree(gate); +err_free_mux: + kfree(mux); +err_free_div: + kfree(div); +err_unmap: + iounmap(reg); + of_address_to_resource(node, 0, &res); + release_mem_region(res.start, resource_size(&res)); } CLK_OF_DECLARE(sun8i_a23_mbus, "allwinner,sun8i-a23-mbus-clk", sun8i_a23_mbus_setup); diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c index 6c4c98324d3c..43f014f85803 100644 --- a/drivers/clk/sunxi/clk-sun9i-core.c +++ b/drivers/clk/sunxi/clk-sun9i-core.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -32,15 +33,14 @@ * p and m are named div1 and div2 in Allwinner's SDK */ -static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, - u8 *n_ret, u8 *k, u8 *m_ret, u8 *p_ret) +static void sun9i_a80_get_pll4_factors(struct factors_request *req) { int n; int m = 1; int p = 1; /* Normalize value to a 6 MHz multiple (24 MHz / 4) */ - n = DIV_ROUND_UP(*freq, 6000000); + n = DIV_ROUND_UP(req->rate, 6000000); /* If n is too large switch to steps of 12 MHz */ if (n > 255) { @@ -60,18 +60,13 @@ static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, else if (n < 12) n = 12; - *freq = ((24000000 * n) >> p) / (m + 1); - - /* we were called to round the frequency, we can now return */ - if (n_ret == NULL) - return; - - *n_ret = n; - *m_ret = m; - *p_ret = p; + req->rate = ((24000000 * n) >> p) / (m + 1); + req->n = n; + req->m = m; + req->p = p; } -static struct clk_factors_config sun9i_a80_pll4_config = { +static const struct clk_factors_config sun9i_a80_pll4_config = { .mshift = 18, .mwidth = 1, .nshift = 8, @@ -111,30 +106,24 @@ CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_se * rate = parent_rate / (m + 1); */ -static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_gt_factors(struct factors_request *req) { u32 div; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* maximum divider is 4 */ if (div > 4) div = 4; - *freq = parent_rate / div; - - /* we were called to round the frequency, we can now return */ - if (!m) - return; - - *m = div; + req->rate = req->parent_rate / div; + req->m = div; } -static struct clk_factors_config sun9i_a80_gt_config = { +static const struct clk_factors_config sun9i_a80_gt_config = { .mshift = 0, .mwidth = 2, }; @@ -176,30 +165,24 @@ CLK_OF_DECLARE(sun9i_a80_gt, "allwinner,sun9i-a80-gt-clk", sun9i_a80_gt_setup); * rate = parent_rate >> p; */ -static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_ahb_factors(struct factors_request *req) { u32 _p; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - _p = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); + _p = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate)); /* maximum p is 3 */ if (_p > 3) _p = 3; - *freq = parent_rate >> _p; - - /* we were called to round the frequency, we can now return */ - if (!p) - return; - - *p = _p; + req->rate = req->parent_rate >> _p; + req->p = _p; } -static struct clk_factors_config sun9i_a80_ahb_config = { +static const struct clk_factors_config sun9i_a80_ahb_config = { .pshift = 0, .pwidth = 2, }; @@ -262,34 +245,25 @@ CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_se * rate = (parent_rate >> p) / (m + 1); */ -static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_apb1_factors(struct factors_request *req) { u32 div; - u8 calcm, calcp; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* Highest possible divider is 256 (p = 3, m = 31) */ if (div > 256) div = 256; - calcp = order_base_2(div); - calcm = (parent_rate >> calcp) - 1; - *freq = (parent_rate >> calcp) / (calcm + 1); - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm; - *p = calcp; + req->p = order_base_2(div); + req->m = (req->parent_rate >> req->p) - 1; + req->rate = (req->parent_rate >> req->p) / (req->m + 1); } -static struct clk_factors_config sun9i_a80_apb1_config = { +static const struct clk_factors_config sun9i_a80_apb1_config = { .mshift = 0, .mwidth = 5, .pshift = 16, diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 5ba2188ee99c..49ce2830489b 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -28,214 +28,6 @@ static DEFINE_SPINLOCK(clk_lock); -/** - * sun6i_a31_ahb1_clk_setup() - Setup function for a31 ahb1 composite clk - */ - -#define SUN6I_AHB1_MAX_PARENTS 4 -#define SUN6I_AHB1_MUX_PARENT_PLL6 3 -#define SUN6I_AHB1_MUX_SHIFT 12 -/* un-shifted mask is what mux_clk expects */ -#define SUN6I_AHB1_MUX_MASK 0x3 -#define SUN6I_AHB1_MUX_GET_PARENT(reg) ((reg >> SUN6I_AHB1_MUX_SHIFT) & \ - SUN6I_AHB1_MUX_MASK) - -#define SUN6I_AHB1_DIV_SHIFT 4 -#define SUN6I_AHB1_DIV_MASK (0x3 << SUN6I_AHB1_DIV_SHIFT) -#define SUN6I_AHB1_DIV_GET(reg) ((reg & SUN6I_AHB1_DIV_MASK) >> \ - SUN6I_AHB1_DIV_SHIFT) -#define SUN6I_AHB1_DIV_SET(reg, div) ((reg & ~SUN6I_AHB1_DIV_MASK) | \ - (div << SUN6I_AHB1_DIV_SHIFT)) -#define SUN6I_AHB1_PLL6_DIV_SHIFT 6 -#define SUN6I_AHB1_PLL6_DIV_MASK (0x3 << SUN6I_AHB1_PLL6_DIV_SHIFT) -#define SUN6I_AHB1_PLL6_DIV_GET(reg) ((reg & SUN6I_AHB1_PLL6_DIV_MASK) >> \ - SUN6I_AHB1_PLL6_DIV_SHIFT) -#define SUN6I_AHB1_PLL6_DIV_SET(reg, div) ((reg & ~SUN6I_AHB1_PLL6_DIV_MASK) | \ - (div << SUN6I_AHB1_PLL6_DIV_SHIFT)) - -struct sun6i_ahb1_clk { - struct clk_hw hw; - void __iomem *reg; -}; - -#define to_sun6i_ahb1_clk(_hw) container_of(_hw, struct sun6i_ahb1_clk, hw) - -static unsigned long sun6i_ahb1_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw); - unsigned long rate; - u32 reg; - - /* Fetch the register value */ - reg = readl(ahb1->reg); - - /* apply pre-divider first if parent is pll6 */ - if (SUN6I_AHB1_MUX_GET_PARENT(reg) == SUN6I_AHB1_MUX_PARENT_PLL6) - parent_rate /= SUN6I_AHB1_PLL6_DIV_GET(reg) + 1; - - /* clk divider */ - rate = parent_rate >> SUN6I_AHB1_DIV_GET(reg); - - return rate; -} - -static long sun6i_ahb1_clk_round(unsigned long rate, u8 *divp, u8 *pre_divp, - u8 parent, unsigned long parent_rate) -{ - u8 div, calcp, calcm = 1; - - /* - * clock can only divide, so we will never be able to achieve - * frequencies higher than the parent frequency - */ - if (parent_rate && rate > parent_rate) - rate = parent_rate; - - div = DIV_ROUND_UP(parent_rate, rate); - - /* calculate pre-divider if parent is pll6 */ - if (parent == SUN6I_AHB1_MUX_PARENT_PLL6) { - if (div < 4) - calcp = 0; - else if (div / 2 < 4) - calcp = 1; - else if (div / 4 < 4) - calcp = 2; - else - calcp = 3; - - calcm = DIV_ROUND_UP(div, 1 << calcp); - } else { - calcp = __roundup_pow_of_two(div); - calcp = calcp > 3 ? 3 : calcp; - } - - /* we were asked to pass back divider values */ - if (divp) { - *divp = calcp; - *pre_divp = calcm - 1; - } - - return (parent_rate / calcm) >> calcp; -} - -static int sun6i_ahb1_clk_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - struct clk_hw *parent, *best_parent = NULL; - int i, num_parents; - unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; - - /* find the parent that can help provide the fastest rate <= rate */ - num_parents = clk_hw_get_num_parents(hw); - for (i = 0; i < num_parents; i++) { - parent = clk_hw_get_parent_by_index(hw, i); - if (!parent) - continue; - if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) - parent_rate = clk_hw_round_rate(parent, req->rate); - else - parent_rate = clk_hw_get_rate(parent); - - child_rate = sun6i_ahb1_clk_round(req->rate, NULL, NULL, i, - parent_rate); - - if (child_rate <= req->rate && child_rate > best_child_rate) { - best_parent = parent; - best = parent_rate; - best_child_rate = child_rate; - } - } - - if (!best_parent) - return -EINVAL; - - req->best_parent_hw = best_parent; - req->best_parent_rate = best; - req->rate = best_child_rate; - - return 0; -} - -static int sun6i_ahb1_clk_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw); - unsigned long flags; - u8 div, pre_div, parent; - u32 reg; - - spin_lock_irqsave(&clk_lock, flags); - - reg = readl(ahb1->reg); - - /* need to know which parent is used to apply pre-divider */ - parent = SUN6I_AHB1_MUX_GET_PARENT(reg); - sun6i_ahb1_clk_round(rate, &div, &pre_div, parent, parent_rate); - - reg = SUN6I_AHB1_DIV_SET(reg, div); - reg = SUN6I_AHB1_PLL6_DIV_SET(reg, pre_div); - writel(reg, ahb1->reg); - - spin_unlock_irqrestore(&clk_lock, flags); - - return 0; -} - -static const struct clk_ops sun6i_ahb1_clk_ops = { - .determine_rate = sun6i_ahb1_clk_determine_rate, - .recalc_rate = sun6i_ahb1_clk_recalc_rate, - .set_rate = sun6i_ahb1_clk_set_rate, -}; - -static void __init sun6i_ahb1_clk_setup(struct device_node *node) -{ - struct clk *clk; - struct sun6i_ahb1_clk *ahb1; - struct clk_mux *mux; - const char *clk_name = node->name; - const char *parents[SUN6I_AHB1_MAX_PARENTS]; - void __iomem *reg; - int i; - - reg = of_io_request_and_map(node, 0, of_node_full_name(node)); - if (IS_ERR(reg)) - return; - - /* we have a mux, we will have >1 parents */ - i = of_clk_parent_fill(node, parents, SUN6I_AHB1_MAX_PARENTS); - of_property_read_string(node, "clock-output-names", &clk_name); - - ahb1 = kzalloc(sizeof(struct sun6i_ahb1_clk), GFP_KERNEL); - if (!ahb1) - return; - - mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); - if (!mux) { - kfree(ahb1); - return; - } - - /* set up clock properties */ - mux->reg = reg; - mux->shift = SUN6I_AHB1_MUX_SHIFT; - mux->mask = SUN6I_AHB1_MUX_MASK; - mux->lock = &clk_lock; - ahb1->reg = reg; - - clk = clk_register_composite(NULL, clk_name, parents, i, - &mux->hw, &clk_mux_ops, - &ahb1->hw, &sun6i_ahb1_clk_ops, - NULL, NULL, 0); - - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } -} -CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_setup); - /* Maximum number of parents our clocks have */ #define SUNXI_MAX_PARENTS 5 @@ -246,49 +38,45 @@ CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_se * parent_rate is always 24Mhz */ -static void sun4i_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_pll1_factors(struct factors_request *req) { u8 div; /* Normalize value to a 6M multiple */ - div = *freq / 6000000; - *freq = 6000000 * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / 6000000; + req->rate = 6000000 * div; /* m is always zero for pll1 */ - *m = 0; + req->m = 0; /* k is 1 only on these cases */ - if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000) - *k = 1; + if (req->rate >= 768000000 || req->rate == 42000000 || + req->rate == 54000000) + req->k = 1; else - *k = 0; + req->k = 0; /* p will be 3 for divs under 10 */ if (div < 10) - *p = 3; + req->p = 3; /* p will be 2 for divs between 10 - 20 and odd divs under 32 */ else if (div < 20 || (div < 32 && (div & 1))) - *p = 2; + req->p = 2; /* p will be 1 for even divs under 32, divs under 40 and odd pairs * of divs between 40-62 */ else if (div < 40 || (div < 64 && (div & 2))) - *p = 1; + req->p = 1; /* any other entries have p = 0 */ else - *p = 0; + req->p = 0; /* calculate a suitable n based on k and p */ - div <<= *p; - div /= (*k + 1); - *n = div / 4; + div <<= req->p; + div /= (req->k + 1); + req->n = div / 4; } /** @@ -297,15 +85,14 @@ static void sun4i_get_pll1_factors(u32 *freq, u32 parent_rate, * rate = parent_rate * (n + 1) * (k + 1) / (m + 1); * parent_rate should always be 24MHz */ -static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun6i_a31_get_pll1_factors(struct factors_request *req) { /* * We can operate only on MHz, this will make our life easier * later. */ - u32 freq_mhz = *freq / 1000000; - u32 parent_freq_mhz = parent_rate / 1000000; + u32 freq_mhz = req->rate / 1000000; + u32 parent_freq_mhz = req->parent_rate / 1000000; /* * Round down the frequency to the closest multiple of either @@ -319,28 +106,20 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, else freq_mhz = round_freq_16; - *freq = freq_mhz * 1000000; - - /* - * If the factors pointer are null, we were just called to - * round down the frequency. - * Exit. - */ - if (n == NULL) - return; + req->rate = freq_mhz * 1000000; /* If the frequency is a multiple of 32 MHz, k is always 3 */ if (!(freq_mhz % 32)) - *k = 3; + req->k = 3; /* If the frequency is a multiple of 9 MHz, k is always 2 */ else if (!(freq_mhz % 9)) - *k = 2; + req->k = 2; /* If the frequency is a multiple of 8 MHz, k is always 1 */ else if (!(freq_mhz % 8)) - *k = 1; + req->k = 1; /* Otherwise, we don't use the k factor */ else - *k = 0; + req->k = 0; /* * If the frequency is a multiple of 2 but not a multiple of @@ -351,27 +130,28 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, * somehow relates to this frequency. */ if ((freq_mhz % 6) == 2 || (freq_mhz % 6) == 4) - *m = 2; + req->m = 2; /* * If the frequency is a multiple of 6MHz, but the factor is * odd, m will be 3 */ else if ((freq_mhz / 6) & 1) - *m = 3; + req->m = 3; /* Otherwise, we end up with m = 1 */ else - *m = 1; + req->m = 1; /* Calculate n thanks to the above factors we already got */ - *n = freq_mhz * (*m + 1) / ((*k + 1) * parent_freq_mhz) - 1; + req->n = freq_mhz * (req->m + 1) / ((req->k + 1) * parent_freq_mhz) + - 1; /* * If n end up being outbound, and that we can still decrease * m, do it. */ - if ((*n + 1) > 31 && (*m + 1) > 1) { - *n = (*n + 1) / 2 - 1; - *m = (*m + 1) / 2 - 1; + if ((req->n + 1) > 31 && (req->m + 1) > 1) { + req->n = (req->n + 1) / 2 - 1; + req->m = (req->m + 1) / 2 - 1; } } @@ -382,45 +162,41 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun8i_a23_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun8i_a23_get_pll1_factors(struct factors_request *req) { u8 div; /* Normalize value to a 6M multiple */ - div = *freq / 6000000; - *freq = 6000000 * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / 6000000; + req->rate = 6000000 * div; /* m is always zero for pll1 */ - *m = 0; + req->m = 0; /* k is 1 only on these cases */ - if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000) - *k = 1; + if (req->rate >= 768000000 || req->rate == 42000000 || + req->rate == 54000000) + req->k = 1; else - *k = 0; + req->k = 0; /* p will be 2 for divs under 20 and odd divs under 32 */ if (div < 20 || (div < 32 && (div & 1))) - *p = 2; + req->p = 2; /* p will be 1 for even divs under 32, divs under 40 and odd pairs * of divs between 40-62 */ else if (div < 40 || (div < 64 && (div & 2))) - *p = 1; + req->p = 1; /* any other entries have p = 0 */ else - *p = 0; + req->p = 0; /* calculate a suitable n based on k and p */ - div <<= *p; - div /= (*k + 1); - *n = div / 4 - 1; + div <<= req->p; + div /= (req->k + 1); + req->n = div / 4 - 1; } /** @@ -430,56 +206,55 @@ static void sun8i_a23_get_pll1_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_pll5_factors(struct factors_request *req) { u8 div; /* Normalize value to a parent_rate multiple (24M) */ - div = *freq / parent_rate; - *freq = parent_rate * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / req->parent_rate; + req->rate = req->parent_rate * div; if (div < 31) - *k = 0; + req->k = 0; else if (div / 2 < 31) - *k = 1; + req->k = 1; else if (div / 3 < 31) - *k = 2; + req->k = 2; else - *k = 3; + req->k = 3; - *n = DIV_ROUND_UP(div, (*k+1)); + req->n = DIV_ROUND_UP(div, (req->k + 1)); } /** - * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6x2 - * PLL6x2 rate is calculated as follows - * rate = parent_rate * (n + 1) * (k + 1) + * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6 + * PLL6 rate is calculated as follows + * rate = parent_rate * (n + 1) * (k + 1) / 2 * parent_rate is always 24Mhz */ -static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun6i_a31_get_pll6_factors(struct factors_request *req) { u8 div; /* Normalize value to a parent_rate multiple (24M) */ - div = *freq / parent_rate; - *freq = parent_rate * div; + div = req->rate / (req->parent_rate / 2); + req->rate = (req->parent_rate / 2) * div; - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + req->k = div / 32; + if (req->k > 3) + req->k = 3; - *k = div / 32; - if (*k > 3) - *k = 3; + req->n = DIV_ROUND_UP(div, (req->k + 1)) - 1; +} + +static void sun6i_a31_pll6_recalc(struct factors_request *req) +{ + req->rate = req->parent_rate; - *n = DIV_ROUND_UP(div, (*k+1)) - 1; + req->rate *= req->n + 1; + req->rate *= req->k + 1; + req->rate /= 2; } /** @@ -488,37 +263,94 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, * rate = parent_rate >> p */ -static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun5i_a13_get_ahb_factors(struct factors_request *req) { u32 div; /* divide only */ - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; /* * user manual says valid speed is 8k ~ 276M, but tests show it * can work at speeds up to 300M, just after reparenting to pll6 */ - if (*freq < 8000) - *freq = 8000; - if (*freq > 300000000) - *freq = 300000000; + if (req->rate < 8000) + req->rate = 8000; + if (req->rate > 300000000) + req->rate = 300000000; - div = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); + div = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate)); /* p = 0 ~ 3 */ if (div > 3) div = 3; - *freq = parent_rate >> div; + req->rate = req->parent_rate >> div; - /* we were called to round the frequency, we can now return */ - if (p == NULL) - return; + req->p = div; +} + +#define SUN6I_AHB1_PARENT_PLL6 3 + +/** + * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB + * AHB rate is calculated as follows + * rate = parent_rate >> p + * + * if parent is pll6, then + * parent_rate = pll6 rate / (m + 1) + */ + +static void sun6i_get_ahb1_factors(struct factors_request *req) +{ + u8 div, calcp, calcm = 1; + + /* + * clock can only divide, so we will never be able to achieve + * frequencies higher than the parent frequency + */ + if (req->parent_rate && req->rate > req->parent_rate) + req->rate = req->parent_rate; + + div = DIV_ROUND_UP(req->parent_rate, req->rate); + + /* calculate pre-divider if parent is pll6 */ + if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) { + if (div < 4) + calcp = 0; + else if (div / 2 < 4) + calcp = 1; + else if (div / 4 < 4) + calcp = 2; + else + calcp = 3; - *p = div; + calcm = DIV_ROUND_UP(div, 1 << calcp); + } else { + calcp = __roundup_pow_of_two(div); + calcp = calcp > 3 ? 3 : calcp; + } + + req->rate = (req->parent_rate / calcm) >> calcp; + req->p = calcp; + req->m = calcm - 1; +} + +/** + * sun6i_ahb1_recalc() - calculates AHB clock rate from m, p factors and + * parent index + */ +static void sun6i_ahb1_recalc(struct factors_request *req) +{ + req->rate = req->parent_rate; + + /* apply pre-divider first if parent is pll6 */ + if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) + req->rate /= req->m + 1; + + /* clk divider */ + req->rate >>= req->p; } /** @@ -527,39 +359,34 @@ static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate, * rate = (parent_rate >> p) / (m + 1); */ -static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_apb1_factors(struct factors_request *req) { u8 calcm, calcp; + int div; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - parent_rate = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* Invalid rate! */ - if (parent_rate > 32) + if (div > 32) return; - if (parent_rate <= 4) + if (div <= 4) calcp = 0; - else if (parent_rate <= 8) + else if (div <= 8) calcp = 1; - else if (parent_rate <= 16) + else if (div <= 16) calcp = 2; else calcp = 3; - calcm = (parent_rate >> calcp) - 1; + calcm = (req->parent_rate >> calcp) - 1; - *freq = (parent_rate >> calcp) / (calcm + 1); - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / (calcm + 1); + req->m = calcm; + req->p = calcp; } @@ -571,17 +398,16 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, * rate = (parent_rate >> p) / (m + 1); */ -static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun7i_a20_get_out_factors(struct factors_request *req) { u8 div, calcm, calcp; /* These clocks can only divide, so we will never be able to achieve * frequencies higher than the parent frequency */ - if (*freq > parent_rate) - *freq = parent_rate; + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); if (div < 32) calcp = 0; @@ -594,21 +420,16 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, calcm = DIV_ROUND_UP(div, 1 << calcp); - *freq = (parent_rate >> calcp) / calcm; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm - 1; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / calcm; + req->m = calcm - 1; + req->p = calcp; } /** * sunxi_factors_clk_setup() - Setup function for factor clocks */ -static struct clk_factors_config sun4i_pll1_config = { +static const struct clk_factors_config sun4i_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -619,7 +440,7 @@ static struct clk_factors_config sun4i_pll1_config = { .pwidth = 2, }; -static struct clk_factors_config sun6i_a31_pll1_config = { +static const struct clk_factors_config sun6i_a31_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -629,7 +450,7 @@ static struct clk_factors_config sun6i_a31_pll1_config = { .n_start = 1, }; -static struct clk_factors_config sun8i_a23_pll1_config = { +static const struct clk_factors_config sun8i_a23_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -641,14 +462,14 @@ static struct clk_factors_config sun8i_a23_pll1_config = { .n_start = 1, }; -static struct clk_factors_config sun4i_pll5_config = { +static const struct clk_factors_config sun4i_pll5_config = { .nshift = 8, .nwidth = 5, .kshift = 4, .kwidth = 2, }; -static struct clk_factors_config sun6i_a31_pll6_config = { +static const struct clk_factors_config sun6i_a31_pll6_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -656,12 +477,19 @@ static struct clk_factors_config sun6i_a31_pll6_config = { .n_start = 1, }; -static struct clk_factors_config sun5i_a13_ahb_config = { +static const struct clk_factors_config sun5i_a13_ahb_config = { + .pshift = 4, + .pwidth = 2, +}; + +static const struct clk_factors_config sun6i_ahb1_config = { + .mshift = 6, + .mwidth = 2, .pshift = 4, .pwidth = 2, }; -static struct clk_factors_config sun4i_apb1_config = { +static const struct clk_factors_config sun4i_apb1_config = { .mshift = 0, .mwidth = 5, .pshift = 16, @@ -669,7 +497,7 @@ static struct clk_factors_config sun4i_apb1_config = { }; /* user manual says "n" but it's really "p" */ -static struct clk_factors_config sun7i_a20_out_config = { +static const struct clk_factors_config sun7i_a20_out_config = { .mshift = 8, .mwidth = 5, .pshift = 20, @@ -718,7 +546,7 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = { .enable = 31, .table = &sun6i_a31_pll6_config, .getter = sun6i_a31_get_pll6_factors, - .name = "pll6x2", + .recalc = sun6i_a31_pll6_recalc, }; static const struct factors_data sun5i_a13_ahb_data __initconst = { @@ -728,6 +556,14 @@ static const struct factors_data sun5i_a13_ahb_data __initconst = { .getter = sun5i_a13_get_ahb_factors, }; +static const struct factors_data sun6i_ahb1_data __initconst = { + .mux = 12, + .muxmask = BIT(1) | BIT(0), + .table = &sun6i_ahb1_config, + .getter = sun6i_get_ahb1_factors, + .recalc = sun6i_ahb1_recalc, +}; + static const struct factors_data sun4i_apb1_data __initconst = { .mux = 24, .muxmask = BIT(1) | BIT(0), @@ -758,6 +594,68 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, return sunxi_factors_register(node, data, &clk_lock, reg); } +static void __init sun4i_pll1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun4i_pll1_data); +} +CLK_OF_DECLARE(sun4i_pll1, "allwinner,sun4i-a10-pll1-clk", + sun4i_pll1_clk_setup); + +static void __init sun6i_pll1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun6i_a31_pll1_data); +} +CLK_OF_DECLARE(sun6i_pll1, "allwinner,sun6i-a31-pll1-clk", + sun6i_pll1_clk_setup); + +static void __init sun8i_pll1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun8i_a23_pll1_data); +} +CLK_OF_DECLARE(sun8i_pll1, "allwinner,sun8i-a23-pll1-clk", + sun8i_pll1_clk_setup); + +static void __init sun7i_pll4_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun7i_a20_pll4_data); +} +CLK_OF_DECLARE(sun7i_pll4, "allwinner,sun7i-a20-pll4-clk", + sun7i_pll4_clk_setup); + +static void __init sun6i_pll6_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun6i_a31_pll6_data); +} +CLK_OF_DECLARE(sun6i_pll6, "allwinner,sun6i-a31-pll6-clk", + sun6i_pll6_clk_setup); + +static void __init sun5i_ahb_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun5i_a13_ahb_data); +} +CLK_OF_DECLARE(sun5i_ahb, "allwinner,sun5i-a13-ahb-clk", + sun5i_ahb_clk_setup); + +static void __init sun6i_ahb1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun6i_ahb1_data); +} +CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", + sun6i_ahb1_clk_setup); + +static void __init sun4i_apb1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun4i_apb1_data); +} +CLK_OF_DECLARE(sun4i_apb1, "allwinner,sun4i-a10-apb1-clk", + sun4i_apb1_clk_setup); + +static void __init sun7i_out_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun7i_a20_out_data); +} +CLK_OF_DECLARE(sun7i_out, "allwinner,sun7i-a20-out-clk", + sun7i_out_clk_setup); /** @@ -782,8 +680,8 @@ static const struct mux_data sun8i_h3_ahb2_mux_data __initconst = { .shift = 0, }; -static void __init sunxi_mux_clk_setup(struct device_node *node, - struct mux_data *data) +static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, + const struct mux_data *data) { struct clk *clk; const char *clk_name = node->name; @@ -794,19 +692,60 @@ static void __init sunxi_mux_clk_setup(struct device_node *node, reg = of_iomap(node, 0); i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); - of_property_read_string(node, "clock-output-names", &clk_name); + if (of_property_read_string(node, "clock-output-names", &clk_name)) { + pr_warn("%s: could not read clock-output-names for \"%s\"\n", + __func__, clk_name); + goto out_unmap; + } clk = clk_register_mux(NULL, clk_name, parents, i, CLK_SET_RATE_PARENT, reg, data->shift, SUNXI_MUX_GATE_WIDTH, 0, &clk_lock); - if (clk) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); + if (IS_ERR(clk)) { + pr_warn("%s: failed to register mux clock %s: %ld\n", __func__, + clk_name, PTR_ERR(clk)); + goto out_unmap; } + + of_clk_add_provider(node, of_clk_src_simple_get, clk); + + return clk; + +out_unmap: + iounmap(reg); + return NULL; } +static void __init sun4i_cpu_clk_setup(struct device_node *node) +{ + struct clk *clk; + + clk = sunxi_mux_clk_setup(node, &sun4i_cpu_mux_data); + if (!clk) + return; + + /* Protect CPU clock */ + __clk_get(clk); + clk_prepare_enable(clk); +} +CLK_OF_DECLARE(sun4i_cpu, "allwinner,sun4i-a10-cpu-clk", + sun4i_cpu_clk_setup); + +static void __init sun6i_ahb1_mux_clk_setup(struct device_node *node) +{ + sunxi_mux_clk_setup(node, &sun6i_a31_ahb1_mux_data); +} +CLK_OF_DECLARE(sun6i_ahb1_mux, "allwinner,sun6i-a31-ahb1-mux-clk", + sun6i_ahb1_mux_clk_setup); + +static void __init sun8i_ahb2_clk_setup(struct device_node *node) +{ + sunxi_mux_clk_setup(node, &sun8i_h3_ahb2_mux_data); +} +CLK_OF_DECLARE(sun8i_ahb2, "allwinner,sun8i-h3-ahb2-clk", + sun8i_ahb2_clk_setup); /** @@ -865,7 +804,7 @@ static const struct div_data sun4i_apb0_data __initconst = { }; static void __init sunxi_divider_clk_setup(struct device_node *node, - struct div_data *data) + const struct div_data *data) { struct clk *clk; const char *clk_name = node->name; @@ -882,12 +821,38 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, reg, data->shift, data->width, data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, data->table, &clk_lock); - if (clk) { + if (clk) of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } } +static void __init sun4i_ahb_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun4i_ahb_data); +} +CLK_OF_DECLARE(sun4i_ahb, "allwinner,sun4i-a10-ahb-clk", + sun4i_ahb_clk_setup); + +static void __init sun4i_apb0_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun4i_apb0_data); +} +CLK_OF_DECLARE(sun4i_apb0, "allwinner,sun4i-a10-apb0-clk", + sun4i_apb0_clk_setup); + +static void __init sun4i_axi_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun4i_axi_data); +} +CLK_OF_DECLARE(sun4i_axi, "allwinner,sun4i-a10-axi-clk", + sun4i_axi_clk_setup); + +static void __init sun8i_axi_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun8i_a23_axi_data); +} +CLK_OF_DECLARE(sun8i_axi, "allwinner,sun8i-a23-axi-clk", + sun8i_axi_clk_setup); + /** @@ -955,15 +920,6 @@ static const struct divs_data pll6_divs_data __initconst = { } }; -static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { - .factors = &sun6i_a31_pll6_data, - .ndivs = 2, - .div = { - { .fixed = 2 }, /* normal output */ - { .self = 1 }, /* base factor clock, 2x */ - } -}; - /** * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks * @@ -975,8 +931,8 @@ static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { * |________________________| */ -static void __init sunxi_divs_clk_setup(struct device_node *node, - struct divs_data *data) +static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, + const struct divs_data *data) { struct clk_onecell_data *clk_data; const char *parent; @@ -1003,7 +959,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); if (!clk_data) - return; + return NULL; clks = kcalloc(ndivs, sizeof(*clks), GFP_KERNEL); if (!clks) @@ -1081,7 +1037,6 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, clkflags); WARN_ON(IS_ERR(clk_data->clks[i])); - clk_register_clkdev(clks[i], clk_name, NULL); } /* Adjust to the real max */ @@ -1089,7 +1044,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); - return; + return clks; free_gate: kfree(gate); @@ -1097,130 +1052,28 @@ free_clks: kfree(clks); free_clkdata: kfree(clk_data); + return NULL; } - - -/* Matches for factors clocks */ -static const struct of_device_id clk_factors_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-pll1-clk", .data = &sun4i_pll1_data,}, - {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, - {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, - {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, - {.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,}, - {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, - {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, - {} -}; - -/* Matches for divider clocks */ -static const struct of_device_id clk_div_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-axi-clk", .data = &sun4i_axi_data,}, - {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,}, - {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, - {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, - {} -}; - -/* Matches for divided outputs */ -static const struct of_device_id clk_divs_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, - {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,}, - {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_divs_data,}, - {} -}; - -/* Matches for mux clocks */ -static const struct of_device_id clk_mux_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, - {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, - {.compatible = "allwinner,sun8i-h3-ahb2-clk", .data = &sun8i_h3_ahb2_mux_data,}, - {} -}; - - -static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_match, - void *function) -{ - struct device_node *np; - const struct div_data *data; - const struct of_device_id *match; - void (*setup_function)(struct device_node *, const void *) = function; - - for_each_matching_node_and_match(np, clk_match, &match) { - data = match->data; - setup_function(np, data); - } -} - -static void __init sunxi_init_clocks(const char *clocks[], int nclocks) -{ - unsigned int i; - - /* Register divided output clocks */ - of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup); - - /* Register factor clocks */ - of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup); - - /* Register divider clocks */ - of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup); - - /* Register mux clocks */ - of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup); - - /* Protect the clocks that needs to stay on */ - for (i = 0; i < nclocks; i++) { - struct clk *clk = clk_get(NULL, clocks[i]); - - if (!IS_ERR(clk)) - clk_prepare_enable(clk); - } -} - -static const char *sun4i_a10_critical_clocks[] __initdata = { - "pll5_ddr", -}; - -static void __init sun4i_a10_init_clocks(struct device_node *node) +static void __init sun4i_pll5_clk_setup(struct device_node *node) { - sunxi_init_clocks(sun4i_a10_critical_clocks, - ARRAY_SIZE(sun4i_a10_critical_clocks)); -} -CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks); + struct clk **clks; -static const char *sun5i_critical_clocks[] __initdata = { - "cpu", - "pll5_ddr", -}; + clks = sunxi_divs_clk_setup(node, &pll5_divs_data); + if (!clks) + return; -static void __init sun5i_init_clocks(struct device_node *node) -{ - sunxi_init_clocks(sun5i_critical_clocks, - ARRAY_SIZE(sun5i_critical_clocks)); + /* Protect PLL5_DDR */ + __clk_get(clks[0]); + clk_prepare_enable(clks[0]); } -CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sun5i_init_clocks); -CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sun5i_init_clocks); -CLK_OF_DECLARE(sun5i_r8_clk_init, "allwinner,sun5i-r8", sun5i_init_clocks); -CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sun5i_init_clocks); +CLK_OF_DECLARE(sun4i_pll5, "allwinner,sun4i-a10-pll5-clk", + sun4i_pll5_clk_setup); -static const char *sun6i_critical_clocks[] __initdata = { - "cpu", -}; - -static void __init sun6i_init_clocks(struct device_node *node) +static void __init sun4i_pll6_clk_setup(struct device_node *node) { - sunxi_init_clocks(sun6i_critical_clocks, - ARRAY_SIZE(sun6i_critical_clocks)); + sunxi_divs_clk_setup(node, &pll6_divs_data); } -CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); -CLK_OF_DECLARE(sun6i_a31s_clk_init, "allwinner,sun6i-a31s", sun6i_init_clocks); -CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks); -CLK_OF_DECLARE(sun8i_a33_clk_init, "allwinner,sun8i-a33", sun6i_init_clocks); -CLK_OF_DECLARE(sun8i_h3_clk_init, "allwinner,sun8i-h3", sun6i_init_clocks); +CLK_OF_DECLARE(sun4i_pll6, "allwinner,sun4i-a10-pll6-clk", + sun4i_pll6_clk_setup); -static void __init sun9i_init_clocks(struct device_node *node) -{ - sunxi_init_clocks(NULL, 0); -} -CLK_OF_DECLARE(sun9i_a80_clk_init, "allwinner,sun9i-a80", sun9i_init_clocks); diff --git a/drivers/clk/sunxi/clk-usb.c b/drivers/clk/sunxi/clk-usb.c index 67b8e38f4ee9..5432b1c198a4 100644 --- a/drivers/clk/sunxi/clk-usb.c +++ b/drivers/clk/sunxi/clk-usb.c @@ -216,6 +216,18 @@ static void __init sun8i_a23_usb_setup(struct device_node *node) } CLK_OF_DECLARE(sun8i_a23_usb, "allwinner,sun8i-a23-usb-clk", sun8i_a23_usb_setup); +static const struct usb_clk_data sun8i_h3_usb_clk_data __initconst = { + .clk_mask = BIT(19) | BIT(18) | BIT(17) | BIT(16) | + BIT(11) | BIT(10) | BIT(9) | BIT(8), + .reset_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), +}; + +static void __init sun8i_h3_usb_setup(struct device_node *node) +{ + sunxi_usb_clk_setup(node, &sun8i_h3_usb_clk_data, &sun4i_a10_usb_lock); +} +CLK_OF_DECLARE(sun8i_h3_usb, "allwinner,sun8i-h3-usb-clk", sun8i_h3_usb_setup); + static const struct usb_clk_data sun9i_a80_usb_mod_data __initconst = { .clk_mask = BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1), .reset_mask = BIT(19) | BIT(18) | BIT(17), @@ -243,15 +255,3 @@ static void __init sun9i_a80_usb_phy_setup(struct device_node *node) sunxi_usb_clk_setup(node, &sun9i_a80_usb_phy_data, &a80_usb_phy_lock); } CLK_OF_DECLARE(sun9i_a80_usb_phy, "allwinner,sun9i-a80-usb-phy-clk", sun9i_a80_usb_phy_setup); - -static const struct usb_clk_data sun8i_h3_usb_clk_data __initconst = { - .clk_mask = BIT(19) | BIT(18) | BIT(17) | BIT(16) | - BIT(11) | BIT(10) | BIT(9) | BIT(8), - .reset_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), -}; - -static void __init sun8i_h3_usb_setup(struct device_node *node) -{ - sunxi_usb_clk_setup(node, &sun8i_h3_usb_clk_data, &sun4i_a10_usb_lock); -} -CLK_OF_DECLARE(sun8i_h3_usb, "allwinner,sun8i-h3-usb-clk", sun8i_h3_usb_setup); diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c index e1fe8f35d45c..74e7544f861b 100644 --- a/drivers/clk/tegra/clk-emc.c +++ b/drivers/clk/tegra/clk-emc.c @@ -450,8 +450,10 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra, struct emc_timing *timing = tegra->timings + (i++); err = load_one_timing_from_dt(tegra, timing, child); - if (err) + if (err) { + of_node_put(child); return err; + } timing->ram_code = ram_code; } @@ -499,9 +501,9 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np, * fuses until the apbmisc driver is loaded. */ err = load_timings_from_dt(tegra, node, node_ram_code); + of_node_put(node); if (err) return ERR_PTR(err); - of_node_put(node); break; } diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index 19ce0738ee76..62ea38187b71 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h @@ -11,6 +11,7 @@ enum clk_id { tegra_clk_afi, tegra_clk_amx, tegra_clk_amx1, + tegra_clk_apb2ape, tegra_clk_apbdma, tegra_clk_apbif, tegra_clk_ape, diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index a534bfab30b3..6ac3f843e7ca 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -86,15 +86,21 @@ #define PLLE_SS_DISABLE (PLLE_SS_CNTL_BYPASS_SS | PLLE_SS_CNTL_INTERP_RESET |\ PLLE_SS_CNTL_SSC_BYP) #define PLLE_SS_MAX_MASK 0x1ff -#define PLLE_SS_MAX_VAL 0x25 +#define PLLE_SS_MAX_VAL_TEGRA114 0x25 +#define PLLE_SS_MAX_VAL_TEGRA210 0x21 #define PLLE_SS_INC_MASK (0xff << 16) #define PLLE_SS_INC_VAL (0x1 << 16) #define PLLE_SS_INCINTRV_MASK (0x3f << 24) -#define PLLE_SS_INCINTRV_VAL (0x20 << 24) +#define PLLE_SS_INCINTRV_VAL_TEGRA114 (0x20 << 24) +#define PLLE_SS_INCINTRV_VAL_TEGRA210 (0x23 << 24) #define PLLE_SS_COEFFICIENTS_MASK \ (PLLE_SS_MAX_MASK | PLLE_SS_INC_MASK | PLLE_SS_INCINTRV_MASK) -#define PLLE_SS_COEFFICIENTS_VAL \ - (PLLE_SS_MAX_VAL | PLLE_SS_INC_VAL | PLLE_SS_INCINTRV_VAL) +#define PLLE_SS_COEFFICIENTS_VAL_TEGRA114 \ + (PLLE_SS_MAX_VAL_TEGRA114 | PLLE_SS_INC_VAL |\ + PLLE_SS_INCINTRV_VAL_TEGRA114) +#define PLLE_SS_COEFFICIENTS_VAL_TEGRA210 \ + (PLLE_SS_MAX_VAL_TEGRA210 | PLLE_SS_INC_VAL |\ + PLLE_SS_INCINTRV_VAL_TEGRA210) #define PLLE_AUX_PLLP_SEL BIT(2) #define PLLE_AUX_USE_LOCKDET BIT(3) @@ -880,7 +886,7 @@ static int clk_plle_training(struct tegra_clk_pll *pll) static int clk_plle_enable(struct clk_hw *hw) { struct tegra_clk_pll *pll = to_clk_pll(hw); - unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); + unsigned long input_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); struct tegra_clk_pll_freq_table sel; u32 val; int err; @@ -1378,7 +1384,7 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) u32 val; int ret; unsigned long flags = 0; - unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); + unsigned long input_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) return -EINVAL; @@ -1401,7 +1407,7 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) val |= PLLE_MISC_IDDQ_SW_CTRL; val &= ~PLLE_MISC_IDDQ_SW_VALUE; val |= PLLE_MISC_PLLE_PTS; - val |= PLLE_MISC_VREG_BG_CTRL_MASK | PLLE_MISC_VREG_CTRL_MASK; + val &= ~(PLLE_MISC_VREG_BG_CTRL_MASK | PLLE_MISC_VREG_CTRL_MASK); pll_writel_misc(val, pll); udelay(5); @@ -1428,7 +1434,7 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) val = pll_readl(PLLE_SS_CTRL, pll); val &= ~(PLLE_SS_CNTL_CENTER | PLLE_SS_CNTL_INVERT); val &= ~PLLE_SS_COEFFICIENTS_MASK; - val |= PLLE_SS_COEFFICIENTS_VAL; + val |= PLLE_SS_COEFFICIENTS_VAL_TEGRA114; pll_writel(val, PLLE_SS_CTRL, pll); val &= ~(PLLE_SS_CNTL_SSC_BYP | PLLE_SS_CNTL_BYPASS_SS); pll_writel(val, PLLE_SS_CTRL, pll); @@ -2012,9 +2018,9 @@ static int clk_plle_tegra210_enable(struct clk_hw *hw) struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table sel; u32 val; - int ret; + int ret = 0; unsigned long flags = 0; - unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); + unsigned long input_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) return -EINVAL; @@ -2022,22 +2028,20 @@ static int clk_plle_tegra210_enable(struct clk_hw *hw) if (pll->lock) spin_lock_irqsave(pll->lock, flags); + val = pll_readl(pll->params->aux_reg, pll); + if (val & PLLE_AUX_SEQ_ENABLE) + goto out; + val = pll_readl_base(pll); val &= ~BIT(30); /* Disable lock override */ pll_writel_base(val, pll); - val = pll_readl(pll->params->aux_reg, pll); - val |= PLLE_AUX_ENABLE_SWCTL; - val &= ~PLLE_AUX_SEQ_ENABLE; - pll_writel(val, pll->params->aux_reg, pll); - udelay(1); - val = pll_readl_misc(pll); val |= PLLE_MISC_LOCK_ENABLE; val |= PLLE_MISC_IDDQ_SW_CTRL; val &= ~PLLE_MISC_IDDQ_SW_VALUE; val |= PLLE_MISC_PLLE_PTS; - val |= PLLE_MISC_VREG_BG_CTRL_MASK | PLLE_MISC_VREG_CTRL_MASK; + val &= ~(PLLE_MISC_VREG_BG_CTRL_MASK | PLLE_MISC_VREG_CTRL_MASK); pll_writel_misc(val, pll); udelay(5); @@ -2067,7 +2071,7 @@ static int clk_plle_tegra210_enable(struct clk_hw *hw) val = pll_readl(PLLE_SS_CTRL, pll); val &= ~(PLLE_SS_CNTL_CENTER | PLLE_SS_CNTL_INVERT); val &= ~PLLE_SS_COEFFICIENTS_MASK; - val |= PLLE_SS_COEFFICIENTS_VAL; + val |= PLLE_SS_COEFFICIENTS_VAL_TEGRA210; pll_writel(val, PLLE_SS_CTRL, pll); val &= ~(PLLE_SS_CNTL_SSC_BYP | PLLE_SS_CNTL_BYPASS_SS); pll_writel(val, PLLE_SS_CTRL, pll); @@ -2104,15 +2108,25 @@ static void clk_plle_tegra210_disable(struct clk_hw *hw) if (pll->lock) spin_lock_irqsave(pll->lock, flags); + /* If PLLE HW sequencer is enabled, SW should not disable PLLE */ + val = pll_readl(pll->params->aux_reg, pll); + if (val & PLLE_AUX_SEQ_ENABLE) + goto out; + val = pll_readl_base(pll); val &= ~PLLE_BASE_ENABLE; pll_writel_base(val, pll); + val = pll_readl(pll->params->aux_reg, pll); + val |= PLLE_AUX_ENABLE_SWCTL | PLLE_AUX_SS_SWCTL; + pll_writel(val, pll->params->aux_reg, pll); + val = pll_readl_misc(pll); val |= PLLE_MISC_IDDQ_SW_CTRL | PLLE_MISC_IDDQ_SW_VALUE; pll_writel_misc(val, pll); udelay(1); +out: if (pll->lock) spin_unlock_irqrestore(pll->lock, flags); } diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index 6ad381a888a6..ea2b9cbf9e70 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -773,7 +773,7 @@ static struct tegra_periph_init_data periph_clks[] = { XUSB("xusb_dev_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_dev_src), XUSB("xusb_dev_src", mux_clkm_pllp_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_dev_src_8), MUX8("dbgapb", mux_pllp_clkm_2, CLK_SOURCE_DBGAPB, 185, TEGRA_PERIPH_NO_RESET, tegra_clk_dbgapb), - MUX8("msenc", mux_pllc2_c_c3_pllp_plla1_clkm, CLK_SOURCE_NVENC, 219, 0, tegra_clk_nvenc), + MUX8("nvenc", mux_pllc2_c_c3_pllp_plla1_clkm, CLK_SOURCE_NVENC, 219, 0, tegra_clk_nvenc), MUX8("nvdec", mux_pllc2_c_c3_pllp_plla1_clkm, CLK_SOURCE_NVDEC, 194, 0, tegra_clk_nvdec), MUX8("nvjpg", mux_pllc2_c_c3_pllp_plla1_clkm, CLK_SOURCE_NVJPG, 195, 0, tegra_clk_nvjpg), MUX8("ape", mux_plla_pllc4_out0_pllc_pllc4_out1_pllp_pllc4_out2_clkm, CLK_SOURCE_APE, 198, TEGRA_PERIPH_ON_APB, tegra_clk_ape), @@ -782,7 +782,7 @@ static struct tegra_periph_init_data periph_clks[] = { NODIV("sor1", mux_clkm_sor1_brick_sor1_src, CLK_SOURCE_SOR1, 15, MASK(1), 183, 0, tegra_clk_sor1, &sor1_lock), MUX8("sdmmc_legacy", mux_pllp_out3_clkm_pllp_pllc4, CLK_SOURCE_SDMMC_LEGACY, 193, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_sdmmc_legacy), MUX8("qspi", mux_pllp_pllc_pllc_out1_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_QSPI, 211, TEGRA_PERIPH_ON_APB, tegra_clk_qspi), - MUX("vii2c", mux_pllp_pllc_clkm, CLK_SOURCE_VI_I2C, 208, TEGRA_PERIPH_ON_APB, tegra_clk_vi_i2c), + I2C("vii2c", mux_pllp_pllc_clkm, CLK_SOURCE_VI_I2C, 208, tegra_clk_vi_i2c), MUX("mipibif", mux_pllp_clkm, CLK_SOURCE_MIPIBIF, 173, TEGRA_PERIPH_ON_APB, tegra_clk_mipibif), MUX("uartape", mux_pllp_pllc_clkm, CLK_SOURCE_UARTAPE, 212, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_uartape), MUX8("tsecb", mux_pllp_pllc2_c_c3_clkm, CLK_SOURCE_TSECB, 206, 0, tegra_clk_tsecb), @@ -829,6 +829,7 @@ static struct tegra_periph_init_data gate_clks[] = { GATE("xusb_gate", "osc", 143, 0, tegra_clk_xusb_gate, 0), GATE("pll_p_out_cpu", "pll_p", 223, 0, tegra_clk_pll_p_out_cpu, 0), GATE("pll_p_out_adsp", "pll_p", 187, 0, tegra_clk_pll_p_out_adsp, 0), + GATE("apb2ape", "clk_m", 107, 0, tegra_clk_apb2ape, 0), }; static struct tegra_periph_init_data div_clks[] = { diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c index 4559a20e3af6..474de0f0c26d 100644 --- a/drivers/clk/tegra/clk-tegra-super-gen4.c +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c @@ -67,7 +67,7 @@ static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", "pll_p", "pll_p_out4", "unused", "unused", "pll_x", "pll_x_out0" }; -const struct tegra_super_gen_info tegra_super_gen_info_gen4 = { +static const struct tegra_super_gen_info tegra_super_gen_info_gen4 = { .gen = gen4, .sclk_parents = sclk_parents, .cclk_g_parents = cclk_g_parents, @@ -93,7 +93,7 @@ static const char *cclk_lp_parents_gen5[] = { "clk_m", "unused", "clk_32k", "unu "unused", "unused", "unused", "unused", "dfllCPU_out" }; -const struct tegra_super_gen_info tegra_super_gen_info_gen5 = { +static const struct tegra_super_gen_info tegra_super_gen_info_gen5 = { .gen = gen5, .sclk_parents = sclk_parents_gen5, .cclk_g_parents = cclk_g_parents_gen5, @@ -171,7 +171,7 @@ static void __init tegra_sclk_init(void __iomem *clk_base, *dt_clk = clk; } -void __init tegra_super_clk_init(void __iomem *clk_base, +static void __init tegra_super_clk_init(void __iomem *clk_base, void __iomem *pmc_base, struct tegra_clk *tegra_clks, struct tegra_clk_pll_params *params, diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 58514c44ea83..637041fd53ad 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -59,8 +59,8 @@ #define PLLC3_MISC3 0x50c #define PLLM_BASE 0x90 -#define PLLM_MISC0 0x9c #define PLLM_MISC1 0x98 +#define PLLM_MISC2 0x9c #define PLLP_BASE 0xa0 #define PLLP_MISC0 0xac #define PLLP_MISC1 0x680 @@ -99,7 +99,7 @@ #define PLLC4_MISC0 0x5a8 #define PLLC4_OUT 0x5e4 #define PLLMB_BASE 0x5e8 -#define PLLMB_MISC0 0x5ec +#define PLLMB_MISC1 0x5ec #define PLLA1_BASE 0x6a4 #define PLLA1_MISC0 0x6a8 #define PLLA1_MISC1 0x6ac @@ -243,7 +243,8 @@ static unsigned long tegra210_input_freq[] = { }; static const char *mux_pllmcp_clkm[] = { - "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_c2", "pll_c3", + "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_mb", "pll_mb", + "pll_p", }; #define mux_pllmcp_clkm_idx NULL @@ -367,12 +368,12 @@ static const char *mux_pllmcp_clkm[] = { /* PLLMB */ #define PLLMB_BASE_LOCK (1 << 27) -#define PLLMB_MISC0_LOCK_OVERRIDE (1 << 18) -#define PLLMB_MISC0_IDDQ (1 << 17) -#define PLLMB_MISC0_LOCK_ENABLE (1 << 16) +#define PLLMB_MISC1_LOCK_OVERRIDE (1 << 18) +#define PLLMB_MISC1_IDDQ (1 << 17) +#define PLLMB_MISC1_LOCK_ENABLE (1 << 16) -#define PLLMB_MISC0_DEFAULT_VALUE 0x00030000 -#define PLLMB_MISC0_WRITE_MASK 0x0007ffff +#define PLLMB_MISC1_DEFAULT_VALUE 0x00030000 +#define PLLMB_MISC1_WRITE_MASK 0x0007ffff /* PLLP */ #define PLLP_BASE_OVERRIDE (1 << 28) @@ -457,7 +458,8 @@ static void pllcx_check_defaults(struct tegra_clk_pll_params *params) PLLCX_MISC3_WRITE_MASK); } -void tegra210_pllcx_set_defaults(const char *name, struct tegra_clk_pll *pllcx) +static void tegra210_pllcx_set_defaults(const char *name, + struct tegra_clk_pll *pllcx) { pllcx->params->defaults_set = true; @@ -482,22 +484,22 @@ void tegra210_pllcx_set_defaults(const char *name, struct tegra_clk_pll *pllcx) udelay(1); } -void _pllc_set_defaults(struct tegra_clk_pll *pllcx) +static void _pllc_set_defaults(struct tegra_clk_pll *pllcx) { tegra210_pllcx_set_defaults("PLL_C", pllcx); } -void _pllc2_set_defaults(struct tegra_clk_pll *pllcx) +static void _pllc2_set_defaults(struct tegra_clk_pll *pllcx) { tegra210_pllcx_set_defaults("PLL_C2", pllcx); } -void _pllc3_set_defaults(struct tegra_clk_pll *pllcx) +static void _pllc3_set_defaults(struct tegra_clk_pll *pllcx) { tegra210_pllcx_set_defaults("PLL_C3", pllcx); } -void _plla1_set_defaults(struct tegra_clk_pll *pllcx) +static void _plla1_set_defaults(struct tegra_clk_pll *pllcx) { tegra210_pllcx_set_defaults("PLL_A1", pllcx); } @@ -507,7 +509,7 @@ void _plla1_set_defaults(struct tegra_clk_pll *pllcx) * PLL with dynamic ramp and fractional SDM. Dynamic ramp is not used. * Fractional SDM is allowed to provide exact audio rates. */ -void tegra210_plla_set_defaults(struct tegra_clk_pll *plla) +static void tegra210_plla_set_defaults(struct tegra_clk_pll *plla) { u32 mask; u32 val = readl_relaxed(clk_base + plla->params->base_reg); @@ -559,7 +561,7 @@ void tegra210_plla_set_defaults(struct tegra_clk_pll *plla) * PLLD * PLL with fractional SDM. */ -void tegra210_plld_set_defaults(struct tegra_clk_pll *plld) +static void tegra210_plld_set_defaults(struct tegra_clk_pll *plld) { u32 val; u32 mask = 0xffff; @@ -698,7 +700,7 @@ static void plldss_defaults(const char *pll_name, struct tegra_clk_pll *plldss, udelay(1); } -void tegra210_plld2_set_defaults(struct tegra_clk_pll *plld2) +static void tegra210_plld2_set_defaults(struct tegra_clk_pll *plld2) { plldss_defaults("PLL_D2", plld2, PLLD2_MISC0_DEFAULT_VALUE, PLLD2_MISC1_CFG_DEFAULT_VALUE, @@ -706,7 +708,7 @@ void tegra210_plld2_set_defaults(struct tegra_clk_pll *plld2) PLLD2_MISC3_CTRL2_DEFAULT_VALUE); } -void tegra210_plldp_set_defaults(struct tegra_clk_pll *plldp) +static void tegra210_plldp_set_defaults(struct tegra_clk_pll *plldp) { plldss_defaults("PLL_DP", plldp, PLLDP_MISC0_DEFAULT_VALUE, PLLDP_MISC1_CFG_DEFAULT_VALUE, @@ -719,7 +721,7 @@ void tegra210_plldp_set_defaults(struct tegra_clk_pll *plldp) * Base and misc0 layout is the same as PLLD2/PLLDP, but no SDM/SSC support. * VCO is exposed to the clock tree via fixed 1/3 and 1/5 dividers. */ -void tegra210_pllc4_set_defaults(struct tegra_clk_pll *pllc4) +static void tegra210_pllc4_set_defaults(struct tegra_clk_pll *pllc4) { plldss_defaults("PLL_C4", pllc4, PLLC4_MISC0_DEFAULT_VALUE, 0, 0, 0); } @@ -728,7 +730,7 @@ void tegra210_pllc4_set_defaults(struct tegra_clk_pll *pllc4) * PLLRE * VCO is exposed to the clock tree directly along with post-divider output */ -void tegra210_pllre_set_defaults(struct tegra_clk_pll *pllre) +static void tegra210_pllre_set_defaults(struct tegra_clk_pll *pllre) { u32 mask; u32 val = readl_relaxed(clk_base + pllre->params->base_reg); @@ -780,13 +782,13 @@ static void pllx_get_dyn_steps(struct clk_hw *hw, u32 *step_a, u32 *step_b) { unsigned long input_rate; - if (!IS_ERR_OR_NULL(hw->clk)) { + /* cf rate */ + if (!IS_ERR_OR_NULL(hw->clk)) input_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); - /* cf rate */ - input_rate /= tegra_pll_get_fixed_mdiv(hw, input_rate); - } else { + else input_rate = 38400000; - } + + input_rate /= tegra_pll_get_fixed_mdiv(hw, input_rate); switch (input_rate) { case 12000000: @@ -841,7 +843,7 @@ static void pllx_check_defaults(struct tegra_clk_pll *pll) PLLX_MISC5_WRITE_MASK); } -void tegra210_pllx_set_defaults(struct tegra_clk_pll *pllx) +static void tegra210_pllx_set_defaults(struct tegra_clk_pll *pllx) { u32 val; u32 step_a, step_b; @@ -901,7 +903,7 @@ void tegra210_pllx_set_defaults(struct tegra_clk_pll *pllx) } /* PLLMB */ -void tegra210_pllmb_set_defaults(struct tegra_clk_pll *pllmb) +static void tegra210_pllmb_set_defaults(struct tegra_clk_pll *pllmb) { u32 mask, val = readl_relaxed(clk_base + pllmb->params->base_reg); @@ -914,15 +916,15 @@ void tegra210_pllmb_set_defaults(struct tegra_clk_pll *pllmb) * PLL is ON: check if defaults already set, then set those * that can be updated in flight. */ - val = PLLMB_MISC0_DEFAULT_VALUE & (~PLLMB_MISC0_IDDQ); - mask = PLLMB_MISC0_LOCK_ENABLE | PLLMB_MISC0_LOCK_OVERRIDE; + val = PLLMB_MISC1_DEFAULT_VALUE & (~PLLMB_MISC1_IDDQ); + mask = PLLMB_MISC1_LOCK_ENABLE | PLLMB_MISC1_LOCK_OVERRIDE; _pll_misc_chk_default(clk_base, pllmb->params, 0, val, - ~mask & PLLMB_MISC0_WRITE_MASK); + ~mask & PLLMB_MISC1_WRITE_MASK); /* Enable lock detect */ val = readl_relaxed(clk_base + pllmb->params->ext_misc_reg[0]); val &= ~mask; - val |= PLLMB_MISC0_DEFAULT_VALUE & mask; + val |= PLLMB_MISC1_DEFAULT_VALUE & mask; writel_relaxed(val, clk_base + pllmb->params->ext_misc_reg[0]); udelay(1); @@ -930,7 +932,7 @@ void tegra210_pllmb_set_defaults(struct tegra_clk_pll *pllmb) } /* set IDDQ, enable lock detect */ - writel_relaxed(PLLMB_MISC0_DEFAULT_VALUE, + writel_relaxed(PLLMB_MISC1_DEFAULT_VALUE, clk_base + pllmb->params->ext_misc_reg[0]); udelay(1); } @@ -960,7 +962,7 @@ static void pllp_check_defaults(struct tegra_clk_pll *pll, bool enabled) ~mask & PLLP_MISC1_WRITE_MASK); } -void tegra210_pllp_set_defaults(struct tegra_clk_pll *pllp) +static void tegra210_pllp_set_defaults(struct tegra_clk_pll *pllp) { u32 mask; u32 val = readl_relaxed(clk_base + pllp->params->base_reg); @@ -1022,7 +1024,7 @@ static void pllu_check_defaults(struct tegra_clk_pll *pll, bool hw_control) ~mask & PLLU_MISC1_WRITE_MASK); } -void tegra210_pllu_set_defaults(struct tegra_clk_pll *pllu) +static void tegra210_pllu_set_defaults(struct tegra_clk_pll *pllu) { u32 val = readl_relaxed(clk_base + pllu->params->base_reg); @@ -1212,8 +1214,9 @@ static void tegra210_clk_pll_set_gain(struct tegra_clk_pll_freq_table *cfg) cfg->m *= PLL_SDM_COEFF; } -unsigned long tegra210_clk_adjust_vco_min(struct tegra_clk_pll_params *params, - unsigned long parent_rate) +static unsigned long +tegra210_clk_adjust_vco_min(struct tegra_clk_pll_params *params, + unsigned long parent_rate) { unsigned long vco_min = params->vco_min; @@ -1386,7 +1389,7 @@ static struct tegra_clk_pll_params pll_c_params = { .mdiv_default = 3, .div_nmp = &pllc_nmp, .freq_table = pll_cx_freq_table, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK, .set_defaults = _pllc_set_defaults, .calc_rate = tegra210_pll_fixed_mdiv_cfg, }; @@ -1425,7 +1428,7 @@ static struct tegra_clk_pll_params pll_c2_params = { .ext_misc_reg[2] = PLLC2_MISC2, .ext_misc_reg[3] = PLLC2_MISC3, .freq_table = pll_cx_freq_table, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK, .set_defaults = _pllc2_set_defaults, .calc_rate = tegra210_pll_fixed_mdiv_cfg, }; @@ -1455,7 +1458,7 @@ static struct tegra_clk_pll_params pll_c3_params = { .ext_misc_reg[2] = PLLC3_MISC2, .ext_misc_reg[3] = PLLC3_MISC3, .freq_table = pll_cx_freq_table, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK, .set_defaults = _pllc3_set_defaults, .calc_rate = tegra210_pll_fixed_mdiv_cfg, }; @@ -1505,7 +1508,6 @@ static struct tegra_clk_pll_params pll_c4_vco_params = { .base_reg = PLLC4_BASE, .misc_reg = PLLC4_MISC0, .lock_mask = PLL_BASE_LOCK, - .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, .lock_delay = 300, .max_p = PLL_QLIN_PDIV_MAX, .ext_misc_reg[0] = PLLC4_MISC0, @@ -1517,8 +1519,7 @@ static struct tegra_clk_pll_params pll_c4_vco_params = { .div_nmp = &pllss_nmp, .freq_table = pll_c4_vco_freq_table, .set_defaults = tegra210_pllc4_set_defaults, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE | - TEGRA_PLL_VCO_OUT, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_VCO_OUT, .calc_rate = tegra210_pll_fixed_mdiv_cfg, }; @@ -1559,15 +1560,15 @@ static struct tegra_clk_pll_params pll_m_params = { .vco_min = 800000000, .vco_max = 1866000000, .base_reg = PLLM_BASE, - .misc_reg = PLLM_MISC1, + .misc_reg = PLLM_MISC2, .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLLM_MISC_LOCK_ENABLE, .lock_delay = 300, - .iddq_reg = PLLM_MISC0, + .iddq_reg = PLLM_MISC2, .iddq_bit_idx = PLLM_IDDQ_BIT, .max_p = PLL_QLIN_PDIV_MAX, - .ext_misc_reg[0] = PLLM_MISC0, - .ext_misc_reg[0] = PLLM_MISC1, + .ext_misc_reg[0] = PLLM_MISC2, + .ext_misc_reg[1] = PLLM_MISC1, .round_p_to_pdiv = pll_qlin_p_to_pdiv, .pdiv_tohw = pll_qlin_pdiv_to_hw, .div_nmp = &pllm_nmp, @@ -1586,19 +1587,18 @@ static struct tegra_clk_pll_params pll_mb_params = { .vco_min = 800000000, .vco_max = 1866000000, .base_reg = PLLMB_BASE, - .misc_reg = PLLMB_MISC0, + .misc_reg = PLLMB_MISC1, .lock_mask = PLL_BASE_LOCK, - .lock_enable_bit_idx = PLLMB_MISC_LOCK_ENABLE, .lock_delay = 300, - .iddq_reg = PLLMB_MISC0, + .iddq_reg = PLLMB_MISC1, .iddq_bit_idx = PLLMB_IDDQ_BIT, .max_p = PLL_QLIN_PDIV_MAX, - .ext_misc_reg[0] = PLLMB_MISC0, + .ext_misc_reg[0] = PLLMB_MISC1, .round_p_to_pdiv = pll_qlin_p_to_pdiv, .pdiv_tohw = pll_qlin_pdiv_to_hw, .div_nmp = &pllm_nmp, .freq_table = pll_m_freq_table, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK, .set_defaults = tegra210_pllmb_set_defaults, .calc_rate = tegra210_pll_fixed_mdiv_cfg, }; @@ -1671,7 +1671,6 @@ static struct tegra_clk_pll_params pll_re_vco_params = { .base_reg = PLLRE_BASE, .misc_reg = PLLRE_MISC0, .lock_mask = PLLRE_MISC_LOCK, - .lock_enable_bit_idx = PLLRE_MISC_LOCK_ENABLE, .lock_delay = 300, .max_p = PLL_QLIN_PDIV_MAX, .ext_misc_reg[0] = PLLRE_MISC0, @@ -1681,8 +1680,7 @@ static struct tegra_clk_pll_params pll_re_vco_params = { .pdiv_tohw = pll_qlin_pdiv_to_hw, .div_nmp = &pllre_nmp, .freq_table = pll_re_vco_freq_table, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_LOCK_MISC | - TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_VCO_OUT, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_LOCK_MISC | TEGRA_PLL_VCO_OUT, .set_defaults = tegra210_pllre_set_defaults, .calc_rate = tegra210_pll_fixed_mdiv_cfg, }; @@ -1712,7 +1710,6 @@ static struct tegra_clk_pll_params pll_p_params = { .base_reg = PLLP_BASE, .misc_reg = PLLP_MISC0, .lock_mask = PLL_BASE_LOCK, - .lock_enable_bit_idx = PLLP_MISC_LOCK_ENABLE, .lock_delay = 300, .iddq_reg = PLLP_MISC0, .iddq_bit_idx = PLLXP_IDDQ_BIT, @@ -1721,8 +1718,7 @@ static struct tegra_clk_pll_params pll_p_params = { .div_nmp = &pllp_nmp, .freq_table = pll_p_freq_table, .fixed_rate = 408000000, - .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK | - TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_VCO_OUT, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK | TEGRA_PLL_VCO_OUT, .set_defaults = tegra210_pllp_set_defaults, .calc_rate = tegra210_pll_fixed_mdiv_cfg, }; @@ -1750,7 +1746,7 @@ static struct tegra_clk_pll_params pll_a1_params = { .ext_misc_reg[2] = PLLA1_MISC2, .ext_misc_reg[3] = PLLA1_MISC3, .freq_table = pll_cx_freq_table, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK, .set_defaults = _plla1_set_defaults, .calc_rate = tegra210_pll_fixed_mdiv_cfg, }; @@ -1787,7 +1783,6 @@ static struct tegra_clk_pll_params pll_a_params = { .base_reg = PLLA_BASE, .misc_reg = PLLA_MISC0, .lock_mask = PLL_BASE_LOCK, - .lock_enable_bit_idx = PLLA_MISC_LOCK_ENABLE, .lock_delay = 300, .round_p_to_pdiv = pll_qlin_p_to_pdiv, .pdiv_tohw = pll_qlin_pdiv_to_hw, @@ -1802,8 +1797,7 @@ static struct tegra_clk_pll_params pll_a_params = { .ext_misc_reg[1] = PLLA_MISC1, .ext_misc_reg[2] = PLLA_MISC2, .freq_table = pll_a_freq_table, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_MDIV_NEW | - TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_MDIV_NEW, .set_defaults = tegra210_plla_set_defaults, .calc_rate = tegra210_pll_fixed_mdiv_cfg, .set_gain = tegra210_clk_pll_set_gain, @@ -1836,7 +1830,6 @@ static struct tegra_clk_pll_params pll_d_params = { .base_reg = PLLD_BASE, .misc_reg = PLLD_MISC0, .lock_mask = PLL_BASE_LOCK, - .lock_enable_bit_idx = PLLD_MISC_LOCK_ENABLE, .lock_delay = 1000, .iddq_reg = PLLD_MISC0, .iddq_bit_idx = PLLD_IDDQ_BIT, @@ -1850,7 +1843,7 @@ static struct tegra_clk_pll_params pll_d_params = { .ext_misc_reg[0] = PLLD_MISC0, .ext_misc_reg[1] = PLLD_MISC1, .freq_table = pll_d_freq_table, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK, .mdiv_default = 1, .set_defaults = tegra210_plld_set_defaults, .calc_rate = tegra210_pll_fixed_mdiv_cfg, @@ -1876,7 +1869,6 @@ static struct tegra_clk_pll_params pll_d2_params = { .base_reg = PLLD2_BASE, .misc_reg = PLLD2_MISC0, .lock_mask = PLL_BASE_LOCK, - .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, .lock_delay = 300, .iddq_reg = PLLD2_BASE, .iddq_bit_idx = PLLSS_IDDQ_BIT, @@ -1897,7 +1889,7 @@ static struct tegra_clk_pll_params pll_d2_params = { .mdiv_default = 1, .freq_table = tegra210_pll_d2_freq_table, .set_defaults = tegra210_plld2_set_defaults, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK, .calc_rate = tegra210_pll_fixed_mdiv_cfg, .set_gain = tegra210_clk_pll_set_gain, .adjust_vco = tegra210_clk_adjust_vco_min, @@ -1920,7 +1912,6 @@ static struct tegra_clk_pll_params pll_dp_params = { .base_reg = PLLDP_BASE, .misc_reg = PLLDP_MISC, .lock_mask = PLL_BASE_LOCK, - .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, .lock_delay = 300, .iddq_reg = PLLDP_BASE, .iddq_bit_idx = PLLSS_IDDQ_BIT, @@ -1941,7 +1932,7 @@ static struct tegra_clk_pll_params pll_dp_params = { .mdiv_default = 1, .freq_table = pll_dp_freq_table, .set_defaults = tegra210_plldp_set_defaults, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK, .calc_rate = tegra210_pll_fixed_mdiv_cfg, .set_gain = tegra210_clk_pll_set_gain, .adjust_vco = tegra210_clk_adjust_vco_min, @@ -1973,7 +1964,6 @@ static struct tegra_clk_pll_params pll_u_vco_params = { .base_reg = PLLU_BASE, .misc_reg = PLLU_MISC0, .lock_mask = PLL_BASE_LOCK, - .lock_enable_bit_idx = PLLU_MISC_LOCK_ENABLE, .lock_delay = 1000, .iddq_reg = PLLU_MISC0, .iddq_bit_idx = PLLU_IDDQ_BIT, @@ -1983,8 +1973,7 @@ static struct tegra_clk_pll_params pll_u_vco_params = { .pdiv_tohw = pll_qlin_pdiv_to_hw, .div_nmp = &pllu_nmp, .freq_table = pll_u_freq_table, - .flags = TEGRA_PLLU | TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE | - TEGRA_PLL_VCO_OUT, + .flags = TEGRA_PLLU | TEGRA_PLL_USE_LOCK | TEGRA_PLL_VCO_OUT, .set_defaults = tegra210_pllu_set_defaults, .calc_rate = tegra210_pll_fixed_mdiv_cfg, }; @@ -2218,6 +2207,7 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_pll_c4_out1] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT1, .present = true }, [tegra_clk_pll_c4_out2] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT2, .present = true }, [tegra_clk_pll_c4_out3] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT3, .present = true }, + [tegra_clk_apb2ape] = { .dt_id = TEGRA210_CLK_APB2APE, .present = true }, }; static struct tegra_devclk devclks[] __initdata = { @@ -2519,7 +2509,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base, /* PLLU_VCO */ val = readl(clk_base + pll_u_vco_params.base_reg); - val &= ~BIT(24); /* disable PLLU_OVERRIDE */ + val &= ~PLLU_BASE_OVERRIDE; /* disable PLLU_OVERRIDE */ writel(val, clk_base + pll_u_vco_params.base_reg); clk = tegra_clk_register_pllre("pll_u_vco", "pll_ref", clk_base, pmc, @@ -2738,8 +2728,6 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, { TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 672000000, 1 }, - { TEGRA210_CLK_PLL_U_OUT1, TEGRA210_CLK_CLK_MAX, 48000000, 1 }, - { TEGRA210_CLK_PLL_U_OUT2, TEGRA210_CLK_CLK_MAX, 60000000, 1 }, { TEGRA210_CLK_XUSB_GATE, TEGRA210_CLK_CLK_MAX, 0, 1 }, { TEGRA210_CLK_XUSB_SS_SRC, TEGRA210_CLK_PLL_U_480M, 120000000, 0 }, { TEGRA210_CLK_XUSB_FS_SRC, TEGRA210_CLK_PLL_U_48M, 48000000, 0 }, diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 56777f04d2d9..33db7406c0e2 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -30,6 +30,8 @@ config CLKSRC_MMIO config DIGICOLOR_TIMER bool "Digicolor timer driver" if COMPILE_TEST depends on GENERIC_CLOCKEVENTS + select CLKSRC_MMIO + depends on HAS_IOMEM help Enables the support for the digicolor timer driver. @@ -55,6 +57,7 @@ config ARMADA_370_XP_TIMER bool "Armada 370 and XP timer driver" if COMPILE_TEST depends on ARM select CLKSRC_OF + select CLKSRC_MMIO help Enables the support for the Armada 370 and XP timer driver. @@ -76,6 +79,7 @@ config ORION_TIMER config SUN4I_TIMER bool "Sun4i timer driver" if COMPILE_TEST depends on GENERIC_CLOCKEVENTS + depends on HAS_IOMEM select CLKSRC_MMIO help Enables support for the Sun4i timer. @@ -89,6 +93,7 @@ config SUN5I_HSTIMER config TEGRA_TIMER bool "Tegra timer driver" if COMPILE_TEST + select CLKSRC_MMIO depends on ARM help Enables support for the Tegra driver. @@ -96,6 +101,7 @@ config TEGRA_TIMER config VT8500_TIMER bool "VT8500 timer driver" if COMPILE_TEST depends on GENERIC_CLOCKEVENTS + depends on HAS_IOMEM help Enables support for the VT8500 driver. @@ -131,6 +137,7 @@ config CLKSRC_NOMADIK_MTU_SCHED_CLOCK config CLKSRC_DBX500_PRCMU bool "Clocksource PRCMU Timer" if COMPILE_TEST depends on GENERIC_CLOCKEVENTS + depends on HAS_IOMEM help Use the always on PRCMU Timer as clocksource @@ -248,6 +255,7 @@ config CLKSRC_EXYNOS_MCT config CLKSRC_SAMSUNG_PWM bool "PWM timer drvier for Samsung S3C, S5P" if COMPILE_TEST depends on GENERIC_CLOCKEVENTS + depends on HAS_IOMEM help This is a new clocksource driver for the PWM timer found in Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver @@ -257,12 +265,14 @@ config CLKSRC_SAMSUNG_PWM config FSL_FTM_TIMER bool "Freescale FlexTimer Module driver" if COMPILE_TEST depends on GENERIC_CLOCKEVENTS + depends on HAS_IOMEM select CLKSRC_MMIO help Support for Freescale FlexTimer Module (FTM) timer. config VF_PIT_TIMER bool + select CLKSRC_MMIO help Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. @@ -360,6 +370,7 @@ config CLKSRC_TANGO_XTAL config CLKSRC_PXA bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST depends on GENERIC_CLOCKEVENTS + depends on HAS_IOMEM select CLKSRC_MMIO help This enables OST0 support available on PXA and SA-11x0 @@ -394,6 +405,7 @@ config CLKSRC_ST_LPC bool "Low power clocksource found in the LPC" if COMPILE_TEST select CLKSRC_OF if OF depends on HAS_IOMEM + select CLKSRC_MMIO help Enable this option to use the Low Power controller timer as clocksource. diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c index 6ee91401918e..4da2af9694a2 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c @@ -98,7 +98,8 @@ static int tc_shutdown(struct clock_event_device *d) __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR)); __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR)); - clk_disable(tcd->clk); + if (!clockevent_state_detached(d)) + clk_disable(tcd->clk); return 0; } diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 9bc37c437874..0ca74d070058 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -142,15 +142,16 @@ static int allocate_resources(int cpu, struct device **cdev, try_again: cpu_reg = regulator_get_optional(cpu_dev, reg); - if (IS_ERR(cpu_reg)) { + ret = PTR_ERR_OR_ZERO(cpu_reg); + if (ret) { /* * If cpu's regulator supply node is present, but regulator is * not yet registered, we should try defering probe. */ - if (PTR_ERR(cpu_reg) == -EPROBE_DEFER) { + if (ret == -EPROBE_DEFER) { dev_dbg(cpu_dev, "cpu%d regulator not ready, retry\n", cpu); - return -EPROBE_DEFER; + return ret; } /* Try with "cpu-supply" */ @@ -159,18 +160,16 @@ try_again: goto try_again; } - dev_dbg(cpu_dev, "no regulator for cpu%d: %ld\n", - cpu, PTR_ERR(cpu_reg)); + dev_dbg(cpu_dev, "no regulator for cpu%d: %d\n", cpu, ret); } cpu_clk = clk_get(cpu_dev, NULL); - if (IS_ERR(cpu_clk)) { + ret = PTR_ERR_OR_ZERO(cpu_clk); + if (ret) { /* put regulator */ if (!IS_ERR(cpu_reg)) regulator_put(cpu_reg); - ret = PTR_ERR(cpu_clk); - /* * If cpu's clk node is present, but clock is not yet * registered, we should try defering probe. diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c35e7da1ed7a..34b17447e0d1 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -48,11 +48,11 @@ static struct cpufreq_policy *next_policy(struct cpufreq_policy *policy, bool active) { do { - policy = list_next_entry(policy, policy_list); - /* No more policies in the list */ - if (&policy->policy_list == &cpufreq_policy_list) + if (list_is_last(&policy->policy_list, &cpufreq_policy_list)) return NULL; + + policy = list_next_entry(policy, policy_list); } while (!suitable_policy(policy, active)); return policy; @@ -959,6 +959,11 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy) return cpufreq_add_dev_symlink(policy); } +__weak struct cpufreq_governor *cpufreq_default_governor(void) +{ + return NULL; +} + static int cpufreq_init_policy(struct cpufreq_policy *policy) { struct cpufreq_governor *gov = NULL; @@ -968,11 +973,14 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy) /* Update governor of new_policy to the governor used before hotplug */ gov = find_governor(policy->last_governor); - if (gov) + if (gov) { pr_debug("Restoring governor %s for cpu %d\n", policy->governor->name, policy->cpu); - else - gov = CPUFREQ_DEFAULT_GOVERNOR; + } else { + gov = cpufreq_default_governor(); + if (!gov) + return -ENODATA; + } new_policy.governor = gov; @@ -1920,21 +1928,16 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, } EXPORT_SYMBOL_GPL(cpufreq_driver_target); +__weak struct cpufreq_governor *cpufreq_fallback_governor(void) +{ + return NULL; +} + static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) { int ret; - /* Only must be defined when default governor is known to have latency - restrictions, like e.g. conservative or ondemand. - That this is the case is already ensured in Kconfig - */ -#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE - struct cpufreq_governor *gov = &cpufreq_gov_performance; -#else - struct cpufreq_governor *gov = NULL; -#endif - /* Don't start any governor operations if we are entering suspend */ if (cpufreq_suspended) return 0; @@ -1948,12 +1951,14 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, if (policy->governor->max_transition_latency && policy->cpuinfo.transition_latency > policy->governor->max_transition_latency) { - if (!gov) - return -EINVAL; - else { + struct cpufreq_governor *gov = cpufreq_fallback_governor(); + + if (gov) { pr_warn("%s governor failed, too long transition latency of HW, fallback to %s governor\n", policy->governor->name, gov->name); policy->governor = gov; + } else { + return -EINVAL; } } diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 606ad74abe6e..8504a70a4785 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -26,10 +26,7 @@ static DEFINE_PER_CPU(struct cs_cpu_dbs_info_s, cs_cpu_dbs_info); static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event); -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE -static -#endif -struct cpufreq_governor cpufreq_gov_conservative = { +static struct cpufreq_governor cpufreq_gov_conservative = { .name = "conservative", .governor = cs_cpufreq_governor_dbs, .max_transition_latency = TRANSITION_LATENCY_LIMIT, @@ -399,6 +396,11 @@ MODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for " MODULE_LICENSE("GPL"); #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE +struct cpufreq_governor *cpufreq_default_governor(void) +{ + return &cpufreq_gov_conservative; +} + fs_initcall(cpufreq_gov_dbs_init); #else module_init(cpufreq_gov_dbs_init); diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index bab3a514ec12..e0d111024d48 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -387,16 +387,18 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy, if (!have_governor_per_policy()) cdata->gdbs_data = dbs_data; + policy->governor_data = dbs_data; + ret = sysfs_create_group(get_governor_parent_kobj(policy), get_sysfs_attr(dbs_data)); if (ret) goto reset_gdbs_data; - policy->governor_data = dbs_data; - return 0; reset_gdbs_data: + policy->governor_data = NULL; + if (!have_governor_per_policy()) cdata->gdbs_data = NULL; cdata->exit(dbs_data, !policy->governor->initialized); @@ -417,16 +419,19 @@ static int cpufreq_governor_exit(struct cpufreq_policy *policy, if (!cdbs->shared || cdbs->shared->policy) return -EBUSY; - policy->governor_data = NULL; if (!--dbs_data->usage_count) { sysfs_remove_group(get_governor_parent_kobj(policy), get_sysfs_attr(dbs_data)); + policy->governor_data = NULL; + if (!have_governor_per_policy()) cdata->gdbs_data = NULL; cdata->exit(dbs_data, policy->governor->initialized == 1); kfree(dbs_data); + } else { + policy->governor_data = NULL; } free_common_dbs_info(policy, cdata); diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index eae51070c034..929e193ac1c1 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -31,9 +31,7 @@ static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info); static struct od_ops od_ops; -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND static struct cpufreq_governor cpufreq_gov_ondemand; -#endif static unsigned int default_powersave_bias; @@ -554,6 +552,19 @@ static struct common_dbs_data od_dbs_cdata = { .mutex = __MUTEX_INITIALIZER(od_dbs_cdata.mutex), }; +static int od_cpufreq_governor_dbs(struct cpufreq_policy *policy, + unsigned int event) +{ + return cpufreq_governor_dbs(policy, &od_dbs_cdata, event); +} + +static struct cpufreq_governor cpufreq_gov_ondemand = { + .name = "ondemand", + .governor = od_cpufreq_governor_dbs, + .max_transition_latency = TRANSITION_LATENCY_LIMIT, + .owner = THIS_MODULE, +}; + static void od_set_powersave_bias(unsigned int powersave_bias) { struct cpufreq_policy *policy; @@ -605,22 +616,6 @@ void od_unregister_powersave_bias_handler(void) } EXPORT_SYMBOL_GPL(od_unregister_powersave_bias_handler); -static int od_cpufreq_governor_dbs(struct cpufreq_policy *policy, - unsigned int event) -{ - return cpufreq_governor_dbs(policy, &od_dbs_cdata, event); -} - -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND -static -#endif -struct cpufreq_governor cpufreq_gov_ondemand = { - .name = "ondemand", - .governor = od_cpufreq_governor_dbs, - .max_transition_latency = TRANSITION_LATENCY_LIMIT, - .owner = THIS_MODULE, -}; - static int __init cpufreq_gov_dbs_init(void) { return cpufreq_register_governor(&cpufreq_gov_ondemand); @@ -638,6 +633,11 @@ MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for " MODULE_LICENSE("GPL"); #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND +struct cpufreq_governor *cpufreq_default_governor(void) +{ + return &cpufreq_gov_ondemand; +} + fs_initcall(cpufreq_gov_dbs_init); #else module_init(cpufreq_gov_dbs_init); diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c index cf117deb39b1..af9f4b96f5a8 100644 --- a/drivers/cpufreq/cpufreq_performance.c +++ b/drivers/cpufreq/cpufreq_performance.c @@ -33,10 +33,7 @@ static int cpufreq_governor_performance(struct cpufreq_policy *policy, return 0; } -#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE_MODULE -static -#endif -struct cpufreq_governor cpufreq_gov_performance = { +static struct cpufreq_governor cpufreq_gov_performance = { .name = "performance", .governor = cpufreq_governor_performance, .owner = THIS_MODULE, @@ -52,6 +49,19 @@ static void __exit cpufreq_gov_performance_exit(void) cpufreq_unregister_governor(&cpufreq_gov_performance); } +#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE +struct cpufreq_governor *cpufreq_default_governor(void) +{ + return &cpufreq_gov_performance; +} +#endif +#ifndef CONFIG_CPU_FREQ_GOV_PERFORMANCE_MODULE +struct cpufreq_governor *cpufreq_fallback_governor(void) +{ + return &cpufreq_gov_performance; +} +#endif + MODULE_AUTHOR("Dominik Brodowski "); MODULE_DESCRIPTION("CPUfreq policy governor 'performance'"); MODULE_LICENSE("GPL"); diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c index e3b874c235ea..b8b400232a74 100644 --- a/drivers/cpufreq/cpufreq_powersave.c +++ b/drivers/cpufreq/cpufreq_powersave.c @@ -33,10 +33,7 @@ static int cpufreq_governor_powersave(struct cpufreq_policy *policy, return 0; } -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE -static -#endif -struct cpufreq_governor cpufreq_gov_powersave = { +static struct cpufreq_governor cpufreq_gov_powersave = { .name = "powersave", .governor = cpufreq_governor_powersave, .owner = THIS_MODULE, @@ -57,6 +54,11 @@ MODULE_DESCRIPTION("CPUfreq policy governor 'powersave'"); MODULE_LICENSE("GPL"); #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE +struct cpufreq_governor *cpufreq_default_governor(void) +{ + return &cpufreq_gov_powersave; +} + fs_initcall(cpufreq_gov_powersave_init); #else module_init(cpufreq_gov_powersave_init); diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 4dbf1db16aca..4d16f45ee1da 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -89,10 +89,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, return rc; } -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE -static -#endif -struct cpufreq_governor cpufreq_gov_userspace = { +static struct cpufreq_governor cpufreq_gov_userspace = { .name = "userspace", .governor = cpufreq_governor_userspace, .store_setspeed = cpufreq_set, @@ -116,6 +113,11 @@ MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'"); MODULE_LICENSE("GPL"); #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE +struct cpufreq_governor *cpufreq_default_governor(void) +{ + return &cpufreq_gov_userspace; +} + fs_initcall(cpufreq_gov_userspace_init); #else module_init(cpufreq_gov_userspace_init); diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index cd83d477e32d..3a4b39afc0ab 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1431,7 +1431,7 @@ static int __init intel_pstate_init(void) if (!all_cpu_data) return -ENOMEM; - if (static_cpu_has_safe(X86_FEATURE_HWP) && !no_hwp) { + if (static_cpu_has(X86_FEATURE_HWP) && !no_hwp) { pr_info("intel_pstate: HWP enabled\n"); hwp_active++; } diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 547890fd9572..1bbc10a54c59 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -42,13 +44,24 @@ static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; static bool rebooting, throttled, occ_reset; +static unsigned int *core_to_chip_map; + +static const char * const throttle_reason[] = { + "No throttling", + "Power Cap", + "Processor Over Temperature", + "Power Supply Failure", + "Over Current", + "OCC Reset" +}; static struct chip { unsigned int id; bool throttled; + bool restore; + u8 throttle_reason; cpumask_t mask; struct work_struct throttle; - bool restore; } *chips; static int nr_chips; @@ -312,13 +325,14 @@ static inline unsigned int get_nominal_index(void) static void powernv_cpufreq_throttle_check(void *data) { unsigned int cpu = smp_processor_id(); + unsigned int chip_id = core_to_chip_map[cpu_core_index_of_thread(cpu)]; unsigned long pmsr; int pmsr_pmax, i; pmsr = get_pmspr(SPRN_PMSR); for (i = 0; i < nr_chips; i++) - if (chips[i].id == cpu_to_chip_id(cpu)) + if (chips[i].id == chip_id) break; /* Check for Pmax Capping */ @@ -328,17 +342,17 @@ static void powernv_cpufreq_throttle_check(void *data) goto next; chips[i].throttled = true; if (pmsr_pmax < powernv_pstate_info.nominal) - pr_crit("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n", - cpu, chips[i].id, pmsr_pmax, - powernv_pstate_info.nominal); - else - pr_info("CPU %d on Chip %u has Pmax reduced below turbo frequency (%d < %d)\n", - cpu, chips[i].id, pmsr_pmax, - powernv_pstate_info.max); + pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n", + cpu, chips[i].id, pmsr_pmax, + powernv_pstate_info.nominal); + trace_powernv_throttle(chips[i].id, + throttle_reason[chips[i].throttle_reason], + pmsr_pmax); } else if (chips[i].throttled) { chips[i].throttled = false; - pr_info("CPU %d on Chip %u has Pmax restored to %d\n", cpu, - chips[i].id, pmsr_pmax); + trace_powernv_throttle(chips[i].id, + throttle_reason[chips[i].throttle_reason], + pmsr_pmax); } /* Check if Psafe_mode_active is set in PMSR. */ @@ -356,7 +370,7 @@ next: if (throttled) { pr_info("PMSR = %16lx\n", pmsr); - pr_crit("CPU Frequency could be throttled\n"); + pr_warn("CPU Frequency could be throttled\n"); } } @@ -423,18 +437,19 @@ void powernv_cpufreq_work_fn(struct work_struct *work) { struct chip *chip = container_of(work, struct chip, throttle); unsigned int cpu; - cpumask_var_t mask; + cpumask_t mask; - smp_call_function_any(&chip->mask, + get_online_cpus(); + cpumask_and(&mask, &chip->mask, cpu_online_mask); + smp_call_function_any(&mask, powernv_cpufreq_throttle_check, NULL, 0); if (!chip->restore) - return; + goto out; chip->restore = false; - cpumask_copy(mask, &chip->mask); - for_each_cpu_and(cpu, mask, cpu_online_mask) { - int index, tcpu; + for_each_cpu(cpu, &mask) { + int index; struct cpufreq_policy policy; cpufreq_get_policy(&policy, cpu); @@ -442,20 +457,12 @@ void powernv_cpufreq_work_fn(struct work_struct *work) policy.cur, CPUFREQ_RELATION_C, &index); powernv_cpufreq_target_index(&policy, index); - for_each_cpu(tcpu, policy.cpus) - cpumask_clear_cpu(tcpu, mask); + cpumask_andnot(&mask, &mask, policy.cpus); } +out: + put_online_cpus(); } -static char throttle_reason[][30] = { - "No throttling", - "Power Cap", - "Processor Over Temperature", - "Power Supply Failure", - "Over Current", - "OCC Reset" - }; - static int powernv_cpufreq_occ_msg(struct notifier_block *nb, unsigned long msg_type, void *_msg) { @@ -481,7 +488,7 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb, */ if (!throttled) { throttled = true; - pr_crit("CPU frequency is throttled for duration\n"); + pr_warn("CPU frequency is throttled for duration\n"); } break; @@ -505,23 +512,18 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb, return 0; } - if (omsg.throttle_status && + for (i = 0; i < nr_chips; i++) + if (chips[i].id == omsg.chip) + break; + + if (omsg.throttle_status >= 0 && omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS) - pr_info("OCC: Chip %u Pmax reduced due to %s\n", - (unsigned int)omsg.chip, - throttle_reason[omsg.throttle_status]); - else if (!omsg.throttle_status) - pr_info("OCC: Chip %u %s\n", (unsigned int)omsg.chip, - throttle_reason[omsg.throttle_status]); - else - return 0; + chips[i].throttle_reason = omsg.throttle_status; - for (i = 0; i < nr_chips; i++) - if (chips[i].id == omsg.chip) { - if (!omsg.throttle_status) - chips[i].restore = true; - schedule_work(&chips[i].throttle); - } + if (!omsg.throttle_status) + chips[i].restore = true; + + schedule_work(&chips[i].throttle); } return 0; } @@ -556,29 +558,41 @@ static int init_chip_info(void) unsigned int chip[256]; unsigned int cpu, i; unsigned int prev_chip_id = UINT_MAX; + cpumask_t cpu_mask; + int ret = -ENOMEM; + + core_to_chip_map = kcalloc(cpu_nr_cores(), sizeof(unsigned int), + GFP_KERNEL); + if (!core_to_chip_map) + goto out; - for_each_possible_cpu(cpu) { + cpumask_copy(&cpu_mask, cpu_possible_mask); + for_each_cpu(cpu, &cpu_mask) { unsigned int id = cpu_to_chip_id(cpu); if (prev_chip_id != id) { prev_chip_id = id; chip[nr_chips++] = id; } + core_to_chip_map[cpu_core_index_of_thread(cpu)] = id; + cpumask_andnot(&cpu_mask, &cpu_mask, cpu_sibling_mask(cpu)); } - chips = kmalloc_array(nr_chips, sizeof(struct chip), GFP_KERNEL); + chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL); if (!chips) - return -ENOMEM; + goto free_chip_map; for (i = 0; i < nr_chips; i++) { chips[i].id = chip[i]; - chips[i].throttled = false; cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i])); INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn); - chips[i].restore = false; } return 0; +free_chip_map: + kfree(core_to_chip_map); +out: + return ret; } static int __init powernv_cpufreq_init(void) @@ -612,6 +626,8 @@ static void __exit powernv_cpufreq_exit(void) unregister_reboot_notifier(&powernv_cpufreq_reboot_nb); opal_message_notifier_unregister(OPAL_MSG_OCC, &powernv_cpufreq_opal_nb); + kfree(chips); + kfree(core_to_chip_map); cpufreq_unregister_driver(&powernv_cpufreq_driver); } module_exit(powernv_cpufreq_exit); diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index 1d99c97defa9..096377232747 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c @@ -202,7 +202,7 @@ static void __init pxa_cpufreq_init_voltages(void) } } #else -static int pxa_cpufreq_change_voltage(struct pxa_freqs *pxa_freq) +static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq) { return 0; } diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 051a8a8224cd..a145b319d171 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -576,10 +576,8 @@ static struct cpufreq_driver s5pv210_driver = { .get = cpufreq_generic_get, .init = s5pv210_cpu_init, .name = "s5pv210", -#ifdef CONFIG_PM .suspend = cpufreq_generic_suspend, .resume = cpufreq_generic_suspend, /* We need to set SLEEP FREQ again */ -#endif }; static struct notifier_block s5pv210_cpufreq_reboot_notifier = { diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c index 344058f8501a..d5657d50ac40 100644 --- a/drivers/cpuidle/coupled.c +++ b/drivers/cpuidle/coupled.c @@ -119,7 +119,6 @@ struct cpuidle_coupled { #define CPUIDLE_COUPLED_NOT_IDLE (-1) -static DEFINE_MUTEX(cpuidle_coupled_lock); static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb); /* diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 046423b0c5ca..f996efc56605 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -153,7 +153,7 @@ int cpuidle_enter_freeze(struct cpuidle_driver *drv, struct cpuidle_device *dev) * be frozen safely. */ index = find_deepest_state(drv, dev, UINT_MAX, 0, true); - if (index >= 0) + if (index > 0) enter_freeze_proper(drv, dev, index); return index; diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 07d494276aad..fed3ffbec4c1 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -296,6 +296,7 @@ config CRYPTO_DEV_OMAP_AES depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP2PLUS select CRYPTO_AES select CRYPTO_BLKCIPHER + select CRYPTO_ENGINE help OMAP processors have AES module accelerator. Select this if you want to use the OMAP module for AES algorithms. @@ -487,7 +488,7 @@ config CRYPTO_DEV_IMGTEC_HASH config CRYPTO_DEV_SUN4I_SS tristate "Support for Allwinner Security System cryptographic accelerator" - depends on ARCH_SUNXI + depends on ARCH_SUNXI && !64BIT select CRYPTO_MD5 select CRYPTO_SHA1 select CRYPTO_AES diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c index 6dd3317ca365..0751035b2cb0 100644 --- a/drivers/crypto/atmel-aes.c +++ b/drivers/crypto/atmel-aes.c @@ -369,12 +369,6 @@ static inline size_t atmel_aes_padlen(size_t len, size_t block_size) return len ? block_size - len : 0; } -static inline struct aead_request * -aead_request_cast(struct crypto_async_request *req) -{ - return container_of(req, struct aead_request, base); -} - static struct atmel_aes_dev *atmel_aes_find_dev(struct atmel_aes_base_ctx *ctx) { struct atmel_aes_dev *aes_dd = NULL; @@ -400,7 +394,7 @@ static int atmel_aes_hw_init(struct atmel_aes_dev *dd) { int err; - err = clk_prepare_enable(dd->iclk); + err = clk_enable(dd->iclk); if (err) return err; @@ -430,7 +424,7 @@ static int atmel_aes_hw_version_init(struct atmel_aes_dev *dd) dev_info(dd->dev, "version: 0x%x\n", dd->hw_version); - clk_disable_unprepare(dd->iclk); + clk_disable(dd->iclk); return 0; } @@ -448,7 +442,7 @@ static inline bool atmel_aes_is_encrypt(const struct atmel_aes_dev *dd) static inline int atmel_aes_complete(struct atmel_aes_dev *dd, int err) { - clk_disable_unprepare(dd->iclk); + clk_disable(dd->iclk); dd->flags &= ~AES_FLAGS_BUSY; if (dd->is_async) @@ -2091,10 +2085,14 @@ static int atmel_aes_probe(struct platform_device *pdev) goto res_err; } - err = atmel_aes_hw_version_init(aes_dd); + err = clk_prepare(aes_dd->iclk); if (err) goto res_err; + err = atmel_aes_hw_version_init(aes_dd); + if (err) + goto iclk_unprepare; + atmel_aes_get_cap(aes_dd); err = atmel_aes_buff_init(aes_dd); @@ -2127,6 +2125,8 @@ err_algs: err_aes_dma: atmel_aes_buff_cleanup(aes_dd); err_aes_buff: +iclk_unprepare: + clk_unprepare(aes_dd->iclk); res_err: tasklet_kill(&aes_dd->done_task); tasklet_kill(&aes_dd->queue_task); @@ -2155,6 +2155,8 @@ static int atmel_aes_remove(struct platform_device *pdev) atmel_aes_dma_cleanup(aes_dd); atmel_aes_buff_cleanup(aes_dd); + clk_unprepare(aes_dd->iclk); + return 0; } diff --git a/drivers/crypto/atmel-sha-regs.h b/drivers/crypto/atmel-sha-regs.h index 83b2d7425666..e08897109cab 100644 --- a/drivers/crypto/atmel-sha-regs.h +++ b/drivers/crypto/atmel-sha-regs.h @@ -8,6 +8,8 @@ #define SHA_CR_START (1 << 0) #define SHA_CR_FIRST (1 << 4) #define SHA_CR_SWRST (1 << 8) +#define SHA_CR_WUIHV (1 << 12) +#define SHA_CR_WUIEHV (1 << 13) #define SHA_MR 0x04 #define SHA_MR_MODE_MASK (0x3 << 0) @@ -15,6 +17,8 @@ #define SHA_MR_MODE_AUTO 0x1 #define SHA_MR_MODE_PDC 0x2 #define SHA_MR_PROCDLY (1 << 4) +#define SHA_MR_UIHV (1 << 5) +#define SHA_MR_UIEHV (1 << 6) #define SHA_MR_ALGO_SHA1 (0 << 8) #define SHA_MR_ALGO_SHA256 (1 << 8) #define SHA_MR_ALGO_SHA384 (2 << 8) diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index 20de861aa0ea..f8407dc7dd38 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c @@ -53,6 +53,7 @@ #define SHA_FLAGS_FINUP BIT(16) #define SHA_FLAGS_SG BIT(17) +#define SHA_FLAGS_ALGO_MASK GENMASK(22, 18) #define SHA_FLAGS_SHA1 BIT(18) #define SHA_FLAGS_SHA224 BIT(19) #define SHA_FLAGS_SHA256 BIT(20) @@ -60,11 +61,12 @@ #define SHA_FLAGS_SHA512 BIT(22) #define SHA_FLAGS_ERROR BIT(23) #define SHA_FLAGS_PAD BIT(24) +#define SHA_FLAGS_RESTORE BIT(25) #define SHA_OP_UPDATE 1 #define SHA_OP_FINAL 2 -#define SHA_BUFFER_LEN PAGE_SIZE +#define SHA_BUFFER_LEN (PAGE_SIZE / 16) #define ATMEL_SHA_DMA_THRESHOLD 56 @@ -73,10 +75,22 @@ struct atmel_sha_caps { bool has_dualbuff; bool has_sha224; bool has_sha_384_512; + bool has_uihv; }; struct atmel_sha_dev; +/* + * .statesize = sizeof(struct atmel_sha_state) must be <= PAGE_SIZE / 8 as + * tested by the ahash_prepare_alg() function. + */ +struct atmel_sha_state { + u8 digest[SHA512_DIGEST_SIZE]; + u8 buffer[SHA_BUFFER_LEN]; + u64 digcnt[2]; + size_t bufcnt; +}; + struct atmel_sha_reqctx { struct atmel_sha_dev *dd; unsigned long flags; @@ -122,6 +136,7 @@ struct atmel_sha_dev { spinlock_t lock; int err; struct tasklet_struct done_task; + struct tasklet_struct queue_task; unsigned long flags; struct crypto_queue queue; @@ -317,7 +332,8 @@ static int atmel_sha_init(struct ahash_request *req) static void atmel_sha_write_ctrl(struct atmel_sha_dev *dd, int dma) { struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req); - u32 valcr = 0, valmr = SHA_MR_MODE_AUTO; + u32 valmr = SHA_MR_MODE_AUTO; + unsigned int i, hashsize = 0; if (likely(dma)) { if (!dd->caps.has_dma) @@ -329,22 +345,62 @@ static void atmel_sha_write_ctrl(struct atmel_sha_dev *dd, int dma) atmel_sha_write(dd, SHA_IER, SHA_INT_DATARDY); } - if (ctx->flags & SHA_FLAGS_SHA1) + switch (ctx->flags & SHA_FLAGS_ALGO_MASK) { + case SHA_FLAGS_SHA1: valmr |= SHA_MR_ALGO_SHA1; - else if (ctx->flags & SHA_FLAGS_SHA224) + hashsize = SHA1_DIGEST_SIZE; + break; + + case SHA_FLAGS_SHA224: valmr |= SHA_MR_ALGO_SHA224; - else if (ctx->flags & SHA_FLAGS_SHA256) + hashsize = SHA256_DIGEST_SIZE; + break; + + case SHA_FLAGS_SHA256: valmr |= SHA_MR_ALGO_SHA256; - else if (ctx->flags & SHA_FLAGS_SHA384) + hashsize = SHA256_DIGEST_SIZE; + break; + + case SHA_FLAGS_SHA384: valmr |= SHA_MR_ALGO_SHA384; - else if (ctx->flags & SHA_FLAGS_SHA512) + hashsize = SHA512_DIGEST_SIZE; + break; + + case SHA_FLAGS_SHA512: valmr |= SHA_MR_ALGO_SHA512; + hashsize = SHA512_DIGEST_SIZE; + break; + + default: + break; + } /* Setting CR_FIRST only for the first iteration */ - if (!(ctx->digcnt[0] || ctx->digcnt[1])) - valcr = SHA_CR_FIRST; + if (!(ctx->digcnt[0] || ctx->digcnt[1])) { + atmel_sha_write(dd, SHA_CR, SHA_CR_FIRST); + } else if (dd->caps.has_uihv && (ctx->flags & SHA_FLAGS_RESTORE)) { + const u32 *hash = (const u32 *)ctx->digest; + + /* + * Restore the hardware context: update the User Initialize + * Hash Value (UIHV) with the value saved when the latest + * 'update' operation completed on this very same crypto + * request. + */ + ctx->flags &= ~SHA_FLAGS_RESTORE; + atmel_sha_write(dd, SHA_CR, SHA_CR_WUIHV); + for (i = 0; i < hashsize / sizeof(u32); ++i) + atmel_sha_write(dd, SHA_REG_DIN(i), hash[i]); + atmel_sha_write(dd, SHA_CR, SHA_CR_FIRST); + valmr |= SHA_MR_UIHV; + } + /* + * WARNING: If the UIHV feature is not available, the hardware CANNOT + * process concurrent requests: the internal registers used to store + * the hash/digest are still set to the partial digest output values + * computed during the latest round. + */ - atmel_sha_write(dd, SHA_CR, valcr); atmel_sha_write(dd, SHA_MR, valmr); } @@ -713,23 +769,31 @@ static void atmel_sha_copy_hash(struct ahash_request *req) { struct atmel_sha_reqctx *ctx = ahash_request_ctx(req); u32 *hash = (u32 *)ctx->digest; - int i; + unsigned int i, hashsize; - if (ctx->flags & SHA_FLAGS_SHA1) - for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) - hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); - else if (ctx->flags & SHA_FLAGS_SHA224) - for (i = 0; i < SHA224_DIGEST_SIZE / sizeof(u32); i++) - hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); - else if (ctx->flags & SHA_FLAGS_SHA256) - for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(u32); i++) - hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); - else if (ctx->flags & SHA_FLAGS_SHA384) - for (i = 0; i < SHA384_DIGEST_SIZE / sizeof(u32); i++) - hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); - else - for (i = 0; i < SHA512_DIGEST_SIZE / sizeof(u32); i++) - hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); + switch (ctx->flags & SHA_FLAGS_ALGO_MASK) { + case SHA_FLAGS_SHA1: + hashsize = SHA1_DIGEST_SIZE; + break; + + case SHA_FLAGS_SHA224: + case SHA_FLAGS_SHA256: + hashsize = SHA256_DIGEST_SIZE; + break; + + case SHA_FLAGS_SHA384: + case SHA_FLAGS_SHA512: + hashsize = SHA512_DIGEST_SIZE; + break; + + default: + /* Should not happen... */ + return; + } + + for (i = 0; i < hashsize / sizeof(u32); ++i) + hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); + ctx->flags |= SHA_FLAGS_RESTORE; } static void atmel_sha_copy_ready_hash(struct ahash_request *req) @@ -782,20 +846,20 @@ static void atmel_sha_finish_req(struct ahash_request *req, int err) dd->flags &= ~(SHA_FLAGS_BUSY | SHA_FLAGS_FINAL | SHA_FLAGS_CPU | SHA_FLAGS_DMA_READY | SHA_FLAGS_OUTPUT_READY); - clk_disable_unprepare(dd->iclk); + clk_disable(dd->iclk); if (req->base.complete) req->base.complete(&req->base, err); /* handle new request */ - tasklet_schedule(&dd->done_task); + tasklet_schedule(&dd->queue_task); } static int atmel_sha_hw_init(struct atmel_sha_dev *dd) { int err; - err = clk_prepare_enable(dd->iclk); + err = clk_enable(dd->iclk); if (err) return err; @@ -822,7 +886,7 @@ static void atmel_sha_hw_version_init(struct atmel_sha_dev *dd) dev_info(dd->dev, "version: 0x%x\n", dd->hw_version); - clk_disable_unprepare(dd->iclk); + clk_disable(dd->iclk); } static int atmel_sha_handle_queue(struct atmel_sha_dev *dd, @@ -939,6 +1003,7 @@ static int atmel_sha_final(struct ahash_request *req) if (err) goto err1; + dd->req = req; dd->flags |= SHA_FLAGS_BUSY; err = atmel_sha_final_req(dd); } else { @@ -979,6 +1044,39 @@ static int atmel_sha_digest(struct ahash_request *req) return atmel_sha_init(req) ?: atmel_sha_finup(req); } + +static int atmel_sha_export(struct ahash_request *req, void *out) +{ + const struct atmel_sha_reqctx *ctx = ahash_request_ctx(req); + struct atmel_sha_state state; + + memcpy(state.digest, ctx->digest, SHA512_DIGEST_SIZE); + memcpy(state.buffer, ctx->buffer, ctx->bufcnt); + state.bufcnt = ctx->bufcnt; + state.digcnt[0] = ctx->digcnt[0]; + state.digcnt[1] = ctx->digcnt[1]; + + /* out might be unaligned. */ + memcpy(out, &state, sizeof(state)); + return 0; +} + +static int atmel_sha_import(struct ahash_request *req, const void *in) +{ + struct atmel_sha_reqctx *ctx = ahash_request_ctx(req); + struct atmel_sha_state state; + + /* in might be unaligned. */ + memcpy(&state, in, sizeof(state)); + + memcpy(ctx->digest, state.digest, SHA512_DIGEST_SIZE); + memcpy(ctx->buffer, state.buffer, state.bufcnt); + ctx->bufcnt = state.bufcnt; + ctx->digcnt[0] = state.digcnt[0]; + ctx->digcnt[1] = state.digcnt[1]; + return 0; +} + static int atmel_sha_cra_init(struct crypto_tfm *tfm) { crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), @@ -995,8 +1093,11 @@ static struct ahash_alg sha_1_256_algs[] = { .final = atmel_sha_final, .finup = atmel_sha_finup, .digest = atmel_sha_digest, + .export = atmel_sha_export, + .import = atmel_sha_import, .halg = { .digestsize = SHA1_DIGEST_SIZE, + .statesize = sizeof(struct atmel_sha_state), .base = { .cra_name = "sha1", .cra_driver_name = "atmel-sha1", @@ -1016,8 +1117,11 @@ static struct ahash_alg sha_1_256_algs[] = { .final = atmel_sha_final, .finup = atmel_sha_finup, .digest = atmel_sha_digest, + .export = atmel_sha_export, + .import = atmel_sha_import, .halg = { .digestsize = SHA256_DIGEST_SIZE, + .statesize = sizeof(struct atmel_sha_state), .base = { .cra_name = "sha256", .cra_driver_name = "atmel-sha256", @@ -1039,8 +1143,11 @@ static struct ahash_alg sha_224_alg = { .final = atmel_sha_final, .finup = atmel_sha_finup, .digest = atmel_sha_digest, + .export = atmel_sha_export, + .import = atmel_sha_import, .halg = { .digestsize = SHA224_DIGEST_SIZE, + .statesize = sizeof(struct atmel_sha_state), .base = { .cra_name = "sha224", .cra_driver_name = "atmel-sha224", @@ -1062,8 +1169,11 @@ static struct ahash_alg sha_384_512_algs[] = { .final = atmel_sha_final, .finup = atmel_sha_finup, .digest = atmel_sha_digest, + .export = atmel_sha_export, + .import = atmel_sha_import, .halg = { .digestsize = SHA384_DIGEST_SIZE, + .statesize = sizeof(struct atmel_sha_state), .base = { .cra_name = "sha384", .cra_driver_name = "atmel-sha384", @@ -1083,8 +1193,11 @@ static struct ahash_alg sha_384_512_algs[] = { .final = atmel_sha_final, .finup = atmel_sha_finup, .digest = atmel_sha_digest, + .export = atmel_sha_export, + .import = atmel_sha_import, .halg = { .digestsize = SHA512_DIGEST_SIZE, + .statesize = sizeof(struct atmel_sha_state), .base = { .cra_name = "sha512", .cra_driver_name = "atmel-sha512", @@ -1100,16 +1213,18 @@ static struct ahash_alg sha_384_512_algs[] = { }, }; +static void atmel_sha_queue_task(unsigned long data) +{ + struct atmel_sha_dev *dd = (struct atmel_sha_dev *)data; + + atmel_sha_handle_queue(dd, NULL); +} + static void atmel_sha_done_task(unsigned long data) { struct atmel_sha_dev *dd = (struct atmel_sha_dev *)data; int err = 0; - if (!(SHA_FLAGS_BUSY & dd->flags)) { - atmel_sha_handle_queue(dd, NULL); - return; - } - if (SHA_FLAGS_CPU & dd->flags) { if (SHA_FLAGS_OUTPUT_READY & dd->flags) { dd->flags &= ~SHA_FLAGS_OUTPUT_READY; @@ -1272,14 +1387,23 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd) dd->caps.has_dualbuff = 0; dd->caps.has_sha224 = 0; dd->caps.has_sha_384_512 = 0; + dd->caps.has_uihv = 0; /* keep only major version number */ switch (dd->hw_version & 0xff0) { + case 0x510: + dd->caps.has_dma = 1; + dd->caps.has_dualbuff = 1; + dd->caps.has_sha224 = 1; + dd->caps.has_sha_384_512 = 1; + dd->caps.has_uihv = 1; + break; case 0x420: dd->caps.has_dma = 1; dd->caps.has_dualbuff = 1; dd->caps.has_sha224 = 1; dd->caps.has_sha_384_512 = 1; + dd->caps.has_uihv = 1; break; case 0x410: dd->caps.has_dma = 1; @@ -1366,6 +1490,8 @@ static int atmel_sha_probe(struct platform_device *pdev) tasklet_init(&sha_dd->done_task, atmel_sha_done_task, (unsigned long)sha_dd); + tasklet_init(&sha_dd->queue_task, atmel_sha_queue_task, + (unsigned long)sha_dd); crypto_init_queue(&sha_dd->queue, ATMEL_SHA_QUEUE_LENGTH); @@ -1410,6 +1536,10 @@ static int atmel_sha_probe(struct platform_device *pdev) goto res_err; } + err = clk_prepare(sha_dd->iclk); + if (err) + goto res_err; + atmel_sha_hw_version_init(sha_dd); atmel_sha_get_cap(sha_dd); @@ -1421,12 +1551,12 @@ static int atmel_sha_probe(struct platform_device *pdev) if (IS_ERR(pdata)) { dev_err(&pdev->dev, "platform data not available\n"); err = PTR_ERR(pdata); - goto res_err; + goto iclk_unprepare; } } if (!pdata->dma_slave) { err = -ENXIO; - goto res_err; + goto iclk_unprepare; } err = atmel_sha_dma_init(sha_dd, pdata); if (err) @@ -1457,7 +1587,10 @@ err_algs: if (sha_dd->caps.has_dma) atmel_sha_dma_cleanup(sha_dd); err_sha_dma: +iclk_unprepare: + clk_unprepare(sha_dd->iclk); res_err: + tasklet_kill(&sha_dd->queue_task); tasklet_kill(&sha_dd->done_task); sha_dd_err: dev_err(dev, "initialization failed.\n"); @@ -1478,17 +1611,13 @@ static int atmel_sha_remove(struct platform_device *pdev) atmel_sha_unregister_algs(sha_dd); + tasklet_kill(&sha_dd->queue_task); tasklet_kill(&sha_dd->done_task); if (sha_dd->caps.has_dma) atmel_sha_dma_cleanup(sha_dd); - iounmap(sha_dd->io_base); - - clk_put(sha_dd->iclk); - - if (sha_dd->irq >= 0) - free_irq(sha_dd->irq, sha_dd); + clk_unprepare(sha_dd->iclk); return 0; } diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 8abb4bc548cc..44d30b45f3cc 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -534,8 +534,8 @@ static int caam_probe(struct platform_device *pdev) * long pointers in master configuration register */ clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, MCFGR_AWCACHE_CACH | - MCFGR_WDENABLE | (sizeof(dma_addr_t) == sizeof(u64) ? - MCFGR_LONG_PTR : 0)); + MCFGR_AWCACHE_BUFF | MCFGR_WDENABLE | MCFGR_LARGE_BURST | + (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0)); /* * Read the Compile Time paramters and SCFGR to determine diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index a8a79975682f..0ba9c40597dc 100644 --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h @@ -455,7 +455,8 @@ struct caam_ctrl { #define MCFGR_AXIPIPE_MASK (0xf << MCFGR_AXIPIPE_SHIFT) #define MCFGR_AXIPRI 0x00000008 /* Assert AXI priority sideband */ -#define MCFGR_BURST_64 0x00000001 /* Max burst size */ +#define MCFGR_LARGE_BURST 0x00000004 /* 128/256-byte burst size */ +#define MCFGR_BURST_64 0x00000001 /* 64-byte burst size */ /* JRSTART register offsets */ #define JRSTART_JR0_START 0x00000001 /* Start Job ring 0 */ diff --git a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c index d89f20c04266..d095452b8828 100644 --- a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c +++ b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c @@ -220,6 +220,38 @@ static int ccp_aes_cmac_digest(struct ahash_request *req) return ccp_aes_cmac_finup(req); } +static int ccp_aes_cmac_export(struct ahash_request *req, void *out) +{ + struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req); + struct ccp_aes_cmac_exp_ctx state; + + state.null_msg = rctx->null_msg; + memcpy(state.iv, rctx->iv, sizeof(state.iv)); + state.buf_count = rctx->buf_count; + memcpy(state.buf, rctx->buf, sizeof(state.buf)); + + /* 'out' may not be aligned so memcpy from local variable */ + memcpy(out, &state, sizeof(state)); + + return 0; +} + +static int ccp_aes_cmac_import(struct ahash_request *req, const void *in) +{ + struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req); + struct ccp_aes_cmac_exp_ctx state; + + /* 'in' may not be aligned so memcpy to local variable */ + memcpy(&state, in, sizeof(state)); + + rctx->null_msg = state.null_msg; + memcpy(rctx->iv, state.iv, sizeof(rctx->iv)); + rctx->buf_count = state.buf_count; + memcpy(rctx->buf, state.buf, sizeof(rctx->buf)); + + return 0; +} + static int ccp_aes_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, unsigned int key_len) { @@ -352,10 +384,13 @@ int ccp_register_aes_cmac_algs(struct list_head *head) alg->final = ccp_aes_cmac_final; alg->finup = ccp_aes_cmac_finup; alg->digest = ccp_aes_cmac_digest; + alg->export = ccp_aes_cmac_export; + alg->import = ccp_aes_cmac_import; alg->setkey = ccp_aes_cmac_setkey; halg = &alg->halg; halg->digestsize = AES_BLOCK_SIZE; + halg->statesize = sizeof(struct ccp_aes_cmac_exp_ctx); base = &halg->base; snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "cmac(aes)"); diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c b/drivers/crypto/ccp/ccp-crypto-sha.c index d14b3f28e010..7002c6b283e5 100644 --- a/drivers/crypto/ccp/ccp-crypto-sha.c +++ b/drivers/crypto/ccp/ccp-crypto-sha.c @@ -207,6 +207,42 @@ static int ccp_sha_digest(struct ahash_request *req) return ccp_sha_finup(req); } +static int ccp_sha_export(struct ahash_request *req, void *out) +{ + struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req); + struct ccp_sha_exp_ctx state; + + state.type = rctx->type; + state.msg_bits = rctx->msg_bits; + state.first = rctx->first; + memcpy(state.ctx, rctx->ctx, sizeof(state.ctx)); + state.buf_count = rctx->buf_count; + memcpy(state.buf, rctx->buf, sizeof(state.buf)); + + /* 'out' may not be aligned so memcpy from local variable */ + memcpy(out, &state, sizeof(state)); + + return 0; +} + +static int ccp_sha_import(struct ahash_request *req, const void *in) +{ + struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req); + struct ccp_sha_exp_ctx state; + + /* 'in' may not be aligned so memcpy to local variable */ + memcpy(&state, in, sizeof(state)); + + rctx->type = state.type; + rctx->msg_bits = state.msg_bits; + rctx->first = state.first; + memcpy(rctx->ctx, state.ctx, sizeof(rctx->ctx)); + rctx->buf_count = state.buf_count; + memcpy(rctx->buf, state.buf, sizeof(rctx->buf)); + + return 0; +} + static int ccp_sha_setkey(struct crypto_ahash *tfm, const u8 *key, unsigned int key_len) { @@ -403,9 +439,12 @@ static int ccp_register_sha_alg(struct list_head *head, alg->final = ccp_sha_final; alg->finup = ccp_sha_finup; alg->digest = ccp_sha_digest; + alg->export = ccp_sha_export; + alg->import = ccp_sha_import; halg = &alg->halg; halg->digestsize = def->digest_size; + halg->statesize = sizeof(struct ccp_sha_exp_ctx); base = &halg->base; snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name); diff --git a/drivers/crypto/ccp/ccp-crypto.h b/drivers/crypto/ccp/ccp-crypto.h index 76a96f0f44c6..a326ec20bfa8 100644 --- a/drivers/crypto/ccp/ccp-crypto.h +++ b/drivers/crypto/ccp/ccp-crypto.h @@ -129,6 +129,15 @@ struct ccp_aes_cmac_req_ctx { struct ccp_cmd cmd; }; +struct ccp_aes_cmac_exp_ctx { + unsigned int null_msg; + + u8 iv[AES_BLOCK_SIZE]; + + unsigned int buf_count; + u8 buf[AES_BLOCK_SIZE]; +}; + /***** SHA related defines *****/ #define MAX_SHA_CONTEXT_SIZE SHA256_DIGEST_SIZE #define MAX_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE @@ -171,6 +180,19 @@ struct ccp_sha_req_ctx { struct ccp_cmd cmd; }; +struct ccp_sha_exp_ctx { + enum ccp_sha_type type; + + u64 msg_bits; + + unsigned int first; + + u8 ctx[MAX_SHA_CONTEXT_SIZE]; + + unsigned int buf_count; + u8 buf[MAX_SHA_BLOCK_SIZE]; +}; + /***** Common Context Structure *****/ struct ccp_ctx { int (*complete)(struct crypto_async_request *req, int ret); diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index e52496a172d0..2296934455fc 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -1031,6 +1031,18 @@ static int aead_perform(struct aead_request *req, int encrypt, BUG_ON(ivsize && !req->iv); memcpy(crypt->iv, req->iv, ivsize); + buf = chainup_buffers(dev, req->src, crypt->auth_len, + &src_hook, flags, src_direction); + req_ctx->src = src_hook.next; + crypt->src_buf = src_hook.phys_next; + if (!buf) + goto free_buf_src; + + lastlen = buf->buf_len; + if (lastlen >= authsize) + crypt->icv_rev_aes = buf->phys_addr + + buf->buf_len - authsize; + req_ctx->dst = NULL; if (req->src != req->dst) { @@ -1055,20 +1067,6 @@ static int aead_perform(struct aead_request *req, int encrypt, } } - buf = chainup_buffers(dev, req->src, crypt->auth_len, - &src_hook, flags, src_direction); - req_ctx->src = src_hook.next; - crypt->src_buf = src_hook.phys_next; - if (!buf) - goto free_buf_src; - - if (!encrypt || !req_ctx->dst) { - lastlen = buf->buf_len; - if (lastlen >= authsize) - crypt->icv_rev_aes = buf->phys_addr + - buf->buf_len - authsize; - } - if (unlikely(lastlen < authsize)) { /* The 12 hmac bytes are scattered, * we need to copy them into a safe buffer */ diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c index 0643e3366e33..c0656e7f37b5 100644 --- a/drivers/crypto/marvell/cesa.c +++ b/drivers/crypto/marvell/cesa.c @@ -306,7 +306,7 @@ static int mv_cesa_dev_dma_init(struct mv_cesa_dev *cesa) return -ENOMEM; dma->padding_pool = dmam_pool_create("cesa_padding", dev, 72, 1, 0); - if (!dma->cache_pool) + if (!dma->padding_pool) return -ENOMEM; cesa->dma = dma; diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c index 046c1c45411b..d94e25df503b 100644 --- a/drivers/crypto/nx/nx-842.c +++ b/drivers/crypto/nx/nx-842.c @@ -308,7 +308,7 @@ int nx842_crypto_compress(struct crypto_tfm *tfm, h = !n && add_header ? hdrsize : 0; if (ignore) - pr_warn("interal error, ignore is set %x\n", ignore); + pr_warn("internal error, ignore is set %x\n", ignore); ret = compress(ctx, &p, &hdr->group[n], &c, &ignore, h); if (ret) diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index dd355bd19474..d420ec751c7c 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -36,6 +36,7 @@ #include #include #include +#include #define DST_MAXBURST 4 #define DMA_MIN (DST_MAXBURST * sizeof(u32)) @@ -152,13 +153,10 @@ struct omap_aes_dev { unsigned long flags; int err; - spinlock_t lock; - struct crypto_queue queue; - struct tasklet_struct done_task; - struct tasklet_struct queue_task; struct ablkcipher_request *req; + struct crypto_engine *engine; /* * total is used by PIO mode for book keeping so introduce @@ -532,9 +530,7 @@ static void omap_aes_finish_req(struct omap_aes_dev *dd, int err) pr_debug("err: %d\n", err); - dd->flags &= ~FLAGS_BUSY; - - req->base.complete(&req->base, err); + crypto_finalize_request(dd->engine, req, err); } static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd) @@ -604,34 +600,25 @@ static int omap_aes_copy_sgs(struct omap_aes_dev *dd) } static int omap_aes_handle_queue(struct omap_aes_dev *dd, - struct ablkcipher_request *req) + struct ablkcipher_request *req) { - struct crypto_async_request *async_req, *backlog; - struct omap_aes_ctx *ctx; - struct omap_aes_reqctx *rctx; - unsigned long flags; - int err, ret = 0, len; - - spin_lock_irqsave(&dd->lock, flags); if (req) - ret = ablkcipher_enqueue_request(&dd->queue, req); - if (dd->flags & FLAGS_BUSY) { - spin_unlock_irqrestore(&dd->lock, flags); - return ret; - } - backlog = crypto_get_backlog(&dd->queue); - async_req = crypto_dequeue_request(&dd->queue); - if (async_req) - dd->flags |= FLAGS_BUSY; - spin_unlock_irqrestore(&dd->lock, flags); + return crypto_transfer_request_to_engine(dd->engine, req); - if (!async_req) - return ret; + return 0; +} - if (backlog) - backlog->complete(backlog, -EINPROGRESS); +static int omap_aes_prepare_req(struct crypto_engine *engine, + struct ablkcipher_request *req) +{ + struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + struct omap_aes_dev *dd = omap_aes_find_dev(ctx); + struct omap_aes_reqctx *rctx; + int len; - req = ablkcipher_request_cast(async_req); + if (!dd) + return -ENODEV; /* assign new request to device */ dd->req = req; @@ -662,16 +649,20 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd, dd->ctx = ctx; ctx->dd = dd; - err = omap_aes_write_ctrl(dd); - if (!err) - err = omap_aes_crypt_dma_start(dd); - if (err) { - /* aes_task will not finish it, so do it here */ - omap_aes_finish_req(dd, err); - tasklet_schedule(&dd->queue_task); - } + return omap_aes_write_ctrl(dd); +} - return ret; /* return ret, which is enqueue return value */ +static int omap_aes_crypt_req(struct crypto_engine *engine, + struct ablkcipher_request *req) +{ + struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + struct omap_aes_dev *dd = omap_aes_find_dev(ctx); + + if (!dd) + return -ENODEV; + + return omap_aes_crypt_dma_start(dd); } static void omap_aes_done_task(unsigned long data) @@ -704,18 +695,10 @@ static void omap_aes_done_task(unsigned long data) } omap_aes_finish_req(dd, 0); - omap_aes_handle_queue(dd, NULL); pr_debug("exit\n"); } -static void omap_aes_queue_task(unsigned long data) -{ - struct omap_aes_dev *dd = (struct omap_aes_dev *)data; - - omap_aes_handle_queue(dd, NULL); -} - static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode) { struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx( @@ -1175,9 +1158,6 @@ static int omap_aes_probe(struct platform_device *pdev) dd->dev = dev; platform_set_drvdata(pdev, dd); - spin_lock_init(&dd->lock); - crypto_init_queue(&dd->queue, OMAP_AES_QUEUE_LENGTH); - err = (dev->of_node) ? omap_aes_get_res_of(dd, dev, &res) : omap_aes_get_res_pdev(dd, pdev, &res); if (err) @@ -1209,7 +1189,6 @@ static int omap_aes_probe(struct platform_device *pdev) (reg & dd->pdata->minor_mask) >> dd->pdata->minor_shift); tasklet_init(&dd->done_task, omap_aes_done_task, (unsigned long)dd); - tasklet_init(&dd->queue_task, omap_aes_queue_task, (unsigned long)dd); err = omap_aes_dma_init(dd); if (err && AES_REG_IRQ_STATUS(dd) && AES_REG_IRQ_ENABLE(dd)) { @@ -1250,7 +1229,20 @@ static int omap_aes_probe(struct platform_device *pdev) } } + /* Initialize crypto engine */ + dd->engine = crypto_engine_alloc_init(dev, 1); + if (!dd->engine) + goto err_algs; + + dd->engine->prepare_request = omap_aes_prepare_req; + dd->engine->crypt_one_request = omap_aes_crypt_req; + err = crypto_engine_start(dd->engine); + if (err) + goto err_engine; + return 0; +err_engine: + crypto_engine_exit(dd->engine); err_algs: for (i = dd->pdata->algs_info_size - 1; i >= 0; i--) for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) @@ -1260,7 +1252,6 @@ err_algs: omap_aes_dma_cleanup(dd); err_irq: tasklet_kill(&dd->done_task); - tasklet_kill(&dd->queue_task); pm_runtime_disable(dev); err_res: dd = NULL; @@ -1286,8 +1277,8 @@ static int omap_aes_remove(struct platform_device *pdev) crypto_unregister_alg( &dd->pdata->algs_info[i].algs_list[j]); + crypto_engine_exit(dd->engine); tasklet_kill(&dd->done_task); - tasklet_kill(&dd->queue_task); omap_aes_dma_cleanup(dd); pm_runtime_disable(dd->dev); dd = NULL; diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h index f96d427e502c..5a07208ce778 100644 --- a/drivers/crypto/qat/qat_common/adf_accel_devices.h +++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h @@ -55,8 +55,8 @@ #define ADF_DH895XCC_DEVICE_NAME "dh895xcc" #define ADF_DH895XCCVF_DEVICE_NAME "dh895xccvf" -#define ADF_C62X_DEVICE_NAME "c62x" -#define ADF_C62XVF_DEVICE_NAME "c62xvf" +#define ADF_C62X_DEVICE_NAME "c6xx" +#define ADF_C62XVF_DEVICE_NAME "c6xxvf" #define ADF_C3XXX_DEVICE_NAME "c3xxx" #define ADF_C3XXXVF_DEVICE_NAME "c3xxxvf" #define ADF_DH895XCC_PCI_DEVICE_ID 0x435 diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c index e78a1d7d88fc..b40d9c8dad96 100644 --- a/drivers/crypto/qat/qat_common/adf_aer.c +++ b/drivers/crypto/qat/qat_common/adf_aer.c @@ -121,7 +121,6 @@ static void adf_device_reset_worker(struct work_struct *work) adf_dev_restarting_notify(accel_dev); adf_dev_stop(accel_dev); adf_dev_shutdown(accel_dev); - adf_dev_restore(accel_dev); if (adf_dev_init(accel_dev) || adf_dev_start(accel_dev)) { /* The device hanged and we can't restart it so stop here */ dev_err(&GET_DEV(accel_dev), "Restart device failed\n"); diff --git a/drivers/crypto/qat/qat_common/adf_cfg_user.h b/drivers/crypto/qat/qat_common/adf_cfg_user.h index ef5988afd4c6..b5484bfa6996 100644 --- a/drivers/crypto/qat/qat_common/adf_cfg_user.h +++ b/drivers/crypto/qat/qat_common/adf_cfg_user.h @@ -58,7 +58,7 @@ struct adf_user_cfg_key_val { uint64_t padding3; }; enum adf_cfg_val_type type; -}; +} __packed; struct adf_user_cfg_section { char name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES]; @@ -70,7 +70,7 @@ struct adf_user_cfg_section { struct adf_user_cfg_section *next; uint64_t padding3; }; -}; +} __packed; struct adf_user_cfg_ctl_data { union { @@ -78,5 +78,5 @@ struct adf_user_cfg_ctl_data { uint64_t padding; }; uint8_t device_id; -}; +} __packed; #endif diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c index 59e4c3af15ed..1e8852a8a057 100644 --- a/drivers/crypto/qat/qat_common/qat_algs.c +++ b/drivers/crypto/qat/qat_common/qat_algs.c @@ -1064,8 +1064,7 @@ static int qat_alg_aead_init(struct crypto_aead *tfm, if (IS_ERR(ctx->hash_tfm)) return PTR_ERR(ctx->hash_tfm); ctx->qat_hash_alg = hash; - crypto_aead_set_reqsize(tfm, sizeof(struct aead_request) + - sizeof(struct qat_crypto_request)); + crypto_aead_set_reqsize(tfm, sizeof(struct qat_crypto_request)); return 0; } @@ -1114,8 +1113,7 @@ static int qat_alg_ablkcipher_init(struct crypto_tfm *tfm) struct qat_alg_ablkcipher_ctx *ctx = crypto_tfm_ctx(tfm); spin_lock_init(&ctx->lock); - tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + - sizeof(struct qat_crypto_request); + tfm->crt_ablkcipher.reqsize = sizeof(struct qat_crypto_request); ctx->tfm = tfm; return 0; } diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c index f214a8755827..5f161a9777e3 100644 --- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c @@ -224,6 +224,7 @@ static inline struct samsung_aes_variant *find_s5p_sss_version { if (IS_ENABLED(CONFIG_OF) && (pdev->dev.of_node)) { const struct of_device_id *match; + match = of_match_node(s5p_sss_dt_match, pdev->dev.of_node); return (struct samsung_aes_variant *)match->data; @@ -382,7 +383,7 @@ static void s5p_set_aes(struct s5p_aes_dev *dev, void __iomem *keystart; if (iv) - memcpy(dev->aes_ioaddr + SSS_REG_AES_IV_DATA(0), iv, 0x10); + memcpy_toio(dev->aes_ioaddr + SSS_REG_AES_IV_DATA(0), iv, 0x10); if (keylen == AES_KEYSIZE_256) keystart = dev->aes_ioaddr + SSS_REG_AES_KEY_DATA(0); @@ -391,13 +392,12 @@ static void s5p_set_aes(struct s5p_aes_dev *dev, else keystart = dev->aes_ioaddr + SSS_REG_AES_KEY_DATA(4); - memcpy(keystart, key, keylen); + memcpy_toio(keystart, key, keylen); } static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode) { struct ablkcipher_request *req = dev->req; - uint32_t aes_control; int err; unsigned long flags; @@ -518,7 +518,7 @@ static int s5p_aes_crypt(struct ablkcipher_request *req, unsigned long mode) struct s5p_aes_dev *dev = ctx->dev; if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) { - pr_err("request size is not exact amount of AES blocks\n"); + dev_err(dev->dev, "request size is not exact amount of AES blocks\n"); return -EINVAL; } @@ -566,7 +566,7 @@ static int s5p_aes_cbc_decrypt(struct ablkcipher_request *req) static int s5p_aes_cra_init(struct crypto_tfm *tfm) { - struct s5p_aes_ctx *ctx = crypto_tfm_ctx(tfm); + struct s5p_aes_ctx *ctx = crypto_tfm_ctx(tfm); ctx->dev = s5p_dev; tfm->crt_ablkcipher.reqsize = sizeof(struct s5p_aes_reqctx); @@ -701,7 +701,7 @@ static int s5p_aes_probe(struct platform_device *pdev) goto err_algs; } - pr_info("s5p-sss driver registered\n"); + dev_info(dev, "s5p-sss driver registered\n"); return 0; diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c index 6c4f91c5e6b3..c3f3d89e4831 100644 --- a/drivers/crypto/sahara.c +++ b/drivers/crypto/sahara.c @@ -182,7 +182,6 @@ struct sahara_sha_reqctx { u8 buf[SAHARA_MAX_SHA_BLOCK_SIZE]; u8 rembuf[SAHARA_MAX_SHA_BLOCK_SIZE]; u8 context[SHA256_DIGEST_SIZE + 4]; - struct mutex mutex; unsigned int mode; unsigned int digest_size; unsigned int context_size; @@ -1096,7 +1095,6 @@ static int sahara_sha_enqueue(struct ahash_request *req, int last) if (!req->nbytes && !last) return 0; - mutex_lock(&rctx->mutex); rctx->last = last; if (!rctx->active) { @@ -1109,7 +1107,6 @@ static int sahara_sha_enqueue(struct ahash_request *req, int last) mutex_unlock(&dev->queue_mutex); wake_up_process(dev->kthread); - mutex_unlock(&rctx->mutex); return ret; } @@ -1137,8 +1134,6 @@ static int sahara_sha_init(struct ahash_request *req) rctx->context_size = rctx->digest_size + 4; rctx->active = 0; - mutex_init(&rctx->mutex); - return 0; } @@ -1167,26 +1162,18 @@ static int sahara_sha_digest(struct ahash_request *req) static int sahara_sha_export(struct ahash_request *req, void *out) { - struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); - struct sahara_ctx *ctx = crypto_ahash_ctx(ahash); struct sahara_sha_reqctx *rctx = ahash_request_ctx(req); - memcpy(out, ctx, sizeof(struct sahara_ctx)); - memcpy(out + sizeof(struct sahara_sha_reqctx), rctx, - sizeof(struct sahara_sha_reqctx)); + memcpy(out, rctx, sizeof(struct sahara_sha_reqctx)); return 0; } static int sahara_sha_import(struct ahash_request *req, const void *in) { - struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); - struct sahara_ctx *ctx = crypto_ahash_ctx(ahash); struct sahara_sha_reqctx *rctx = ahash_request_ctx(req); - memcpy(ctx, in, sizeof(struct sahara_ctx)); - memcpy(rctx, in + sizeof(struct sahara_sha_reqctx), - sizeof(struct sahara_sha_reqctx)); + memcpy(rctx, in, sizeof(struct sahara_sha_reqctx)); return 0; } @@ -1272,6 +1259,7 @@ static struct ahash_alg sha_v3_algs[] = { .export = sahara_sha_export, .import = sahara_sha_import, .halg.digestsize = SHA1_DIGEST_SIZE, + .halg.statesize = sizeof(struct sahara_sha_reqctx), .halg.base = { .cra_name = "sha1", .cra_driver_name = "sahara-sha1", @@ -1299,6 +1287,7 @@ static struct ahash_alg sha_v4_algs[] = { .export = sahara_sha_export, .import = sahara_sha_import, .halg.digestsize = SHA256_DIGEST_SIZE, + .halg.statesize = sizeof(struct sahara_sha_reqctx), .halg.base = { .cra_name = "sha256", .cra_driver_name = "sahara-sha256", diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c index a19ee127edca..7be3fbcd8d78 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c @@ -251,11 +251,10 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) spaces = readl(ss->base + SS_FCSR); rx_cnt = SS_RXFIFO_SPACES(spaces); tx_cnt = SS_TXFIFO_SPACES(spaces); - dev_dbg(ss->dev, "%x %u/%u %u/%u cnt=%u %u/%u %u/%u cnt=%u %u %u\n", + dev_dbg(ss->dev, "%x %u/%u %u/%u cnt=%u %u/%u %u/%u cnt=%u %u\n", mode, oi, mi.length, ileft, areq->nbytes, rx_cnt, - oo, mo.length, oleft, areq->nbytes, tx_cnt, - todo, ob); + oo, mo.length, oleft, areq->nbytes, tx_cnt, ob); if (tx_cnt == 0) continue; diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 155c1464948e..b2ac13b4ddaa 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -539,13 +539,11 @@ EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); * preparations. Coherency is only guaranteed in the specified range for the * specified access direction. * @dmabuf: [in] buffer to prepare cpu access for. - * @start: [in] start of range for cpu access. - * @len: [in] length of range for cpu access. * @direction: [in] length of range for cpu access. * * Can return negative error values, returns 0 on success. */ -int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, +int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction) { int ret = 0; @@ -554,8 +552,7 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, return -EINVAL; if (dmabuf->ops->begin_cpu_access) - ret = dmabuf->ops->begin_cpu_access(dmabuf, start, - len, direction); + ret = dmabuf->ops->begin_cpu_access(dmabuf, direction); return ret; } @@ -567,19 +564,17 @@ EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); * actions. Coherency is only guaranteed in the specified range for the * specified access direction. * @dmabuf: [in] buffer to complete cpu access for. - * @start: [in] start of range for cpu access. - * @len: [in] length of range for cpu access. * @direction: [in] length of range for cpu access. * * This call must always succeed. */ -void dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, +void dma_buf_end_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction) { WARN_ON(!dmabuf); if (dmabuf->ops->end_cpu_access) - dmabuf->ops->end_cpu_access(dmabuf, start, len, direction); + dmabuf->ops->end_cpu_access(dmabuf, direction); } EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index c50a247be2e0..0cb259c59916 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -496,6 +496,7 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) caps->src_addr_widths = device->src_addr_widths; caps->dst_addr_widths = device->dst_addr_widths; caps->directions = device->directions; + caps->max_burst = device->max_burst; caps->residue_granularity = device->residue_granularity; caps->descriptor_reuse = device->descriptor_reuse; diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index e893318560db..74417e7e3ec8 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -507,8 +507,10 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc) * controller flagged an error instead of scribbling over * random memory locations. */ - dev_WARN(chan2dev(&dwc->chan), "Bad descriptor submitted for DMA!\n" - " cookie: %d\n", bad_desc->txd.cookie); + dev_WARN(chan2dev(&dwc->chan), true, + "Bad descriptor submitted for DMA!\n cookie: %d\n", + bad_desc->txd.cookie); + dwc_dump_lli(dwc, &bad_desc->lli); list_for_each_entry(child, &bad_desc->tx_list, desc_node) dwc_dump_lli(dwc, &child->lli); diff --git a/drivers/dma/dw/pci.c b/drivers/dma/dw/pci.c index 4c30fdd092b3..358f9689a3f5 100644 --- a/drivers/dma/dw/pci.c +++ b/drivers/dma/dw/pci.c @@ -108,6 +108,10 @@ static const struct pci_device_id dw_pci_id_table[] = { /* Haswell */ { PCI_VDEVICE(INTEL, 0x9c60) }, + + /* Broadwell */ + { PCI_VDEVICE(INTEL, 0x9ce0) }, + { } }; MODULE_DEVICE_TABLE(pci, dw_pci_id_table); diff --git a/drivers/dma/dw/regs.h b/drivers/dma/dw/regs.h index 241ff2b1402b..0a50c18d85b8 100644 --- a/drivers/dma/dw/regs.h +++ b/drivers/dma/dw/regs.h @@ -150,7 +150,7 @@ enum dw_dma_msize { #define DWC_CTLL_DST_INC (0<<7) /* DAR update/not */ #define DWC_CTLL_DST_DEC (1<<7) #define DWC_CTLL_DST_FIX (2<<7) -#define DWC_CTLL_SRC_INC (0<<7) /* SAR update/not */ +#define DWC_CTLL_SRC_INC (0<<9) /* SAR update/not */ #define DWC_CTLL_SRC_DEC (1<<9) #define DWC_CTLL_SRC_FIX (2<<9) #define DWC_CTLL_DST_MSIZE(n) ((n)<<11) /* burst, #elements */ diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index d92d65549406..e3d7fcb69b4c 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -113,6 +113,9 @@ #define GET_NUM_REGN(x) ((x & 0x300000) >> 20) /* bits 20-21 */ #define CHMAP_EXIST BIT(24) +/* CCSTAT register */ +#define EDMA_CCSTAT_ACTV BIT(4) + /* * Max of 20 segments per channel to conserve PaRAM slots * Also note that MAX_NR_SG should be atleast the no.of periods @@ -1680,9 +1683,20 @@ static void edma_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&echan->vchan.lock, flags); } +/* + * This limit exists to avoid a possible infinite loop when waiting for proof + * that a particular transfer is completed. This limit can be hit if there + * are large bursts to/from slow devices or the CPU is never able to catch + * the DMA hardware idle. On an AM335x transfering 48 bytes from the UART + * RX-FIFO, as many as 55 loops have been seen. + */ +#define EDMA_MAX_TR_WAIT_LOOPS 1000 + static u32 edma_residue(struct edma_desc *edesc) { bool dst = edesc->direction == DMA_DEV_TO_MEM; + int loop_count = EDMA_MAX_TR_WAIT_LOOPS; + struct edma_chan *echan = edesc->echan; struct edma_pset *pset = edesc->pset; dma_addr_t done, pos; int i; @@ -1691,7 +1705,32 @@ static u32 edma_residue(struct edma_desc *edesc) * We always read the dst/src position from the first RamPar * pset. That's the one which is active now. */ - pos = edma_get_position(edesc->echan->ecc, edesc->echan->slot[0], dst); + pos = edma_get_position(echan->ecc, echan->slot[0], dst); + + /* + * "pos" may represent a transfer request that is still being + * processed by the EDMACC or EDMATC. We will busy wait until + * any one of the situations occurs: + * 1. the DMA hardware is idle + * 2. a new transfer request is setup + * 3. we hit the loop limit + */ + while (edma_read(echan->ecc, EDMA_CCSTAT) & EDMA_CCSTAT_ACTV) { + /* check if a new transfer request is setup */ + if (edma_get_position(echan->ecc, + echan->slot[0], dst) != pos) { + break; + } + + if (!--loop_count) { + dev_dbg_ratelimited(echan->vchan.chan.device->dev, + "%s: timeout waiting for PaRAM update\n", + __func__); + break; + } + + cpu_relax(); + } /* * Cyclic is simple. Just subtract pset[0].addr from pos. diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index 57ff46284f15..21f08cc3352b 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c @@ -421,23 +421,25 @@ static int m2p_hw_interrupt(struct ep93xx_dma_chan *edmac) desc->size); } - switch (irq_status & (M2P_INTERRUPT_STALL | M2P_INTERRUPT_NFB)) { - case M2P_INTERRUPT_STALL: - /* Disable interrupts */ - control = readl(edmac->regs + M2P_CONTROL); - control &= ~(M2P_CONTROL_STALLINT | M2P_CONTROL_NFBINT); - m2p_set_control(edmac, control); - - return INTERRUPT_DONE; - - case M2P_INTERRUPT_NFB: - if (ep93xx_dma_advance_active(edmac)) - m2p_fill_desc(edmac); + /* + * Even latest E2 silicon revision sometimes assert STALL interrupt + * instead of NFB. Therefore we treat them equally, basing on the + * amount of data we still have to transfer. + */ + if (!(irq_status & (M2P_INTERRUPT_STALL | M2P_INTERRUPT_NFB))) + return INTERRUPT_UNKNOWN; + if (ep93xx_dma_advance_active(edmac)) { + m2p_fill_desc(edmac); return INTERRUPT_NEXT_BUFFER; } - return INTERRUPT_UNKNOWN; + /* Disable interrupts */ + control = readl(edmac->regs + M2P_CONTROL); + control &= ~(M2P_CONTROL_STALLINT | M2P_CONTROL_NFBINT); + m2p_set_control(edmac, control); + + return INTERRUPT_DONE; } /* diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 1d5df2ef148b..21539d5c54c3 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -861,32 +861,42 @@ void ioat_timer_event(unsigned long data) return; } + spin_lock_bh(&ioat_chan->cleanup_lock); + + /* handle the no-actives case */ + if (!ioat_ring_active(ioat_chan)) { + spin_lock_bh(&ioat_chan->prep_lock); + check_active(ioat_chan); + spin_unlock_bh(&ioat_chan->prep_lock); + spin_unlock_bh(&ioat_chan->cleanup_lock); + return; + } + /* if we haven't made progress and we have already * acknowledged a pending completion once, then be more * forceful with a restart */ - spin_lock_bh(&ioat_chan->cleanup_lock); if (ioat_cleanup_preamble(ioat_chan, &phys_complete)) __cleanup(ioat_chan, phys_complete); else if (test_bit(IOAT_COMPLETION_ACK, &ioat_chan->state)) { + u32 chanerr; + + chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); + dev_warn(to_dev(ioat_chan), "Restarting channel...\n"); + dev_warn(to_dev(ioat_chan), "CHANSTS: %#Lx CHANERR: %#x\n", + status, chanerr); + dev_warn(to_dev(ioat_chan), "Active descriptors: %d\n", + ioat_ring_active(ioat_chan)); + spin_lock_bh(&ioat_chan->prep_lock); ioat_restart_channel(ioat_chan); spin_unlock_bh(&ioat_chan->prep_lock); spin_unlock_bh(&ioat_chan->cleanup_lock); return; - } else { + } else set_bit(IOAT_COMPLETION_ACK, &ioat_chan->state); - mod_timer(&ioat_chan->timer, jiffies + COMPLETION_TIMEOUT); - } - - if (ioat_ring_active(ioat_chan)) - mod_timer(&ioat_chan->timer, jiffies + COMPLETION_TIMEOUT); - else { - spin_lock_bh(&ioat_chan->prep_lock); - check_active(ioat_chan); - spin_unlock_bh(&ioat_chan->prep_lock); - } + mod_timer(&ioat_chan->timer, jiffies + COMPLETION_TIMEOUT); spin_unlock_bh(&ioat_chan->cleanup_lock); } diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c index 4ef0c5e07912..b49b2944e38d 100644 --- a/drivers/dma/ioat/init.c +++ b/drivers/dma/ioat/init.c @@ -741,7 +741,7 @@ static int ioat_alloc_chan_resources(struct dma_chan *c) chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); - dev_WARN(to_dev(ioat_chan), + dev_WARN(to_dev(ioat_chan), true, "failed to start channel chanerr: %#x\n", chanerr); ioat_free_chan_resources(c); return -EFAULT; diff --git a/drivers/dma/ioat/prep.c b/drivers/dma/ioat/prep.c index 6bb4a13a8fbd..243421af888f 100644 --- a/drivers/dma/ioat/prep.c +++ b/drivers/dma/ioat/prep.c @@ -26,7 +26,7 @@ #include "hw.h" #include "dma.h" -#define MAX_SCF 1024 +#define MAX_SCF 256 /* provide a lookup table for setting the source address in the base or * extended descriptor of an xor or pq descriptor diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 17ee758b419f..1b0453b9e32d 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -33,6 +33,9 @@ #define PL330_MAX_CHAN 8 #define PL330_MAX_IRQS 32 #define PL330_MAX_PERI 32 +#define PL330_MAX_BURST 16 + +#define PL330_QUIRK_BROKEN_NO_FLUSHP BIT(0) enum pl330_cachectrl { CCTRL0, /* Noncacheable and nonbufferable */ @@ -488,6 +491,17 @@ struct pl330_dmac { /* Peripheral channels connected to this DMAC */ unsigned int num_peripherals; struct dma_pl330_chan *peripherals; /* keep at end */ + int quirks; +}; + +static struct pl330_of_quirks { + char *quirk; + int id; +} of_quirks[] = { + { + .quirk = "arm,pl330-broken-no-flushp", + .id = PL330_QUIRK_BROKEN_NO_FLUSHP, + } }; struct dma_pl330_desc { @@ -1137,47 +1151,68 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 buf[], return off; } -static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs, int cyc) +static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run, + u8 buf[], const struct _xfer_spec *pxs, + int cyc) { int off = 0; + enum pl330_cond cond; + + if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) + cond = BURST; + else + cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; while (cyc--) { - off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri); - off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->desc->peri); + off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri); + off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri); off += _emit_ST(dry_run, &buf[off], ALWAYS); - off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); + + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, &buf[off], + pxs->desc->peri); } return off; } -static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs, int cyc) +static inline int _ldst_memtodev(struct pl330_dmac *pl330, + unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs, int cyc) { int off = 0; + enum pl330_cond cond; + + if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) + cond = BURST; + else + cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; + while (cyc--) { - off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri); + off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri); off += _emit_LD(dry_run, &buf[off], ALWAYS); - off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri); - off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); + off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri); + + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, &buf[off], + pxs->desc->peri); } return off; } -static int _bursts(unsigned dry_run, u8 buf[], +static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], const struct _xfer_spec *pxs, int cyc) { int off = 0; switch (pxs->desc->rqtype) { case DMA_MEM_TO_DEV: - off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc); + off += _ldst_memtodev(pl330, dry_run, &buf[off], pxs, cyc); break; case DMA_DEV_TO_MEM: - off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc); + off += _ldst_devtomem(pl330, dry_run, &buf[off], pxs, cyc); break; case DMA_MEM_TO_MEM: off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc); @@ -1191,7 +1226,7 @@ static int _bursts(unsigned dry_run, u8 buf[], } /* Returns bytes consumed and updates bursts */ -static inline int _loop(unsigned dry_run, u8 buf[], +static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], unsigned long *bursts, const struct _xfer_spec *pxs) { int cyc, cycmax, szlp, szlpend, szbrst, off; @@ -1199,7 +1234,7 @@ static inline int _loop(unsigned dry_run, u8 buf[], struct _arg_LPEND lpend; if (*bursts == 1) - return _bursts(dry_run, buf, pxs, 1); + return _bursts(pl330, dry_run, buf, pxs, 1); /* Max iterations possible in DMALP is 256 */ if (*bursts >= 256*256) { @@ -1217,7 +1252,7 @@ static inline int _loop(unsigned dry_run, u8 buf[], } szlp = _emit_LP(1, buf, 0, 0); - szbrst = _bursts(1, buf, pxs, 1); + szbrst = _bursts(pl330, 1, buf, pxs, 1); lpend.cond = ALWAYS; lpend.forever = false; @@ -1249,7 +1284,7 @@ static inline int _loop(unsigned dry_run, u8 buf[], off += _emit_LP(dry_run, &buf[off], 1, lcnt1); ljmp1 = off; - off += _bursts(dry_run, &buf[off], pxs, cyc); + off += _bursts(pl330, dry_run, &buf[off], pxs, cyc); lpend.cond = ALWAYS; lpend.forever = false; @@ -1272,8 +1307,9 @@ static inline int _loop(unsigned dry_run, u8 buf[], return off; } -static inline int _setup_loops(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs) +static inline int _setup_loops(struct pl330_dmac *pl330, + unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs) { struct pl330_xfer *x = &pxs->desc->px; u32 ccr = pxs->ccr; @@ -1282,15 +1318,16 @@ static inline int _setup_loops(unsigned dry_run, u8 buf[], while (bursts) { c = bursts; - off += _loop(dry_run, &buf[off], &c, pxs); + off += _loop(pl330, dry_run, &buf[off], &c, pxs); bursts -= c; } return off; } -static inline int _setup_xfer(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs) +static inline int _setup_xfer(struct pl330_dmac *pl330, + unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs) { struct pl330_xfer *x = &pxs->desc->px; int off = 0; @@ -1301,7 +1338,7 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[], off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); /* Setup Loop(s) */ - off += _setup_loops(dry_run, &buf[off], pxs); + off += _setup_loops(pl330, dry_run, &buf[off], pxs); return off; } @@ -1310,8 +1347,9 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[], * A req is a sequence of one or more xfer units. * Returns the number of bytes taken to setup the MC for the req. */ -static int _setup_req(unsigned dry_run, struct pl330_thread *thrd, - unsigned index, struct _xfer_spec *pxs) +static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run, + struct pl330_thread *thrd, unsigned index, + struct _xfer_spec *pxs) { struct _pl330_req *req = &thrd->req[index]; struct pl330_xfer *x; @@ -1328,7 +1366,7 @@ static int _setup_req(unsigned dry_run, struct pl330_thread *thrd, if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) return -EINVAL; - off += _setup_xfer(dry_run, &buf[off], pxs); + off += _setup_xfer(pl330, dry_run, &buf[off], pxs); /* DMASEV peripheral/event */ off += _emit_SEV(dry_run, &buf[off], thrd->ev); @@ -1422,7 +1460,7 @@ static int pl330_submit_req(struct pl330_thread *thrd, xs.desc = desc; /* First dry run to check if req is acceptable */ - ret = _setup_req(1, thrd, idx, &xs); + ret = _setup_req(pl330, 1, thrd, idx, &xs); if (ret < 0) goto xfer_exit; @@ -1436,7 +1474,7 @@ static int pl330_submit_req(struct pl330_thread *thrd, /* Hook the request */ thrd->lstenq = idx; thrd->req[idx].desc = desc; - _setup_req(0, thrd, idx, &xs); + _setup_req(pl330, 0, thrd, idx, &xs); ret = 0; @@ -2560,7 +2598,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( desc->rqtype = direction; desc->rqcfg.brst_size = pch->burst_sz; - desc->rqcfg.brst_len = 1; + desc->rqcfg.brst_len = pch->burst_len; desc->bytes_requested = period_len; fill_px(&desc->px, dst, src, period_len); @@ -2705,7 +2743,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, } desc->rqcfg.brst_size = pch->burst_sz; - desc->rqcfg.brst_len = 1; + desc->rqcfg.brst_len = pch->burst_len; desc->rqtype = direction; desc->bytes_requested = sg_dma_len(sg); } @@ -2781,6 +2819,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res; int i, ret, irq; int num_chan; + struct device_node *np = adev->dev.of_node; pdat = dev_get_platdata(&adev->dev); @@ -2800,6 +2839,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0; + /* get quirk */ + for (i = 0; i < ARRAY_SIZE(of_quirks); i++) + if (of_property_read_bool(np, of_quirks[i].quirk)) + pl330->quirks |= of_quirks[i].id; + res = &adev->res; pl330->base = devm_ioremap_resource(&adev->dev, res); if (IS_ERR(pl330->base)) @@ -2895,6 +2939,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pd->dst_addr_widths = PL330_DMA_BUSWIDTHS; pd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); pd->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; + pd->max_burst = ((pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) ? + 1 : PL330_MAX_BURST); ret = dma_async_device_register(pd); if (ret) { diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig index f32c430eb16c..6e0685f1a838 100644 --- a/drivers/dma/sh/Kconfig +++ b/drivers/dma/sh/Kconfig @@ -12,7 +12,7 @@ config RENESAS_DMA config SH_DMAE_BASE bool "Renesas SuperH DMA Engine support" - depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST + depends on SUPERH || ARCH_RENESAS || COMPILE_TEST depends on !SUPERH || SH_DMA depends on !SH_DMA_API default y @@ -41,7 +41,7 @@ endif config RCAR_DMAC tristate "Renesas R-Car Gen2 DMA Controller" - depends on ARCH_SHMOBILE || COMPILE_TEST + depends on ARCH_RENESAS || COMPILE_TEST select RENESAS_DMA help This driver supports the general purpose DMA controller found in the @@ -49,7 +49,7 @@ config RCAR_DMAC config RENESAS_USB_DMAC tristate "Renesas USB-DMA Controller" - depends on ARCH_SHMOBILE || COMPILE_TEST + depends on ARCH_RENESAS || COMPILE_TEST select RENESAS_DMA select DMA_VIRTUAL_CHANNELS help diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 9eee13ef83a5..d87a47547ba5 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1452,7 +1452,7 @@ static u64 f1x_get_norm_dct_addr(struct amd64_pvt *pvt, u8 range, u64 chan_off; u64 dram_base = get_dram_base(pvt, range); u64 hole_off = f10_dhar_offset(pvt); - u64 dct_sel_base_off = (pvt->dct_sel_hi & 0xFFFFFC00) << 16; + u64 dct_sel_base_off = (u64)(pvt->dct_sel_hi & 0xFFFFFC00) << 16; if (hi_rng) { /* diff --git a/drivers/edac/debugfs.c b/drivers/edac/debugfs.c index 54d2f668cb0a..92dbb7e2320c 100644 --- a/drivers/edac/debugfs.c +++ b/drivers/edac/debugfs.c @@ -53,7 +53,7 @@ int __init edac_debugfs_init(void) void edac_debugfs_exit(void) { - debugfs_remove(edac_debugfs); + debugfs_remove_recursive(edac_debugfs); } int edac_create_debugfs_nodes(struct mem_ctl_info *mci) diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 8adfc167c2e3..1472f48c8ac6 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -535,59 +535,20 @@ static void edac_mc_workq_function(struct work_struct *work_req) mutex_lock(&mem_ctls_mutex); - /* if this control struct has movd to offline state, we are done */ - if (mci->op_state == OP_OFFLINE) { + if (mci->op_state != OP_RUNNING_POLL) { mutex_unlock(&mem_ctls_mutex); return; } - /* Only poll controllers that are running polled and have a check */ - if (edac_mc_assert_error_check_and_clear() && (mci->edac_check != NULL)) + if (edac_mc_assert_error_check_and_clear()) mci->edac_check(mci); mutex_unlock(&mem_ctls_mutex); - /* Reschedule */ + /* Queue ourselves again. */ edac_queue_work(&mci->work, msecs_to_jiffies(edac_mc_get_poll_msec())); } -/* - * edac_mc_workq_setup - * initialize a workq item for this mci - * passing in the new delay period in msec - * - * locking model: - * - * called with the mem_ctls_mutex held - */ -static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec) -{ - edac_dbg(0, "\n"); - - /* if this instance is not in the POLL state, then simply return */ - if (mci->op_state != OP_RUNNING_POLL) - return; - - INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function); - - edac_queue_work(&mci->work, msecs_to_jiffies(msec)); -} - -/* - * edac_mc_workq_teardown - * stop the workq processing on this mci - * - * locking model: - * - * called WITHOUT lock held - */ -static void edac_mc_workq_teardown(struct mem_ctl_info *mci) -{ - mci->op_state = OP_OFFLINE; - - edac_stop_work(&mci->work); -} - /* * edac_mc_reset_delay_period(unsigned long value) * @@ -771,12 +732,12 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci, goto fail1; } - /* If there IS a check routine, then we are running POLLED */ - if (mci->edac_check != NULL) { - /* This instance is NOW RUNNING */ + if (mci->edac_check) { mci->op_state = OP_RUNNING_POLL; - edac_mc_workq_setup(mci, edac_mc_get_poll_msec()); + INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function); + edac_queue_work(&mci->work, msecs_to_jiffies(edac_mc_get_poll_msec())); + } else { mci->op_state = OP_RUNNING_INTERRUPT; } @@ -823,15 +784,16 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev) return NULL; } + /* mark MCI offline: */ + mci->op_state = OP_OFFLINE; + if (!del_mc_from_global_list(mci)) edac_mc_owner = NULL; - mutex_unlock(&mem_ctls_mutex); - /* flush workq processes */ - edac_mc_workq_teardown(mci); + mutex_unlock(&mem_ctls_mutex); - /* marking MCI offline */ - mci->op_state = OP_OFFLINE; + if (mci->edac_check) + edac_stop_work(&mci->work); /* remove from sysfs */ edac_remove_sysfs_mci_device(mci); diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c index 99685388d3fb..8f2f2899a7a2 100644 --- a/drivers/edac/edac_pci.c +++ b/drivers/edac/edac_pci.c @@ -195,55 +195,24 @@ static void edac_pci_workq_function(struct work_struct *work_req) mutex_lock(&edac_pci_ctls_mutex); - if (pci->op_state == OP_RUNNING_POLL) { - /* we might be in POLL mode, but there may NOT be a poll func - */ - if ((pci->edac_check != NULL) && edac_pci_get_check_errors()) - pci->edac_check(pci); - - /* if we are on a one second period, then use round */ - msec = edac_pci_get_poll_msec(); - if (msec == 1000) - delay = round_jiffies_relative(msecs_to_jiffies(msec)); - else - delay = msecs_to_jiffies(msec); - - /* Reschedule only if we are in POLL mode */ - edac_queue_work(&pci->work, delay); + if (pci->op_state != OP_RUNNING_POLL) { + mutex_unlock(&edac_pci_ctls_mutex); + return; } - mutex_unlock(&edac_pci_ctls_mutex); -} - -/* - * edac_pci_workq_setup() - * initialize a workq item for this edac_pci instance - * passing in the new delay period in msec - * - * locking model: - * called when 'edac_pci_ctls_mutex' is locked - */ -static void edac_pci_workq_setup(struct edac_pci_ctl_info *pci, - unsigned int msec) -{ - edac_dbg(0, "\n"); + if (edac_pci_get_check_errors()) + pci->edac_check(pci); - INIT_DELAYED_WORK(&pci->work, edac_pci_workq_function); + /* if we are on a one second period, then use round */ + msec = edac_pci_get_poll_msec(); + if (msec == 1000) + delay = round_jiffies_relative(msecs_to_jiffies(msec)); + else + delay = msecs_to_jiffies(msec); - edac_queue_work(&pci->work, msecs_to_jiffies(edac_pci_get_poll_msec())); -} + edac_queue_work(&pci->work, delay); -/* - * edac_pci_workq_teardown() - * stop the workq processing on this edac_pci instance - */ -static void edac_pci_workq_teardown(struct edac_pci_ctl_info *pci) -{ - edac_dbg(0, "\n"); - - pci->op_state = OP_OFFLINE; - - edac_stop_work(&pci->work); + mutex_unlock(&edac_pci_ctls_mutex); } /* @@ -289,10 +258,12 @@ int edac_pci_add_device(struct edac_pci_ctl_info *pci, int edac_idx) goto fail1; } - if (pci->edac_check != NULL) { + if (pci->edac_check) { pci->op_state = OP_RUNNING_POLL; - edac_pci_workq_setup(pci, 1000); + INIT_DELAYED_WORK(&pci->work, edac_pci_workq_function); + edac_queue_work(&pci->work, msecs_to_jiffies(edac_pci_get_poll_msec())); + } else { pci->op_state = OP_RUNNING_INTERRUPT; } @@ -350,8 +321,8 @@ struct edac_pci_ctl_info *edac_pci_del_device(struct device *dev) mutex_unlock(&edac_pci_ctls_mutex); - /* stop the workq timer */ - edac_pci_workq_teardown(pci); + if (pci->edac_check) + edac_stop_work(&pci->work); edac_printk(KERN_INFO, EDAC_PCI, "Removed device %d for %s %s: DEV %s\n", diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index b7139c160baf..ca63d0da8889 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -1244,7 +1244,7 @@ static struct platform_driver * const drivers[] = { static int __init mpc85xx_mc_init(void) { int res = 0; - u32 pvr = 0; + u32 __maybe_unused pvr = 0; printk(KERN_INFO "Freescale(R) MPC85xx EDAC driver, " "(C) 2006 Montavista Software\n"); diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c index 41f876414a18..bf19b6e3bd12 100644 --- a/drivers/edac/xgene_edac.c +++ b/drivers/edac/xgene_edac.c @@ -61,6 +61,7 @@ struct xgene_edac { struct regmap *mcba_map; struct regmap *mcbb_map; struct regmap *efuse_map; + struct regmap *rb_map; void __iomem *pcp_csr; spinlock_t lock; struct dentry *dfs; @@ -1057,7 +1058,7 @@ static bool xgene_edac_l3_promote_to_uc_err(u32 l3cesr, u32 l3celr) case 0x041: return true; } - } else if (L3C_ELR_ERRSYN(l3celr) == 9) + } else if (L3C_ELR_ERRWAY(l3celr) == 9) return true; return false; @@ -1353,6 +1354,17 @@ static int xgene_edac_l3_remove(struct xgene_edac_dev_ctx *l3) #define GLBL_MDED_ERRH 0x0848 #define GLBL_MDED_ERRHMASK 0x084c +/* IO Bus Registers */ +#define RBCSR 0x0000 +#define STICKYERR_MASK BIT(0) +#define RBEIR 0x0008 +#define AGENT_OFFLINE_ERR_MASK BIT(30) +#define UNIMPL_RBPAGE_ERR_MASK BIT(29) +#define WORD_ALIGNED_ERR_MASK BIT(28) +#define PAGE_ACCESS_ERR_MASK BIT(27) +#define WRITE_ACCESS_MASK BIT(26) +#define RBERRADDR_RD(src) ((src) & 0x03FFFFFF) + static const char * const soc_mem_err_v1[] = { "10GbE0", "10GbE1", @@ -1470,6 +1482,51 @@ static void xgene_edac_rb_report(struct edac_device_ctl_info *edac_dev) u32 err_addr_hi; u32 reg; + /* If the register bus resource isn't available, just skip it */ + if (!ctx->edac->rb_map) + goto rb_skip; + + /* + * Check RB access errors + * 1. Out of range + * 2. Un-implemented page + * 3. Un-aligned access + * 4. Offline slave IP + */ + if (regmap_read(ctx->edac->rb_map, RBCSR, ®)) + return; + if (reg & STICKYERR_MASK) { + bool write; + u32 address; + + dev_err(edac_dev->dev, "IOB bus access error(s)\n"); + if (regmap_read(ctx->edac->rb_map, RBEIR, ®)) + return; + write = reg & WRITE_ACCESS_MASK ? 1 : 0; + address = RBERRADDR_RD(reg); + if (reg & AGENT_OFFLINE_ERR_MASK) + dev_err(edac_dev->dev, + "IOB bus %s access to offline agent error\n", + write ? "write" : "read"); + if (reg & UNIMPL_RBPAGE_ERR_MASK) + dev_err(edac_dev->dev, + "IOB bus %s access to unimplemented page error\n", + write ? "write" : "read"); + if (reg & WORD_ALIGNED_ERR_MASK) + dev_err(edac_dev->dev, + "IOB bus %s word aligned access error\n", + write ? "write" : "read"); + if (reg & PAGE_ACCESS_ERR_MASK) + dev_err(edac_dev->dev, + "IOB bus %s to page out of range access error\n", + write ? "write" : "read"); + if (regmap_write(ctx->edac->rb_map, RBEIR, 0)) + return; + if (regmap_write(ctx->edac->rb_map, RBCSR, 0)) + return; + } +rb_skip: + /* IOB Bridge agent transaction error interrupt */ reg = readl(ctx->dev_csr + IOBBATRANSERRINTSTS); if (!reg) @@ -1852,6 +1909,17 @@ static int xgene_edac_probe(struct platform_device *pdev) goto out_err; } + /* + * NOTE: The register bus resource is optional for compatibility + * reason. + */ + edac->rb_map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "regmap-rb"); + if (IS_ERR(edac->rb_map)) { + dev_warn(edac->dev, "missing syscon regmap rb\n"); + edac->rb_map = NULL; + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); edac->pcp_csr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(edac->pcp_csr)) { diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 2cd37dad67a6..3a69ed5ecfcb 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -182,6 +182,7 @@ static int generic_ops_register(void) { generic_ops.get_variable = efi.get_variable; generic_ops.set_variable = efi.set_variable; + generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking; generic_ops.get_next_variable = efi.get_next_variable; generic_ops.query_variable_store = efi_query_variable_store; @@ -326,38 +327,6 @@ u64 __init efi_mem_desc_end(efi_memory_desc_t *md) return end; } -/* - * We can't ioremap data in EFI boot services RAM, because we've already mapped - * it as RAM. So, look it up in the existing EFI memory map instead. Only - * callable after efi_enter_virtual_mode and before efi_free_boot_services. - */ -void __iomem *efi_lookup_mapped_addr(u64 phys_addr) -{ - struct efi_memory_map *map; - void *p; - map = efi.memmap; - if (!map) - return NULL; - if (WARN_ON(!map->map)) - return NULL; - for (p = map->map; p < map->map_end; p += map->desc_size) { - efi_memory_desc_t *md = p; - u64 size = md->num_pages << EFI_PAGE_SHIFT; - u64 end = md->phys_addr + size; - if (!(md->attribute & EFI_MEMORY_RUNTIME) && - md->type != EFI_BOOT_SERVICES_CODE && - md->type != EFI_BOOT_SERVICES_DATA) - continue; - if (!md->virt_addr) - continue; - if (phys_addr >= md->phys_addr && phys_addr < end) { - phys_addr += md->virt_addr - md->phys_addr; - return (__force void __iomem *)(unsigned long)phys_addr; - } - } - return NULL; -} - static __initdata efi_config_table_type_t common_tables[] = { {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20}, {ACPI_TABLE_GUID, "ACPI", &efi.acpi}, @@ -586,7 +555,8 @@ static __initdata char memory_type_name[][20] = { "ACPI Memory NVS", "Memory Mapped I/O", "MMIO Port Space", - "PAL Code" + "PAL Code", + "Persistent Memory", }; char * __init efi_md_typeattr_format(char *buf, size_t size, @@ -613,13 +583,16 @@ char * __init efi_md_typeattr_format(char *buf, size_t size, if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO | EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP | + EFI_MEMORY_NV | EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE)) snprintf(pos, size, "|attr=0x%016llx]", (unsigned long long)attr); else - snprintf(pos, size, "|%3s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", + snprintf(pos, size, + "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", attr & EFI_MEMORY_RUNTIME ? "RUN" : "", attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "", + attr & EFI_MEMORY_NV ? "NV" : "", attr & EFI_MEMORY_XP ? "XP" : "", attr & EFI_MEMORY_RP ? "RP" : "", attr & EFI_MEMORY_WP ? "WP" : "", diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index 756eca8c4cf8..c5b0d2bc1111 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c @@ -386,7 +386,7 @@ static const struct sysfs_ops efivar_attr_ops = { static void efivar_release(struct kobject *kobj) { - struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); + struct efivar_entry *var = to_efivar_entry(kobj); kfree(var); } diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c index 22c5285f7705..75feb3f5829b 100644 --- a/drivers/firmware/efi/esrt.c +++ b/drivers/firmware/efi/esrt.c @@ -167,14 +167,11 @@ static struct kset *esrt_kset; static int esre_create_sysfs_entry(void *esre, int entry_num) { struct esre_entry *entry; - char name[20]; entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) return -ENOMEM; - sprintf(name, "entry%d", entry_num); - entry->kobj.kset = esrt_kset; if (esrt->fw_resource_version == 1) { @@ -182,7 +179,7 @@ static int esre_create_sysfs_entry(void *esre, int entry_num) entry->esre.esre1 = esre; rc = kobject_init_and_add(&entry->kobj, &esre1_ktype, NULL, - "%s", name); + "entry%d", entry_num); if (rc) { kfree(entry); return rc; diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 228bbf910461..7b8b2f2702ca 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -61,50 +61,14 @@ */ static DEFINE_SPINLOCK(efi_runtime_lock); -/* - * Some runtime services calls can be reentrant under NMI, even if the table - * above says they are not. (source: UEFI Specification v2.4A) - * - * Table 32. Functions that may be called after Machine Check, INIT and NMI - * +----------------------------+------------------------------------------+ - * | Function | Called after Machine Check, INIT and NMI | - * +----------------------------+------------------------------------------+ - * | GetTime() | Yes, even if previously busy. | - * | GetVariable() | Yes, even if previously busy | - * | GetNextVariableName() | Yes, even if previously busy | - * | QueryVariableInfo() | Yes, even if previously busy | - * | SetVariable() | Yes, even if previously busy | - * | UpdateCapsule() | Yes, even if previously busy | - * | QueryCapsuleCapabilities() | Yes, even if previously busy | - * | ResetSystem() | Yes, even if previously busy | - * +----------------------------+------------------------------------------+ - * - * In order to prevent deadlocks under NMI, the wrappers for these functions - * may only grab the efi_runtime_lock or rtc_lock spinlocks if !efi_in_nmi(). - * However, not all of the services listed are reachable through NMI code paths, - * so the the special handling as suggested by the UEFI spec is only implemented - * for QueryVariableInfo() and SetVariable(), as these can be reached in NMI - * context through efi_pstore_write(). - */ - -/* - * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"), - * the EFI specification requires that callers of the time related runtime - * functions serialize with other CMOS accesses in the kernel, as the EFI time - * functions may choose to also use the legacy CMOS RTC. - */ -__weak DEFINE_SPINLOCK(rtc_lock); - static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) { unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); - spin_lock(&efi_runtime_lock); + spin_lock_irqsave(&efi_runtime_lock, flags); status = efi_call_virt(get_time, tm, tc); - spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock_irqrestore(&efi_runtime_lock, flags); return status; } @@ -113,11 +77,9 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm) unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); - spin_lock(&efi_runtime_lock); + spin_lock_irqsave(&efi_runtime_lock, flags); status = efi_call_virt(set_time, tm); - spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock_irqrestore(&efi_runtime_lock, flags); return status; } @@ -128,11 +90,9 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled, unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); - spin_lock(&efi_runtime_lock); + spin_lock_irqsave(&efi_runtime_lock, flags); status = efi_call_virt(get_wakeup_time, enabled, pending, tm); - spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock_irqrestore(&efi_runtime_lock, flags); return status; } @@ -141,11 +101,9 @@ static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); - spin_lock(&efi_runtime_lock); + spin_lock_irqsave(&efi_runtime_lock, flags); status = efi_call_virt(set_wakeup_time, enabled, tm); - spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock_irqrestore(&efi_runtime_lock, flags); return status; } @@ -230,6 +188,27 @@ static efi_status_t virt_efi_query_variable_info(u32 attr, return status; } +static efi_status_t +virt_efi_query_variable_info_nonblocking(u32 attr, + u64 *storage_space, + u64 *remaining_space, + u64 *max_variable_size) +{ + unsigned long flags; + efi_status_t status; + + if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) + return EFI_UNSUPPORTED; + + if (!spin_trylock_irqsave(&efi_runtime_lock, flags)) + return EFI_NOT_READY; + + status = efi_call_virt(query_variable_info, attr, storage_space, + remaining_space, max_variable_size); + spin_unlock_irqrestore(&efi_runtime_lock, flags); + return status; +} + static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) { unsigned long flags; @@ -300,6 +279,7 @@ void efi_native_runtime_setup(void) efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; efi.reset_system = virt_efi_reset_system; efi.query_variable_info = virt_efi_query_variable_info; + efi.query_variable_info_nonblocking = virt_efi_query_variable_info_nonblocking; efi.update_capsule = virt_efi_update_capsule; efi.query_capsule_caps = virt_efi_query_capsule_caps; } diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index 70a0fb10517f..d2a49626a335 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c @@ -234,7 +234,18 @@ check_var_size(u32 attributes, unsigned long size) if (!fops->query_variable_store) return EFI_UNSUPPORTED; - return fops->query_variable_store(attributes, size); + return fops->query_variable_store(attributes, size, false); +} + +static efi_status_t +check_var_size_nonblocking(u32 attributes, unsigned long size) +{ + const struct efivar_operations *fops = __efivars->ops; + + if (!fops->query_variable_store) + return EFI_UNSUPPORTED; + + return fops->query_variable_store(attributes, size, true); } static int efi_status_to_err(efi_status_t status) @@ -615,7 +626,8 @@ efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor, if (!spin_trylock_irqsave(&__efivars->lock, flags)) return -EBUSY; - status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); + status = check_var_size_nonblocking(attributes, + size + ucs2_strsize(name, 1024)); if (status != EFI_SUCCESS) { spin_unlock_irqrestore(&__efivars->lock, flags); return -ENOSPC; diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index f25cd79c8a79..11bfee8b79a9 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -14,6 +14,7 @@ #define pr_fmt(fmt) "psci: " fmt #include +#include #include #include #include @@ -21,10 +22,12 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -244,6 +247,123 @@ static int __init psci_features(u32 psci_func_id) psci_func_id, 0, 0); } +#ifdef CONFIG_CPU_IDLE +static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state); + +static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu) +{ + int i, ret, count = 0; + u32 *psci_states; + struct device_node *state_node; + + /* + * If the PSCI cpu_suspend function hook has not been initialized + * idle states must not be enabled, so bail out + */ + if (!psci_ops.cpu_suspend) + return -EOPNOTSUPP; + + /* Count idle states */ + while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states", + count))) { + count++; + of_node_put(state_node); + } + + if (!count) + return -ENODEV; + + psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL); + if (!psci_states) + return -ENOMEM; + + for (i = 0; i < count; i++) { + u32 state; + + state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i); + + ret = of_property_read_u32(state_node, + "arm,psci-suspend-param", + &state); + if (ret) { + pr_warn(" * %s missing arm,psci-suspend-param property\n", + state_node->full_name); + of_node_put(state_node); + goto free_mem; + } + + of_node_put(state_node); + pr_debug("psci-power-state %#x index %d\n", state, i); + if (!psci_power_state_is_valid(state)) { + pr_warn("Invalid PSCI power state %#x\n", state); + ret = -EINVAL; + goto free_mem; + } + psci_states[i] = state; + } + /* Idle states parsed correctly, initialize per-cpu pointer */ + per_cpu(psci_power_state, cpu) = psci_states; + return 0; + +free_mem: + kfree(psci_states); + return ret; +} + +int psci_cpu_init_idle(unsigned int cpu) +{ + struct device_node *cpu_node; + int ret; + + cpu_node = of_get_cpu_node(cpu, NULL); + if (!cpu_node) + return -ENODEV; + + ret = psci_dt_cpu_init_idle(cpu_node, cpu); + + of_node_put(cpu_node); + + return ret; +} + +static int psci_suspend_finisher(unsigned long index) +{ + u32 *state = __this_cpu_read(psci_power_state); + + return psci_ops.cpu_suspend(state[index - 1], + virt_to_phys(cpu_resume)); +} + +int psci_cpu_suspend_enter(unsigned long index) +{ + int ret; + u32 *state = __this_cpu_read(psci_power_state); + /* + * idle state index 0 corresponds to wfi, should never be called + * from the cpu_suspend operations + */ + if (WARN_ON_ONCE(!index)) + return -EINVAL; + + if (!psci_power_state_loses_context(state[index - 1])) + ret = psci_ops.cpu_suspend(state[index - 1], 0); + else + ret = cpu_suspend(index, psci_suspend_finisher); + + return ret; +} + +/* ARM specific CPU idle operations */ +#ifdef CONFIG_ARM +static struct cpuidle_ops psci_cpuidle_ops __initdata = { + .suspend = psci_cpu_suspend_enter, + .init = psci_dt_cpu_init_idle, +}; + +CPUIDLE_METHOD_OF_DECLARE(psci, "arm,psci", &psci_cpuidle_ops); +#endif +#endif + static int psci_system_suspend(unsigned long unused) { return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 0883292f640f..c1e43259c044 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -499,3 +499,85 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) return qcom_scm_call(QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP, req, req_cnt * sizeof(*req), resp, sizeof(*resp)); } + +bool __qcom_scm_pas_supported(u32 peripheral) +{ + __le32 out; + __le32 in; + int ret; + + in = cpu_to_le32(peripheral); + ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_IS_SUPPORTED_CMD, + &in, sizeof(in), + &out, sizeof(out)); + + return ret ? false : !!out; +} + +int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys) +{ + __le32 scm_ret; + int ret; + struct { + __le32 proc; + __le32 image_addr; + } request; + + request.proc = cpu_to_le32(peripheral); + request.image_addr = cpu_to_le32(metadata_phys); + + ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_INIT_IMAGE_CMD, + &request, sizeof(request), + &scm_ret, sizeof(scm_ret)); + + return ret ? : le32_to_cpu(scm_ret); +} + +int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size) +{ + __le32 scm_ret; + int ret; + struct { + __le32 proc; + __le32 addr; + __le32 len; + } request; + + request.proc = cpu_to_le32(peripheral); + request.addr = cpu_to_le32(addr); + request.len = cpu_to_le32(size); + + ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MEM_SETUP_CMD, + &request, sizeof(request), + &scm_ret, sizeof(scm_ret)); + + return ret ? : le32_to_cpu(scm_ret); +} + +int __qcom_scm_pas_auth_and_reset(u32 peripheral) +{ + __le32 out; + __le32 in; + int ret; + + in = cpu_to_le32(peripheral); + ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_AUTH_AND_RESET_CMD, + &in, sizeof(in), + &out, sizeof(out)); + + return ret ? : le32_to_cpu(out); +} + +int __qcom_scm_pas_shutdown(u32 peripheral) +{ + __le32 out; + __le32 in; + int ret; + + in = cpu_to_le32(peripheral); + ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_SHUTDOWN_CMD, + &in, sizeof(in), + &out, sizeof(out)); + + return ret ? : le32_to_cpu(out); +} diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index bb6555f6d63b..e64fd927e5ae 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -61,3 +61,28 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { return -ENOTSUPP; } + +bool __qcom_scm_pas_supported(u32 peripheral) +{ + return false; +} + +int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys) +{ + return -ENOTSUPP; +} + +int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size) +{ + return -ENOTSUPP; +} + +int __qcom_scm_pas_auth_and_reset(u32 peripheral) +{ + return -ENOTSUPP; +} + +int __qcom_scm_pas_shutdown(u32 peripheral) +{ + return -ENOTSUPP; +} diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 45c008d68891..6fc9580a26bd 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -10,19 +10,59 @@ * 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ - +#include +#include #include #include +#include #include #include +#include +#include #include "qcom_scm.h" +struct qcom_scm { + struct device *dev; + struct clk *core_clk; + struct clk *iface_clk; + struct clk *bus_clk; +}; + +static struct qcom_scm *__scm; + +static int qcom_scm_clk_enable(void) +{ + int ret; + + ret = clk_prepare_enable(__scm->core_clk); + if (ret) + goto bail; + ret = clk_prepare_enable(__scm->iface_clk); + if (ret) + goto disable_core; + ret = clk_prepare_enable(__scm->bus_clk); + if (ret) + goto disable_iface; + + return 0; + +disable_iface: + clk_disable_unprepare(__scm->iface_clk); +disable_core: + clk_disable_unprepare(__scm->core_clk); +bail: + return ret; +} + +static void qcom_scm_clk_disable(void) +{ + clk_disable_unprepare(__scm->core_clk); + clk_disable_unprepare(__scm->iface_clk); + clk_disable_unprepare(__scm->bus_clk); +} + /** * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus * @entry: Entry point function for the cpus @@ -72,11 +112,17 @@ EXPORT_SYMBOL(qcom_scm_cpu_power_down); */ bool qcom_scm_hdcp_available(void) { - int ret; + int ret = qcom_scm_clk_enable(); + + if (ret) + goto clk_err; ret = __qcom_scm_is_call_available(QCOM_SCM_SVC_HDCP, - QCOM_SCM_CMD_HDCP); + QCOM_SCM_CMD_HDCP); + qcom_scm_clk_disable(); + +clk_err: return (ret > 0) ? true : false; } EXPORT_SYMBOL(qcom_scm_hdcp_available); @@ -91,6 +137,215 @@ EXPORT_SYMBOL(qcom_scm_hdcp_available); */ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { - return __qcom_scm_hdcp_req(req, req_cnt, resp); + int ret = qcom_scm_clk_enable(); + + if (ret) + return ret; + + ret = __qcom_scm_hdcp_req(req, req_cnt, resp); + qcom_scm_clk_disable(); + return ret; } EXPORT_SYMBOL(qcom_scm_hdcp_req); + +/** + * qcom_scm_pas_supported() - Check if the peripheral authentication service is + * available for the given peripherial + * @peripheral: peripheral id + * + * Returns true if PAS is supported for this peripheral, otherwise false. + */ +bool qcom_scm_pas_supported(u32 peripheral) +{ + int ret; + + ret = __qcom_scm_is_call_available(QCOM_SCM_SVC_PIL, + QCOM_SCM_PAS_IS_SUPPORTED_CMD); + if (ret <= 0) + return false; + + return __qcom_scm_pas_supported(peripheral); +} +EXPORT_SYMBOL(qcom_scm_pas_supported); + +/** + * qcom_scm_pas_init_image() - Initialize peripheral authentication service + * state machine for a given peripheral, using the + * metadata + * @peripheral: peripheral id + * @metadata: pointer to memory containing ELF header, program header table + * and optional blob of data used for authenticating the metadata + * and the rest of the firmware + * @size: size of the metadata + * + * Returns 0 on success. + */ +int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) +{ + dma_addr_t mdata_phys; + void *mdata_buf; + int ret; + + /* + * During the scm call memory protection will be enabled for the meta + * data blob, so make sure it's physically contiguous, 4K aligned and + * non-cachable to avoid XPU violations. + */ + mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys, GFP_KERNEL); + if (!mdata_buf) { + dev_err(__scm->dev, "Allocation of metadata buffer failed.\n"); + return -ENOMEM; + } + memcpy(mdata_buf, metadata, size); + + ret = qcom_scm_clk_enable(); + if (ret) + goto free_metadata; + + ret = __qcom_scm_pas_init_image(peripheral, mdata_phys); + + qcom_scm_clk_disable(); + +free_metadata: + dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys); + + return ret; +} +EXPORT_SYMBOL(qcom_scm_pas_init_image); + +/** + * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral + * for firmware loading + * @peripheral: peripheral id + * @addr: start address of memory area to prepare + * @size: size of the memory area to prepare + * + * Returns 0 on success. + */ +int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size) +{ + int ret; + + ret = qcom_scm_clk_enable(); + if (ret) + return ret; + + ret = __qcom_scm_pas_mem_setup(peripheral, addr, size); + qcom_scm_clk_disable(); + + return ret; +} +EXPORT_SYMBOL(qcom_scm_pas_mem_setup); + +/** + * qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware + * and reset the remote processor + * @peripheral: peripheral id + * + * Return 0 on success. + */ +int qcom_scm_pas_auth_and_reset(u32 peripheral) +{ + int ret; + + ret = qcom_scm_clk_enable(); + if (ret) + return ret; + + ret = __qcom_scm_pas_auth_and_reset(peripheral); + qcom_scm_clk_disable(); + + return ret; +} +EXPORT_SYMBOL(qcom_scm_pas_auth_and_reset); + +/** + * qcom_scm_pas_shutdown() - Shut down the remote processor + * @peripheral: peripheral id + * + * Returns 0 on success. + */ +int qcom_scm_pas_shutdown(u32 peripheral) +{ + int ret; + + ret = qcom_scm_clk_enable(); + if (ret) + return ret; + + ret = __qcom_scm_pas_shutdown(peripheral); + qcom_scm_clk_disable(); + + return ret; +} +EXPORT_SYMBOL(qcom_scm_pas_shutdown); + +/** + * qcom_scm_is_available() - Checks if SCM is available + */ +bool qcom_scm_is_available(void) +{ + return !!__scm; +} +EXPORT_SYMBOL(qcom_scm_is_available); + +static int qcom_scm_probe(struct platform_device *pdev) +{ + struct qcom_scm *scm; + long rate; + int ret; + + scm = devm_kzalloc(&pdev->dev, sizeof(*scm), GFP_KERNEL); + if (!scm) + return -ENOMEM; + + scm->dev = &pdev->dev; + + scm->core_clk = devm_clk_get(&pdev->dev, "core"); + if (IS_ERR(scm->core_clk)) { + if (PTR_ERR(scm->core_clk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to acquire core clk\n"); + return PTR_ERR(scm->core_clk); + } + + scm->iface_clk = devm_clk_get(&pdev->dev, "iface"); + if (IS_ERR(scm->iface_clk)) { + if (PTR_ERR(scm->iface_clk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to acquire iface clk\n"); + return PTR_ERR(scm->iface_clk); + } + + scm->bus_clk = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(scm->bus_clk)) { + if (PTR_ERR(scm->bus_clk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to acquire bus clk\n"); + return PTR_ERR(scm->bus_clk); + } + + /* vote for max clk rate for highest performance */ + rate = clk_round_rate(scm->core_clk, INT_MAX); + ret = clk_set_rate(scm->core_clk, rate); + if (ret) + return ret; + + __scm = scm; + + return 0; +} + +static const struct of_device_id qcom_scm_dt_match[] = { + { .compatible = "qcom,scm",}, + {}, +}; + +MODULE_DEVICE_TABLE(of, qcom_scm_dt_match); + +static struct platform_driver qcom_scm_driver = { + .driver = { + .name = "qcom_scm", + .of_match_table = qcom_scm_dt_match, + }, + .probe = qcom_scm_probe, +}; + +builtin_platform_driver(qcom_scm_driver); diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 2cce75c08b99..220d19c93cfc 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -36,6 +36,18 @@ extern int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id); extern int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); +#define QCOM_SCM_SVC_PIL 0x2 +#define QCOM_SCM_PAS_INIT_IMAGE_CMD 0x1 +#define QCOM_SCM_PAS_MEM_SETUP_CMD 0x2 +#define QCOM_SCM_PAS_AUTH_AND_RESET_CMD 0x5 +#define QCOM_SCM_PAS_SHUTDOWN_CMD 0x6 +#define QCOM_SCM_PAS_IS_SUPPORTED_CMD 0x7 +extern bool __qcom_scm_pas_supported(u32 peripheral); +extern int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys); +extern int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size); +extern int __qcom_scm_pas_auth_and_reset(u32 peripheral); +extern int __qcom_scm_pas_shutdown(u32 peripheral); + /* common error codes */ #define QCOM_SCM_ENOMEM -5 #define QCOM_SCM_EOPNOTSUPP -4 diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 8ae7ab68cb97..438e92d4c389 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -106,6 +106,8 @@ config DRM_TDFX Choose this option if you have a 3dfx Banshee or Voodoo3 (or later), graphics card. If M is selected, the module will be called tdfx. +source "drivers/gpu/drm/arm/Kconfig" + config DRM_R128 tristate "ATI Rage 128" depends on DRM && PCI diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 61766dec6a8d..f80fdbaeb641 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -33,6 +33,7 @@ CFLAGS_drm_trace_points.o := -I$(src) obj-$(CONFIG_DRM) += drm.o obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o +obj-$(CONFIG_DRM_ARM) += arm/ obj-$(CONFIG_DRM_TTM) += ttm/ obj-$(CONFIG_DRM_TDFX) += tdfx/ obj-$(CONFIG_DRM_R128) += r128/ diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 66f729eaf00b..20c9539abc36 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -25,7 +25,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o # add asic specific block -amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o gmc_v7_0.o cik_ih.o kv_smc.o kv_dpm.o \ +amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ ci_smc.o ci_dpm.o dce_v8_0.o gfx_v7_0.o cik_sdma.o uvd_v4_2.o vce_v2_0.o \ amdgpu_amdkfd_gfx_v7.o @@ -34,6 +34,7 @@ amdgpu-y += \ # add GMC block amdgpu-y += \ + gmc_v7_0.o \ gmc_v8_0.o # add IH block diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 313b0cc8d676..82edf95b7740 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -2278,60 +2278,60 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) #define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e)) #define amdgpu_dpm_get_temperature(adev) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->get_temperature((adev)->powerplay.pp_handle) : \ - (adev)->pm.funcs->get_temperature((adev)) + (adev)->pm.funcs->get_temperature((adev))) #define amdgpu_dpm_set_fan_control_mode(adev, m) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->set_fan_control_mode((adev)->powerplay.pp_handle, (m)) : \ - (adev)->pm.funcs->set_fan_control_mode((adev), (m)) + (adev)->pm.funcs->set_fan_control_mode((adev), (m))) #define amdgpu_dpm_get_fan_control_mode(adev) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->get_fan_control_mode((adev)->powerplay.pp_handle) : \ - (adev)->pm.funcs->get_fan_control_mode((adev)) + (adev)->pm.funcs->get_fan_control_mode((adev))) #define amdgpu_dpm_set_fan_speed_percent(adev, s) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->set_fan_speed_percent((adev)->powerplay.pp_handle, (s)) : \ - (adev)->pm.funcs->set_fan_speed_percent((adev), (s)) + (adev)->pm.funcs->set_fan_speed_percent((adev), (s))) #define amdgpu_dpm_get_fan_speed_percent(adev, s) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->get_fan_speed_percent((adev)->powerplay.pp_handle, (s)) : \ - (adev)->pm.funcs->get_fan_speed_percent((adev), (s)) + (adev)->pm.funcs->get_fan_speed_percent((adev), (s))) #define amdgpu_dpm_get_sclk(adev, l) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (l)) : \ - (adev)->pm.funcs->get_sclk((adev), (l)) + (adev)->pm.funcs->get_sclk((adev), (l))) #define amdgpu_dpm_get_mclk(adev, l) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->get_mclk((adev)->powerplay.pp_handle, (l)) : \ - (adev)->pm.funcs->get_mclk((adev), (l)) + (adev)->pm.funcs->get_mclk((adev), (l))) #define amdgpu_dpm_force_performance_level(adev, l) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->force_performance_level((adev)->powerplay.pp_handle, (l)) : \ - (adev)->pm.funcs->force_performance_level((adev), (l)) + (adev)->pm.funcs->force_performance_level((adev), (l))) #define amdgpu_dpm_powergate_uvd(adev, g) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->powergate_uvd((adev)->powerplay.pp_handle, (g)) : \ - (adev)->pm.funcs->powergate_uvd((adev), (g)) + (adev)->pm.funcs->powergate_uvd((adev), (g))) #define amdgpu_dpm_powergate_vce(adev, g) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->powergate_vce((adev)->powerplay.pp_handle, (g)) : \ - (adev)->pm.funcs->powergate_vce((adev), (g)) + (adev)->pm.funcs->powergate_vce((adev), (g))) #define amdgpu_dpm_debugfs_print_current_performance_level(adev, m) \ - (adev)->pp_enabled ? \ + ((adev)->pp_enabled ? \ (adev)->powerplay.pp_funcs->print_current_performance_level((adev)->powerplay.pp_handle, (m)) : \ - (adev)->pm.funcs->debugfs_print_current_performance_level((adev), (m)) + (adev)->pm.funcs->debugfs_print_current_performance_level((adev), (m))) #define amdgpu_dpm_get_current_power_state(adev) \ (adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c index 0e1376317683..362bedc9e507 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c @@ -154,7 +154,7 @@ static const struct kfd2kgd_calls kfd2kgd = { .get_fw_version = get_fw_version }; -struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions() +struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void) { return (struct kfd2kgd_calls *)&kfd2kgd; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c index 79fa5c7de856..04b744d64b57 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c @@ -115,7 +115,7 @@ static const struct kfd2kgd_calls kfd2kgd = { .get_fw_version = get_fw_version }; -struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions() +struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void) { return (struct kfd2kgd_calls *)&kfd2kgd; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 3c895863fcf5..fa948dcbdd5d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -552,13 +552,14 @@ static bool amdgpu_atpx_detect(void) void amdgpu_register_atpx_handler(void) { bool r; + enum vga_switcheroo_handler_flags_t handler_flags = 0; /* detect if we have any ATPX + 2 VGA in the system */ r = amdgpu_atpx_detect(); if (!r) return; - vga_switcheroo_register_handler(&amdgpu_atpx_handler); + vga_switcheroo_register_handler(&amdgpu_atpx_handler, handler_flags); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 6f89f8e034d0..b882e8175615 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -478,9 +478,9 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo struct amdgpu_fpriv *fpriv = parser->filp->driver_priv; unsigned i; - amdgpu_vm_move_pt_bos_in_lru(parser->adev, &fpriv->vm); - if (!error) { + amdgpu_vm_move_pt_bos_in_lru(parser->adev, &fpriv->vm); + /* Sort the buffer list from the smallest to largest buffer, * which affects the order of buffers in the LRU list. * This assures that the smallest buffers are added first diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index b5dbbb573491..9c1af8976bef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -256,11 +256,11 @@ static struct pci_device_id pciidlist[] = { {0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMD_IS_MOBILITY|AMD_IS_APU}, #endif /* topaz */ - {0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT}, - {0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT}, - {0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT}, - {0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT}, - {0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT}, + {0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ}, + {0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ}, + {0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ}, + {0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ}, + {0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ}, /* tonga */ {0x1002, 0x6920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA}, {0x1002, 0x6921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA}, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index cfb6caad2a73..919146780a15 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -333,6 +333,10 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev) if (!adev->mode_info.mode_config_initialized) return 0; + /* don't init fbdev if there are no connectors */ + if (list_empty(&adev->ddev->mode_config.connector_list)) + return 0; + /* select 8 bpp console on low vram cards */ if (adev->mc.real_vram_size <= (32*1024*1024)) bpp_sel = 8; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index c3ce103b6a33..b8fbbd7699e4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "amdgpu.h" #include "amdgpu_trace.h" @@ -261,6 +262,13 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev, AMDGPU_GEM_DOMAIN_OA); bo->flags = flags; + + /* For architectures that don't support WC memory, + * mask out the WC flag from the BO + */ + if (!drm_arch_can_wc_memory()) + bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC; + amdgpu_fill_placement_to_bo(bo, placement); /* Kernel allocation are uninterruptible */ r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type, @@ -399,7 +407,8 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, } if (fpfn > bo->placements[i].fpfn) bo->placements[i].fpfn = fpfn; - if (lpfn && lpfn < bo->placements[i].lpfn) + if (!bo->placements[i].lpfn || + (lpfn && lpfn < bo->placements[i].lpfn)) bo->placements[i].lpfn = lpfn; bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 5ee9a0690278..b9d0d55f6b47 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -99,13 +99,24 @@ static int amdgpu_pp_early_init(void *handle) #ifdef CONFIG_DRM_AMD_POWERPLAY switch (adev->asic_type) { - case CHIP_TONGA: - case CHIP_FIJI: - adev->pp_enabled = (amdgpu_powerplay > 0) ? true : false; - break; - default: - adev->pp_enabled = (amdgpu_powerplay > 0) ? true : false; - break; + case CHIP_TONGA: + case CHIP_FIJI: + adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true; + break; + case CHIP_CARRIZO: + case CHIP_STONEY: + adev->pp_enabled = (amdgpu_powerplay > 0) ? true : false; + break; + /* These chips don't have powerplay implemenations */ + case CHIP_BONAIRE: + case CHIP_HAWAII: + case CHIP_KABINI: + case CHIP_MULLINS: + case CHIP_KAVERI: + case CHIP_TOPAZ: + default: + adev->pp_enabled = false; + break; } #else adev->pp_enabled = false; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 78e9b0f14661..d1f234dd2126 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -487,7 +487,7 @@ static int amdgpu_debugfs_ring_info(struct seq_file *m, void *data) seq_printf(m, "rptr: 0x%08x [%5d]\n", rptr, rptr); - rptr_next = ~0; + rptr_next = le32_to_cpu(*ring->next_rptr_cpu_addr); seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", ring->wptr, ring->wptr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 8a1752ff3d8e..55cf05e1c81c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -808,7 +808,7 @@ uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, flags |= AMDGPU_PTE_SNOOPED; } - if (adev->asic_type >= CHIP_TOPAZ) + if (adev->asic_type >= CHIP_TONGA) flags |= AMDGPU_PTE_EXECUTABLE; flags |= AMDGPU_PTE_READABLE; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index aefc668e6b5d..9599f7559b3d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1282,7 +1282,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) { const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE, AMDGPU_VM_PTE_COUNT * 8); - unsigned pd_size, pd_entries, pts_size; + unsigned pd_size, pd_entries; int i, r; for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { @@ -1300,8 +1300,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) pd_entries = amdgpu_vm_num_pdes(adev); /* allocate page table array */ - pts_size = pd_entries * sizeof(struct amdgpu_vm_pt); - vm->page_tables = kzalloc(pts_size, GFP_KERNEL); + vm->page_tables = drm_calloc_large(pd_entries, sizeof(struct amdgpu_vm_pt)); if (vm->page_tables == NULL) { DRM_ERROR("Cannot allocate memory for page table array\n"); return -ENOMEM; @@ -1361,7 +1360,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) for (i = 0; i < amdgpu_vm_num_pdes(adev); i++) amdgpu_bo_unref(&vm->page_tables[i].entry.robj); - kfree(vm->page_tables); + drm_free_large(vm->page_tables); amdgpu_bo_unref(&vm->page_directory); fence_put(vm->page_directory_fence); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 72793f93e2fc..6c76139de1c9 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -4738,6 +4738,22 @@ static int gfx_v7_0_early_init(void *handle) return 0; } +static int gfx_v7_0_late_init(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + int r; + + r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0); + if (r) + return r; + + r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0); + if (r) + return r; + + return 0; +} + static int gfx_v7_0_sw_init(void *handle) { struct amdgpu_ring *ring; @@ -4890,6 +4906,8 @@ static int gfx_v7_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); + amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); gfx_v7_0_cp_enable(adev, false); gfx_v7_0_rlc_stop(adev); gfx_v7_0_fini_pg(adev); @@ -5527,7 +5545,7 @@ static int gfx_v7_0_set_powergating_state(void *handle, const struct amd_ip_funcs gfx_v7_0_ip_funcs = { .early_init = gfx_v7_0_early_init, - .late_init = NULL, + .late_init = gfx_v7_0_late_init, .sw_init = gfx_v7_0_sw_init, .sw_fini = gfx_v7_0_sw_fini, .hw_init = gfx_v7_0_hw_init, diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 13235d84e5a6..8f8ec37ecd88 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -111,7 +111,6 @@ MODULE_FIRMWARE("amdgpu/topaz_ce.bin"); MODULE_FIRMWARE("amdgpu/topaz_pfp.bin"); MODULE_FIRMWARE("amdgpu/topaz_me.bin"); MODULE_FIRMWARE("amdgpu/topaz_mec.bin"); -MODULE_FIRMWARE("amdgpu/topaz_mec2.bin"); MODULE_FIRMWARE("amdgpu/topaz_rlc.bin"); MODULE_FIRMWARE("amdgpu/fiji_ce.bin"); @@ -828,7 +827,8 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) adev->gfx.mec_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); adev->gfx.mec_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); - if (adev->asic_type != CHIP_STONEY) { + if ((adev->asic_type != CHIP_STONEY) && + (adev->asic_type != CHIP_TOPAZ)) { snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name); err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev); if (!err) { @@ -3851,10 +3851,16 @@ static int gfx_v8_0_cp_resume(struct amdgpu_device *adev) if (r) return -EINVAL; - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_CP_MEC1); - if (r) - return -EINVAL; + if (adev->asic_type == CHIP_TOPAZ) { + r = gfx_v8_0_cp_compute_load_microcode(adev); + if (r) + return r; + } else { + r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, + AMDGPU_UCODE_ID_CP_MEC1); + if (r) + return -EINVAL; + } } } @@ -3901,6 +3907,8 @@ static int gfx_v8_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); + amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); gfx_v8_0_cp_enable(adev, false); gfx_v8_0_rlc_stop(adev); gfx_v8_0_cp_compute_fini(adev); @@ -4186,7 +4194,18 @@ static int gfx_v8_0_soft_reset(void *handle) gfx_v8_0_cp_gfx_enable(adev, false); /* Disable MEC parsing/prefetching */ - /* XXX todo */ + gfx_v8_0_cp_compute_enable(adev, false); + + if (grbm_soft_reset || srbm_soft_reset) { + tmp = RREG32(mmGMCON_DEBUG); + tmp = REG_SET_FIELD(tmp, + GMCON_DEBUG, GFX_STALL, 1); + tmp = REG_SET_FIELD(tmp, + GMCON_DEBUG, GFX_CLEAR, 1); + WREG32(mmGMCON_DEBUG, tmp); + + udelay(50); + } if (grbm_soft_reset) { tmp = RREG32(mmGRBM_SOFT_RESET); @@ -4215,6 +4234,16 @@ static int gfx_v8_0_soft_reset(void *handle) WREG32(mmSRBM_SOFT_RESET, tmp); tmp = RREG32(mmSRBM_SOFT_RESET); } + + if (grbm_soft_reset || srbm_soft_reset) { + tmp = RREG32(mmGMCON_DEBUG); + tmp = REG_SET_FIELD(tmp, + GMCON_DEBUG, GFX_STALL, 0); + tmp = REG_SET_FIELD(tmp, + GMCON_DEBUG, GFX_CLEAR, 0); + WREG32(mmGMCON_DEBUG, tmp); + } + /* Wait a little for things to settle down */ udelay(50); gfx_v8_0_print_status((void *)adev); @@ -4308,6 +4337,14 @@ static int gfx_v8_0_late_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; int r; + r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0); + if (r) + return r; + + r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0); + if (r) + return r; + /* requires IBs so do in late init after IB pool is initialized */ r = gfx_v8_0_do_edc_gpr_workarounds(adev); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 3f956065d069..8aa2991ab379 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -42,9 +42,39 @@ static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev); MODULE_FIRMWARE("radeon/bonaire_mc.bin"); MODULE_FIRMWARE("radeon/hawaii_mc.bin"); +MODULE_FIRMWARE("amdgpu/topaz_mc.bin"); + +static const u32 golden_settings_iceland_a11[] = +{ + mmVM_PRT_APERTURE0_LOW_ADDR, 0x0fffffff, 0x0fffffff, + mmVM_PRT_APERTURE1_LOW_ADDR, 0x0fffffff, 0x0fffffff, + mmVM_PRT_APERTURE2_LOW_ADDR, 0x0fffffff, 0x0fffffff, + mmVM_PRT_APERTURE3_LOW_ADDR, 0x0fffffff, 0x0fffffff +}; + +static const u32 iceland_mgcg_cgcg_init[] = +{ + mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104 +}; + +static void gmc_v7_0_init_golden_registers(struct amdgpu_device *adev) +{ + switch (adev->asic_type) { + case CHIP_TOPAZ: + amdgpu_program_register_sequence(adev, + iceland_mgcg_cgcg_init, + (const u32)ARRAY_SIZE(iceland_mgcg_cgcg_init)); + amdgpu_program_register_sequence(adev, + golden_settings_iceland_a11, + (const u32)ARRAY_SIZE(golden_settings_iceland_a11)); + break; + default: + break; + } +} /** - * gmc8_mc_wait_for_idle - wait for MC idle callback. + * gmc7_mc_wait_for_idle - wait for MC idle callback. * * @adev: amdgpu_device pointer * @@ -132,13 +162,20 @@ static int gmc_v7_0_init_microcode(struct amdgpu_device *adev) case CHIP_HAWAII: chip_name = "hawaii"; break; + case CHIP_TOPAZ: + chip_name = "topaz"; + break; case CHIP_KAVERI: case CHIP_KABINI: return 0; default: BUG(); } - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); + if (adev->asic_type == CHIP_TOPAZ) + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mc.bin", chip_name); + else + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); + err = request_firmware(&adev->mc.fw, fw_name, adev->dev); if (err) goto out; @@ -984,6 +1021,8 @@ static int gmc_v7_0_hw_init(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + gmc_v7_0_init_golden_registers(adev); + gmc_v7_0_mc_program(adev); if (!(adev->flags & AMD_IS_APU)) { diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index c0c9a0101eb4..3efd45546241 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -42,9 +42,7 @@ static void gmc_v8_0_set_gart_funcs(struct amdgpu_device *adev); static void gmc_v8_0_set_irq_funcs(struct amdgpu_device *adev); -MODULE_FIRMWARE("amdgpu/topaz_mc.bin"); MODULE_FIRMWARE("amdgpu/tonga_mc.bin"); -MODULE_FIRMWARE("amdgpu/fiji_mc.bin"); static const u32 golden_settings_tonga_a11[] = { @@ -75,19 +73,6 @@ static const u32 fiji_mgcg_cgcg_init[] = mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104 }; -static const u32 golden_settings_iceland_a11[] = -{ - mmVM_PRT_APERTURE0_LOW_ADDR, 0x0fffffff, 0x0fffffff, - mmVM_PRT_APERTURE1_LOW_ADDR, 0x0fffffff, 0x0fffffff, - mmVM_PRT_APERTURE2_LOW_ADDR, 0x0fffffff, 0x0fffffff, - mmVM_PRT_APERTURE3_LOW_ADDR, 0x0fffffff, 0x0fffffff -}; - -static const u32 iceland_mgcg_cgcg_init[] = -{ - mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104 -}; - static const u32 cz_mgcg_cgcg_init[] = { mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104 @@ -102,14 +87,6 @@ static const u32 stoney_mgcg_cgcg_init[] = static void gmc_v8_0_init_golden_registers(struct amdgpu_device *adev) { switch (adev->asic_type) { - case CHIP_TOPAZ: - amdgpu_program_register_sequence(adev, - iceland_mgcg_cgcg_init, - (const u32)ARRAY_SIZE(iceland_mgcg_cgcg_init)); - amdgpu_program_register_sequence(adev, - golden_settings_iceland_a11, - (const u32)ARRAY_SIZE(golden_settings_iceland_a11)); - break; case CHIP_FIJI: amdgpu_program_register_sequence(adev, fiji_mgcg_cgcg_init, @@ -229,15 +206,10 @@ static int gmc_v8_0_init_microcode(struct amdgpu_device *adev) DRM_DEBUG("\n"); switch (adev->asic_type) { - case CHIP_TOPAZ: - chip_name = "topaz"; - break; case CHIP_TONGA: chip_name = "tonga"; break; case CHIP_FIJI: - chip_name = "fiji"; - break; case CHIP_CARRIZO: case CHIP_STONEY: return 0; @@ -1007,7 +979,7 @@ static int gmc_v8_0_hw_init(void *handle) gmc_v8_0_mc_program(adev); - if (!(adev->flags & AMD_IS_APU)) { + if (adev->asic_type == CHIP_TONGA) { r = gmc_v8_0_mc_load_microcode(adev); if (r) { DRM_ERROR("Failed to load MC firmware!\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c index 966d4b2ed9da..090486c18249 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c @@ -432,7 +432,7 @@ static uint32_t iceland_smu_get_mask_for_fw_type(uint32_t fw_type) case AMDGPU_UCODE_ID_CP_ME: return UCODE_ID_CP_ME_MASK; case AMDGPU_UCODE_ID_CP_MEC1: - return UCODE_ID_CP_MEC_MASK | UCODE_ID_CP_MEC_JT1_MASK | UCODE_ID_CP_MEC_JT2_MASK; + return UCODE_ID_CP_MEC_MASK | UCODE_ID_CP_MEC_JT1_MASK; case AMDGPU_UCODE_ID_CP_MEC2: return UCODE_ID_CP_MEC_MASK; case AMDGPU_UCODE_ID_RLC_G: @@ -522,12 +522,6 @@ static int iceland_smu_request_load_fw(struct amdgpu_device *adev) return -EINVAL; } - if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT2, - &toc->entry[toc->num_entries++])) { - DRM_ERROR("Failed to get firmware entry for MEC_JT2\n"); - return -EINVAL; - } - if (iceland_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA0, &toc->entry[toc->num_entries++])) { DRM_ERROR("Failed to get firmware entry for SDMA0\n"); @@ -550,8 +544,8 @@ static int iceland_smu_request_load_fw(struct amdgpu_device *adev) UCODE_ID_CP_ME_MASK | UCODE_ID_CP_PFP_MASK | UCODE_ID_CP_MEC_MASK | - UCODE_ID_CP_MEC_JT1_MASK | - UCODE_ID_CP_MEC_JT2_MASK; + UCODE_ID_CP_MEC_JT1_MASK; + if (iceland_send_msg_to_smc_with_parameter_without_waiting(adev, PPSMC_MSG_LoadUcodes, fw_to_load)) { DRM_ERROR("Fail to request SMU load ucode\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c index f4a1346525fe..0497784b3652 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c @@ -122,25 +122,12 @@ static int tonga_dpm_hw_fini(void *handle) static int tonga_dpm_suspend(void *handle) { - return 0; + return tonga_dpm_hw_fini(handle); } static int tonga_dpm_resume(void *handle) { - int ret; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - - mutex_lock(&adev->pm.mutex); - - ret = tonga_smu_start(adev); - if (ret) { - DRM_ERROR("SMU start failed\n"); - goto fail; - } - -fail: - mutex_unlock(&adev->pm.mutex); - return ret; + return tonga_dpm_hw_init(handle); } static int tonga_dpm_set_clockgating_state(void *handle, diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 652e76644c31..89f5a1ff6f43 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -61,6 +61,7 @@ #include "vi.h" #include "vi_dpm.h" #include "gmc_v8_0.h" +#include "gmc_v7_0.h" #include "gfx_v8_0.h" #include "sdma_v2_4.h" #include "sdma_v3_0.h" @@ -1109,10 +1110,10 @@ static const struct amdgpu_ip_block_version topaz_ip_blocks[] = }, { .type = AMD_IP_BLOCK_TYPE_GMC, - .major = 8, - .minor = 0, + .major = 7, + .minor = 4, .rev = 0, - .funcs = &gmc_v8_0_ip_funcs, + .funcs = &gmc_v7_0_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_IH, @@ -1442,8 +1443,7 @@ static int vi_common_early_init(void *handle) break; case CHIP_FIJI: adev->has_uvd = true; - adev->cg_flags = AMDGPU_CG_SUPPORT_UVD_MGCG | - AMDGPU_CG_SUPPORT_VCE_MGCG; + adev->cg_flags = 0; adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x3c; break; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 9be007081b72..a902ae037398 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -194,7 +194,7 @@ static void kfd_process_wq_release(struct work_struct *work) kfree(p); - kfree((void *)work); + kfree(work); } static void kfd_process_destroy_delayed(struct rcu_head *rcu) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 8f5d5edcf193..aa67244a77ae 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -64,6 +64,11 @@ static int pp_sw_init(void *handle) if (ret == 0) ret = hwmgr->hwmgr_func->backend_init(hwmgr); + if (ret) + printk("amdgpu: powerplay initialization failed\n"); + else + printk("amdgpu: powerplay initialized\n"); + return ret; } diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c index 873a8d264d5c..ec222c665602 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c @@ -272,6 +272,9 @@ static int cz_start_smu(struct pp_smumgr *smumgr) UCODE_ID_CP_MEC_JT1_MASK | UCODE_ID_CP_MEC_JT2_MASK; + if (smumgr->chip_id == CHIP_STONEY) + fw_to_check &= ~(UCODE_ID_SDMA1_MASK | UCODE_ID_CP_MEC_JT2_MASK); + cz_request_smu_load_fw(smumgr); cz_check_fw_load_finish(smumgr, fw_to_check); @@ -282,7 +285,7 @@ static int cz_start_smu(struct pp_smumgr *smumgr) return ret; } -static uint8_t cz_translate_firmware_enum_to_arg( +static uint8_t cz_translate_firmware_enum_to_arg(struct pp_smumgr *smumgr, enum cz_scratch_entry firmware_enum) { uint8_t ret = 0; @@ -292,7 +295,10 @@ static uint8_t cz_translate_firmware_enum_to_arg( ret = UCODE_ID_SDMA0; break; case CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1: - ret = UCODE_ID_SDMA1; + if (smumgr->chip_id == CHIP_STONEY) + ret = UCODE_ID_SDMA0; + else + ret = UCODE_ID_SDMA1; break; case CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE: ret = UCODE_ID_CP_CE; @@ -307,7 +313,10 @@ static uint8_t cz_translate_firmware_enum_to_arg( ret = UCODE_ID_CP_MEC_JT1; break; case CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2: - ret = UCODE_ID_CP_MEC_JT2; + if (smumgr->chip_id == CHIP_STONEY) + ret = UCODE_ID_CP_MEC_JT1; + else + ret = UCODE_ID_CP_MEC_JT2; break; case CZ_SCRATCH_ENTRY_UCODE_ID_GMCON_RENG: ret = UCODE_ID_GMCON_RENG; @@ -396,7 +405,7 @@ static int cz_smu_populate_single_scratch_task( struct SMU_Task *task = &toc->tasks[cz_smu->toc_entry_used_count++]; task->type = type; - task->arg = cz_translate_firmware_enum_to_arg(fw_enum); + task->arg = cz_translate_firmware_enum_to_arg(smumgr, fw_enum); task->next = is_last ? END_OF_TASK_LIST : cz_smu->toc_entry_used_count; for (i = 0; i < cz_smu->scratch_buffer_length; i++) @@ -433,7 +442,7 @@ static int cz_smu_populate_single_ucode_load_task( struct SMU_Task *task = &toc->tasks[cz_smu->toc_entry_used_count++]; task->type = TASK_TYPE_UCODE_LOAD; - task->arg = cz_translate_firmware_enum_to_arg(fw_enum); + task->arg = cz_translate_firmware_enum_to_arg(smumgr, fw_enum); task->next = is_last ? END_OF_TASK_LIST : cz_smu->toc_entry_used_count; for (i = 0; i < cz_smu->driver_buffer_length; i++) @@ -509,8 +518,14 @@ static int cz_smu_construct_toc_for_vddgfx_exit(struct pp_smumgr *smumgr) CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false); cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false); - cz_smu_populate_single_ucode_load_task(smumgr, + + if (smumgr->chip_id == CHIP_STONEY) + cz_smu_populate_single_ucode_load_task(smumgr, + CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false); + else + cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false); + cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G, false); @@ -551,7 +566,11 @@ static int cz_smu_construct_toc_for_bootup(struct pp_smumgr *smumgr) cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false); - cz_smu_populate_single_ucode_load_task(smumgr, + if (smumgr->chip_id == CHIP_STONEY) + cz_smu_populate_single_ucode_load_task(smumgr, + CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false); + else + cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1, false); cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE, false); @@ -561,7 +580,11 @@ static int cz_smu_construct_toc_for_bootup(struct pp_smumgr *smumgr) CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false); cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false); - cz_smu_populate_single_ucode_load_task(smumgr, + if (smumgr->chip_id == CHIP_STONEY) + cz_smu_populate_single_ucode_load_task(smumgr, + CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false); + else + cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false); cz_smu_populate_single_ucode_load_task(smumgr, CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G, true); @@ -618,7 +641,7 @@ static int cz_smu_populate_firmware_entries(struct pp_smumgr *smumgr) for (i = 0; i < sizeof(firmware_list)/sizeof(*firmware_list); i++) { - firmware_type = cz_translate_firmware_enum_to_arg( + firmware_type = cz_translate_firmware_enum_to_arg(smumgr, firmware_list[i]); ucode_id = cz_convert_fw_type_to_cgs(firmware_type); diff --git a/drivers/gpu/drm/arm/Kconfig b/drivers/gpu/drm/arm/Kconfig new file mode 100644 index 000000000000..eaed454e043c --- /dev/null +++ b/drivers/gpu/drm/arm/Kconfig @@ -0,0 +1,27 @@ +config DRM_ARM + bool + help + Choose this option to select drivers for ARM's devices + +config DRM_HDLCD + tristate "ARM HDLCD" + depends on DRM && OF && (ARM || ARM64) + depends on COMMON_CLK + select DRM_ARM + select DRM_KMS_HELPER + select DRM_KMS_FB_HELPER + select DRM_KMS_CMA_HELPER + help + Choose this option if you have an ARM High Definition Colour LCD + controller. + + If M is selected the module will be called hdlcd. + +config DRM_HDLCD_SHOW_UNDERRUN + bool "Show underrun conditions" + depends on DRM_HDLCD + default n + help + Enable this option to show in red colour the pixels that the + HDLCD device did not fetch from framebuffer due to underrun + conditions. diff --git a/drivers/gpu/drm/arm/Makefile b/drivers/gpu/drm/arm/Makefile new file mode 100644 index 000000000000..89dcb7bab93a --- /dev/null +++ b/drivers/gpu/drm/arm/Makefile @@ -0,0 +1,2 @@ +hdlcd-y := hdlcd_drv.o hdlcd_crtc.o +obj-$(CONFIG_DRM_HDLCD) += hdlcd.o diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c new file mode 100644 index 000000000000..fef1b04c2aab --- /dev/null +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2013-2015 ARM Limited + * Author: Liviu Dudau + * + * 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. + * + * Implementation of a CRTC class for the HDLCD driver. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include