This is the 4.19.47 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlzxMDsACgkQONu9yGCS aT6kjxAAvyKCDNGaQgBXGXe6xvBK7ad+mk+MU6WVycN+PIQzA8zVfR7RcGJgEP8t 65QrePyacMe5bmSgTnUKGz6DpwpWbCMamyftjoaPWIhxDFmQy7FB9ANOVoPDBw49 +jKT30ioBSI6LYQDU4xhxDO01HVEXmmLZquqYDfLoHOMLeXCivfTlM7PQPfxMZzn fdeLtvfCnfMiftkXZjGqaWoUAnrlTmncQk9nXMcDgxrGy9pHJ6B1WWE5ygqr4Z5s MaKfHotCSYD/eP8JsyIdJg+iMESv5Z0ZDCjbVslm81fCLeUD6atdnmpYxCphmT7Q ifN23i4FJrXBX4xLpD9RYzavH3+hQzqb2pt02aBZRW0OLFK0qjYrkdayjwWGOIUI zK9bgfHiiNKtoyvakQJ09uMhpO2thWeTMh8a6iBLTQ5Koi60adW1l5GrPuTTZYG7 V8xNB2cLsUktDsAr1I/kwrCMlE/oNFgy2La5zMzmELnFTUJRlMAoAGaa1DPcOFLt QVdT8luJMu+1KTeMZPoK/7QQGszMDTAot4+Ys56KyPQ6zN/rGr2vm7kHYn41FyEp KXpyeIm0/RKxUysz2Fyx+dL75e4ZhBof+amQ7Kotz6bF45o+ZwJ7THT6XKIOoln5 E7iI5RhQMZ2WuVIHLKa0QFBRn4RPpzie1lwOXWAAF6oqNgewXHw= =fjPE -----END PGP SIGNATURE----- Merge 4.19.47 into android-4.19-q Changes in 4.19.47 x86: Hide the int3_emulate_call/jmp functions from UML ext4: do not delete unlinked inode from orphan list on failed truncate ext4: wait for outstanding dio during truncate in nojournal mode f2fs: Fix use of number of devices KVM: x86: fix return value for reserved EFER bio: fix improper use of smp_mb__before_atomic() sbitmap: fix improper use of smp_mb__before_atomic() Revert "scsi: sd: Keep disk read-only when re-reading partition" crypto: vmx - CTR: always increment IV as quadword mmc: sdhci-iproc: cygnus: Set NO_HISPD bit to fix HS50 data hold time problem mmc: sdhci-iproc: Set NO_HISPD bit to fix HS50 data hold time problem kvm: svm/avic: fix off-by-one in checking host APIC ID libnvdimm/pmem: Bypass CONFIG_HARDENED_USERCOPY overhead arm64/kernel: kaslr: reduce module randomization range to 2 GB arm64/iommu: handle non-remapped addresses in ->mmap and ->get_sgtable gfs2: Fix sign extension bug in gfs2_update_stats btrfs: don't double unlock on error in btrfs_punch_hole Btrfs: do not abort transaction at btrfs_update_root() after failure to COW path Btrfs: avoid fallback to transaction commit during fsync of files with holes Btrfs: fix race between ranged fsync and writeback of adjacent ranges btrfs: sysfs: Fix error path kobject memory leak btrfs: sysfs: don't leak memory when failing add fsid udlfb: fix some inconsistent NULL checking fbdev: fix divide error in fb_var_to_videomode NFSv4.2 fix unnecessary retry in nfs4_copy_file_range NFSv4.1 fix incorrect return value in copy_file_range bpf: add bpf_jit_limit knob to restrict unpriv allocations brcmfmac: assure SSID length from firmware is limited brcmfmac: add subtype check for event handling in data path arm64: errata: Add workaround for Cortex-A76 erratum #1463225 btrfs: honor path->skip_locking in backref code ovl: relax WARN_ON() for overlapping layers use case fbdev: fix WARNING in __alloc_pages_nodemask bug media: cpia2: Fix use-after-free in cpia2_exit media: serial_ir: Fix use-after-free in serial_ir_init_module media: vb2: add waiting_in_dqbuf flag media: vivid: use vfree() instead of kfree() for dev->bitmap_cap ssb: Fix possible NULL pointer dereference in ssb_host_pcmcia_exit bpf: devmap: fix use-after-free Read in __dev_map_entry_free batman-adv: mcast: fix multicast tt/tvlv worker locking at76c50x-usb: Don't register led_trigger if usb_register_driver failed acct_on(): don't mess with freeze protection Revert "btrfs: Honour FITRIM range constraints during free space trim" gfs2: Fix lru_count going negative cxgb4: Fix error path in cxgb4_init_module NFS: make nfs_match_client killable IB/hfi1: Fix WQ_MEM_RECLAIM warning gfs2: Fix occasional glock use-after-free mmc: core: Verify SD bus width tools/bpf: fix perf build error with uClibc (seen on ARC) selftests/bpf: set RLIMIT_MEMLOCK properly for test_libbpf_open.c bpftool: exclude bash-completion/bpftool from .gitignore pattern dmaengine: tegra210-dma: free dma controller in remove() net: ena: gcc 8: fix compilation warning hv_netvsc: fix race that may miss tx queue wakeup Bluetooth: Ignore CC events not matching the last HCI command pinctrl: zte: fix leaked of_node references ASoC: Intel: kbl_da7219_max98357a: Map BTN_0 to KEY_PLAYPAUSE usb: dwc2: gadget: Increase descriptors count for ISOC's usb: dwc3: move synchronize_irq() out of the spinlock protected block ASoC: hdmi-codec: unlock the device on startup errors powerpc/perf: Return accordingly on invalid chip-id in powerpc/boot: Fix missing check of lseek() return value powerpc/perf: Fix loop exit condition in nest_imc_event_init ASoC: imx: fix fiq dependencies spi: pxa2xx: fix SCR (divisor) calculation brcm80211: potential NULL dereference in brcmf_cfg80211_vndr_cmds_dcmd_handler() ACPI / property: fix handling of data_nodes in acpi_get_next_subnode() drm/nouveau/bar/nv50: ensure BAR is mapped media: stm32-dcmi: return appropriate error codes during probe ARM: vdso: Remove dependency with the arch_timer driver internals arm64: Fix compiler warning from pte_unmap() with -Wunused-but-set-variable powerpc/watchdog: Use hrtimers for per-CPU heartbeat sched/cpufreq: Fix kobject memleak scsi: qla2xxx: Fix a qla24xx_enable_msix() error path scsi: qla2xxx: Fix abort handling in tcm_qla2xxx_write_pending() scsi: qla2xxx: Avoid that lockdep complains about unsafe locking in tcm_qla2xxx_close_session() scsi: qla2xxx: Fix hardirq-unsafe locking x86/modules: Avoid breaking W^X while loading modules Btrfs: fix data bytes_may_use underflow with fallocate due to failed quota reserve btrfs: fix panic during relocation after ENOSPC before writeback happens btrfs: Don't panic when we can't find a root key iwlwifi: pcie: don't crash on invalid RX interrupt rtc: 88pm860x: prevent use-after-free on device remove rtc: stm32: manage the get_irq probe defer case scsi: qedi: Abort ep termination if offload not scheduled s390/kexec_file: Fix detection of text segment in ELF loader sched/nohz: Run NOHZ idle load balancer on HK_FLAG_MISC CPUs w1: fix the resume command API s390: qeth: address type mismatch warning dmaengine: pl330: _stop: clear interrupt status mac80211/cfg80211: update bss channel on channel switch libbpf: fix samples/bpf build failure due to undefined UINT32_MAX slimbus: fix a potential NULL pointer dereference in of_qcom_slim_ngd_register ASoC: fsl_sai: Update is_slave_mode with correct value mwifiex: prevent an array overflow rsi: Fix NULL pointer dereference in kmalloc net: cw1200: fix a NULL pointer dereference nvme: set 0 capacity if namespace block size exceeds PAGE_SIZE nvme-rdma: fix a NULL deref when an admin connect times out crypto: sun4i-ss - Fix invalid calculation of hash end bcache: avoid potential memleak of list of journal_replay(s) in the CACHE_SYNC branch of run_cache_set bcache: return error immediately in bch_journal_replay() bcache: fix failure in journal relplay bcache: add failure check to run_cache_set() for journal replay bcache: avoid clang -Wunintialized warning RDMA/cma: Consider scope_id while binding to ipv6 ll address vfio-ccw: Do not call flush_workqueue while holding the spinlock vfio-ccw: Release any channel program when releasing/removing vfio-ccw mdev x86/build: Move _etext to actual end of .text smpboot: Place the __percpu annotation correctly x86/mm: Remove in_nmi() warning from 64-bit implementation of vmalloc_fault() mm/uaccess: Use 'unsigned long' to placate UBSAN warnings on older GCC versions Bluetooth: hci_qca: Give enough time to ROME controller to bootup. HID: logitech-hidpp: use RAP instead of FAP to get the protocol version pinctrl: pistachio: fix leaked of_node references pinctrl: samsung: fix leaked of_node references clk: rockchip: undo several noc and special clocks as critical on rk3288 perf/arm-cci: Remove broken race mitigation dmaengine: at_xdmac: remove BUG_ON macro in tasklet media: coda: clear error return value before picture run media: ov6650: Move v4l2_clk_get() to ov6650_video_probe() helper media: au0828: stop video streaming only when last user stops media: ov2659: make S_FMT succeed even if requested format doesn't match audit: fix a memory leak bug media: stm32-dcmi: fix crash when subdev do not expose any formats media: au0828: Fix NULL pointer dereference in au0828_analog_stream_enable() media: pvrusb2: Prevent a buffer overflow iio: adc: stm32-dfsdm: fix unmet direct dependencies detected block: fix use-after-free on gendisk powerpc/numa: improve control of topology updates powerpc/64: Fix booting large kernels with STRICT_KERNEL_RWX random: fix CRNG initialization when random.trust_cpu=1 random: add a spinlock_t to struct batched_entropy cgroup: protect cgroup->nr_(dying_)descendants by css_set_lock sched/core: Check quota and period overflow at usec to nsec conversion sched/rt: Check integer overflow at usec to nsec conversion sched/core: Handle overflow in cpu_shares_write_u64 staging: vc04_services: handle kzalloc failure drm/msm: a5xx: fix possible object reference leak irq_work: Do not raise an IPI when queueing work on the local CPU thunderbolt: Take domain lock in switch sysfs attribute callbacks s390/qeth: handle error from qeth_update_from_chp_desc() USB: core: Don't unbind interfaces following device reset failure x86/irq/64: Limit IST stack overflow check to #DB stack drm: etnaviv: avoid DMA API warning when importing buffers phy: sun4i-usb: Make sure to disable PHY0 passby for peripheral mode phy: mapphone-mdm6600: add gpiolib dependency i40e: Able to add up to 16 MAC filters on an untrusted VF i40e: don't allow changes to HW VLAN stripping on active port VLANs ACPI/IORT: Reject platform device creation on NUMA node mapping failure arm64: vdso: Fix clock_getres() for CLOCK_REALTIME RDMA/cxgb4: Fix null pointer dereference on alloc_skb failure perf/x86/msr: Add Icelake support perf/x86/intel/rapl: Add Icelake support perf/x86/intel/cstate: Add Icelake support hwmon: (vt1211) Use request_muxed_region for Super-IO accesses hwmon: (smsc47m1) Use request_muxed_region for Super-IO accesses hwmon: (smsc47b397) Use request_muxed_region for Super-IO accesses hwmon: (pc87427) Use request_muxed_region for Super-IO accesses hwmon: (f71805f) Use request_muxed_region for Super-IO accesses scsi: libsas: Do discovery on empty PHY to update PHY info mmc: core: make pwrseq_emmc (partially) support sleepy GPIO controllers mmc_spi: add a status check for spi_sync_locked mmc: sdhci-of-esdhc: add erratum eSDHC5 support mmc: sdhci-of-esdhc: add erratum A-009204 support mmc: sdhci-of-esdhc: add erratum eSDHC-A001 and A-008358 support drm/amdgpu: fix old fence check in amdgpu_fence_emit PM / core: Propagate dev->power.wakeup_path when no callbacks clk: rockchip: Fix video codec clocks on rk3288 extcon: arizona: Disable mic detect if running when driver is removed clk: rockchip: Make rkpwm a critical clock on rk3288 s390: zcrypt: initialize variables before_use x86/microcode: Fix the ancient deprecated microcode loading method s390/mm: silence compiler warning when compiling without CONFIG_PGSTE s390: cio: fix cio_irb declaration selftests: cgroup: fix cleanup path in test_memcg_subtree_control() qmi_wwan: Add quirk for Quectel dynamic config cpufreq: ppc_cbe: fix possible object reference leak cpufreq/pasemi: fix possible object reference leak cpufreq: pmac32: fix possible object reference leak cpufreq: kirkwood: fix possible object reference leak block: sed-opal: fix IOC_OPAL_ENABLE_DISABLE_MBR x86/build: Keep local relocations with ld.lld drm/pl111: fix possible object reference leak iio: ad_sigma_delta: Properly handle SPI bus locking vs CS assertion iio: hmc5843: fix potential NULL pointer dereferences iio: common: ssp_sensors: Initialize calculated_time in ssp_common_process_data iio: adc: ti-ads7950: Fix improper use of mlock selftests/bpf: ksym_search won't check symbols exists rtlwifi: fix a potential NULL pointer dereference mwifiex: Fix mem leak in mwifiex_tm_cmd brcmfmac: fix missing checks for kmemdup b43: shut up clang -Wuninitialized variable warning brcmfmac: convert dev_init_lock mutex to completion brcmfmac: fix WARNING during USB disconnect in case of unempty psq brcmfmac: fix race during disconnect when USB completion is in progress brcmfmac: fix Oops when bringing up interface during USB disconnect rtc: xgene: fix possible race condition rtlwifi: fix potential NULL pointer dereference scsi: ufs: Fix regulator load and icc-level configuration scsi: ufs: Avoid configuring regulator with undefined voltage range drm/panel: otm8009a: Add delay at the end of initialization arm64: cpu_ops: fix a leaked reference by adding missing of_node_put wil6210: fix return code of wmi_mgmt_tx and wmi_mgmt_tx_ext x86/uaccess, ftrace: Fix ftrace_likely_update() vs. SMAP x86/uaccess, signal: Fix AC=1 bloat x86/ia32: Fix ia32_restore_sigcontext() AC leak x86/uaccess: Fix up the fixup chardev: add additional check for minor range overlap RDMA/hns: Fix bad endianess of port_pd variable sh: sh7786: Add explicit I/O cast to sh7786_mm_sel() HID: core: move Usage Page concatenation to Main item ASoC: eukrea-tlv320: fix a leaked reference by adding missing of_node_put ASoC: fsl_utils: fix a leaked reference by adding missing of_node_put cxgb3/l2t: Fix undefined behaviour HID: logitech-hidpp: change low battery level threshold from 31 to 30 percent spi: tegra114: reset controller on probe kobject: Don't trigger kobject_uevent(KOBJ_REMOVE) twice. media: video-mux: fix null pointer dereferences media: wl128x: prevent two potential buffer overflows media: gspca: Kill URBs on USB device disconnect efifb: Omit memory map check on legacy boot thunderbolt: property: Fix a missing check of kzalloc thunderbolt: Fix to check the return value of kmemdup timekeeping: Force upper bound for setting CLOCK_REALTIME scsi: qedf: Add missing return in qedf_post_io_req() in the fcport offload check virtio_console: initialize vtermno value for ports tty: ipwireless: fix missing checks for ioremap overflow: Fix -Wtype-limits compilation warnings x86/mce: Fix machine_check_poll() tests for error types rcutorture: Fix cleanup path for invalid torture_type strings x86/mce: Handle varying MCA bank counts rcuperf: Fix cleanup path for invalid perf_type strings usb: core: Add PM runtime calls to usb_hcd_platform_shutdown scsi: qla4xxx: avoid freeing unallocated dma memory scsi: lpfc: avoid uninitialized variable warning selinux: avoid uninitialized variable warning batman-adv: allow updating DAT entry timeouts on incoming ARP Replies dmaengine: tegra210-adma: use devm_clk_*() helpers hwrng: omap - Set default quality thunderbolt: Fix to check return value of ida_simple_get thunderbolt: Fix to check for kmemdup failure drm/amd/display: fix releasing planes when exiting odm thunderbolt: property: Fix a NULL pointer dereference e1000e: Disable runtime PM on CNP+ tinydrm/mipi-dbi: Use dma-safe buffers for all SPI transfers igb: Exclude device from suspend direct complete optimization media: si2165: fix a missing check of return value media: dvbsky: Avoid leaking dvb frontend media: m88ds3103: serialize reset messages in m88ds3103_set_frontend media: staging: davinci_vpfe: disallow building with COMPILE_TEST drm/amd/display: Fix Divide by 0 in memory calculations drm/amd/display: Set stream->mode_changed when connectors change scsi: ufs: fix a missing check of devm_reset_control_get media: vimc: stream: fix thread state before sleep media: gspca: do not resubmit URBs when streaming has stopped media: go7007: avoid clang frame overflow warning with KASAN media: vimc: zero the media_device on probe scsi: lpfc: Fix FDMI manufacturer attribute value scsi: lpfc: Fix fc4type information for FDMI media: saa7146: avoid high stack usage with clang scsi: lpfc: Fix SLI3 commands being issued on SLI4 devices spi : spi-topcliff-pch: Fix to handle empty DMA buffers drm/omap: dsi: Fix PM for display blank with paired dss_pll calls spi: rspi: Fix sequencer reset during initialization spi: imx: stop buffer overflow in RX FIFO flush spi: Fix zero length xfer bug ASoC: davinci-mcasp: Fix clang warning without CONFIG_PM drm/v3d: Handle errors from IRQ setup. drm/drv: Hold ref on parent device during drm_device lifetime drm: Wake up next in drm_read() chain if we are forced to putback the event drm/sun4i: dsi: Change the start delay calculation vfio-ccw: Prevent quiesce function going into an infinite loop drm/sun4i: dsi: Enforce boundaries on the start delay NFS: Fix a double unlock from nfs_match,get_client Linux 4.19.47 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
f4aedf06d3
@ -58,6 +58,7 @@ stable kernels.
|
||||
| ARM | Cortex-A72 | #853709 | N/A |
|
||||
| ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 |
|
||||
| ARM | Cortex-A55 | #1024718 | ARM64_ERRATUM_1024718 |
|
||||
| ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 |
|
||||
| ARM | MMU-500 | #841119,#826419 | N/A |
|
||||
| | | | |
|
||||
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
|
||||
|
@ -92,6 +92,14 @@ Values :
|
||||
0 - disable JIT kallsyms export (default value)
|
||||
1 - enable JIT kallsyms export for privileged users only
|
||||
|
||||
bpf_jit_limit
|
||||
-------------
|
||||
|
||||
This enforces a global limit for memory allocations to the BPF JIT
|
||||
compiler in order to reject unprivileged JIT requests once it has
|
||||
been surpassed. bpf_jit_limit contains the value of the global limit
|
||||
in bytes.
|
||||
|
||||
dev_weight
|
||||
--------------
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 19
|
||||
SUBLEVEL = 46
|
||||
SUBLEVEL = 47
|
||||
EXTRAVERSION =
|
||||
NAME = "People's Front"
|
||||
|
||||
|
@ -68,6 +68,8 @@
|
||||
#define BPIALL __ACCESS_CP15(c7, 0, c5, 6)
|
||||
#define ICIALLU __ACCESS_CP15(c7, 0, c5, 0)
|
||||
|
||||
#define CNTVCT __ACCESS_CP15_64(1, c14)
|
||||
|
||||
extern unsigned long cr_alignment; /* defined in entry-armv.S */
|
||||
|
||||
static inline unsigned long get_cr(void)
|
||||
|
@ -18,9 +18,9 @@
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/time.h>
|
||||
#include <asm/arch_timer.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/bug.h>
|
||||
#include <asm/cp15.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/vdso_datapage.h>
|
||||
@ -123,7 +123,8 @@ static notrace u64 get_ns(struct vdso_data *vdata)
|
||||
u64 cycle_now;
|
||||
u64 nsec;
|
||||
|
||||
cycle_now = arch_counter_get_cntvct();
|
||||
isb();
|
||||
cycle_now = read_sysreg(CNTVCT);
|
||||
|
||||
cycle_delta = (cycle_now - vdata->cs_cycle_last) & vdata->cs_mask;
|
||||
|
||||
|
@ -480,6 +480,24 @@ config ARM64_ERRATUM_1024718
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config ARM64_ERRATUM_1463225
|
||||
bool "Cortex-A76: Software Step might prevent interrupt recognition"
|
||||
default y
|
||||
help
|
||||
This option adds a workaround for Arm Cortex-A76 erratum 1463225.
|
||||
|
||||
On the affected Cortex-A76 cores (r0p0 to r3p1), software stepping
|
||||
of a system call instruction (SVC) can prevent recognition of
|
||||
subsequent interrupts when software stepping is disabled in the
|
||||
exception handler of the system call and either kernel debugging
|
||||
is enabled or VHE is in use.
|
||||
|
||||
Work around the erratum by triggering a dummy step exception
|
||||
when handling a system call from a task that is being stepped
|
||||
in a VHE configuration of the kernel.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config CAVIUM_ERRATUM_22375
|
||||
bool "Cavium erratum 22375, 24313"
|
||||
default y
|
||||
|
@ -51,7 +51,8 @@
|
||||
#define ARM64_SSBD 30
|
||||
#define ARM64_MISMATCHED_CACHE_TYPE 31
|
||||
#define ARM64_HAS_STAGE2_FWB 32
|
||||
#define ARM64_WORKAROUND_1463225 33
|
||||
|
||||
#define ARM64_NCAPS 33
|
||||
#define ARM64_NCAPS 34
|
||||
|
||||
#endif /* __ASM_CPUCAPS_H */
|
||||
|
@ -86,6 +86,7 @@
|
||||
#define ARM_CPU_PART_CORTEX_A75 0xD0A
|
||||
#define ARM_CPU_PART_CORTEX_A35 0xD04
|
||||
#define ARM_CPU_PART_CORTEX_A55 0xD05
|
||||
#define ARM_CPU_PART_CORTEX_A76 0xD0B
|
||||
|
||||
#define APM_CPU_PART_POTENZA 0x000
|
||||
|
||||
@ -110,6 +111,7 @@
|
||||
#define MIDR_CORTEX_A75 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A75)
|
||||
#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35)
|
||||
#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
|
||||
#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
|
||||
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
|
||||
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
|
||||
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
|
||||
|
@ -444,6 +444,8 @@ static inline phys_addr_t pmd_page_paddr(pmd_t pmd)
|
||||
return __pmd_to_phys(pmd);
|
||||
}
|
||||
|
||||
static inline void pte_unmap(pte_t *pte) { }
|
||||
|
||||
/* Find an entry in the third-level page table. */
|
||||
#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
|
||||
|
||||
@ -452,7 +454,6 @@ static inline phys_addr_t pmd_page_paddr(pmd_t pmd)
|
||||
|
||||
#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))
|
||||
|
@ -38,6 +38,7 @@ struct vdso_data {
|
||||
__u32 tz_minuteswest; /* Whacky timezone stuff */
|
||||
__u32 tz_dsttime;
|
||||
__u32 use_syscall;
|
||||
__u32 hrtimer_res;
|
||||
};
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
@ -99,7 +99,7 @@ int main(void)
|
||||
DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
|
||||
DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
|
||||
DEFINE(CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_RAW);
|
||||
DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
|
||||
DEFINE(CLOCK_REALTIME_RES, offsetof(struct vdso_data, hrtimer_res));
|
||||
DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
|
||||
DEFINE(CLOCK_MONOTONIC_COARSE,CLOCK_MONOTONIC_COARSE);
|
||||
DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC);
|
||||
|
@ -411,6 +411,22 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
|
||||
}
|
||||
#endif /* CONFIG_ARM64_SSBD */
|
||||
|
||||
#ifdef CONFIG_ARM64_ERRATUM_1463225
|
||||
DEFINE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
|
||||
|
||||
static bool
|
||||
has_cortex_a76_erratum_1463225(const struct arm64_cpu_capabilities *entry,
|
||||
int scope)
|
||||
{
|
||||
u32 midr = read_cpuid_id();
|
||||
/* Cortex-A76 r0p0 - r3p1 */
|
||||
struct midr_range range = MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 1);
|
||||
|
||||
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
|
||||
return is_midr_in_range(midr, &range) && is_kernel_in_hyp_mode();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CAP_MIDR_RANGE(model, v_min, r_min, v_max, r_max) \
|
||||
.matches = is_affected_midr_range, \
|
||||
.midr_range = MIDR_RANGE(model, v_min, r_min, v_max, r_max)
|
||||
@ -679,6 +695,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
|
||||
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
|
||||
.matches = has_ssbd_mitigation,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARM64_ERRATUM_1463225
|
||||
{
|
||||
.desc = "ARM erratum 1463225",
|
||||
.capability = ARM64_WORKAROUND_1463225,
|
||||
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
|
||||
.matches = has_cortex_a76_erratum_1463225,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ static const char *__init cpu_read_enable_method(int cpu)
|
||||
pr_err("%pOF: missing enable-method property\n",
|
||||
dn);
|
||||
}
|
||||
of_node_put(dn);
|
||||
} else {
|
||||
enable_method = acpi_get_enable_method(cpu);
|
||||
if (!enable_method) {
|
||||
|
@ -145,15 +145,15 @@ u64 __init kaslr_early_init(u64 dt_phys)
|
||||
|
||||
if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) {
|
||||
/*
|
||||
* Randomize the module region over a 4 GB window covering the
|
||||
* Randomize the module region over a 2 GB window covering the
|
||||
* kernel. This reduces the risk of modules leaking information
|
||||
* about the address of the kernel itself, but results in
|
||||
* branches between modules and the core kernel that are
|
||||
* resolved via PLTs. (Branches between modules will be
|
||||
* resolved normally.)
|
||||
*/
|
||||
module_range = SZ_4G - (u64)(_end - _stext);
|
||||
module_alloc_base = max((u64)_end + offset - SZ_4G,
|
||||
module_range = SZ_2G - (u64)(_end - _stext);
|
||||
module_alloc_base = max((u64)_end + offset - SZ_2G,
|
||||
(u64)MODULES_VADDR);
|
||||
} else {
|
||||
/*
|
||||
|
@ -56,7 +56,7 @@ void *module_alloc(unsigned long size)
|
||||
* can simply omit this fallback in that case.
|
||||
*/
|
||||
p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
|
||||
module_alloc_base + SZ_4G, GFP_KERNEL,
|
||||
module_alloc_base + SZ_2G, GFP_KERNEL,
|
||||
PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/syscalls.h>
|
||||
|
||||
#include <asm/daifflags.h>
|
||||
#include <asm/debug-monitors.h>
|
||||
#include <asm/fpsimd.h>
|
||||
#include <asm/syscall.h>
|
||||
#include <asm/thread_info.h>
|
||||
@ -60,6 +61,35 @@ static inline bool has_syscall_work(unsigned long flags)
|
||||
int syscall_trace_enter(struct pt_regs *regs);
|
||||
void syscall_trace_exit(struct pt_regs *regs);
|
||||
|
||||
#ifdef CONFIG_ARM64_ERRATUM_1463225
|
||||
DECLARE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
|
||||
|
||||
static void cortex_a76_erratum_1463225_svc_handler(void)
|
||||
{
|
||||
u32 reg, val;
|
||||
|
||||
if (!unlikely(test_thread_flag(TIF_SINGLESTEP)))
|
||||
return;
|
||||
|
||||
if (!unlikely(this_cpu_has_cap(ARM64_WORKAROUND_1463225)))
|
||||
return;
|
||||
|
||||
__this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 1);
|
||||
reg = read_sysreg(mdscr_el1);
|
||||
val = reg | DBG_MDSCR_SS | DBG_MDSCR_KDE;
|
||||
write_sysreg(val, mdscr_el1);
|
||||
asm volatile("msr daifclr, #8");
|
||||
isb();
|
||||
|
||||
/* We will have taken a single-step exception by this point */
|
||||
|
||||
write_sysreg(reg, mdscr_el1);
|
||||
__this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 0);
|
||||
}
|
||||
#else
|
||||
static void cortex_a76_erratum_1463225_svc_handler(void) { }
|
||||
#endif /* CONFIG_ARM64_ERRATUM_1463225 */
|
||||
|
||||
static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
|
||||
const syscall_fn_t syscall_table[])
|
||||
{
|
||||
@ -68,6 +98,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
|
||||
regs->orig_x0 = regs->regs[0];
|
||||
regs->syscallno = scno;
|
||||
|
||||
cortex_a76_erratum_1463225_svc_handler();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
user_exit();
|
||||
|
||||
|
@ -232,6 +232,9 @@ void update_vsyscall(struct timekeeper *tk)
|
||||
vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec;
|
||||
vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
|
||||
|
||||
/* Read without the seqlock held by clock_getres() */
|
||||
WRITE_ONCE(vdso_data->hrtimer_res, hrtimer_resolution);
|
||||
|
||||
if (!use_syscall) {
|
||||
/* tkr_mono.cycle_last == tkr_raw.cycle_last */
|
||||
vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
|
||||
|
@ -308,13 +308,14 @@ ENTRY(__kernel_clock_getres)
|
||||
ccmp w0, #CLOCK_MONOTONIC_RAW, #0x4, ne
|
||||
b.ne 1f
|
||||
|
||||
ldr x2, 5f
|
||||
adr vdso_data, _vdso_data
|
||||
ldr w2, [vdso_data, #CLOCK_REALTIME_RES]
|
||||
b 2f
|
||||
1:
|
||||
cmp w0, #CLOCK_REALTIME_COARSE
|
||||
ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
|
||||
b.ne 4f
|
||||
ldr x2, 6f
|
||||
ldr x2, 5f
|
||||
2:
|
||||
cbz x1, 3f
|
||||
stp xzr, x2, [x1]
|
||||
@ -328,8 +329,6 @@ ENTRY(__kernel_clock_getres)
|
||||
svc #0
|
||||
ret
|
||||
5:
|
||||
.quad CLOCK_REALTIME_RES
|
||||
6:
|
||||
.quad CLOCK_COARSE_RES
|
||||
.cfi_endproc
|
||||
ENDPROC(__kernel_clock_getres)
|
||||
|
@ -664,6 +664,11 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
|
||||
if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
|
||||
return ret;
|
||||
|
||||
if (!is_vmalloc_addr(cpu_addr)) {
|
||||
unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
|
||||
return __swiotlb_mmap_pfn(vma, pfn, size);
|
||||
}
|
||||
|
||||
if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) {
|
||||
/*
|
||||
* DMA_ATTR_FORCE_CONTIGUOUS allocations are always remapped,
|
||||
@ -687,6 +692,11 @@ static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
|
||||
struct vm_struct *area = find_vm_area(cpu_addr);
|
||||
|
||||
if (!is_vmalloc_addr(cpu_addr)) {
|
||||
struct page *page = virt_to_page(cpu_addr);
|
||||
return __swiotlb_get_sgtable_page(sgt, page, size);
|
||||
}
|
||||
|
||||
if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) {
|
||||
/*
|
||||
* DMA_ATTR_FORCE_CONTIGUOUS allocations are always remapped,
|
||||
|
@ -827,14 +827,47 @@ void __init hook_debug_fault_code(int nr,
|
||||
debug_fault_info[nr].name = name;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM64_ERRATUM_1463225
|
||||
DECLARE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
|
||||
|
||||
static int __exception
|
||||
cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
|
||||
{
|
||||
if (user_mode(regs))
|
||||
return 0;
|
||||
|
||||
if (!__this_cpu_read(__in_cortex_a76_erratum_1463225_wa))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We've taken a dummy step exception from the kernel to ensure
|
||||
* that interrupts are re-enabled on the syscall path. Return back
|
||||
* to cortex_a76_erratum_1463225_svc_handler() with debug exceptions
|
||||
* masked so that we can safely restore the mdscr and get on with
|
||||
* handling the syscall.
|
||||
*/
|
||||
regs->pstate |= PSR_D_BIT;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
static int __exception
|
||||
cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ARM64_ERRATUM_1463225 */
|
||||
|
||||
asmlinkage int __exception do_debug_exception(unsigned long addr_if_watchpoint,
|
||||
unsigned int esr,
|
||||
struct pt_regs *regs)
|
||||
unsigned int esr,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr);
|
||||
unsigned long pc = instruction_pointer(regs);
|
||||
int rv;
|
||||
|
||||
if (cortex_a76_erratum_1463225_debug_handler(regs))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Tell lockdep we disabled irqs in entry.S. Do nothing if they were
|
||||
* already disabled to preserve the last enabled/disabled addresses.
|
||||
|
@ -223,7 +223,11 @@ main(int ac, char **av)
|
||||
PUT_16(E_PHNUM, np + 2);
|
||||
|
||||
/* write back */
|
||||
lseek(fd, (long) 0, SEEK_SET);
|
||||
i = lseek(fd, (long) 0, SEEK_SET);
|
||||
if (i < 0) {
|
||||
perror("lseek");
|
||||
exit(1);
|
||||
}
|
||||
i = write(fd, buf, n);
|
||||
if (i < 0) {
|
||||
perror("write");
|
||||
|
@ -970,7 +970,9 @@ start_here_multiplatform:
|
||||
|
||||
/* Restore parameters passed from prom_init/kexec */
|
||||
mr r3,r31
|
||||
bl early_setup /* also sets r13 and SPRG_PACA */
|
||||
LOAD_REG_ADDR(r12, DOTSYM(early_setup))
|
||||
mtctr r12
|
||||
bctrl /* also sets r13 and SPRG_PACA */
|
||||
|
||||
LOAD_REG_ADDR(r3, start_here_common)
|
||||
ld r4,PACAKMSR(r13)
|
||||
|
@ -77,7 +77,7 @@ static u64 wd_smp_panic_timeout_tb __read_mostly; /* panic other CPUs */
|
||||
|
||||
static u64 wd_timer_period_ms __read_mostly; /* interval between heartbeat */
|
||||
|
||||
static DEFINE_PER_CPU(struct timer_list, wd_timer);
|
||||
static DEFINE_PER_CPU(struct hrtimer, wd_hrtimer);
|
||||
static DEFINE_PER_CPU(u64, wd_timer_tb);
|
||||
|
||||
/* SMP checker bits */
|
||||
@ -293,21 +293,21 @@ out:
|
||||
nmi_exit();
|
||||
}
|
||||
|
||||
static void wd_timer_reset(unsigned int cpu, struct timer_list *t)
|
||||
{
|
||||
t->expires = jiffies + msecs_to_jiffies(wd_timer_period_ms);
|
||||
if (wd_timer_period_ms > 1000)
|
||||
t->expires = __round_jiffies_up(t->expires, cpu);
|
||||
add_timer_on(t, cpu);
|
||||
}
|
||||
|
||||
static void wd_timer_fn(struct timer_list *t)
|
||||
static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
|
||||
return HRTIMER_NORESTART;
|
||||
|
||||
if (!cpumask_test_cpu(cpu, &watchdog_cpumask))
|
||||
return HRTIMER_NORESTART;
|
||||
|
||||
watchdog_timer_interrupt(cpu);
|
||||
|
||||
wd_timer_reset(cpu, t);
|
||||
hrtimer_forward_now(hrtimer, ms_to_ktime(wd_timer_period_ms));
|
||||
|
||||
return HRTIMER_RESTART;
|
||||
}
|
||||
|
||||
void arch_touch_nmi_watchdog(void)
|
||||
@ -323,37 +323,22 @@ void arch_touch_nmi_watchdog(void)
|
||||
}
|
||||
EXPORT_SYMBOL(arch_touch_nmi_watchdog);
|
||||
|
||||
static void start_watchdog_timer_on(unsigned int cpu)
|
||||
{
|
||||
struct timer_list *t = per_cpu_ptr(&wd_timer, cpu);
|
||||
|
||||
per_cpu(wd_timer_tb, cpu) = get_tb();
|
||||
|
||||
timer_setup(t, wd_timer_fn, TIMER_PINNED);
|
||||
wd_timer_reset(cpu, t);
|
||||
}
|
||||
|
||||
static void stop_watchdog_timer_on(unsigned int cpu)
|
||||
{
|
||||
struct timer_list *t = per_cpu_ptr(&wd_timer, cpu);
|
||||
|
||||
del_timer_sync(t);
|
||||
}
|
||||
|
||||
static int start_wd_on_cpu(unsigned int cpu)
|
||||
static void start_watchdog(void *arg)
|
||||
{
|
||||
struct hrtimer *hrtimer = this_cpu_ptr(&wd_hrtimer);
|
||||
int cpu = smp_processor_id();
|
||||
unsigned long flags;
|
||||
|
||||
if (cpumask_test_cpu(cpu, &wd_cpus_enabled)) {
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (!cpumask_test_cpu(cpu, &watchdog_cpumask))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
wd_smp_lock(&flags);
|
||||
cpumask_set_cpu(cpu, &wd_cpus_enabled);
|
||||
@ -363,27 +348,40 @@ static int start_wd_on_cpu(unsigned int cpu)
|
||||
}
|
||||
wd_smp_unlock(&flags);
|
||||
|
||||
start_watchdog_timer_on(cpu);
|
||||
*this_cpu_ptr(&wd_timer_tb) = get_tb();
|
||||
|
||||
return 0;
|
||||
hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
hrtimer->function = watchdog_timer_fn;
|
||||
hrtimer_start(hrtimer, ms_to_ktime(wd_timer_period_ms),
|
||||
HRTIMER_MODE_REL_PINNED);
|
||||
}
|
||||
|
||||
static int stop_wd_on_cpu(unsigned int cpu)
|
||||
static int start_watchdog_on_cpu(unsigned int cpu)
|
||||
{
|
||||
return smp_call_function_single(cpu, start_watchdog, NULL, true);
|
||||
}
|
||||
|
||||
static void stop_watchdog(void *arg)
|
||||
{
|
||||
struct hrtimer *hrtimer = this_cpu_ptr(&wd_hrtimer);
|
||||
int cpu = smp_processor_id();
|
||||
unsigned long flags;
|
||||
|
||||
if (!cpumask_test_cpu(cpu, &wd_cpus_enabled))
|
||||
return 0; /* Can happen in CPU unplug case */
|
||||
return; /* Can happen in CPU unplug case */
|
||||
|
||||
stop_watchdog_timer_on(cpu);
|
||||
hrtimer_cancel(hrtimer);
|
||||
|
||||
wd_smp_lock(&flags);
|
||||
cpumask_clear_cpu(cpu, &wd_cpus_enabled);
|
||||
wd_smp_unlock(&flags);
|
||||
|
||||
wd_smp_clear_cpu_pending(cpu, get_tb());
|
||||
}
|
||||
|
||||
return 0;
|
||||
static int stop_watchdog_on_cpu(unsigned int cpu)
|
||||
{
|
||||
return smp_call_function_single(cpu, stop_watchdog, NULL, true);
|
||||
}
|
||||
|
||||
static void watchdog_calc_timeouts(void)
|
||||
@ -402,7 +400,7 @@ void watchdog_nmi_stop(void)
|
||||
int cpu;
|
||||
|
||||
for_each_cpu(cpu, &wd_cpus_enabled)
|
||||
stop_wd_on_cpu(cpu);
|
||||
stop_watchdog_on_cpu(cpu);
|
||||
}
|
||||
|
||||
void watchdog_nmi_start(void)
|
||||
@ -411,7 +409,7 @@ void watchdog_nmi_start(void)
|
||||
|
||||
watchdog_calc_timeouts();
|
||||
for_each_cpu_and(cpu, cpu_online_mask, &watchdog_cpumask)
|
||||
start_wd_on_cpu(cpu);
|
||||
start_watchdog_on_cpu(cpu);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -423,7 +421,8 @@ int __init watchdog_nmi_probe(void)
|
||||
|
||||
err = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
|
||||
"powerpc/watchdog:online",
|
||||
start_wd_on_cpu, stop_wd_on_cpu);
|
||||
start_watchdog_on_cpu,
|
||||
stop_watchdog_on_cpu);
|
||||
if (err < 0) {
|
||||
pr_warn("could not be initialized");
|
||||
return err;
|
||||
|
@ -1495,6 +1495,9 @@ int start_topology_update(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!topology_updates_enabled)
|
||||
return 0;
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_PRRN)) {
|
||||
if (!prrn_enabled) {
|
||||
prrn_enabled = 1;
|
||||
@ -1524,6 +1527,9 @@ int stop_topology_update(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!topology_updates_enabled)
|
||||
return 0;
|
||||
|
||||
if (prrn_enabled) {
|
||||
prrn_enabled = 0;
|
||||
#ifdef CONFIG_SMP
|
||||
@ -1579,11 +1585,13 @@ static ssize_t topology_write(struct file *file, const char __user *buf,
|
||||
|
||||
kbuf[read_len] = '\0';
|
||||
|
||||
if (!strncmp(kbuf, "on", 2))
|
||||
if (!strncmp(kbuf, "on", 2)) {
|
||||
topology_updates_enabled = true;
|
||||
start_topology_update();
|
||||
else if (!strncmp(kbuf, "off", 3))
|
||||
} else if (!strncmp(kbuf, "off", 3)) {
|
||||
stop_topology_update();
|
||||
else
|
||||
topology_updates_enabled = false;
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
return count;
|
||||
@ -1598,9 +1606,7 @@ static const struct file_operations topology_ops = {
|
||||
|
||||
static int topology_update_init(void)
|
||||
{
|
||||
/* Do not poll for changes if disabled at boot */
|
||||
if (topology_updates_enabled)
|
||||
start_topology_update();
|
||||
start_topology_update();
|
||||
|
||||
if (vphn_enabled)
|
||||
topology_schedule_update();
|
||||
|
@ -496,6 +496,11 @@ static int nest_imc_event_init(struct perf_event *event)
|
||||
* Get the base memory addresss for this cpu.
|
||||
*/
|
||||
chip_id = cpu_to_chip_id(event->cpu);
|
||||
|
||||
/* Return, if chip_id is not valid */
|
||||
if (chip_id < 0)
|
||||
return -ENODEV;
|
||||
|
||||
pcni = pmu->mem_info;
|
||||
do {
|
||||
if (pcni->id == chip_id) {
|
||||
@ -503,7 +508,7 @@ static int nest_imc_event_init(struct perf_event *event)
|
||||
break;
|
||||
}
|
||||
pcni++;
|
||||
} while (pcni);
|
||||
} while (pcni->vbase != 0);
|
||||
|
||||
if (!flag)
|
||||
return -ENODEV;
|
||||
|
@ -127,7 +127,7 @@ static int imc_get_mem_addr_nest(struct device_node *node,
|
||||
nr_chips))
|
||||
goto error;
|
||||
|
||||
pmu_ptr->mem_info = kcalloc(nr_chips, sizeof(*pmu_ptr->mem_info),
|
||||
pmu_ptr->mem_info = kcalloc(nr_chips + 1, sizeof(*pmu_ptr->mem_info),
|
||||
GFP_KERNEL);
|
||||
if (!pmu_ptr->mem_info)
|
||||
goto error;
|
||||
|
@ -19,10 +19,15 @@ static int kexec_file_add_elf_kernel(struct kimage *image,
|
||||
struct kexec_buf buf;
|
||||
const Elf_Ehdr *ehdr;
|
||||
const Elf_Phdr *phdr;
|
||||
Elf_Addr entry;
|
||||
int i, ret;
|
||||
|
||||
ehdr = (Elf_Ehdr *)kernel;
|
||||
buf.image = image;
|
||||
if (image->type == KEXEC_TYPE_CRASH)
|
||||
entry = STARTUP_KDUMP_OFFSET;
|
||||
else
|
||||
entry = ehdr->e_entry;
|
||||
|
||||
phdr = (void *)ehdr + ehdr->e_phoff;
|
||||
for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
|
||||
@ -35,7 +40,7 @@ static int kexec_file_add_elf_kernel(struct kimage *image,
|
||||
buf.mem = ALIGN(phdr->p_paddr, phdr->p_align);
|
||||
buf.memsz = phdr->p_memsz;
|
||||
|
||||
if (phdr->p_paddr == 0) {
|
||||
if (entry - phdr->p_paddr < phdr->p_memsz) {
|
||||
data->kernel_buf = buf.buffer;
|
||||
data->memsz += STARTUP_NORMAL_OFFSET;
|
||||
|
||||
|
@ -410,6 +410,7 @@ static inline pmd_t pmdp_flush_lazy(struct mm_struct *mm,
|
||||
return old;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PGSTE
|
||||
static pmd_t *pmd_alloc_map(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
@ -427,6 +428,7 @@ static pmd_t *pmd_alloc_map(struct mm_struct *mm, unsigned long addr)
|
||||
pmd = pmd_alloc(mm, pud, addr);
|
||||
return pmd;
|
||||
}
|
||||
#endif
|
||||
|
||||
pmd_t pmdp_xchg_direct(struct mm_struct *mm, unsigned long addr,
|
||||
pmd_t *pmdp, pmd_t new)
|
||||
|
@ -135,7 +135,7 @@ enum {
|
||||
|
||||
static inline u32 sh7786_mm_sel(void)
|
||||
{
|
||||
return __raw_readl(0xFC400020) & 0x7;
|
||||
return __raw_readl((const volatile void __iomem *)0xFC400020) & 0x7;
|
||||
}
|
||||
|
||||
#endif /* __CPU_SH7786_H__ */
|
||||
|
@ -584,6 +584,8 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
|
||||
X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_X, glm_cstates),
|
||||
|
||||
X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates),
|
||||
|
||||
X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_MOBILE, snb_cstates),
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
|
||||
|
@ -780,6 +780,8 @@ static const struct x86_cpu_id rapl_cpu_match[] __initconst = {
|
||||
X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_X, hsw_rapl_init),
|
||||
|
||||
X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_PLUS, hsw_rapl_init),
|
||||
|
||||
X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE_MOBILE, skl_rapl_init),
|
||||
{},
|
||||
};
|
||||
|
||||
|
@ -89,6 +89,7 @@ static bool test_intel(int idx)
|
||||
case INTEL_FAM6_SKYLAKE_X:
|
||||
case INTEL_FAM6_KABYLAKE_MOBILE:
|
||||
case INTEL_FAM6_KABYLAKE_DESKTOP:
|
||||
case INTEL_FAM6_ICELAKE_MOBILE:
|
||||
if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF)
|
||||
return true;
|
||||
break;
|
||||
|
@ -61,9 +61,8 @@
|
||||
} while (0)
|
||||
|
||||
#define RELOAD_SEG(seg) { \
|
||||
unsigned int pre = GET_SEG(seg); \
|
||||
unsigned int pre = (seg) | 3; \
|
||||
unsigned int cur = get_user_seg(seg); \
|
||||
pre |= 3; \
|
||||
if (pre != cur) \
|
||||
set_user_seg(seg, pre); \
|
||||
}
|
||||
@ -72,6 +71,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
|
||||
struct sigcontext_32 __user *sc)
|
||||
{
|
||||
unsigned int tmpflags, err = 0;
|
||||
u16 gs, fs, es, ds;
|
||||
void __user *buf;
|
||||
u32 tmp;
|
||||
|
||||
@ -79,16 +79,10 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
|
||||
current->restart_block.fn = do_no_restart_syscall;
|
||||
|
||||
get_user_try {
|
||||
/*
|
||||
* Reload fs and gs if they have changed in the signal
|
||||
* handler. This does not handle long fs/gs base changes in
|
||||
* the handler, but does not clobber them at least in the
|
||||
* normal case.
|
||||
*/
|
||||
RELOAD_SEG(gs);
|
||||
RELOAD_SEG(fs);
|
||||
RELOAD_SEG(ds);
|
||||
RELOAD_SEG(es);
|
||||
gs = GET_SEG(gs);
|
||||
fs = GET_SEG(fs);
|
||||
ds = GET_SEG(ds);
|
||||
es = GET_SEG(es);
|
||||
|
||||
COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
|
||||
COPY(dx); COPY(cx); COPY(ip); COPY(ax);
|
||||
@ -106,6 +100,17 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
|
||||
buf = compat_ptr(tmp);
|
||||
} get_user_catch(err);
|
||||
|
||||
/*
|
||||
* Reload fs and gs if they have changed in the signal
|
||||
* handler. This does not handle long fs/gs base changes in
|
||||
* the handler, but does not clobber them at least in the
|
||||
* normal case.
|
||||
*/
|
||||
RELOAD_SEG(gs);
|
||||
RELOAD_SEG(fs);
|
||||
RELOAD_SEG(ds);
|
||||
RELOAD_SEG(es);
|
||||
|
||||
err |= fpu__restore_sig(buf, 1);
|
||||
|
||||
force_iret();
|
||||
|
@ -662,15 +662,29 @@ void __init alternative_instructions(void)
|
||||
* handlers seeing an inconsistent instruction while you patch.
|
||||
*/
|
||||
void *__init_or_module text_poke_early(void *addr, const void *opcode,
|
||||
size_t len)
|
||||
size_t len)
|
||||
{
|
||||
unsigned long flags;
|
||||
local_irq_save(flags);
|
||||
memcpy(addr, opcode, len);
|
||||
local_irq_restore(flags);
|
||||
sync_core();
|
||||
/* Could also do a CLFLUSH here to speed up CPU recovery; but
|
||||
that causes hangs on some VIA CPUs. */
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_NX) &&
|
||||
is_module_text_address((unsigned long)addr)) {
|
||||
/*
|
||||
* Modules text is marked initially as non-executable, so the
|
||||
* code cannot be running and speculative code-fetches are
|
||||
* prevented. Just change the code.
|
||||
*/
|
||||
memcpy(addr, opcode, len);
|
||||
} else {
|
||||
local_irq_save(flags);
|
||||
memcpy(addr, opcode, len);
|
||||
local_irq_restore(flags);
|
||||
sync_core();
|
||||
|
||||
/*
|
||||
* Could also do a CLFLUSH here to speed up CPU recovery; but
|
||||
* that causes hangs on some VIA CPUs.
|
||||
*/
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,6 @@
|
||||
static struct mce i_mce;
|
||||
static struct dentry *dfs_inj;
|
||||
|
||||
static u8 n_banks;
|
||||
|
||||
#define MAX_FLAG_OPT_SIZE 4
|
||||
#define NBCFG 0x44
|
||||
|
||||
@ -567,9 +565,15 @@ err:
|
||||
static int inj_bank_set(void *data, u64 val)
|
||||
{
|
||||
struct mce *m = (struct mce *)data;
|
||||
u8 n_banks;
|
||||
u64 cap;
|
||||
|
||||
/* Get bank count on target CPU so we can handle non-uniform values. */
|
||||
rdmsrl_on_cpu(m->extcpu, MSR_IA32_MCG_CAP, &cap);
|
||||
n_banks = cap & MCG_BANKCNT_MASK;
|
||||
|
||||
if (val >= n_banks) {
|
||||
pr_err("Non-existent MCE bank: %llu\n", val);
|
||||
pr_err("MCA bank %llu non-existent on CPU%d\n", val, m->extcpu);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -659,10 +663,6 @@ static struct dfs_node {
|
||||
static int __init debugfs_init(void)
|
||||
{
|
||||
unsigned int i;
|
||||
u64 cap;
|
||||
|
||||
rdmsrl(MSR_IA32_MCG_CAP, cap);
|
||||
n_banks = cap & MCG_BANKCNT_MASK;
|
||||
|
||||
dfs_inj = debugfs_create_dir("mce-inject", NULL);
|
||||
if (!dfs_inj)
|
||||
|
@ -711,19 +711,49 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
|
||||
|
||||
barrier();
|
||||
m.status = mce_rdmsrl(msr_ops.status(i));
|
||||
|
||||
/* If this entry is not valid, ignore it */
|
||||
if (!(m.status & MCI_STATUS_VAL))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Uncorrected or signalled events are handled by the exception
|
||||
* handler when it is enabled, so don't process those here.
|
||||
*
|
||||
* TBD do the same check for MCI_STATUS_EN here?
|
||||
* If we are logging everything (at CPU online) or this
|
||||
* is a corrected error, then we must log it.
|
||||
*/
|
||||
if (!(flags & MCP_UC) &&
|
||||
(m.status & (mca_cfg.ser ? MCI_STATUS_S : MCI_STATUS_UC)))
|
||||
continue;
|
||||
if ((flags & MCP_UC) || !(m.status & MCI_STATUS_UC))
|
||||
goto log_it;
|
||||
|
||||
/*
|
||||
* Newer Intel systems that support software error
|
||||
* recovery need to make additional checks. Other
|
||||
* CPUs should skip over uncorrected errors, but log
|
||||
* everything else.
|
||||
*/
|
||||
if (!mca_cfg.ser) {
|
||||
if (m.status & MCI_STATUS_UC)
|
||||
continue;
|
||||
goto log_it;
|
||||
}
|
||||
|
||||
/* Log "not enabled" (speculative) errors */
|
||||
if (!(m.status & MCI_STATUS_EN))
|
||||
goto log_it;
|
||||
|
||||
/*
|
||||
* Log UCNA (SDM: 15.6.3 "UCR Error Classification")
|
||||
* UC == 1 && PCC == 0 && S == 0
|
||||
*/
|
||||
if (!(m.status & MCI_STATUS_PCC) && !(m.status & MCI_STATUS_S))
|
||||
goto log_it;
|
||||
|
||||
/*
|
||||
* Skip anything else. Presumption is that our read of this
|
||||
* bank is racing with a machine check. Leave the log alone
|
||||
* for do_machine_check() to deal with it.
|
||||
*/
|
||||
continue;
|
||||
|
||||
log_it:
|
||||
error_seen = true;
|
||||
|
||||
mce_read_aux(&m, i);
|
||||
@ -1450,13 +1480,12 @@ EXPORT_SYMBOL_GPL(mce_notify_irq);
|
||||
static int __mcheck_cpu_mce_banks_init(void)
|
||||
{
|
||||
int i;
|
||||
u8 num_banks = mca_cfg.banks;
|
||||
|
||||
mce_banks = kcalloc(num_banks, sizeof(struct mce_bank), GFP_KERNEL);
|
||||
mce_banks = kcalloc(MAX_NR_BANKS, sizeof(struct mce_bank), GFP_KERNEL);
|
||||
if (!mce_banks)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num_banks; i++) {
|
||||
for (i = 0; i < MAX_NR_BANKS; i++) {
|
||||
struct mce_bank *b = &mce_banks[i];
|
||||
|
||||
b->ctl = -1ULL;
|
||||
@ -1470,28 +1499,19 @@ static int __mcheck_cpu_mce_banks_init(void)
|
||||
*/
|
||||
static int __mcheck_cpu_cap_init(void)
|
||||
{
|
||||
unsigned b;
|
||||
u64 cap;
|
||||
u8 b;
|
||||
|
||||
rdmsrl(MSR_IA32_MCG_CAP, cap);
|
||||
|
||||
b = cap & MCG_BANKCNT_MASK;
|
||||
if (!mca_cfg.banks)
|
||||
pr_info("CPU supports %d MCE banks\n", b);
|
||||
|
||||
if (b > MAX_NR_BANKS) {
|
||||
pr_warn("Using only %u machine check banks out of %u\n",
|
||||
MAX_NR_BANKS, b);
|
||||
if (WARN_ON_ONCE(b > MAX_NR_BANKS))
|
||||
b = MAX_NR_BANKS;
|
||||
}
|
||||
|
||||
/* Don't support asymmetric configurations today */
|
||||
WARN_ON(mca_cfg.banks != 0 && b != mca_cfg.banks);
|
||||
mca_cfg.banks = b;
|
||||
mca_cfg.banks = max(mca_cfg.banks, b);
|
||||
|
||||
if (!mce_banks) {
|
||||
int err = __mcheck_cpu_mce_banks_init();
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@ -2473,6 +2493,8 @@ EXPORT_SYMBOL_GPL(mcsafe_key);
|
||||
|
||||
static int __init mcheck_late_init(void)
|
||||
{
|
||||
pr_info("Using %d MCE banks\n", mca_cfg.banks);
|
||||
|
||||
if (mca_cfg.recovery)
|
||||
static_branch_inc(&mcsafe_key);
|
||||
|
||||
|
@ -418,8 +418,9 @@ static int do_microcode_update(const void __user *buf, size_t size)
|
||||
if (ustate == UCODE_ERROR) {
|
||||
error = -1;
|
||||
break;
|
||||
} else if (ustate == UCODE_OK)
|
||||
} else if (ustate == UCODE_NEW) {
|
||||
apply_microcode_on_target(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -26,9 +26,18 @@ int sysctl_panic_on_stackoverflow;
|
||||
/*
|
||||
* Probabilistic stack overflow check:
|
||||
*
|
||||
* Only check the stack in process context, because everything else
|
||||
* runs on the big interrupt stacks. Checking reliably is too expensive,
|
||||
* so we just check from interrupts.
|
||||
* Regular device interrupts can enter on the following stacks:
|
||||
*
|
||||
* - User stack
|
||||
*
|
||||
* - Kernel task stack
|
||||
*
|
||||
* - Interrupt stack if a device driver reenables interrupts
|
||||
* which should only happen in really old drivers.
|
||||
*
|
||||
* - Debug IST stack
|
||||
*
|
||||
* All other contexts are invalid.
|
||||
*/
|
||||
static inline void stack_overflow_check(struct pt_regs *regs)
|
||||
{
|
||||
@ -53,8 +62,8 @@ static inline void stack_overflow_check(struct pt_regs *regs)
|
||||
return;
|
||||
|
||||
oist = this_cpu_ptr(&orig_ist);
|
||||
estack_top = (u64)oist->ist[0] - EXCEPTION_STKSZ + STACK_TOP_MARGIN;
|
||||
estack_bottom = (u64)oist->ist[N_EXCEPTION_STACKS - 1];
|
||||
estack_bottom = (u64)oist->ist[DEBUG_STACK];
|
||||
estack_top = estack_bottom - DEBUG_STKSZ + STACK_TOP_MARGIN;
|
||||
if (regs->sp >= estack_top && regs->sp <= estack_bottom)
|
||||
return;
|
||||
|
||||
|
@ -87,7 +87,7 @@ void *module_alloc(unsigned long size)
|
||||
p = __vmalloc_node_range(size, MODULE_ALIGN,
|
||||
MODULES_VADDR + get_module_load_offset(),
|
||||
MODULES_END, GFP_KERNEL,
|
||||
PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
|
||||
PAGE_KERNEL, 0, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
if (p && (kasan_module_alloc(p, size) < 0)) {
|
||||
vfree(p);
|
||||
|
@ -132,16 +132,6 @@ static int restore_sigcontext(struct pt_regs *regs,
|
||||
COPY_SEG_CPL3(cs);
|
||||
COPY_SEG_CPL3(ss);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* Fix up SS if needed for the benefit of old DOSEMU and
|
||||
* CRIU.
|
||||
*/
|
||||
if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) &&
|
||||
user_64bit_mode(regs)))
|
||||
force_valid_ss(regs);
|
||||
#endif
|
||||
|
||||
get_user_ex(tmpflags, &sc->flags);
|
||||
regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
|
||||
regs->orig_ax = -1; /* disable syscall checks */
|
||||
@ -150,6 +140,15 @@ static int restore_sigcontext(struct pt_regs *regs,
|
||||
buf = (void __user *)buf_val;
|
||||
} get_user_catch(err);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* Fix up SS if needed for the benefit of old DOSEMU and
|
||||
* CRIU.
|
||||
*/
|
||||
if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) && user_64bit_mode(regs)))
|
||||
force_valid_ss(regs);
|
||||
#endif
|
||||
|
||||
err |= fpu__restore_sig(buf, IS_ENABLED(CONFIG_X86_32));
|
||||
|
||||
force_iret();
|
||||
@ -461,6 +460,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
||||
{
|
||||
struct rt_sigframe __user *frame;
|
||||
void __user *fp = NULL;
|
||||
unsigned long uc_flags;
|
||||
int err = 0;
|
||||
|
||||
frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp);
|
||||
@ -473,9 +473,11 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
uc_flags = frame_uc_flags(regs);
|
||||
|
||||
put_user_try {
|
||||
/* Create the ucontext. */
|
||||
put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags);
|
||||
put_user_ex(uc_flags, &frame->uc.uc_flags);
|
||||
put_user_ex(0, &frame->uc.uc_link);
|
||||
save_altstack_ex(&frame->uc.uc_stack, regs->sp);
|
||||
|
||||
@ -541,6 +543,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
|
||||
{
|
||||
#ifdef CONFIG_X86_X32_ABI
|
||||
struct rt_sigframe_x32 __user *frame;
|
||||
unsigned long uc_flags;
|
||||
void __user *restorer;
|
||||
int err = 0;
|
||||
void __user *fpstate = NULL;
|
||||
@ -555,9 +558,11 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
uc_flags = frame_uc_flags(regs);
|
||||
|
||||
put_user_try {
|
||||
/* Create the ucontext. */
|
||||
put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags);
|
||||
put_user_ex(uc_flags, &frame->uc.uc_flags);
|
||||
put_user_ex(0, &frame->uc.uc_link);
|
||||
compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
|
||||
put_user_ex(0, &frame->uc.uc__pad0);
|
||||
|
@ -151,11 +151,11 @@ SECTIONS
|
||||
*(.text.__x86.indirect_thunk)
|
||||
__indirect_thunk_end = .;
|
||||
#endif
|
||||
|
||||
/* End of text section */
|
||||
_etext = .;
|
||||
} :text = 0x9090
|
||||
|
||||
/* End of text section */
|
||||
_etext = .;
|
||||
|
||||
NOTES :text :note
|
||||
|
||||
EXCEPTION_TABLE(16) :text = 0x9090
|
||||
|
@ -2022,7 +2022,11 @@ static void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
if (!kvm_vcpu_apicv_active(vcpu))
|
||||
return;
|
||||
|
||||
if (WARN_ON(h_physical_id >= AVIC_MAX_PHYSICAL_ID_COUNT))
|
||||
/*
|
||||
* Since the host physical APIC id is 8 bits,
|
||||
* we can support host APIC ID upto 255.
|
||||
*/
|
||||
if (WARN_ON(h_physical_id > AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK))
|
||||
return;
|
||||
|
||||
entry = READ_ONCE(*(svm->avic_physical_id_cache));
|
||||
|
@ -1188,7 +1188,7 @@ static int set_efer(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
||||
u64 efer = msr_info->data;
|
||||
|
||||
if (efer & efer_reserved_bits)
|
||||
return false;
|
||||
return 1;
|
||||
|
||||
if (!msr_info->host_initiated) {
|
||||
if (!__kvm_valid_efer(vcpu, efer))
|
||||
|
@ -257,6 +257,7 @@ ENTRY(__memcpy_mcsafe)
|
||||
/* Copy successful. Return zero */
|
||||
.L_done_memcpy_trap:
|
||||
xorl %eax, %eax
|
||||
.L_done:
|
||||
ret
|
||||
ENDPROC(__memcpy_mcsafe)
|
||||
EXPORT_SYMBOL_GPL(__memcpy_mcsafe)
|
||||
@ -273,7 +274,7 @@ EXPORT_SYMBOL_GPL(__memcpy_mcsafe)
|
||||
addl %edx, %ecx
|
||||
.E_trailing_bytes:
|
||||
mov %ecx, %eax
|
||||
ret
|
||||
jmp .L_done
|
||||
|
||||
/*
|
||||
* For write fault handling, given the destination is unaligned,
|
||||
|
@ -427,8 +427,6 @@ static noinline int vmalloc_fault(unsigned long address)
|
||||
if (!(address >= VMALLOC_START && address < VMALLOC_END))
|
||||
return -1;
|
||||
|
||||
WARN_ON_ONCE(in_nmi());
|
||||
|
||||
/*
|
||||
* Copy kernel mappings over when needed. This can also
|
||||
* happen within a race in page table update. In the later
|
||||
|
@ -518,6 +518,18 @@ void blk_free_devt(dev_t devt)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We invalidate devt by assigning NULL pointer for devt in idr.
|
||||
*/
|
||||
void blk_invalidate_devt(dev_t devt)
|
||||
{
|
||||
if (MAJOR(devt) == BLOCK_EXT_MAJOR) {
|
||||
spin_lock_bh(&ext_devt_lock);
|
||||
idr_replace(&ext_devt_idr, NULL, blk_mangle_minor(MINOR(devt)));
|
||||
spin_unlock_bh(&ext_devt_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static char *bdevt_str(dev_t devt, char *buf)
|
||||
{
|
||||
if (MAJOR(devt) <= 0xff && MINOR(devt) <= 0xff) {
|
||||
@ -769,6 +781,13 @@ void del_gendisk(struct gendisk *disk)
|
||||
|
||||
if (!(disk->flags & GENHD_FL_HIDDEN))
|
||||
blk_unregister_region(disk_devt(disk), disk->minors);
|
||||
/*
|
||||
* Remove gendisk pointer from idr so that it cannot be looked up
|
||||
* while RCU period before freeing gendisk is running to prevent
|
||||
* use-after-free issues. Note that the device number stays
|
||||
* "in-use" until we really free the gendisk.
|
||||
*/
|
||||
blk_invalidate_devt(disk_devt(disk));
|
||||
|
||||
kobject_put(disk->part0.holder_dir);
|
||||
kobject_put(disk->slave_dir);
|
||||
|
@ -289,6 +289,13 @@ void delete_partition(struct gendisk *disk, int partno)
|
||||
kobject_put(part->holder_dir);
|
||||
device_del(part_to_dev(part));
|
||||
|
||||
/*
|
||||
* Remove gendisk pointer from idr so that it cannot be looked up
|
||||
* while RCU period before freeing gendisk is running to prevent
|
||||
* use-after-free issues. Note that the device number stays
|
||||
* "in-use" until we really free the gendisk.
|
||||
*/
|
||||
blk_invalidate_devt(part_devt(part));
|
||||
hd_struct_kill(part);
|
||||
}
|
||||
|
||||
|
@ -2095,13 +2095,16 @@ static int opal_erase_locking_range(struct opal_dev *dev,
|
||||
static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
|
||||
struct opal_mbr_data *opal_mbr)
|
||||
{
|
||||
u8 enable_disable = opal_mbr->enable_disable == OPAL_MBR_ENABLE ?
|
||||
OPAL_TRUE : OPAL_FALSE;
|
||||
|
||||
const struct opal_step mbr_steps[] = {
|
||||
{ opal_discovery0, },
|
||||
{ start_admin1LSP_opal_session, &opal_mbr->key },
|
||||
{ set_mbr_done, &opal_mbr->enable_disable },
|
||||
{ set_mbr_done, &enable_disable },
|
||||
{ end_opal_session, },
|
||||
{ start_admin1LSP_opal_session, &opal_mbr->key },
|
||||
{ set_mbr_enable_disable, &opal_mbr->enable_disable },
|
||||
{ set_mbr_enable_disable, &enable_disable },
|
||||
{ end_opal_session, },
|
||||
{ NULL, }
|
||||
};
|
||||
@ -2221,7 +2224,7 @@ static int __opal_lock_unlock(struct opal_dev *dev,
|
||||
|
||||
static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
|
||||
{
|
||||
u8 mbr_done_tf = 1;
|
||||
u8 mbr_done_tf = OPAL_TRUE;
|
||||
const struct opal_step mbrdone_step [] = {
|
||||
{ opal_discovery0, },
|
||||
{ start_admin1LSP_opal_session, key },
|
||||
|
@ -1231,18 +1231,24 @@ static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)
|
||||
/*
|
||||
* set numa proximity domain for smmuv3 device
|
||||
*/
|
||||
static void __init arm_smmu_v3_set_proximity(struct device *dev,
|
||||
static int __init arm_smmu_v3_set_proximity(struct device *dev,
|
||||
struct acpi_iort_node *node)
|
||||
{
|
||||
struct acpi_iort_smmu_v3 *smmu;
|
||||
|
||||
smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
|
||||
if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) {
|
||||
set_dev_node(dev, acpi_map_pxm_to_node(smmu->pxm));
|
||||
int node = acpi_map_pxm_to_node(smmu->pxm);
|
||||
|
||||
if (node != NUMA_NO_NODE && !node_online(node))
|
||||
return -EINVAL;
|
||||
|
||||
set_dev_node(dev, node);
|
||||
pr_info("SMMU-v3[%llx] Mapped to Proximity domain %d\n",
|
||||
smmu->base_address,
|
||||
smmu->pxm);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define arm_smmu_v3_set_proximity NULL
|
||||
@ -1317,7 +1323,7 @@ struct iort_dev_config {
|
||||
int (*dev_count_resources)(struct acpi_iort_node *node);
|
||||
void (*dev_init_resources)(struct resource *res,
|
||||
struct acpi_iort_node *node);
|
||||
void (*dev_set_proximity)(struct device *dev,
|
||||
int (*dev_set_proximity)(struct device *dev,
|
||||
struct acpi_iort_node *node);
|
||||
};
|
||||
|
||||
@ -1368,8 +1374,11 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node,
|
||||
if (!pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
if (ops->dev_set_proximity)
|
||||
ops->dev_set_proximity(&pdev->dev, node);
|
||||
if (ops->dev_set_proximity) {
|
||||
ret = ops->dev_set_proximity(&pdev->dev, node);
|
||||
if (ret)
|
||||
goto dev_put;
|
||||
}
|
||||
|
||||
count = ops->dev_count_resources(node);
|
||||
|
||||
|
@ -975,6 +975,14 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,
|
||||
const struct acpi_data_node *data = to_acpi_data_node(fwnode);
|
||||
struct acpi_data_node *dn;
|
||||
|
||||
/*
|
||||
* We can have a combination of device and data nodes, e.g. with
|
||||
* hierarchical _DSD properties. Make sure the adev pointer is
|
||||
* restored before going through data nodes, otherwise we will
|
||||
* be looking for data_nodes below the last device found instead
|
||||
* of the common fwnode shared by device_nodes and data_nodes.
|
||||
*/
|
||||
adev = to_acpi_device_node(fwnode);
|
||||
if (adev)
|
||||
head = &adev->data.subnodes;
|
||||
else if (data)
|
||||
|
@ -1741,6 +1741,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
|
||||
if (dev->power.syscore)
|
||||
goto Complete;
|
||||
|
||||
/* Avoid direct_complete to let wakeup_path propagate. */
|
||||
if (device_may_wakeup(dev) || dev->power.wakeup_path)
|
||||
dev->power.direct_complete = false;
|
||||
|
||||
if (dev->power.direct_complete) {
|
||||
if (pm_runtime_status_suspended(dev)) {
|
||||
pm_runtime_disable(dev);
|
||||
|
@ -504,6 +504,8 @@ static int qca_open(struct hci_uart *hu)
|
||||
qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
if (qcadev->btsoc_type != QCA_WCN3990) {
|
||||
gpiod_set_value_cansleep(qcadev->bt_en, 1);
|
||||
/* Controller needs time to bootup. */
|
||||
msleep(150);
|
||||
} else {
|
||||
hu->init_speed = qcadev->init_speed;
|
||||
hu->oper_speed = qcadev->oper_speed;
|
||||
|
@ -443,6 +443,7 @@ static int omap_rng_probe(struct platform_device *pdev)
|
||||
priv->rng.read = omap_rng_do_read;
|
||||
priv->rng.init = omap_rng_init;
|
||||
priv->rng.cleanup = omap_rng_cleanup;
|
||||
priv->rng.quality = 900;
|
||||
|
||||
priv->rng.priv = (unsigned long)priv;
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
@ -777,6 +777,7 @@ static struct crng_state **crng_node_pool __read_mostly;
|
||||
#endif
|
||||
|
||||
static void invalidate_batched_entropy(void);
|
||||
static void numa_crng_init(void);
|
||||
|
||||
static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
|
||||
static int __init parse_trust_cpu(char *arg)
|
||||
@ -805,7 +806,9 @@ static void crng_initialize(struct crng_state *crng)
|
||||
}
|
||||
crng->state[i] ^= rv;
|
||||
}
|
||||
if (trust_cpu && arch_init) {
|
||||
if (trust_cpu && arch_init && crng == &primary_crng) {
|
||||
invalidate_batched_entropy();
|
||||
numa_crng_init();
|
||||
crng_init = 2;
|
||||
pr_notice("random: crng done (trusting CPU's manufacturer)\n");
|
||||
}
|
||||
@ -2211,8 +2214,8 @@ struct batched_entropy {
|
||||
u32 entropy_u32[CHACHA_BLOCK_SIZE / sizeof(u32)];
|
||||
};
|
||||
unsigned int position;
|
||||
spinlock_t batch_lock;
|
||||
};
|
||||
static rwlock_t batched_entropy_reset_lock = __RW_LOCK_UNLOCKED(batched_entropy_reset_lock);
|
||||
|
||||
/*
|
||||
* Get a random word for internal kernel use only. The quality of the random
|
||||
@ -2222,12 +2225,14 @@ static rwlock_t batched_entropy_reset_lock = __RW_LOCK_UNLOCKED(batched_entropy_
|
||||
* wait_for_random_bytes() should be called and return 0 at least once
|
||||
* at any point prior.
|
||||
*/
|
||||
static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
|
||||
static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64) = {
|
||||
.batch_lock = __SPIN_LOCK_UNLOCKED(batched_entropy_u64.lock),
|
||||
};
|
||||
|
||||
u64 get_random_u64(void)
|
||||
{
|
||||
u64 ret;
|
||||
bool use_lock;
|
||||
unsigned long flags = 0;
|
||||
unsigned long flags;
|
||||
struct batched_entropy *batch;
|
||||
static void *previous;
|
||||
|
||||
@ -2242,28 +2247,25 @@ u64 get_random_u64(void)
|
||||
|
||||
warn_unseeded_randomness(&previous);
|
||||
|
||||
use_lock = READ_ONCE(crng_init) < 2;
|
||||
batch = &get_cpu_var(batched_entropy_u64);
|
||||
if (use_lock)
|
||||
read_lock_irqsave(&batched_entropy_reset_lock, flags);
|
||||
batch = raw_cpu_ptr(&batched_entropy_u64);
|
||||
spin_lock_irqsave(&batch->batch_lock, flags);
|
||||
if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) {
|
||||
extract_crng((u8 *)batch->entropy_u64);
|
||||
batch->position = 0;
|
||||
}
|
||||
ret = batch->entropy_u64[batch->position++];
|
||||
if (use_lock)
|
||||
read_unlock_irqrestore(&batched_entropy_reset_lock, flags);
|
||||
put_cpu_var(batched_entropy_u64);
|
||||
spin_unlock_irqrestore(&batch->batch_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(get_random_u64);
|
||||
|
||||
static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32);
|
||||
static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32) = {
|
||||
.batch_lock = __SPIN_LOCK_UNLOCKED(batched_entropy_u32.lock),
|
||||
};
|
||||
u32 get_random_u32(void)
|
||||
{
|
||||
u32 ret;
|
||||
bool use_lock;
|
||||
unsigned long flags = 0;
|
||||
unsigned long flags;
|
||||
struct batched_entropy *batch;
|
||||
static void *previous;
|
||||
|
||||
@ -2272,18 +2274,14 @@ u32 get_random_u32(void)
|
||||
|
||||
warn_unseeded_randomness(&previous);
|
||||
|
||||
use_lock = READ_ONCE(crng_init) < 2;
|
||||
batch = &get_cpu_var(batched_entropy_u32);
|
||||
if (use_lock)
|
||||
read_lock_irqsave(&batched_entropy_reset_lock, flags);
|
||||
batch = raw_cpu_ptr(&batched_entropy_u32);
|
||||
spin_lock_irqsave(&batch->batch_lock, flags);
|
||||
if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) {
|
||||
extract_crng((u8 *)batch->entropy_u32);
|
||||
batch->position = 0;
|
||||
}
|
||||
ret = batch->entropy_u32[batch->position++];
|
||||
if (use_lock)
|
||||
read_unlock_irqrestore(&batched_entropy_reset_lock, flags);
|
||||
put_cpu_var(batched_entropy_u32);
|
||||
spin_unlock_irqrestore(&batch->batch_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(get_random_u32);
|
||||
@ -2297,12 +2295,19 @@ static void invalidate_batched_entropy(void)
|
||||
int cpu;
|
||||
unsigned long flags;
|
||||
|
||||
write_lock_irqsave(&batched_entropy_reset_lock, flags);
|
||||
for_each_possible_cpu (cpu) {
|
||||
per_cpu_ptr(&batched_entropy_u32, cpu)->position = 0;
|
||||
per_cpu_ptr(&batched_entropy_u64, cpu)->position = 0;
|
||||
struct batched_entropy *batched_entropy;
|
||||
|
||||
batched_entropy = per_cpu_ptr(&batched_entropy_u32, cpu);
|
||||
spin_lock_irqsave(&batched_entropy->batch_lock, flags);
|
||||
batched_entropy->position = 0;
|
||||
spin_unlock(&batched_entropy->batch_lock);
|
||||
|
||||
batched_entropy = per_cpu_ptr(&batched_entropy_u64, cpu);
|
||||
spin_lock(&batched_entropy->batch_lock);
|
||||
batched_entropy->position = 0;
|
||||
spin_unlock_irqrestore(&batched_entropy->batch_lock, flags);
|
||||
}
|
||||
write_unlock_irqrestore(&batched_entropy_reset_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,7 +75,7 @@ struct ports_driver_data {
|
||||
/* All the console devices handled by this driver */
|
||||
struct list_head consoles;
|
||||
};
|
||||
static struct ports_driver_data pdrvdata;
|
||||
static struct ports_driver_data pdrvdata = { .next_vtermno = 1};
|
||||
|
||||
static DEFINE_SPINLOCK(pdrvdata_lock);
|
||||
static DECLARE_COMPLETION(early_console_added);
|
||||
@ -1405,6 +1405,7 @@ static int add_port(struct ports_device *portdev, u32 id)
|
||||
port->async_queue = NULL;
|
||||
|
||||
port->cons.ws.ws_row = port->cons.ws.ws_col = 0;
|
||||
port->cons.vtermno = 0;
|
||||
|
||||
port->host_connected = port->guest_connected = false;
|
||||
port->stats = (struct port_stats) { 0 };
|
||||
|
@ -198,7 +198,7 @@ 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_aclk_vcodec_pre_p) = { "aclk_vepu", "aclk_vdpu" };
|
||||
PNAME(mux_aclk_vcodec_pre_p) = { "aclk_vdpu", "aclk_vepu" };
|
||||
PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m",
|
||||
"sclk_otgphy0_480m" };
|
||||
PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" };
|
||||
@ -292,13 +292,13 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED,
|
||||
RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK3288_CLKGATE_CON(12), 6, GFLAGS),
|
||||
COMPOSITE_NOMUX(0, "atclk", "armclk", CLK_IGNORE_UNUSED,
|
||||
COMPOSITE_NOMUX(0, "atclk", "armclk", 0,
|
||||
RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK3288_CLKGATE_CON(12), 7, GFLAGS),
|
||||
COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED,
|
||||
RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK3288_CLKGATE_CON(12), 8, GFLAGS),
|
||||
GATE(0, "pclk_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED,
|
||||
GATE(0, "pclk_dbg", "pclk_dbg_pre", 0,
|
||||
RK3288_CLKGATE_CON(12), 9, GFLAGS),
|
||||
GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED,
|
||||
RK3288_CLKGATE_CON(12), 10, GFLAGS),
|
||||
@ -399,7 +399,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0,
|
||||
RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK3288_CLKGATE_CON(3), 11, GFLAGS),
|
||||
MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, 0,
|
||||
MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, CLK_SET_RATE_PARENT,
|
||||
RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS),
|
||||
GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0,
|
||||
RK3288_CLKGATE_CON(9), 0, GFLAGS),
|
||||
@ -626,7 +626,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out",
|
||||
RK3288_CLKSEL_CON(22), 7, IFLAGS),
|
||||
|
||||
GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED,
|
||||
GATE(0, "jtag", "ext_jtag", 0,
|
||||
RK3288_CLKGATE_CON(4), 14, GFLAGS),
|
||||
|
||||
COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0,
|
||||
@ -635,7 +635,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
|
||||
RK3288_CLKSEL_CON(29), 0, 2, MFLAGS,
|
||||
RK3288_CLKGATE_CON(3), 6, GFLAGS),
|
||||
GATE(0, "hsicphy12m_xin12m", "xin12m", CLK_IGNORE_UNUSED,
|
||||
GATE(0, "hsicphy12m_xin12m", "xin12m", 0,
|
||||
RK3288_CLKGATE_CON(13), 9, GFLAGS),
|
||||
DIV(0, "hsicphy12m_usbphy", "sclk_hsicphy480m", 0,
|
||||
RK3288_CLKSEL_CON(11), 8, 6, DFLAGS),
|
||||
@ -676,7 +676,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS),
|
||||
GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS),
|
||||
GATE(PCLK_EFUSE256, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
|
||||
GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS),
|
||||
GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS),
|
||||
|
||||
/* ddrctrl [DDR Controller PHY clock] gates */
|
||||
GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS),
|
||||
@ -816,12 +816,9 @@ static const char *const rk3288_critical_clocks[] __initconst = {
|
||||
"pclk_alive_niu",
|
||||
"pclk_pd_pmu",
|
||||
"pclk_pmu_niu",
|
||||
"pclk_core_niu",
|
||||
"pclk_ddrupctl0",
|
||||
"pclk_publ0",
|
||||
"pclk_ddrupctl1",
|
||||
"pclk_publ1",
|
||||
"pmu_hclk_otg0",
|
||||
/* pwm-regulators on some boards, so handoff-critical later */
|
||||
"pclk_rkpwm",
|
||||
};
|
||||
|
||||
static void __iomem *rk3288_cru_base;
|
||||
|
@ -1111,6 +1111,7 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
|
||||
cpufreq_global_kobject, "policy%u", cpu);
|
||||
if (ret) {
|
||||
pr_err("%s: failed to init policy->kobj: %d\n", __func__, ret);
|
||||
kobject_put(&policy->kobj);
|
||||
goto err_free_real_cpus;
|
||||
}
|
||||
|
||||
|
@ -459,6 +459,8 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)
|
||||
/* Failure, so roll back. */
|
||||
pr_err("initialization failed (dbs_data kobject init error %d)\n", ret);
|
||||
|
||||
kobject_put(&dbs_data->attr_set.kobj);
|
||||
|
||||
policy->governor_data = NULL;
|
||||
|
||||
if (!have_governor_per_policy())
|
||||
|
@ -124,13 +124,14 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
|
||||
priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk");
|
||||
if (IS_ERR(priv.cpu_clk)) {
|
||||
dev_err(priv.dev, "Unable to get cpuclk\n");
|
||||
return PTR_ERR(priv.cpu_clk);
|
||||
err = PTR_ERR(priv.cpu_clk);
|
||||
goto out_node;
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(priv.cpu_clk);
|
||||
if (err) {
|
||||
dev_err(priv.dev, "Unable to prepare cpuclk\n");
|
||||
return err;
|
||||
goto out_node;
|
||||
}
|
||||
|
||||
kirkwood_freq_table[0].frequency = clk_get_rate(priv.cpu_clk) / 1000;
|
||||
@ -161,20 +162,22 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
|
||||
goto out_ddr;
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
np = NULL;
|
||||
|
||||
err = cpufreq_register_driver(&kirkwood_cpufreq_driver);
|
||||
if (!err)
|
||||
return 0;
|
||||
if (err) {
|
||||
dev_err(priv.dev, "Failed to register cpufreq driver\n");
|
||||
goto out_powersave;
|
||||
}
|
||||
|
||||
dev_err(priv.dev, "Failed to register cpufreq driver\n");
|
||||
of_node_put(np);
|
||||
return 0;
|
||||
|
||||
out_powersave:
|
||||
clk_disable_unprepare(priv.powersave_clk);
|
||||
out_ddr:
|
||||
clk_disable_unprepare(priv.ddr_clk);
|
||||
out_cpu:
|
||||
clk_disable_unprepare(priv.cpu_clk);
|
||||
out_node:
|
||||
of_node_put(np);
|
||||
|
||||
return err;
|
||||
|
@ -146,6 +146,7 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
|
||||
cpu = of_get_cpu_node(policy->cpu, NULL);
|
||||
|
||||
of_node_put(cpu);
|
||||
if (!cpu)
|
||||
goto out;
|
||||
|
||||
|
@ -552,6 +552,7 @@ static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
|
||||
volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
|
||||
if (volt_gpio_np)
|
||||
voltage_gpio = read_gpio(volt_gpio_np);
|
||||
of_node_put(volt_gpio_np);
|
||||
if (!voltage_gpio){
|
||||
pr_err("missing cpu-vcore-select gpio\n");
|
||||
return 1;
|
||||
@ -588,6 +589,7 @@ static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
|
||||
if (volt_gpio_np)
|
||||
voltage_gpio = read_gpio(volt_gpio_np);
|
||||
|
||||
of_node_put(volt_gpio_np);
|
||||
pvr = mfspr(SPRN_PVR);
|
||||
has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
|
||||
|
||||
|
@ -86,6 +86,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
if (!cbe_get_cpu_pmd_regs(policy->cpu) ||
|
||||
!cbe_get_cpu_mic_tm_regs(policy->cpu)) {
|
||||
pr_info("invalid CBE regs pointers for cpufreq\n");
|
||||
of_node_put(cpu);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,10 @@ static int sun4i_hash(struct ahash_request *areq)
|
||||
}
|
||||
} else {
|
||||
/* Since we have the flag final, we can go up to modulo 4 */
|
||||
end = ((areq->nbytes + op->len) / 4) * 4 - op->len;
|
||||
if (areq->nbytes < 4)
|
||||
end = 0;
|
||||
else
|
||||
end = ((areq->nbytes + op->len) / 4) * 4 - op->len;
|
||||
}
|
||||
|
||||
/* TODO if SGlen % 4 and !op->len then DMA */
|
||||
|
@ -1357,7 +1357,7 @@ Loop_ctr32_enc:
|
||||
addi $idx,$idx,16
|
||||
bdnz Loop_ctr32_enc
|
||||
|
||||
vadduwm $ivec,$ivec,$one
|
||||
vadduqm $ivec,$ivec,$one
|
||||
vmr $dat,$inptail
|
||||
lvx $inptail,0,$inp
|
||||
addi $inp,$inp,16
|
||||
|
@ -1606,7 +1606,11 @@ static void at_xdmac_tasklet(unsigned long data)
|
||||
struct at_xdmac_desc,
|
||||
xfer_node);
|
||||
dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc);
|
||||
BUG_ON(!desc->active_xfer);
|
||||
if (!desc->active_xfer) {
|
||||
dev_err(chan2dev(&atchan->chan), "Xfer not active: exiting");
|
||||
spin_unlock_bh(&atchan->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
txd = &desc->tx_dma_desc;
|
||||
|
||||
|
@ -961,6 +961,7 @@ static void _stop(struct pl330_thread *thrd)
|
||||
{
|
||||
void __iomem *regs = thrd->dmac->base;
|
||||
u8 insn[6] = {0, 0, 0, 0, 0, 0};
|
||||
u32 inten = readl(regs + INTEN);
|
||||
|
||||
if (_state(thrd) == PL330_STATE_FAULT_COMPLETING)
|
||||
UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
|
||||
@ -973,10 +974,13 @@ static void _stop(struct pl330_thread *thrd)
|
||||
|
||||
_emit_KILL(0, insn);
|
||||
|
||||
/* Stop generating interrupts for SEV */
|
||||
writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN);
|
||||
|
||||
_execute_DBGINSN(thrd, insn, is_manager(thrd));
|
||||
|
||||
/* clear the event */
|
||||
if (inten & (1 << thrd->ev))
|
||||
writel(1 << thrd->ev, regs + INTCLR);
|
||||
/* Stop generating interrupts for SEV */
|
||||
writel(inten & ~(1 << thrd->ev), regs + INTEN);
|
||||
}
|
||||
|
||||
/* Start doing req 'idx' of thread 'thrd' */
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_dma.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/pm_clock.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
@ -141,6 +140,7 @@ struct tegra_adma {
|
||||
struct dma_device dma_dev;
|
||||
struct device *dev;
|
||||
void __iomem *base_addr;
|
||||
struct clk *ahub_clk;
|
||||
unsigned int nr_channels;
|
||||
unsigned long rx_requests_reserved;
|
||||
unsigned long tx_requests_reserved;
|
||||
@ -637,8 +637,9 @@ static int tegra_adma_runtime_suspend(struct device *dev)
|
||||
struct tegra_adma *tdma = dev_get_drvdata(dev);
|
||||
|
||||
tdma->global_cmd = tdma_read(tdma, ADMA_GLOBAL_CMD);
|
||||
clk_disable_unprepare(tdma->ahub_clk);
|
||||
|
||||
return pm_clk_suspend(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_adma_runtime_resume(struct device *dev)
|
||||
@ -646,10 +647,11 @@ static int tegra_adma_runtime_resume(struct device *dev)
|
||||
struct tegra_adma *tdma = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = pm_clk_resume(dev);
|
||||
if (ret)
|
||||
ret = clk_prepare_enable(tdma->ahub_clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "ahub clk_enable failed: %d\n", ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
tdma_write(tdma, ADMA_GLOBAL_CMD, tdma->global_cmd);
|
||||
|
||||
return 0;
|
||||
@ -692,13 +694,11 @@ static int tegra_adma_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(tdma->base_addr))
|
||||
return PTR_ERR(tdma->base_addr);
|
||||
|
||||
ret = pm_clk_create(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = of_pm_clk_add_clk(&pdev->dev, "d_audio");
|
||||
if (ret)
|
||||
goto clk_destroy;
|
||||
tdma->ahub_clk = devm_clk_get(&pdev->dev, "d_audio");
|
||||
if (IS_ERR(tdma->ahub_clk)) {
|
||||
dev_err(&pdev->dev, "Error: Missing ahub controller clock\n");
|
||||
return PTR_ERR(tdma->ahub_clk);
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
@ -775,8 +775,6 @@ rpm_put:
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
rpm_disable:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
clk_destroy:
|
||||
pm_clk_destroy(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -786,6 +784,7 @@ static int tegra_adma_remove(struct platform_device *pdev)
|
||||
struct tegra_adma *tdma = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
of_dma_controller_free(pdev->dev.of_node);
|
||||
dma_async_device_unregister(&tdma->dma_dev);
|
||||
|
||||
for (i = 0; i < tdma->nr_channels; ++i)
|
||||
@ -793,7 +792,6 @@ static int tegra_adma_remove(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_clk_destroy(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1726,6 +1726,16 @@ static int arizona_extcon_remove(struct platform_device *pdev)
|
||||
struct arizona_extcon_info *info = platform_get_drvdata(pdev);
|
||||
struct arizona *arizona = info->arizona;
|
||||
int jack_irq_rise, jack_irq_fall;
|
||||
bool change;
|
||||
|
||||
regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
|
||||
ARIZONA_MICD_ENA, 0,
|
||||
&change);
|
||||
|
||||
if (change) {
|
||||
regulator_disable(info->micvdd);
|
||||
pm_runtime_put(info->dev);
|
||||
}
|
||||
|
||||
gpiod_put(info->micd_pol_gpio);
|
||||
|
||||
|
@ -136,8 +136,9 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_fence *fence;
|
||||
struct dma_fence *old, **ptr;
|
||||
struct dma_fence __rcu **ptr;
|
||||
uint32_t seq;
|
||||
int r;
|
||||
|
||||
fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL);
|
||||
if (fence == NULL)
|
||||
@ -153,15 +154,24 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
|
||||
seq, flags | AMDGPU_FENCE_FLAG_INT);
|
||||
|
||||
ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
|
||||
if (unlikely(rcu_dereference_protected(*ptr, 1))) {
|
||||
struct dma_fence *old;
|
||||
|
||||
rcu_read_lock();
|
||||
old = dma_fence_get_rcu_safe(ptr);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (old) {
|
||||
r = dma_fence_wait(old, false);
|
||||
dma_fence_put(old);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function can't be called concurrently anyway, otherwise
|
||||
* emitting the fence would mess up the hardware ring buffer.
|
||||
*/
|
||||
old = rcu_dereference_protected(*ptr, 1);
|
||||
if (old && !dma_fence_is_signaled(old)) {
|
||||
DRM_INFO("rcu slot is busy\n");
|
||||
dma_fence_wait(old, false);
|
||||
}
|
||||
|
||||
rcu_assign_pointer(*ptr, dma_fence_get(&fence->base));
|
||||
|
||||
*f = &fence->base;
|
||||
|
@ -4369,8 +4369,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
static void amdgpu_dm_crtc_copy_transient_flags(struct drm_crtc_state *crtc_state,
|
||||
struct dc_stream_state *stream_state)
|
||||
{
|
||||
stream_state->mode_changed =
|
||||
crtc_state->mode_changed || crtc_state->active_changed;
|
||||
stream_state->mode_changed = drm_atomic_crtc_needs_modeset(crtc_state);
|
||||
}
|
||||
|
||||
static int amdgpu_dm_atomic_commit(struct drm_device *dev,
|
||||
|
@ -1401,10 +1401,12 @@ bool dc_remove_plane_from_context(
|
||||
* For head pipe detach surfaces from pipe for tail
|
||||
* pipe just zero it out
|
||||
*/
|
||||
if (!pipe_ctx->top_pipe) {
|
||||
if (!pipe_ctx->top_pipe ||
|
||||
(!pipe_ctx->top_pipe->top_pipe &&
|
||||
pipe_ctx->top_pipe->stream_res.opp != pipe_ctx->stream_res.opp)) {
|
||||
pipe_ctx->plane_state = NULL;
|
||||
pipe_ctx->bottom_pipe = NULL;
|
||||
} else {
|
||||
} else {
|
||||
memset(pipe_ctx, 0, sizeof(*pipe_ctx));
|
||||
}
|
||||
}
|
||||
|
@ -406,15 +406,25 @@ void dpp1_dscl_calc_lb_num_partitions(
|
||||
int *num_part_y,
|
||||
int *num_part_c)
|
||||
{
|
||||
int lb_memory_size, lb_memory_size_c, lb_memory_size_a, num_partitions_a,
|
||||
lb_bpc, memory_line_size_y, memory_line_size_c, memory_line_size_a;
|
||||
|
||||
int line_size = scl_data->viewport.width < scl_data->recout.width ?
|
||||
scl_data->viewport.width : scl_data->recout.width;
|
||||
int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ?
|
||||
scl_data->viewport_c.width : scl_data->recout.width;
|
||||
int lb_bpc = dpp1_dscl_get_lb_depth_bpc(scl_data->lb_params.depth);
|
||||
int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */
|
||||
int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */
|
||||
int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */
|
||||
int lb_memory_size, lb_memory_size_c, lb_memory_size_a, num_partitions_a;
|
||||
|
||||
if (line_size == 0)
|
||||
line_size = 1;
|
||||
|
||||
if (line_size_c == 0)
|
||||
line_size_c = 1;
|
||||
|
||||
|
||||
lb_bpc = dpp1_dscl_get_lb_depth_bpc(scl_data->lb_params.depth);
|
||||
memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */
|
||||
memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */
|
||||
memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */
|
||||
|
||||
if (lb_config == LB_MEMORY_CONFIG_1) {
|
||||
lb_memory_size = 816;
|
||||
|
@ -499,7 +499,7 @@ int drm_dev_init(struct drm_device *dev,
|
||||
}
|
||||
|
||||
kref_init(&dev->ref);
|
||||
dev->dev = parent;
|
||||
dev->dev = get_device(parent);
|
||||
dev->driver = driver;
|
||||
|
||||
INIT_LIST_HEAD(&dev->filelist);
|
||||
@ -568,6 +568,7 @@ err_minors:
|
||||
drm_minor_free(dev, DRM_MINOR_RENDER);
|
||||
drm_fs_inode_free(dev->anon_inode);
|
||||
err_free:
|
||||
put_device(dev->dev);
|
||||
mutex_destroy(&dev->master_mutex);
|
||||
mutex_destroy(&dev->ctxlist_mutex);
|
||||
mutex_destroy(&dev->clientlist_mutex);
|
||||
@ -603,6 +604,8 @@ void drm_dev_fini(struct drm_device *dev)
|
||||
drm_minor_free(dev, DRM_MINOR_PRIMARY);
|
||||
drm_minor_free(dev, DRM_MINOR_RENDER);
|
||||
|
||||
put_device(dev->dev);
|
||||
|
||||
mutex_destroy(&dev->master_mutex);
|
||||
mutex_destroy(&dev->ctxlist_mutex);
|
||||
mutex_destroy(&dev->clientlist_mutex);
|
||||
|
@ -567,6 +567,7 @@ put_back_event:
|
||||
file_priv->event_space -= length;
|
||||
list_add(&e->link, &file_priv->event_list);
|
||||
spin_unlock_irq(&dev->event_lock);
|
||||
wake_up_interruptible(&file_priv->event_wait);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -527,6 +527,9 @@ static int etnaviv_bind(struct device *dev)
|
||||
}
|
||||
drm->dev_private = priv;
|
||||
|
||||
dev->dma_parms = &priv->dma_parms;
|
||||
dma_set_max_seg_size(dev, SZ_2G);
|
||||
|
||||
mutex_init(&priv->gem_lock);
|
||||
INIT_LIST_HEAD(&priv->gem_list);
|
||||
priv->num_gpus = 0;
|
||||
@ -564,6 +567,8 @@ static void etnaviv_unbind(struct device *dev)
|
||||
|
||||
component_unbind_all(dev, drm);
|
||||
|
||||
dev->dma_parms = NULL;
|
||||
|
||||
drm->dev_private = NULL;
|
||||
kfree(priv);
|
||||
|
||||
|
@ -43,6 +43,7 @@ struct etnaviv_file_private {
|
||||
|
||||
struct etnaviv_drm_private {
|
||||
int num_gpus;
|
||||
struct device_dma_parameters dma_parms;
|
||||
struct etnaviv_gpu *gpu[ETNA_MAX_PIPES];
|
||||
|
||||
/* list of GEM objects: */
|
||||
|
@ -35,7 +35,7 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname)
|
||||
{
|
||||
struct device *dev = &gpu->pdev->dev;
|
||||
const struct firmware *fw;
|
||||
struct device_node *np;
|
||||
struct device_node *np, *mem_np;
|
||||
struct resource r;
|
||||
phys_addr_t mem_phys;
|
||||
ssize_t mem_size;
|
||||
@ -49,11 +49,13 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname)
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
np = of_parse_phandle(np, "memory-region", 0);
|
||||
if (!np)
|
||||
mem_np = of_parse_phandle(np, "memory-region", 0);
|
||||
of_node_put(np);
|
||||
if (!mem_np)
|
||||
return -EINVAL;
|
||||
|
||||
ret = of_address_to_resource(np, 0, &r);
|
||||
ret = of_address_to_resource(mem_np, 0, &r);
|
||||
of_node_put(mem_np);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -109,7 +109,7 @@ nv50_bar_oneinit(struct nvkm_bar *base)
|
||||
struct nvkm_device *device = bar->base.subdev.device;
|
||||
static struct lock_class_key bar1_lock;
|
||||
static struct lock_class_key bar2_lock;
|
||||
u64 start, limit;
|
||||
u64 start, limit, size;
|
||||
int ret;
|
||||
|
||||
ret = nvkm_gpuobj_new(device, 0x20000, 0, false, NULL, &bar->mem);
|
||||
@ -127,7 +127,10 @@ nv50_bar_oneinit(struct nvkm_bar *base)
|
||||
|
||||
/* BAR2 */
|
||||
start = 0x0100000000ULL;
|
||||
limit = start + device->func->resource_size(device, 3);
|
||||
size = device->func->resource_size(device, 3);
|
||||
if (!size)
|
||||
return -ENOMEM;
|
||||
limit = start + size;
|
||||
|
||||
ret = nvkm_vmm_new(device, start, limit-- - start, NULL, 0,
|
||||
&bar2_lock, "bar2", &bar->bar2_vmm);
|
||||
@ -164,7 +167,10 @@ nv50_bar_oneinit(struct nvkm_bar *base)
|
||||
|
||||
/* BAR1 */
|
||||
start = 0x0000000000ULL;
|
||||
limit = start + device->func->resource_size(device, 1);
|
||||
size = device->func->resource_size(device, 1);
|
||||
if (!size)
|
||||
return -ENOMEM;
|
||||
limit = start + size;
|
||||
|
||||
ret = nvkm_vmm_new(device, start, limit-- - start, NULL, 0,
|
||||
&bar1_lock, "bar1", &bar->bar1_vmm);
|
||||
|
@ -1386,12 +1386,9 @@ static int dsi_pll_enable(struct dss_pll *pll)
|
||||
*/
|
||||
dsi_enable_scp_clk(dsi);
|
||||
|
||||
if (!dsi->vdds_dsi_enabled) {
|
||||
r = regulator_enable(dsi->vdds_dsi_reg);
|
||||
if (r)
|
||||
goto err0;
|
||||
dsi->vdds_dsi_enabled = true;
|
||||
}
|
||||
r = regulator_enable(dsi->vdds_dsi_reg);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
||||
/* XXX PLL does not come out of reset without this... */
|
||||
dispc_pck_free_enable(dsi->dss->dispc, 1);
|
||||
@ -1416,36 +1413,25 @@ static int dsi_pll_enable(struct dss_pll *pll)
|
||||
|
||||
return 0;
|
||||
err1:
|
||||
if (dsi->vdds_dsi_enabled) {
|
||||
regulator_disable(dsi->vdds_dsi_reg);
|
||||
dsi->vdds_dsi_enabled = false;
|
||||
}
|
||||
regulator_disable(dsi->vdds_dsi_reg);
|
||||
err0:
|
||||
dsi_disable_scp_clk(dsi);
|
||||
dsi_runtime_put(dsi);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void dsi_pll_uninit(struct dsi_data *dsi, bool disconnect_lanes)
|
||||
{
|
||||
dsi_pll_power(dsi, DSI_PLL_POWER_OFF);
|
||||
if (disconnect_lanes) {
|
||||
WARN_ON(!dsi->vdds_dsi_enabled);
|
||||
regulator_disable(dsi->vdds_dsi_reg);
|
||||
dsi->vdds_dsi_enabled = false;
|
||||
}
|
||||
|
||||
dsi_disable_scp_clk(dsi);
|
||||
dsi_runtime_put(dsi);
|
||||
|
||||
DSSDBG("PLL uninit done\n");
|
||||
}
|
||||
|
||||
static void dsi_pll_disable(struct dss_pll *pll)
|
||||
{
|
||||
struct dsi_data *dsi = container_of(pll, struct dsi_data, pll);
|
||||
|
||||
dsi_pll_uninit(dsi, true);
|
||||
dsi_pll_power(dsi, DSI_PLL_POWER_OFF);
|
||||
|
||||
regulator_disable(dsi->vdds_dsi_reg);
|
||||
|
||||
dsi_disable_scp_clk(dsi);
|
||||
dsi_runtime_put(dsi);
|
||||
|
||||
DSSDBG("PLL disable done\n");
|
||||
}
|
||||
|
||||
static void dsi_dump_dsi_clocks(struct dsi_data *dsi, struct seq_file *s)
|
||||
@ -4195,11 +4181,11 @@ static int dsi_display_init_dsi(struct dsi_data *dsi)
|
||||
|
||||
r = dss_pll_enable(&dsi->pll);
|
||||
if (r)
|
||||
goto err0;
|
||||
return r;
|
||||
|
||||
r = dsi_configure_dsi_clocks(dsi);
|
||||
if (r)
|
||||
goto err1;
|
||||
goto err0;
|
||||
|
||||
dss_select_dsi_clk_source(dsi->dss, dsi->module_id,
|
||||
dsi->module_id == 0 ?
|
||||
@ -4207,6 +4193,14 @@ static int dsi_display_init_dsi(struct dsi_data *dsi)
|
||||
|
||||
DSSDBG("PLL OK\n");
|
||||
|
||||
if (!dsi->vdds_dsi_enabled) {
|
||||
r = regulator_enable(dsi->vdds_dsi_reg);
|
||||
if (r)
|
||||
goto err1;
|
||||
|
||||
dsi->vdds_dsi_enabled = true;
|
||||
}
|
||||
|
||||
r = dsi_cio_init(dsi);
|
||||
if (r)
|
||||
goto err2;
|
||||
@ -4235,10 +4229,13 @@ static int dsi_display_init_dsi(struct dsi_data *dsi)
|
||||
err3:
|
||||
dsi_cio_uninit(dsi);
|
||||
err2:
|
||||
dss_select_dsi_clk_source(dsi->dss, dsi->module_id, DSS_CLK_SRC_FCK);
|
||||
regulator_disable(dsi->vdds_dsi_reg);
|
||||
dsi->vdds_dsi_enabled = false;
|
||||
err1:
|
||||
dss_pll_disable(&dsi->pll);
|
||||
dss_select_dsi_clk_source(dsi->dss, dsi->module_id, DSS_CLK_SRC_FCK);
|
||||
err0:
|
||||
dss_pll_disable(&dsi->pll);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -4257,7 +4254,12 @@ static void dsi_display_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
|
||||
|
||||
dss_select_dsi_clk_source(dsi->dss, dsi->module_id, DSS_CLK_SRC_FCK);
|
||||
dsi_cio_uninit(dsi);
|
||||
dsi_pll_uninit(dsi, disconnect_lanes);
|
||||
dss_pll_disable(&dsi->pll);
|
||||
|
||||
if (disconnect_lanes) {
|
||||
regulator_disable(dsi->vdds_dsi_reg);
|
||||
dsi->vdds_dsi_enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
static int dsi_display_enable(struct omap_dss_device *dssdev)
|
||||
|
@ -248,6 +248,9 @@ static int otm8009a_init_sequence(struct otm8009a *ctx)
|
||||
/* Send Command GRAM memory write (no parameters) */
|
||||
dcs_write_seq(ctx, MIPI_DCS_WRITE_MEMORY_START);
|
||||
|
||||
/* Wait a short while to let the panel be ready before the 1st frame */
|
||||
mdelay(10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -330,6 +330,7 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv)
|
||||
ret = vexpress_muxfpga_init();
|
||||
if (ret) {
|
||||
dev_err(dev, "unable to initialize muxfpga driver\n");
|
||||
of_node_put(np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -337,17 +338,20 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv)
|
||||
pdev = of_find_device_by_node(np);
|
||||
if (!pdev) {
|
||||
dev_err(dev, "can't find the sysreg device, deferring\n");
|
||||
of_node_put(np);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
map = dev_get_drvdata(&pdev->dev);
|
||||
if (!map) {
|
||||
dev_err(dev, "sysreg has not yet probed\n");
|
||||
platform_device_put(pdev);
|
||||
of_node_put(np);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
} else {
|
||||
map = syscon_node_to_regmap(np);
|
||||
}
|
||||
of_node_put(np);
|
||||
|
||||
if (IS_ERR(map)) {
|
||||
dev_err(dev, "no Versatile syscon regmap\n");
|
||||
|
@ -357,7 +357,13 @@ static void sun6i_dsi_inst_init(struct sun6i_dsi *dsi,
|
||||
static u16 sun6i_dsi_get_video_start_delay(struct sun6i_dsi *dsi,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
return mode->vtotal - (mode->vsync_end - mode->vdisplay) + 1;
|
||||
u16 start = clamp(mode->vtotal - mode->vdisplay - 10, 8, 100);
|
||||
u16 delay = mode->vtotal - (mode->vsync_end - mode->vdisplay) + start;
|
||||
|
||||
if (delay > mode->vtotal)
|
||||
delay = delay % mode->vtotal;
|
||||
|
||||
return max_t(u16, delay, 1);
|
||||
}
|
||||
|
||||
static void sun6i_dsi_setup_burst(struct sun6i_dsi *dsi,
|
||||
|
@ -278,7 +278,7 @@ static void ili9225_pipe_disable(struct drm_simple_display_pipe *pipe)
|
||||
mipi->enabled = false;
|
||||
}
|
||||
|
||||
static int ili9225_dbi_command(struct mipi_dbi *mipi, u8 cmd, u8 *par,
|
||||
static int ili9225_dbi_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
|
||||
size_t num)
|
||||
{
|
||||
struct spi_device *spi = mipi->spi;
|
||||
@ -288,11 +288,11 @@ static int ili9225_dbi_command(struct mipi_dbi *mipi, u8 cmd, u8 *par,
|
||||
|
||||
gpiod_set_value_cansleep(mipi->dc, 0);
|
||||
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
|
||||
ret = tinydrm_spi_transfer(spi, speed_hz, NULL, 8, &cmd, 1);
|
||||
ret = tinydrm_spi_transfer(spi, speed_hz, NULL, 8, cmd, 1);
|
||||
if (ret || !num)
|
||||
return ret;
|
||||
|
||||
if (cmd == ILI9225_WRITE_DATA_TO_GRAM && !mipi->swap_bytes)
|
||||
if (*cmd == ILI9225_WRITE_DATA_TO_GRAM && !mipi->swap_bytes)
|
||||
bpw = 16;
|
||||
|
||||
gpiod_set_value_cansleep(mipi->dc, 1);
|
||||
|
@ -144,16 +144,42 @@ EXPORT_SYMBOL(mipi_dbi_command_read);
|
||||
*/
|
||||
int mipi_dbi_command_buf(struct mipi_dbi *mipi, u8 cmd, u8 *data, size_t len)
|
||||
{
|
||||
u8 *cmdbuf;
|
||||
int ret;
|
||||
|
||||
/* SPI requires dma-safe buffers */
|
||||
cmdbuf = kmemdup(&cmd, 1, GFP_KERNEL);
|
||||
if (!cmdbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&mipi->cmdlock);
|
||||
ret = mipi->command(mipi, cmd, data, len);
|
||||
ret = mipi->command(mipi, cmdbuf, data, len);
|
||||
mutex_unlock(&mipi->cmdlock);
|
||||
|
||||
kfree(cmdbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(mipi_dbi_command_buf);
|
||||
|
||||
/* This should only be used by mipi_dbi_command() */
|
||||
int mipi_dbi_command_stackbuf(struct mipi_dbi *mipi, u8 cmd, u8 *data, size_t len)
|
||||
{
|
||||
u8 *buf;
|
||||
int ret;
|
||||
|
||||
buf = kmemdup(data, len, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = mipi_dbi_command_buf(mipi, cmd, buf, len);
|
||||
|
||||
kfree(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(mipi_dbi_command_stackbuf);
|
||||
|
||||
/**
|
||||
* mipi_dbi_buf_copy - Copy a framebuffer, transforming it if necessary
|
||||
* @dst: The destination buffer
|
||||
@ -741,18 +767,18 @@ static int mipi_dbi_spi1_transfer(struct mipi_dbi *mipi, int dc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mipi_dbi_typec1_command(struct mipi_dbi *mipi, u8 cmd,
|
||||
static int mipi_dbi_typec1_command(struct mipi_dbi *mipi, u8 *cmd,
|
||||
u8 *parameters, size_t num)
|
||||
{
|
||||
unsigned int bpw = (cmd == MIPI_DCS_WRITE_MEMORY_START) ? 16 : 8;
|
||||
unsigned int bpw = (*cmd == MIPI_DCS_WRITE_MEMORY_START) ? 16 : 8;
|
||||
int ret;
|
||||
|
||||
if (mipi_dbi_command_is_read(mipi, cmd))
|
||||
if (mipi_dbi_command_is_read(mipi, *cmd))
|
||||
return -ENOTSUPP;
|
||||
|
||||
MIPI_DBI_DEBUG_COMMAND(cmd, parameters, num);
|
||||
MIPI_DBI_DEBUG_COMMAND(*cmd, parameters, num);
|
||||
|
||||
ret = mipi_dbi_spi1_transfer(mipi, 0, &cmd, 1, 8);
|
||||
ret = mipi_dbi_spi1_transfer(mipi, 0, cmd, 1, 8);
|
||||
if (ret || !num)
|
||||
return ret;
|
||||
|
||||
@ -761,7 +787,7 @@ static int mipi_dbi_typec1_command(struct mipi_dbi *mipi, u8 cmd,
|
||||
|
||||
/* MIPI DBI Type C Option 3 */
|
||||
|
||||
static int mipi_dbi_typec3_command_read(struct mipi_dbi *mipi, u8 cmd,
|
||||
static int mipi_dbi_typec3_command_read(struct mipi_dbi *mipi, u8 *cmd,
|
||||
u8 *data, size_t len)
|
||||
{
|
||||
struct spi_device *spi = mipi->spi;
|
||||
@ -770,7 +796,7 @@ static int mipi_dbi_typec3_command_read(struct mipi_dbi *mipi, u8 cmd,
|
||||
struct spi_transfer tr[2] = {
|
||||
{
|
||||
.speed_hz = speed_hz,
|
||||
.tx_buf = &cmd,
|
||||
.tx_buf = cmd,
|
||||
.len = 1,
|
||||
}, {
|
||||
.speed_hz = speed_hz,
|
||||
@ -788,8 +814,8 @@ static int mipi_dbi_typec3_command_read(struct mipi_dbi *mipi, u8 cmd,
|
||||
* Support non-standard 24-bit and 32-bit Nokia read commands which
|
||||
* start with a dummy clock, so we need to read an extra byte.
|
||||
*/
|
||||
if (cmd == MIPI_DCS_GET_DISPLAY_ID ||
|
||||
cmd == MIPI_DCS_GET_DISPLAY_STATUS) {
|
||||
if (*cmd == MIPI_DCS_GET_DISPLAY_ID ||
|
||||
*cmd == MIPI_DCS_GET_DISPLAY_STATUS) {
|
||||
if (!(len == 3 || len == 4))
|
||||
return -EINVAL;
|
||||
|
||||
@ -819,7 +845,7 @@ static int mipi_dbi_typec3_command_read(struct mipi_dbi *mipi, u8 cmd,
|
||||
data[i] = (buf[i] << 1) | !!(buf[i + 1] & BIT(7));
|
||||
}
|
||||
|
||||
MIPI_DBI_DEBUG_COMMAND(cmd, data, len);
|
||||
MIPI_DBI_DEBUG_COMMAND(*cmd, data, len);
|
||||
|
||||
err_free:
|
||||
kfree(buf);
|
||||
@ -827,7 +853,7 @@ err_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 cmd,
|
||||
static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 *cmd,
|
||||
u8 *par, size_t num)
|
||||
{
|
||||
struct spi_device *spi = mipi->spi;
|
||||
@ -835,18 +861,18 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 cmd,
|
||||
u32 speed_hz;
|
||||
int ret;
|
||||
|
||||
if (mipi_dbi_command_is_read(mipi, cmd))
|
||||
if (mipi_dbi_command_is_read(mipi, *cmd))
|
||||
return mipi_dbi_typec3_command_read(mipi, cmd, par, num);
|
||||
|
||||
MIPI_DBI_DEBUG_COMMAND(cmd, par, num);
|
||||
MIPI_DBI_DEBUG_COMMAND(*cmd, par, num);
|
||||
|
||||
gpiod_set_value_cansleep(mipi->dc, 0);
|
||||
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
|
||||
ret = tinydrm_spi_transfer(spi, speed_hz, NULL, 8, &cmd, 1);
|
||||
ret = tinydrm_spi_transfer(spi, speed_hz, NULL, 8, cmd, 1);
|
||||
if (ret || !num)
|
||||
return ret;
|
||||
|
||||
if (cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes)
|
||||
if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes)
|
||||
bpw = 16;
|
||||
|
||||
gpiod_set_value_cansleep(mipi->dc, 1);
|
||||
|
@ -305,14 +305,18 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto dev_destroy;
|
||||
|
||||
v3d_irq_init(v3d);
|
||||
|
||||
ret = drm_dev_register(drm, 0);
|
||||
ret = v3d_irq_init(v3d);
|
||||
if (ret)
|
||||
goto gem_destroy;
|
||||
|
||||
ret = drm_dev_register(drm, 0);
|
||||
if (ret)
|
||||
goto irq_disable;
|
||||
|
||||
return 0;
|
||||
|
||||
irq_disable:
|
||||
v3d_irq_disable(v3d);
|
||||
gem_destroy:
|
||||
v3d_gem_destroy(drm);
|
||||
dev_destroy:
|
||||
|
@ -284,7 +284,7 @@ void v3d_invalidate_caches(struct v3d_dev *v3d);
|
||||
void v3d_flush_caches(struct v3d_dev *v3d);
|
||||
|
||||
/* v3d_irq.c */
|
||||
void v3d_irq_init(struct v3d_dev *v3d);
|
||||
int v3d_irq_init(struct v3d_dev *v3d);
|
||||
void v3d_irq_enable(struct v3d_dev *v3d);
|
||||
void v3d_irq_disable(struct v3d_dev *v3d);
|
||||
void v3d_irq_reset(struct v3d_dev *v3d);
|
||||
|
@ -137,7 +137,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
v3d_irq_init(struct v3d_dev *v3d)
|
||||
{
|
||||
int ret, core;
|
||||
@ -154,13 +154,22 @@ v3d_irq_init(struct v3d_dev *v3d)
|
||||
ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0),
|
||||
v3d_hub_irq, IRQF_SHARED,
|
||||
"v3d_hub", v3d);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 1),
|
||||
v3d_irq, IRQF_SHARED,
|
||||
"v3d_core0", v3d);
|
||||
if (ret)
|
||||
dev_err(v3d->dev, "IRQ setup failed: %d\n", ret);
|
||||
goto fail;
|
||||
|
||||
v3d_irq_enable(v3d);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(v3d->dev, "IRQ setup failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -215,13 +215,14 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
|
||||
* Add a usage to the temporary parser table.
|
||||
*/
|
||||
|
||||
static int hid_add_usage(struct hid_parser *parser, unsigned usage)
|
||||
static int hid_add_usage(struct hid_parser *parser, unsigned usage, u8 size)
|
||||
{
|
||||
if (parser->local.usage_index >= HID_MAX_USAGES) {
|
||||
hid_err(parser->device, "usage index exceeded\n");
|
||||
return -1;
|
||||
}
|
||||
parser->local.usage[parser->local.usage_index] = usage;
|
||||
parser->local.usage_size[parser->local.usage_index] = size;
|
||||
parser->local.collection_index[parser->local.usage_index] =
|
||||
parser->collection_stack_ptr ?
|
||||
parser->collection_stack[parser->collection_stack_ptr - 1] : 0;
|
||||
@ -482,10 +483,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (item->size <= 2)
|
||||
data = (parser->global.usage_page << 16) + data;
|
||||
|
||||
return hid_add_usage(parser, data);
|
||||
return hid_add_usage(parser, data, item->size);
|
||||
|
||||
case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
|
||||
|
||||
@ -494,9 +492,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (item->size <= 2)
|
||||
data = (parser->global.usage_page << 16) + data;
|
||||
|
||||
parser->local.usage_minimum = data;
|
||||
return 0;
|
||||
|
||||
@ -507,9 +502,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (item->size <= 2)
|
||||
data = (parser->global.usage_page << 16) + data;
|
||||
|
||||
count = data - parser->local.usage_minimum;
|
||||
if (count + parser->local.usage_index >= HID_MAX_USAGES) {
|
||||
/*
|
||||
@ -529,7 +521,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
|
||||
}
|
||||
|
||||
for (n = parser->local.usage_minimum; n <= data; n++)
|
||||
if (hid_add_usage(parser, n)) {
|
||||
if (hid_add_usage(parser, n, item->size)) {
|
||||
dbg_hid("hid_add_usage failed\n");
|
||||
return -1;
|
||||
}
|
||||
@ -543,6 +535,22 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Concatenate Usage Pages into Usages where relevant:
|
||||
* As per specification, 6.2.2.8: "When the parser encounters a main item it
|
||||
* concatenates the last declared Usage Page with a Usage to form a complete
|
||||
* usage value."
|
||||
*/
|
||||
|
||||
static void hid_concatenate_usage_page(struct hid_parser *parser)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < parser->local.usage_index; i++)
|
||||
if (parser->local.usage_size[i] <= 2)
|
||||
parser->local.usage[i] += parser->global.usage_page << 16;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a main item.
|
||||
*/
|
||||
@ -552,6 +560,8 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
|
||||
__u32 data;
|
||||
int ret;
|
||||
|
||||
hid_concatenate_usage_page(parser);
|
||||
|
||||
data = item_udata(item);
|
||||
|
||||
switch (item->tag) {
|
||||
@ -761,6 +771,8 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
|
||||
__u32 data;
|
||||
int i;
|
||||
|
||||
hid_concatenate_usage_page(parser);
|
||||
|
||||
data = item_udata(item);
|
||||
|
||||
switch (item->tag) {
|
||||
|
@ -725,13 +725,16 @@ static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature,
|
||||
|
||||
static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
|
||||
{
|
||||
const u8 ping_byte = 0x5a;
|
||||
u8 ping_data[3] = { 0, 0, ping_byte };
|
||||
struct hidpp_report response;
|
||||
int ret;
|
||||
|
||||
ret = hidpp_send_fap_command_sync(hidpp,
|
||||
ret = hidpp_send_rap_command_sync(hidpp,
|
||||
REPORT_ID_HIDPP_SHORT,
|
||||
HIDPP_PAGE_ROOT_IDX,
|
||||
CMD_ROOT_GET_PROTOCOL_VERSION,
|
||||
NULL, 0, &response);
|
||||
ping_data, sizeof(ping_data), &response);
|
||||
|
||||
if (ret == HIDPP_ERROR_INVALID_SUBID) {
|
||||
hidpp->protocol_major = 1;
|
||||
@ -751,8 +754,14 @@ static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hidpp->protocol_major = response.fap.params[0];
|
||||
hidpp->protocol_minor = response.fap.params[1];
|
||||
if (response.rap.params[2] != ping_byte) {
|
||||
hid_err(hidpp->hid_dev, "%s: ping mismatch 0x%02x != 0x%02x\n",
|
||||
__func__, response.rap.params[2], ping_byte);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
hidpp->protocol_major = response.rap.params[0];
|
||||
hidpp->protocol_minor = response.rap.params[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -901,7 +910,11 @@ static int hidpp_map_battery_level(int capacity)
|
||||
{
|
||||
if (capacity < 11)
|
||||
return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
|
||||
else if (capacity < 31)
|
||||
/*
|
||||
* The spec says this should be < 31 but some devices report 30
|
||||
* with brand new batteries and Windows reports 30 as "Good".
|
||||
*/
|
||||
else if (capacity < 30)
|
||||
return POWER_SUPPLY_CAPACITY_LEVEL_LOW;
|
||||
else if (capacity < 81)
|
||||
return POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
|
||||
|
@ -96,17 +96,23 @@ superio_select(int base, int ld)
|
||||
outb(ld, base + 1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
static inline int
|
||||
superio_enter(int base)
|
||||
{
|
||||
if (!request_muxed_region(base, 2, DRVNAME))
|
||||
return -EBUSY;
|
||||
|
||||
outb(0x87, base);
|
||||
outb(0x87, base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
superio_exit(int base)
|
||||
{
|
||||
outb(0xaa, base);
|
||||
release_region(base, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1561,7 +1567,7 @@ exit:
|
||||
static int __init f71805f_find(int sioaddr, unsigned short *address,
|
||||
struct f71805f_sio_data *sio_data)
|
||||
{
|
||||
int err = -ENODEV;
|
||||
int err;
|
||||
u16 devid;
|
||||
|
||||
static const char * const names[] = {
|
||||
@ -1569,8 +1575,11 @@ static int __init f71805f_find(int sioaddr, unsigned short *address,
|
||||
"F71872F/FG or F71806F/FG",
|
||||
};
|
||||
|
||||
superio_enter(sioaddr);
|
||||
err = superio_enter(sioaddr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = -ENODEV;
|
||||
devid = superio_inw(sioaddr, SIO_REG_MANID);
|
||||
if (devid != SIO_FINTEK_ID)
|
||||
goto exit;
|
||||
|
@ -106,6 +106,13 @@ static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" };
|
||||
#define LD_IN 1
|
||||
#define LD_TEMP 1
|
||||
|
||||
static inline int superio_enter(int sioaddr)
|
||||
{
|
||||
if (!request_muxed_region(sioaddr, 2, DRVNAME))
|
||||
return -EBUSY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void superio_outb(int sioaddr, int reg, int val)
|
||||
{
|
||||
outb(reg, sioaddr);
|
||||
@ -122,6 +129,7 @@ static inline void superio_exit(int sioaddr)
|
||||
{
|
||||
outb(0x02, sioaddr);
|
||||
outb(0x02, sioaddr + 1);
|
||||
release_region(sioaddr, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1220,7 +1228,11 @@ static int __init pc87427_find(int sioaddr, struct pc87427_sio_data *sio_data)
|
||||
{
|
||||
u16 val;
|
||||
u8 cfg, cfg_b;
|
||||
int i, err = 0;
|
||||
int i, err;
|
||||
|
||||
err = superio_enter(sioaddr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Identify device */
|
||||
val = force_id ? force_id : superio_inb(sioaddr, SIOREG_DEVID);
|
||||
|
@ -72,14 +72,19 @@ static inline void superio_select(int ld)
|
||||
superio_outb(0x07, ld);
|
||||
}
|
||||
|
||||
static inline void superio_enter(void)
|
||||
static inline int superio_enter(void)
|
||||
{
|
||||
if (!request_muxed_region(REG, 2, DRVNAME))
|
||||
return -EBUSY;
|
||||
|
||||
outb(0x55, REG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void superio_exit(void)
|
||||
{
|
||||
outb(0xAA, REG);
|
||||
release_region(REG, 2);
|
||||
}
|
||||
|
||||
#define SUPERIO_REG_DEVID 0x20
|
||||
@ -300,8 +305,12 @@ static int __init smsc47b397_find(void)
|
||||
u8 id, rev;
|
||||
char *name;
|
||||
unsigned short addr;
|
||||
int err;
|
||||
|
||||
err = superio_enter();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
superio_enter();
|
||||
id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
|
||||
|
||||
switch (id) {
|
||||
|
@ -73,16 +73,21 @@ superio_inb(int reg)
|
||||
/* logical device for fans is 0x0A */
|
||||
#define superio_select() superio_outb(0x07, 0x0A)
|
||||
|
||||
static inline void
|
||||
static inline int
|
||||
superio_enter(void)
|
||||
{
|
||||
if (!request_muxed_region(REG, 2, DRVNAME))
|
||||
return -EBUSY;
|
||||
|
||||
outb(0x55, REG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
superio_exit(void)
|
||||
{
|
||||
outb(0xAA, REG);
|
||||
release_region(REG, 2);
|
||||
}
|
||||
|
||||
#define SUPERIO_REG_ACT 0x30
|
||||
@ -531,8 +536,12 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
|
||||
{
|
||||
u8 val;
|
||||
unsigned short addr;
|
||||
int err;
|
||||
|
||||
err = superio_enter();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
superio_enter();
|
||||
val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
|
||||
|
||||
/*
|
||||
@ -608,13 +617,14 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
|
||||
static void smsc47m1_restore(const struct smsc47m1_sio_data *sio_data)
|
||||
{
|
||||
if ((sio_data->activate & 0x01) == 0) {
|
||||
superio_enter();
|
||||
superio_select();
|
||||
|
||||
pr_info("Disabling device\n");
|
||||
superio_outb(SUPERIO_REG_ACT, sio_data->activate);
|
||||
|
||||
superio_exit();
|
||||
if (!superio_enter()) {
|
||||
superio_select();
|
||||
pr_info("Disabling device\n");
|
||||
superio_outb(SUPERIO_REG_ACT, sio_data->activate);
|
||||
superio_exit();
|
||||
} else {
|
||||
pr_warn("Failed to disable device\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,15 +226,21 @@ static inline void superio_select(int sio_cip, int ldn)
|
||||
outb(ldn, sio_cip + 1);
|
||||
}
|
||||
|
||||
static inline void superio_enter(int sio_cip)
|
||||
static inline int superio_enter(int sio_cip)
|
||||
{
|
||||
if (!request_muxed_region(sio_cip, 2, DRVNAME))
|
||||
return -EBUSY;
|
||||
|
||||
outb(0x87, sio_cip);
|
||||
outb(0x87, sio_cip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void superio_exit(int sio_cip)
|
||||
{
|
||||
outb(0xaa, sio_cip);
|
||||
release_region(sio_cip, 2);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
@ -1282,11 +1288,14 @@ EXIT:
|
||||
|
||||
static int __init vt1211_find(int sio_cip, unsigned short *address)
|
||||
{
|
||||
int err = -ENODEV;
|
||||
int err;
|
||||
int devid;
|
||||
|
||||
superio_enter(sio_cip);
|
||||
err = superio_enter(sio_cip);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = -ENODEV;
|
||||
devid = force_id ? force_id : superio_inb(sio_cip, SIO_VT1211_DEVID);
|
||||
if (devid != SIO_VT1211_ID)
|
||||
goto EXIT;
|
||||
|
@ -696,6 +696,7 @@ config STM32_DFSDM_ADC
|
||||
depends on (ARCH_STM32 && OF) || COMPILE_TEST
|
||||
select STM32_DFSDM_CORE
|
||||
select REGMAP_MMIO
|
||||
select IIO_BUFFER
|
||||
select IIO_BUFFER_HW_CONSUMER
|
||||
help
|
||||
Select this option to support ADCSigma delta modulator for
|
||||
|
@ -62,7 +62,7 @@ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
|
||||
struct spi_transfer t = {
|
||||
.tx_buf = data,
|
||||
.len = size + 1,
|
||||
.cs_change = sigma_delta->bus_locked,
|
||||
.cs_change = sigma_delta->keep_cs_asserted,
|
||||
};
|
||||
struct spi_message m;
|
||||
int ret;
|
||||
@ -218,6 +218,7 @@ static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
|
||||
|
||||
spi_bus_lock(sigma_delta->spi->master);
|
||||
sigma_delta->bus_locked = true;
|
||||
sigma_delta->keep_cs_asserted = true;
|
||||
reinit_completion(&sigma_delta->completion);
|
||||
|
||||
ret = ad_sigma_delta_set_mode(sigma_delta, mode);
|
||||
@ -235,9 +236,10 @@ static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
|
||||
ret = 0;
|
||||
}
|
||||
out:
|
||||
sigma_delta->keep_cs_asserted = false;
|
||||
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
|
||||
sigma_delta->bus_locked = false;
|
||||
spi_bus_unlock(sigma_delta->spi->master);
|
||||
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -289,6 +291,7 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
|
||||
|
||||
spi_bus_lock(sigma_delta->spi->master);
|
||||
sigma_delta->bus_locked = true;
|
||||
sigma_delta->keep_cs_asserted = true;
|
||||
reinit_completion(&sigma_delta->completion);
|
||||
|
||||
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_SINGLE);
|
||||
@ -298,9 +301,6 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
|
||||
ret = wait_for_completion_interruptible_timeout(
|
||||
&sigma_delta->completion, HZ);
|
||||
|
||||
sigma_delta->bus_locked = false;
|
||||
spi_bus_unlock(sigma_delta->spi->master);
|
||||
|
||||
if (ret == 0)
|
||||
ret = -EIO;
|
||||
if (ret < 0)
|
||||
@ -316,7 +316,10 @@ out:
|
||||
sigma_delta->irq_dis = true;
|
||||
}
|
||||
|
||||
sigma_delta->keep_cs_asserted = false;
|
||||
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
|
||||
sigma_delta->bus_locked = false;
|
||||
spi_bus_unlock(sigma_delta->spi->master);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
|
||||
if (ret)
|
||||
@ -353,6 +356,8 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
|
||||
|
||||
spi_bus_lock(sigma_delta->spi->master);
|
||||
sigma_delta->bus_locked = true;
|
||||
sigma_delta->keep_cs_asserted = true;
|
||||
|
||||
ret = ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_CONTINUOUS);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
@ -381,6 +386,7 @@ static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev)
|
||||
sigma_delta->irq_dis = true;
|
||||
}
|
||||
|
||||
sigma_delta->keep_cs_asserted = false;
|
||||
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
|
||||
|
||||
sigma_delta->bus_locked = false;
|
||||
|
@ -56,6 +56,9 @@ struct ti_ads7950_state {
|
||||
struct spi_message ring_msg;
|
||||
struct spi_message scan_single_msg;
|
||||
|
||||
/* Lock to protect the spi xfer buffers */
|
||||
struct mutex slock;
|
||||
|
||||
struct regulator *reg;
|
||||
unsigned int vref_mv;
|
||||
|
||||
@ -277,6 +280,7 @@ static irqreturn_t ti_ads7950_trigger_handler(int irq, void *p)
|
||||
struct ti_ads7950_state *st = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&st->slock);
|
||||
ret = spi_sync(st->spi, &st->ring_msg);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@ -285,6 +289,7 @@ static irqreturn_t ti_ads7950_trigger_handler(int irq, void *p)
|
||||
iio_get_time_ns(indio_dev));
|
||||
|
||||
out:
|
||||
mutex_unlock(&st->slock);
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@ -295,7 +300,7 @@ static int ti_ads7950_scan_direct(struct iio_dev *indio_dev, unsigned int ch)
|
||||
struct ti_ads7950_state *st = iio_priv(indio_dev);
|
||||
int ret, cmd;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->slock);
|
||||
|
||||
cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(ch) | st->settings;
|
||||
st->single_tx = cpu_to_be16(cmd);
|
||||
@ -307,7 +312,7 @@ static int ti_ads7950_scan_direct(struct iio_dev *indio_dev, unsigned int ch)
|
||||
ret = be16_to_cpu(st->single_rx);
|
||||
|
||||
out:
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->slock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -423,16 +428,19 @@ static int ti_ads7950_probe(struct spi_device *spi)
|
||||
if (ACPI_COMPANION(&spi->dev))
|
||||
st->vref_mv = TI_ADS7950_VA_MV_ACPI_DEFAULT;
|
||||
|
||||
mutex_init(&st->slock);
|
||||
|
||||
st->reg = devm_regulator_get(&spi->dev, "vref");
|
||||
if (IS_ERR(st->reg)) {
|
||||
dev_err(&spi->dev, "Failed get get regulator \"vref\"\n");
|
||||
return PTR_ERR(st->reg);
|
||||
ret = PTR_ERR(st->reg);
|
||||
goto error_destroy_mutex;
|
||||
}
|
||||
|
||||
ret = regulator_enable(st->reg);
|
||||
if (ret) {
|
||||
dev_err(&spi->dev, "Failed to enable regulator \"vref\"\n");
|
||||
return ret;
|
||||
goto error_destroy_mutex;
|
||||
}
|
||||
|
||||
ret = iio_triggered_buffer_setup(indio_dev, NULL,
|
||||
@ -454,6 +462,8 @@ error_cleanup_ring:
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
error_disable_reg:
|
||||
regulator_disable(st->reg);
|
||||
error_destroy_mutex:
|
||||
mutex_destroy(&st->slock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -466,6 +476,7 @@ static int ti_ads7950_remove(struct spi_device *spi)
|
||||
iio_device_unregister(indio_dev);
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
regulator_disable(st->reg);
|
||||
mutex_destroy(&st->slock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ int ssp_common_process_data(struct iio_dev *indio_dev, void *buf,
|
||||
unsigned int len, int64_t timestamp)
|
||||
{
|
||||
__le32 time;
|
||||
int64_t calculated_time;
|
||||
int64_t calculated_time = 0;
|
||||
struct ssp_sensor_data *spd = iio_priv(indio_dev);
|
||||
|
||||
if (indio_dev->scan_bytes == 0)
|
||||
|
@ -58,8 +58,13 @@ static const struct regmap_config hmc5843_i2c_regmap_config = {
|
||||
static int hmc5843_i2c_probe(struct i2c_client *cli,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct regmap *regmap = devm_regmap_init_i2c(cli,
|
||||
&hmc5843_i2c_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
return hmc5843_common_probe(&cli->dev,
|
||||
devm_regmap_init_i2c(cli, &hmc5843_i2c_regmap_config),
|
||||
regmap,
|
||||
id->driver_data, id->name);
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ static const struct regmap_config hmc5843_spi_regmap_config = {
|
||||
static int hmc5843_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
int ret;
|
||||
struct regmap *regmap;
|
||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
|
||||
spi->mode = SPI_MODE_3;
|
||||
@ -67,8 +68,12 @@ static int hmc5843_spi_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap = devm_regmap_init_spi(spi, &hmc5843_spi_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
return hmc5843_common_probe(&spi->dev,
|
||||
devm_regmap_init_spi(spi, &hmc5843_spi_regmap_config),
|
||||
regmap,
|
||||
id->driver_data, id->name);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user