S: Supported
F: drivers/video/backlight/adp8860_bl.c
-ADS1015 HARDWARE MONITOR DRIVER
-S: Maintained
-F: Documentation/hwmon/ads1015.rst
-F: drivers/hwmon/ads1015.c
-F: include/linux/platform_data/ads1015.h
-
ADT746X FAN DRIVER
S: Maintained
S: Maintained
-F: Documentation/i2c/busses/i2c-ali1563
+F: Documentation/i2c/busses/i2c-ali1563.rst
F: drivers/i2c/busses/i2c-ali1563.c
ALLEGRO DVT VIDEO IP CORE DRIVER
S: Maintained
F: drivers/staging/media/allegro-dvt/
+ ALLWINNER CPUFREQ DRIVER
+ S: Maintained
+ F: Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt
+ F: drivers/cpufreq/sun50i-cpufreq-nvmem.c
+
ALLWINNER SECURITY SYSTEM
S: Maintained
-F: drivers/iommu/arm-smmu.c
-F: drivers/iommu/arm-smmu-v3.c
+F: drivers/iommu/arm-smmu*
F: drivers/iommu/io-pgtable-arm.c
F: drivers/iommu/io-pgtable-arm-v7s.c
F: drivers/soc/sunxi/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git
+Allwinner A10 CSI driver
+T: git git://linuxtv.org/media_tree.git
+F: drivers/media/platform/sunxi/sun4i-csi/
+F: Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
+S: Maintained
+
ARM/Amlogic Meson SoC CLOCK FRAMEWORK
F: arch/arm/boot/dts/artpec6*
F: drivers/clk/axis
F: drivers/crypto/axis
+F: drivers/mmc/host/usdhi6rol0.c
F: drivers/pinctrl/pinctrl-artpec*
F: Documentation/devicetree/bindings/pinctrl/axis,artpec6-pinctrl.txt
S: Maintained
F: drivers/hwtracing/coresight/*
-F: Documentation/trace/coresight.txt
-F: Documentation/trace/coresight-cpu-debug.txt
+F: Documentation/trace/coresight.rst
+F: Documentation/trace/coresight-cpu-debug.rst
F: Documentation/devicetree/bindings/arm/coresight.txt
F: Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
F: Documentation/ABI/testing/sysfs-bus-coresight-devices-*
N: [^a-z]sirf
X: drivers/gnss
+ARM/CZ.NIC TURRIS MOX SUPPORT
+W: http://mox.turris.cz
+S: Maintained
+F: Documentation/ABI/testing/debugfs-moxtet
+F: Documentation/ABI/testing/sysfs-bus-moxtet-devices
+F: Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm
+F: Documentation/devicetree/bindings/bus/moxtet.txt
+F: Documentation/devicetree/bindings/firmware/cznic,turris-mox-rwtm.txt
+F: Documentation/devicetree/bindings/gpio/gpio-moxtet.txt
+F: include/linux/moxtet.h
+F: drivers/bus/moxtet.c
+F: drivers/firmware/turris-mox-rwtm.c
+F: drivers/gpio/gpio-moxtet.c
+
ARM/EBSA110 MACHINE SUPPORT
S: Maintained
F: arch/arm/mach-pxa/colibri-pxa270-income.c
-ARM/INTEL IOP13XX ARM ARCHITECTURE
-S: Maintained
-
ARM/INTEL IOP32X ARM ARCHITECTURE
S: Maintained
-ARM/INTEL IOP33X ARM ARCHITECTURE
-S: Orphan
-
ARM/INTEL IQ81342EX MACHINE SUPPORT
F: drivers/phy/mediatek/
F: Documentation/devicetree/bindings/phy/phy-mtk-*
-ARM/MICREL KS8695 ARCHITECTURE
-F: arch/arm/mach-ks8695/
-S: Odd Fixes
-
ARM/Microchip (AT91) SoC support
F: arch/arm/mach-nomadik/
F: arch/arm/mach-u300/
F: arch/arm/mach-ux500/
+F: drivers/soc/ux500/
F: arch/arm/boot/dts/ste-*
F: drivers/clk/clk-nomadik.c
F: drivers/clk/clk-u300.c
F: Documentation/devicetree/bindings/*/*npcm*
F: Documentation/devicetree/bindings/*/*/*npcm*
-ARM/NUVOTON W90X900 ARM ARCHITECTURE
-W: http://www.mcuos.com
-S: Maintained
-F: arch/arm/mach-w90x900/
-F: drivers/input/keyboard/w90p910_keypad.c
-F: drivers/input/touchscreen/w90p910_ts.c
-F: drivers/watchdog/nuc900_wdt.c
-F: drivers/net/ethernet/nuvoton/w90p910_ether.c
-F: drivers/mtd/nand/raw/nuc900_nand.c
-F: drivers/rtc/rtc-nuc900.c
-F: drivers/spi/spi-nuc900.c
-F: drivers/usb/host/ehci-w90x900.c
-F: drivers/video/fbdev/nuc900fb.c
-
ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
W: http://wiki.openmoko.org/wiki/Neo_FreeRunner
F: drivers/*/*/*s3c24*
F: drivers/*/*s3c64xx*
F: drivers/*/*s5pv210*
-F: drivers/memory/samsung/*
-F: drivers/soc/samsung/*
+F: drivers/memory/samsung/
+F: drivers/soc/samsung/
+F: include/linux/soc/samsung/
F: Documentation/arm/samsung/
F: Documentation/devicetree/bindings/arm/samsung/
F: Documentation/devicetree/bindings/sram/samsung-sram.txt
W: http://linux-cifs.samba.org/
T: git git://git.samba.org/sfrench/cifs-2.6.git
S: Supported
-F: Documentation/filesystems/cifs/
+F: Documentation/admin-guide/cifs/
F: fs/cifs/
COMPACTPCI HOTPLUG CORE
F: drivers/cpuidle/cpuidle-exynos.c
F: arch/arm/mach-exynos/pm.c
+CPUIDLE DRIVER - ARM PSCI
+S: Supported
+F: drivers/cpuidle/cpuidle-psci.c
+
CPU IDLE TIME MANAGEMENT FRAMEWORK
S: Maintained
F: Documentation/
+F: scripts/documentation-file-ref-check
F: scripts/kernel-doc
+F: scripts/sphinx-pre-install
X: Documentation/ABI/
X: Documentation/firmware-guide/acpi/
X: Documentation/devicetree/
S: Maintained
F: Documentation/translations/it_IT
+DOCUMENTATION SCRIPTS
+S: Maintained
+F: scripts/documentation-file-ref-check
+F: scripts/sphinx-pre-install
+F: Documentation/sphinx/parse-headers.pl
+
DONGWOON DW9714 LENS VOICE COIL DRIVER
F: drivers/edac/aspeed_edac.c
F: Documentation/devicetree/bindings/edac/aspeed-sdram-edac.txt
+EDAC-BLUEFIELD
+S: Supported
+F: drivers/edac/bluefield_edac.c
+
EDAC-CALXEDA
EDAC-CORE
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git for-next
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac.git linux_next
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras.git edac-for-next
S: Supported
F: Documentation/admin-guide/ras.rst
F: Documentation/driver-api/edac.rst
F: drivers/hwmon/f75375s.c
F: include/linux/f75375s.h
-FIREWIRE AUDIO DRIVERS
+FIREWIRE AUDIO DRIVERS and IEC 61883-1/6 PACKET STREAMING ENGINE
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
S: Maintained
F: sound/firewire/
+F: include/uapi/sound/firewire.h
FIREWIRE MEDIA DRIVERS (firedtv)
S: Maintained
-F: Documentation/ABI/testing/sysfs-bus-counter-ftm-quadddec
+F: Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec
F: Documentation/devicetree/bindings/counter/ftm-quaddec.txt
F: drivers/counter/ftm-quaddec.c
F: drivers/block/floppy.c
-FMC SUBSYSTEM
-W: http://www.ohwr.org/projects/fmc-bus
-S: Supported
-F: drivers/fmc/
-F: include/linux/fmc*.h
-F: include/linux/ipmi-fru.h
-K: fmc_d.*register
-
FPGA MANAGER FRAMEWORK
S: Maintained
F: drivers/perf/fsl_imx8_ddr_perf.c
+F: Documentation/admin-guide/perf/imx-ddr.rst
F: Documentation/devicetree/bindings/perf/fsl-imx-ddr.txt
FREESCALE IMX I2C DRIVER
S: Maintained
F: drivers/media/radio/radio-gemtek*
+GENERIC ARCHITECTURE TOPOLOGY
+S: Maintained
+F: drivers/base/arch_topology.c
+F: include/linux/arch_topology.h
+
GENERIC GPIO I2C DRIVER
S: Supported
S: Supported
F: drivers/i2c/muxes/i2c-mux-gpio.c
F: include/linux/platform_data/i2c-mux-gpio.h
-F: Documentation/i2c/muxes/i2c-mux-gpio
+F: Documentation/i2c/muxes/i2c-mux-gpio.rst
GENERIC HDLC (WAN) DRIVERS
S: Maintained
-F: Documentation/i2c/busses/i2c-nvidia-gpu
+F: Documentation/i2c/busses/i2c-nvidia-gpu.rst
F: drivers/i2c/busses/i2c-nvidia-gpu.c
I2C MUXES
S: Maintained
-F: Documentation/i2c/i2c-topology
+F: Documentation/i2c/i2c-topology.rst
F: Documentation/i2c/muxes/
F: Documentation/devicetree/bindings/i2c/i2c-mux*
F: Documentation/devicetree/bindings/i2c/i2c-arb*
S: Maintained
-F: Documentation/i2c/busses/i2c-parport
-F: Documentation/i2c/busses/i2c-parport-light
+F: Documentation/i2c/busses/i2c-parport.rst
+F: Documentation/i2c/busses/i2c-parport-light.rst
F: drivers/i2c/busses/i2c-parport.c
F: drivers/i2c/busses/i2c-parport-light.c
S: Maintained
-F: Documentation/i2c/busses/i2c-taos-evm
+F: Documentation/i2c/busses/i2c-taos-evm.rst
F: drivers/i2c/busses/i2c-taos-evm.c
I2C-TINY-USB DRIVER
S: Maintained
-F: Documentation/i2c/busses/i2c-ali1535
-F: Documentation/i2c/busses/i2c-ali1563
-F: Documentation/i2c/busses/i2c-ali15x3
-F: Documentation/i2c/busses/i2c-amd756
-F: Documentation/i2c/busses/i2c-amd8111
-F: Documentation/i2c/busses/i2c-i801
-F: Documentation/i2c/busses/i2c-nforce2
-F: Documentation/i2c/busses/i2c-piix4
-F: Documentation/i2c/busses/i2c-sis5595
-F: Documentation/i2c/busses/i2c-sis630
-F: Documentation/i2c/busses/i2c-sis96x
-F: Documentation/i2c/busses/i2c-via
-F: Documentation/i2c/busses/i2c-viapro
+F: Documentation/i2c/busses/i2c-ali1535.rst
+F: Documentation/i2c/busses/i2c-ali1563.rst
+F: Documentation/i2c/busses/i2c-ali15x3.rst
+F: Documentation/i2c/busses/i2c-amd756.rst
+F: Documentation/i2c/busses/i2c-amd8111.rst
+F: Documentation/i2c/busses/i2c-i801.rst
+F: Documentation/i2c/busses/i2c-nforce2.rst
+F: Documentation/i2c/busses/i2c-piix4.rst
+F: Documentation/i2c/busses/i2c-sis5595.rst
+F: Documentation/i2c/busses/i2c-sis630.rst
+F: Documentation/i2c/busses/i2c-sis96x.rst
+F: Documentation/i2c/busses/i2c-via.rst
+F: Documentation/i2c/busses/i2c-viapro.rst
F: drivers/i2c/busses/i2c-ali1535.c
F: drivers/i2c/busses/i2c-ali1563.c
F: drivers/i2c/busses/i2c-ali15x3.c
F: drivers/i2c/busses/i2c-ismt.c
-F: Documentation/i2c/busses/i2c-ismt
+F: Documentation/i2c/busses/i2c-ismt.rst
I2C/SMBUS STUB DRIVER
S: Supported
W: http://linuxwimax.org
-F: Documentation/wimax/README.i2400m
+F: Documentation/admin-guide/wimax/i2400m.rst
F: drivers/net/wimax/i2400m/
F: include/uapi/linux/wimax/i2400m.h
F: include/linux/tboot.h
F: arch/x86/kernel/tboot.c
-INTEL-MID GPIO DRIVER
-S: Maintained
-F: drivers/gpio/gpio-intel-mid.c
-
INTERCONNECT API
S: Maintained
F: drivers/net/ethernet/sgi/ioc3-eth.c
-IOC3 SERIAL DRIVER
-S: Maintained
-F: drivers/tty/serial/ioc3_serial.c
-
IOMAP FILESYSTEM LIBRARY
W: http://jfs.sourceforge.net/
T: git git://github.com/kleikamp/linux-shaggy.git
S: Maintained
-F: Documentation/filesystems/jfs.txt
+F: Documentation/admin-guide/jfs.rst
F: fs/jfs/
JME NETWORK DRIVER
KEYS-TRUSTED
KS0108 LCD CONTROLLER DRIVER
S: Maintained
-F: Documentation/auxdisplay/ks0108
+F: Documentation/admin-guide/auxdisplay/ks0108.rst
F: drivers/auxdisplay/ks0108.c
F: include/linux/ks0108.h
LINUX KERNEL MEMORY CONSISTENCY MODEL (LKMM)
-M: Andrea Parri <andrea.parri@amarulasolutions.com>
+M: Andrea Parri <parri.andrea@gmail.com>
-M: "Paul E. McKenney" <paulmck@linux.ibm.com>
+M: "Paul E. McKenney" <paulmck@kernel.org>
F: include/net/mac80211.h
F: net/mac80211/
F: drivers/net/wireless/mac80211_hwsim.[ch]
-F: Documentation/networking/mac80211_hwsim/README
+F: Documentation/networking/mac80211_hwsim/mac80211_hwsim.rst
MAILBOX API
T: git git://linuxtv.org/media_tree.git
S: Supported
-F: Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
-F: Documentation/devicetree/bindings/media/rcar_vin.txt
+F: Documentation/devicetree/bindings/media/renesas,csi2.txt
+F: Documentation/devicetree/bindings/media/renesas,vin.txt
F: drivers/media/platform/rcar-vin/
MEDIA DRIVERS FOR RENESAS - VSP1
S: Supported
F: drivers/i2c/busses/i2c-mlxcpld.c
F: drivers/i2c/muxes/i2c-mux-mlxcpld.c
-F: Documentation/i2c/busses/i2c-mlxcpld
+F: Documentation/i2c/busses/i2c-mlxcpld.rst
MELLANOX MLXCPLD LED DRIVER
MEMBARRIER SUPPORT
-M: "Paul E. McKenney" <paulmck@linux.ibm.com>
+M: "Paul E. McKenney" <paulmck@kernel.org>
S: Supported
F: kernel/sched/membarrier.c
S: Supported
F: drivers/power/reset/at91-sama5d2_shdwc.c
-MICROCHIP SAMA5D2-COMPATIBLE PIOBU GPIO
-F: drivers/gpio/gpio-sama5d2-piobu.c
-
MICROCHIP SPI DRIVER
S: Supported
F: drivers/misc/atmel-ssc.c
F: include/linux/atmel-ssc.h
-MICROCHIP TIMER COUNTER (TC) AND CLOCKSOURCE DRIVERS
-S: Supported
-F: drivers/misc/atmel_tclib.c
-F: drivers/clocksource/tcb_clksrc.c
-
MICROCHIP USBA UDC DRIVER
S: Maintained
F: drivers/media/i2c/ov5647.c
+OMNIVISION OV5670 SENSOR DRIVER
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/i2c/ov5670.c
+
+OMNIVISION OV5675 SENSOR DRIVER
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/i2c/ov5675.c
+
OMNIVISION OV5695 SENSOR DRIVER
S: Maintained
F: Documentation/devicetree/bindings/i2c/i2c-ocores.txt
-F: Documentation/i2c/busses/i2c-ocores
+F: Documentation/i2c/busses/i2c-ocores.rst
F: drivers/i2c/busses/i2c-ocores.c
F: include/linux/platform_data/i2c-ocores.h
S: Supported
F: lib/packing.c
F: include/linux/packing.h
-F: Documentation/packing.txt
+F: Documentation/core-api/packing.rst
PADATA PARALLEL EXECUTION MECHANISM
S: Supported
F: drivers/pinctrl/pinctrl-at91*
+F: drivers/gpio/gpio-sama5d2-piobu.c
PIN CONTROLLER - FREESCALE
S: Maintained
- F: Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
- F: drivers/cpufreq/qcom-cpufreq-kryo.c
+ F: Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt
+ F: drivers/cpufreq/qcom-cpufreq-nvmem.c
QUALCOMM EMAC GIGABIT ETHERNET DRIVER
F: drivers/net/wireless/ray*
RCUTORTURE TEST FRAMEWORK
-M: "Paul E. McKenney" <paulmck@linux.ibm.com>
+M: "Paul E. McKenney" <paulmck@kernel.org>
F: Documentation/x86/resctrl*
READ-COPY UPDATE (RCU)
-M: "Paul E. McKenney" <paulmck@linux.ibm.com>
+M: "Paul E. McKenney" <paulmck@kernel.org>
RESTARTABLE SEQUENCES SUPPORT
-M: "Paul E. McKenney" <paulmck@linux.ibm.com>
+M: "Paul E. McKenney" <paulmck@kernel.org>
S: Supported
F: Documentation/ABI/*/sysfs-driver-hid-roccat*
ROCKCHIP RASTER 2D GRAPHIC ACCELERATION UNIT DRIVER
S: Maintained
F: drivers/media/platform/rockchip/rga/
S: Maintained
-F: drivers/staging/media/platform/hantro/
+F: drivers/staging/media/hantro/
F: Documentation/devicetree/bindings/media/rockchip-vpu.txt
ROCKER DRIVER
S: Maintained
+F: Documentation/devicetree/bindings/crypto/samsung-slimsss.txt
+F: Documentation/devicetree/bindings/crypto/samsung-sss.txt
F: drivers/crypto/s5p-sss.c
SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS
F: drivers/clk/samsung/
F: include/dt-bindings/clock/exynos*.h
F: Documentation/devicetree/bindings/clock/exynos*.txt
+F: Documentation/devicetree/bindings/clock/samsung,s3c*
+F: Documentation/devicetree/bindings/clock/samsung,s5p*
SAMSUNG SPI DRIVERS
SCHEDULER
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched/core
S: Maintained
SCx200 CPU SUPPORT
S: Odd Fixes
-F: Documentation/i2c/busses/scx200_acb
+F: Documentation/i2c/busses/scx200_acb.rst
F: arch/x86/platform/scx200/
F: drivers/watchdog/scx200_wdt.c
F: drivers/i2c/busses/scx200*
SLEEPABLE READ-COPY UPDATE (SRCU)
-M: "Paul E. McKenney" <paulmck@linux.ibm.com>
+M: "Paul E. McKenney" <paulmck@kernel.org>
SYNOPSYS DESIGNWARE AXI DMAC DRIVER
S: Maintained
-F: drivers/dma/dwi-axi-dmac/
+F: drivers/dma/dw-axi-dmac/
F: Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt
SYNOPSYS DESIGNWARE DMAC DRIVER
F: drivers/cpufreq/sc[mp]i-cpufreq.c
F: drivers/firmware/arm_scpi.c
F: drivers/firmware/arm_scmi/
+F: drivers/reset/reset-scmi.c
F: include/linux/sc[mp]i_protocol.h
SYSTEM RESET/SHUTDOWN DRIVERS
F: include/linux/soc/ti/ti_sci_protocol.h
F: Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
F: drivers/soc/ti/ti_sci_pm_domains.c
+F: include/dt-bindings/soc/ti,sci_pm_domain.h
F: Documentation/devicetree/bindings/reset/ti,sci-reset.txt
F: Documentation/devicetree/bindings/clock/ti,sci-clk.txt
F: drivers/clk/keystone/sci-clk.c
S: Supported
-F: Documentation/thermal/cpu-cooling-api.rst
+F: Documentation/driver-api/thermal/cpu-cooling-api.rst
F: drivers/thermal/cpu_cooling.c
F: include/linux/cpu_cooling.h
TORTURE-TEST MODULES
-M: "Paul E. McKenney" <paulmck@linux.ibm.com>
+M: "Paul E. McKenney" <paulmck@kernel.org>
S: Supported
UFS FILESYSTEM
S: Maintained
-F: Documentation/filesystems/ufs.txt
+F: Documentation/admin-guide/ufs.rst
F: fs/ufs/
UHID USERSPACE HID IO DRIVER:
S: Supported
F: arch/x86/kernel/cpu/vmware.c
+F: arch/x86/include/asm/vmware.h
VMWARE PVRDMA DRIVER
F: drivers/regulator/
F: include/dt-bindings/regulator/
F: include/linux/regulator/
+K: regulator_get_optional
VRF
S: Supported
W: http://linuxwimax.org
-F: Documentation/wimax/README.wimax
+F: Documentation/admin-guide/wimax/wimax.rst
F: include/linux/wimax/debug.h
F: include/net/wimax.h
F: include/uapi/linux/wimax.h
T: git git://git.infradead.org/linux-platform-drivers-x86.git
-S: Maintained
+S: Odd Fixes
F: drivers/platform/x86/
F: drivers/platform/olpc/
F: include/uapi/linux/fsmap.h
XILINX AXI ETHERNET DRIVER
S: Maintained
F: drivers/net/ethernet/xilinx/xilinx_axienet*
F: mm/zpool.c
F: include/linux/zpool.h
-ZR36067 VIDEO FOR LINUX DRIVER
-W: http://mjpeg.sourceforge.net/driver-zoran/
-T: hg https://linuxtv.org/hg/v4l-dvb
-S: Odd Fixes
-F: drivers/staging/media/zoran/
-
ZRAM COMPRESSED RAM BLOCK DEVICE DRVIER
bool "KVM Guest support (including kvmclock)"
depends on PARAVIRT
select PARAVIRT_CLOCK
+ select ARCH_CPUIDLE_HALTPOLL
default y
---help---
This option enables various optimizations for running under the KVM
underlying device model, the host provides the guest with
timing infrastructure such as time of day, and system time
+ config ARCH_CPUIDLE_HALTPOLL
+ def_bool n
+ prompt "Disable host haltpoll when loading haltpoll driver"
+ help
+ If virtualized under KVM, disable host haltpoll.
+
config PVH
bool "Support for running PVH guests"
---help---
config X86_DIRECT_GBPAGES
def_bool y
- depends on X86_64 && !DEBUG_PAGEALLOC
+ depends on X86_64
---help---
Certain kernel features effectively disable kernel
linear 1 GB mappings (even if the CPU otherwise
if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) {
u64 pa = slow_virt_to_phys(this_cpu_ptr(&apf_reason));
-#ifdef CONFIG_PREEMPT
+#ifdef CONFIG_PREEMPTION
pa |= KVM_ASYNC_PF_SEND_ALWAYS;
#endif
pa |= KVM_ASYNC_PF_ENABLED;
{
return cpuid_edx(kvm_cpuid_base() | KVM_CPUID_FEATURES);
}
+ EXPORT_SYMBOL_GPL(kvm_arch_para_hints);
static uint32_t __init kvm_detect(void)
{
}
#endif /* CONFIG_PARAVIRT_SPINLOCKS */
+
+ #ifdef CONFIG_ARCH_CPUIDLE_HALTPOLL
+
+ static void kvm_disable_host_haltpoll(void *i)
+ {
+ wrmsrl(MSR_KVM_POLL_CONTROL, 0);
+ }
+
+ static void kvm_enable_host_haltpoll(void *i)
+ {
+ wrmsrl(MSR_KVM_POLL_CONTROL, 1);
+ }
+
+ void arch_haltpoll_enable(unsigned int cpu)
+ {
+ if (!kvm_para_has_feature(KVM_FEATURE_POLL_CONTROL)) {
+ pr_err_once("kvm: host does not support poll control\n");
+ pr_err_once("kvm: host upgrade recommended\n");
+ return;
+ }
+
+ /* Enable guest halt poll disables host halt poll */
+ smp_call_function_single(cpu, kvm_disable_host_haltpoll, NULL, 1);
+ }
+ EXPORT_SYMBOL_GPL(arch_haltpoll_enable);
+
+ void arch_haltpoll_disable(unsigned int cpu)
+ {
+ if (!kvm_para_has_feature(KVM_FEATURE_POLL_CONTROL))
+ return;
+
+ /* Enable guest halt poll disables host halt poll */
+ smp_call_function_single(cpu, kvm_enable_host_haltpoll, NULL, 1);
+ }
+ EXPORT_SYMBOL_GPL(arch_haltpoll_disable);
+ #endif
#include <linux/string.h>
#include <linux/sched/topology.h>
#include <linux/cpuset.h>
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/percpu.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE;
if (!raw_capacity)
return 0;
- if (val != CPUFREQ_NOTIFY)
+ if (val != CPUFREQ_CREATE_POLICY)
return 0;
pr_debug("cpu_capacity: init cpu capacity for CPUs [%*pbl] (to_visit=%*pbl)\n",
#else
core_initcall(free_raw_capacity);
#endif
+
+#if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
+static int __init get_cpu_for_node(struct device_node *node)
+{
+ struct device_node *cpu_node;
+ int cpu;
+
+ cpu_node = of_parse_phandle(node, "cpu", 0);
+ if (!cpu_node)
+ return -1;
+
+ cpu = of_cpu_node_to_id(cpu_node);
+ if (cpu >= 0)
+ topology_parse_cpu_capacity(cpu_node, cpu);
+ else
+ pr_crit("Unable to find CPU node for %pOF\n", cpu_node);
+
+ of_node_put(cpu_node);
+ return cpu;
+}
+
+static int __init parse_core(struct device_node *core, int package_id,
+ int core_id)
+{
+ char name[10];
+ bool leaf = true;
+ int i = 0;
+ int cpu;
+ struct device_node *t;
+
+ do {
+ snprintf(name, sizeof(name), "thread%d", i);
+ t = of_get_child_by_name(core, name);
+ if (t) {
+ leaf = false;
+ cpu = get_cpu_for_node(t);
+ if (cpu >= 0) {
+ cpu_topology[cpu].package_id = package_id;
+ cpu_topology[cpu].core_id = core_id;
+ cpu_topology[cpu].thread_id = i;
+ } else {
+ pr_err("%pOF: Can't get CPU for thread\n",
+ t);
+ of_node_put(t);
+ return -EINVAL;
+ }
+ of_node_put(t);
+ }
+ i++;
+ } while (t);
+
+ cpu = get_cpu_for_node(core);
+ if (cpu >= 0) {
+ if (!leaf) {
+ pr_err("%pOF: Core has both threads and CPU\n",
+ core);
+ return -EINVAL;
+ }
+
+ cpu_topology[cpu].package_id = package_id;
+ cpu_topology[cpu].core_id = core_id;
+ } else if (leaf) {
+ pr_err("%pOF: Can't get CPU for leaf core\n", core);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __init parse_cluster(struct device_node *cluster, int depth)
+{
+ char name[10];
+ bool leaf = true;
+ bool has_cores = false;
+ struct device_node *c;
+ static int package_id __initdata;
+ int core_id = 0;
+ int i, ret;
+
+ /*
+ * First check for child clusters; we currently ignore any
+ * information about the nesting of clusters and present the
+ * scheduler with a flat list of them.
+ */
+ i = 0;
+ do {
+ snprintf(name, sizeof(name), "cluster%d", i);
+ c = of_get_child_by_name(cluster, name);
+ if (c) {
+ leaf = false;
+ ret = parse_cluster(c, depth + 1);
+ of_node_put(c);
+ if (ret != 0)
+ return ret;
+ }
+ i++;
+ } while (c);
+
+ /* Now check for cores */
+ i = 0;
+ do {
+ snprintf(name, sizeof(name), "core%d", i);
+ c = of_get_child_by_name(cluster, name);
+ if (c) {
+ has_cores = true;
+
+ if (depth == 0) {
+ pr_err("%pOF: cpu-map children should be clusters\n",
+ c);
+ of_node_put(c);
+ return -EINVAL;
+ }
+
+ if (leaf) {
+ ret = parse_core(c, package_id, core_id++);
+ } else {
+ pr_err("%pOF: Non-leaf cluster with core %s\n",
+ cluster, name);
+ ret = -EINVAL;
+ }
+
+ of_node_put(c);
+ if (ret != 0)
+ return ret;
+ }
+ i++;
+ } while (c);
+
+ if (leaf && !has_cores)
+ pr_warn("%pOF: empty cluster\n", cluster);
+
+ if (leaf)
+ package_id++;
+
+ return 0;
+}
+
+static int __init parse_dt_topology(void)
+{
+ struct device_node *cn, *map;
+ int ret = 0;
+ int cpu;
+
+ cn = of_find_node_by_path("/cpus");
+ if (!cn) {
+ pr_err("No CPU information found in DT\n");
+ return 0;
+ }
+
+ /*
+ * When topology is provided cpu-map is essentially a root
+ * cluster with restricted subnodes.
+ */
+ map = of_get_child_by_name(cn, "cpu-map");
+ if (!map)
+ goto out;
+
+ ret = parse_cluster(map, 0);
+ if (ret != 0)
+ goto out_map;
+
+ topology_normalize_cpu_scale();
+
+ /*
+ * Check that all cores are in the topology; the SMP code will
+ * only mark cores described in the DT as possible.
+ */
+ for_each_possible_cpu(cpu)
+ if (cpu_topology[cpu].package_id == -1)
+ ret = -EINVAL;
+
+out_map:
+ of_node_put(map);
+out:
+ of_node_put(cn);
+ return ret;
+}
+#endif
+
+/*
+ * cpu topology table
+ */
+struct cpu_topology cpu_topology[NR_CPUS];
+EXPORT_SYMBOL_GPL(cpu_topology);
+
+const struct cpumask *cpu_coregroup_mask(int cpu)
+{
+ const cpumask_t *core_mask = cpumask_of_node(cpu_to_node(cpu));
+
+ /* Find the smaller of NUMA, core or LLC siblings */
+ if (cpumask_subset(&cpu_topology[cpu].core_sibling, core_mask)) {
+ /* not numa in package, lets use the package siblings */
+ core_mask = &cpu_topology[cpu].core_sibling;
+ }
+ if (cpu_topology[cpu].llc_id != -1) {
+ if (cpumask_subset(&cpu_topology[cpu].llc_sibling, core_mask))
+ core_mask = &cpu_topology[cpu].llc_sibling;
+ }
+
+ return core_mask;
+}
+
+void update_siblings_masks(unsigned int cpuid)
+{
+ struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
+ int cpu;
+
+ /* update core and thread sibling masks */
+ for_each_online_cpu(cpu) {
+ cpu_topo = &cpu_topology[cpu];
+
+ if (cpuid_topo->llc_id == cpu_topo->llc_id) {
+ cpumask_set_cpu(cpu, &cpuid_topo->llc_sibling);
+ cpumask_set_cpu(cpuid, &cpu_topo->llc_sibling);
+ }
+
+ if (cpuid_topo->package_id != cpu_topo->package_id)
+ continue;
+
+ cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+ cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
+
+ if (cpuid_topo->core_id != cpu_topo->core_id)
+ continue;
+
+ cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
+ cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
+ }
+}
+
+static void clear_cpu_topology(int cpu)
+{
+ struct cpu_topology *cpu_topo = &cpu_topology[cpu];
+
+ cpumask_clear(&cpu_topo->llc_sibling);
+ cpumask_set_cpu(cpu, &cpu_topo->llc_sibling);
+
+ cpumask_clear(&cpu_topo->core_sibling);
+ cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
+ cpumask_clear(&cpu_topo->thread_sibling);
+ cpumask_set_cpu(cpu, &cpu_topo->thread_sibling);
+}
+
+void __init reset_cpu_topology(void)
+{
+ unsigned int cpu;
+
+ for_each_possible_cpu(cpu) {
+ struct cpu_topology *cpu_topo = &cpu_topology[cpu];
+
+ cpu_topo->thread_id = -1;
+ cpu_topo->core_id = -1;
+ cpu_topo->package_id = -1;
+ cpu_topo->llc_id = -1;
+
+ clear_cpu_topology(cpu);
+ }
+}
+
+void remove_cpu_topology(unsigned int cpu)
+{
+ int sibling;
+
+ for_each_cpu(sibling, topology_core_cpumask(cpu))
+ cpumask_clear_cpu(cpu, topology_core_cpumask(sibling));
+ for_each_cpu(sibling, topology_sibling_cpumask(cpu))
+ cpumask_clear_cpu(cpu, topology_sibling_cpumask(sibling));
+ for_each_cpu(sibling, topology_llc_cpumask(cpu))
+ cpumask_clear_cpu(cpu, topology_llc_cpumask(sibling));
+
+ clear_cpu_topology(cpu);
+}
+
+__weak int __init parse_acpi_topology(void)
+{
+ return 0;
+}
+
+#if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
+void __init init_cpu_topology(void)
+{
+ reset_cpu_topology();
+
+ /*
+ * Discard anything that was parsed if we hit an error so we
+ * don't use partial information.
+ */
+ if (parse_acpi_topology())
+ reset_cpu_topology();
+ else if (of_have_populated_dt() && parse_dt_topology())
+ reset_cpu_topology();
+}
+#endif
#include <linux/fs.h>
#include <linux/acpi.h>
#include <linux/vmalloc.h>
+ #include <linux/pm_qos.h>
#include <trace/events/power.h>
#include <asm/div64.h>
return count;
}
+ static struct cpufreq_driver intel_pstate;
+
+ static void update_qos_request(enum dev_pm_qos_req_type type)
+ {
+ int max_state, turbo_max, freq, i, perf_pct;
+ struct dev_pm_qos_request *req;
+ struct cpufreq_policy *policy;
+
+ for_each_possible_cpu(i) {
+ struct cpudata *cpu = all_cpu_data[i];
+
+ policy = cpufreq_cpu_get(i);
+ if (!policy)
+ continue;
+
+ req = policy->driver_data;
+ cpufreq_cpu_put(policy);
+
+ if (!req)
+ continue;
+
+ if (hwp_active)
+ intel_pstate_get_hwp_max(i, &turbo_max, &max_state);
+ else
+ turbo_max = cpu->pstate.turbo_pstate;
+
+ if (type == DEV_PM_QOS_MIN_FREQUENCY) {
+ perf_pct = global.min_perf_pct;
+ } else {
+ req++;
+ perf_pct = global.max_perf_pct;
+ }
+
+ freq = DIV_ROUND_UP(turbo_max * perf_pct, 100);
+ freq *= cpu->pstate.scaling;
+
+ if (dev_pm_qos_update_request(req, freq) < 0)
+ pr_warn("Failed to update freq constraint: CPU%d\n", i);
+ }
+ }
+
static ssize_t store_max_perf_pct(struct kobject *a, struct kobj_attribute *b,
const char *buf, size_t count)
{
mutex_unlock(&intel_pstate_limits_lock);
- intel_pstate_update_policies();
+ if (intel_pstate_driver == &intel_pstate)
+ intel_pstate_update_policies();
+ else
+ update_qos_request(DEV_PM_QOS_MAX_FREQUENCY);
mutex_unlock(&intel_pstate_driver_lock);
mutex_unlock(&intel_pstate_limits_lock);
- intel_pstate_update_policies();
+ if (intel_pstate_driver == &intel_pstate)
+ intel_pstate_update_policies();
+ else
+ update_qos_request(DEV_PM_QOS_MIN_FREQUENCY);
mutex_unlock(&intel_pstate_driver_lock);
(unsigned long)&policy }
static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
- ICPU(INTEL_FAM6_SANDYBRIDGE, core_funcs),
+ ICPU(INTEL_FAM6_SANDYBRIDGE, core_funcs),
ICPU(INTEL_FAM6_SANDYBRIDGE_X, core_funcs),
ICPU(INTEL_FAM6_ATOM_SILVERMONT, silvermont_funcs),
ICPU(INTEL_FAM6_IVYBRIDGE, core_funcs),
- ICPU(INTEL_FAM6_HASWELL_CORE, core_funcs),
- ICPU(INTEL_FAM6_BROADWELL_CORE, core_funcs),
+ ICPU(INTEL_FAM6_HASWELL, core_funcs),
+ ICPU(INTEL_FAM6_BROADWELL, core_funcs),
ICPU(INTEL_FAM6_IVYBRIDGE_X, core_funcs),
ICPU(INTEL_FAM6_HASWELL_X, core_funcs),
- ICPU(INTEL_FAM6_HASWELL_ULT, core_funcs),
- ICPU(INTEL_FAM6_HASWELL_GT3E, core_funcs),
- ICPU(INTEL_FAM6_BROADWELL_GT3E, core_funcs),
+ ICPU(INTEL_FAM6_HASWELL_L, core_funcs),
+ ICPU(INTEL_FAM6_HASWELL_G, core_funcs),
+ ICPU(INTEL_FAM6_BROADWELL_G, core_funcs),
ICPU(INTEL_FAM6_ATOM_AIRMONT, airmont_funcs),
- ICPU(INTEL_FAM6_SKYLAKE_MOBILE, core_funcs),
+ ICPU(INTEL_FAM6_SKYLAKE_L, core_funcs),
ICPU(INTEL_FAM6_BROADWELL_X, core_funcs),
- ICPU(INTEL_FAM6_SKYLAKE_DESKTOP, core_funcs),
- ICPU(INTEL_FAM6_BROADWELL_XEON_D, core_funcs),
+ ICPU(INTEL_FAM6_SKYLAKE, core_funcs),
+ ICPU(INTEL_FAM6_BROADWELL_D, core_funcs),
ICPU(INTEL_FAM6_XEON_PHI_KNL, knl_funcs),
ICPU(INTEL_FAM6_XEON_PHI_KNM, knl_funcs),
ICPU(INTEL_FAM6_ATOM_GOLDMONT, core_funcs),
MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = {
- ICPU(INTEL_FAM6_BROADWELL_XEON_D, core_funcs),
+ ICPU(INTEL_FAM6_BROADWELL_D, core_funcs),
ICPU(INTEL_FAM6_BROADWELL_X, core_funcs),
ICPU(INTEL_FAM6_SKYLAKE_X, core_funcs),
{}
};
static const struct x86_cpu_id intel_pstate_cpu_ee_disable_ids[] = {
- ICPU(INTEL_FAM6_KABYLAKE_DESKTOP, core_funcs),
+ ICPU(INTEL_FAM6_KABYLAKE, core_funcs),
{}
};
static const struct x86_cpu_id intel_pstate_hwp_boost_ids[] = {
ICPU(INTEL_FAM6_SKYLAKE_X, core_funcs),
- ICPU(INTEL_FAM6_SKYLAKE_DESKTOP, core_funcs),
+ ICPU(INTEL_FAM6_SKYLAKE, core_funcs),
{}
};
static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
- int ret = __intel_pstate_cpu_init(policy);
+ int max_state, turbo_max, min_freq, max_freq, ret;
+ struct dev_pm_qos_request *req;
+ struct cpudata *cpu;
+ struct device *dev;
+
+ dev = get_cpu_device(policy->cpu);
+ if (!dev)
+ return -ENODEV;
+ ret = __intel_pstate_cpu_init(policy);
if (ret)
return ret;
/* This reflects the intel_pstate_get_cpu_pstates() setting. */
policy->cur = policy->cpuinfo.min_freq;
+ req = kcalloc(2, sizeof(*req), GFP_KERNEL);
+ if (!req) {
+ ret = -ENOMEM;
+ goto pstate_exit;
+ }
+
+ cpu = all_cpu_data[policy->cpu];
+
+ if (hwp_active)
+ intel_pstate_get_hwp_max(policy->cpu, &turbo_max, &max_state);
+ else
+ turbo_max = cpu->pstate.turbo_pstate;
+
+ min_freq = DIV_ROUND_UP(turbo_max * global.min_perf_pct, 100);
+ min_freq *= cpu->pstate.scaling;
+ max_freq = DIV_ROUND_UP(turbo_max * global.max_perf_pct, 100);
+ max_freq *= cpu->pstate.scaling;
+
+ ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_MIN_FREQUENCY,
+ min_freq);
+ if (ret < 0) {
+ dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret);
+ goto free_req;
+ }
+
+ ret = dev_pm_qos_add_request(dev, req + 1, DEV_PM_QOS_MAX_FREQUENCY,
+ max_freq);
+ if (ret < 0) {
+ dev_err(dev, "Failed to add max-freq constraint (%d)\n", ret);
+ goto remove_min_req;
+ }
+
+ policy->driver_data = req;
+
return 0;
+
+ remove_min_req:
+ dev_pm_qos_remove_request(req);
+ free_req:
+ kfree(req);
+ pstate_exit:
+ intel_pstate_exit_perf_limits(policy);
+
+ return ret;
+ }
+
+ static int intel_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+ {
+ struct dev_pm_qos_request *req;
+
+ req = policy->driver_data;
+
+ dev_pm_qos_remove_request(req + 1);
+ dev_pm_qos_remove_request(req);
+ kfree(req);
+
+ return intel_pstate_cpu_exit(policy);
}
static struct cpufreq_driver intel_cpufreq = {
.target = intel_cpufreq_target,
.fast_switch = intel_cpufreq_fast_switch,
.init = intel_cpufreq_cpu_init,
- .exit = intel_pstate_cpu_exit,
+ .exit = intel_cpufreq_cpu_exit,
.stop_cpu = intel_cpufreq_stop_cpu,
.update_limits = intel_pstate_update_limits,
.name = "intel_cpufreq",
static const struct x86_cpu_id hwp_support_ids[] __initconst = {
ICPU_HWP(INTEL_FAM6_BROADWELL_X, INTEL_PSTATE_HWP_BROADWELL),
- ICPU_HWP(INTEL_FAM6_BROADWELL_XEON_D, INTEL_PSTATE_HWP_BROADWELL),
+ ICPU_HWP(INTEL_FAM6_BROADWELL_D, INTEL_PSTATE_HWP_BROADWELL),
ICPU_HWP(X86_MODEL_ANY, 0),
{}
};
obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
obj-$(CONFIG_DT_IDLE_STATES) += dt_idle_states.o
obj-$(CONFIG_ARCH_HAS_CPU_RELAX) += poll_state.o
+ obj-$(CONFIG_HALTPOLL_CPUIDLE) += cpuidle-haltpoll.o
##################################################################################
# ARM SoC drivers
obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o
obj-$(CONFIG_ARM_EXYNOS_CPUIDLE) += cpuidle-exynos.o
obj-$(CONFIG_ARM_CPUIDLE) += cpuidle-arm.o
+obj-$(CONFIG_ARM_PSCI_CPUIDLE) += cpuidle-psci.o
###############################################################################
# MIPS drivers
int acpi_subsys_suspend(struct device *dev);
int acpi_subsys_freeze(struct device *dev);
int acpi_subsys_poweroff(struct device *dev);
+ void acpi_ec_mark_gpe_for_wake(void);
+ void acpi_ec_set_gpe_wake_mask(u8 action);
#else
static inline int acpi_subsys_prepare(struct device *dev) { return 0; }
static inline void acpi_subsys_complete(struct device *dev) {}
static inline int acpi_subsys_suspend(struct device *dev) { return 0; }
static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
static inline int acpi_subsys_poweroff(struct device *dev) { return 0; }
+ static inline void acpi_ec_mark_gpe_for_wake(void) {}
+ static inline void acpi_ec_set_gpe_wake_mask(u8 action) {}
#endif
#ifdef CONFIG_ACPI
#endif
#endif
-struct acpi_gpio_params {
- unsigned int crs_entry_index;
- unsigned int line_index;
- bool active_low;
-};
-
-struct acpi_gpio_mapping {
- const char *name;
- const struct acpi_gpio_params *data;
- unsigned int size;
-
-/* Ignore IoRestriction field */
-#define ACPI_GPIO_QUIRK_NO_IO_RESTRICTION BIT(0)
-/*
- * When ACPI GPIO mapping table is in use the index parameter inside it
- * refers to the GPIO resource in _CRS method. That index has no
- * distinction of actual type of the resource. When consumer wants to
- * get GpioIo type explicitly, this quirk may be used.
- */
-#define ACPI_GPIO_QUIRK_ONLY_GPIOIO BIT(1)
-
- unsigned int quirks;
-};
-
#if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB)
-int acpi_dev_add_driver_gpios(struct acpi_device *adev,
- const struct acpi_gpio_mapping *gpios);
-
-static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev)
-{
- if (adev)
- adev->driver_gpios = NULL;
-}
-
-int devm_acpi_dev_add_driver_gpios(struct device *dev,
- const struct acpi_gpio_mapping *gpios);
-void devm_acpi_dev_remove_driver_gpios(struct device *dev);
-
bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
struct acpi_resource_gpio **agpio);
int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index);
#else
-static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev,
- const struct acpi_gpio_mapping *gpios)
-{
- return -ENXIO;
-}
-static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) {}
-
-static inline int devm_acpi_dev_add_driver_gpios(struct device *dev,
- const struct acpi_gpio_mapping *gpios)
-{
- return -ENXIO;
-}
-static inline void devm_acpi_dev_remove_driver_gpios(struct device *dev) {}
-
static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
struct acpi_resource_gpio **agpio)
{
#endif
#ifdef CONFIG_ACPI_PPTT
+int acpi_pptt_cpu_is_thread(unsigned int cpu);
int find_acpi_cpu_topology(unsigned int cpu, int level);
int find_acpi_cpu_topology_package(unsigned int cpu);
int find_acpi_cpu_topology_hetero_id(unsigned int cpu);
int find_acpi_cpu_cache_topology(unsigned int cpu, int level);
#else
+static inline int acpi_pptt_cpu_is_thread(unsigned int cpu)
+{
+ return -EINVAL;
+}
static inline int find_acpi_cpu_topology(unsigned int cpu, int level)
{
return -EINVAL;
unsigned int cpu;
ktime_t next_hrtimer;
+ int last_state_idx;
int last_residency;
+ u64 poll_limit_ns;
struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX];
struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
struct cpuidle_driver_kobj *kobj_driver;
/* the driver handles the cpus in cpumask */
struct cpumask *cpumask;
+
+ /* preferred governor to switch at register time */
+ const char *governor;
};
#ifdef CONFIG_CPU_IDLE
extern int cpuidle_enter(struct cpuidle_driver *drv,
struct cpuidle_device *dev, int index);
extern void cpuidle_reflect(struct cpuidle_device *dev, int index);
+ extern u64 cpuidle_poll_time(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev);
extern int cpuidle_register_driver(struct cpuidle_driver *drv);
extern struct cpuidle_driver *cpuidle_get_driver(void);
struct cpuidle_device *dev, int index)
{return -ENODEV; }
static inline void cpuidle_reflect(struct cpuidle_device *dev, int index) { }
+ static inline u64 cpuidle_poll_time(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev)
+ {return 0; }
static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
{return -ENODEV; }
static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
{return 0;}
#endif
-#define __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, is_retention) \
+#define __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, \
+ idx, \
+ state, \
+ is_retention) \
({ \
int __ret = 0; \
\
if (!is_retention) \
__ret = cpu_pm_enter(); \
if (!__ret) { \
- __ret = low_level_idle_enter(idx); \
+ __ret = low_level_idle_enter(state); \
if (!is_retention) \
cpu_pm_exit(); \
} \
})
#define CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx) \
- __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, 0)
+ __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, idx, 0)
#define CPU_PM_CPU_IDLE_ENTER_RETENTION(low_level_idle_enter, idx) \
- __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, 1)
+ __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, idx, 1)
+
+#define CPU_PM_CPU_IDLE_ENTER_PARAM(low_level_idle_enter, idx, state) \
+ __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, state, 0)
+
+#define CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(low_level_idle_enter, idx, state) \
+ __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, state, 1)
#endif /* _LINUX_CPUIDLE_H */
/* The following three functions are for the core kernel use only. */
extern void suspend_device_irqs(void);
extern void resume_device_irqs(void);
+ extern void rearm_wake_irq(unsigned int irq);
/**
* struct irq_affinity_notify - context for notification of IRQ affinity changes
bool state);
#ifdef CONFIG_IRQ_FORCED_THREADING
+# ifdef CONFIG_PREEMPT_RT
+# define force_irqthreads (true)
+# else
extern bool force_irqthreads;
+# endif
#else
#define force_irqthreads (0)
#endif
unsigned int next_freq)
{
struct cpufreq_policy *policy = sg_policy->policy;
+ int cpu;
if (!sugov_update_next_freq(sg_policy, time, next_freq))
return;
return;
policy->cur = next_freq;
- trace_cpu_frequency(next_freq, smp_processor_id());
+
+ if (trace_cpu_frequency_enabled()) {
+ for_each_cpu(cpu, policy->cpus)
+ trace_cpu_frequency(next_freq, cpu);
+ }
}
static void sugov_deferred_update(struct sugov_policy *sg_policy, u64 time,
* irq metric. Because IRQ/steal time is hidden from the task clock we
* need to scale the task numbers:
*
- * 1 - irq
- * U' = irq + ------- * U
- * max
+ * max - irq
+ * U' = irq + --------- * U
+ * max
*/
util = scale_irq_capacity(util, irq, max);
util += irq;
check_pgt_cache();
rmb();
+ local_irq_disable();
+
if (cpu_is_offline(cpu)) {
- tick_nohz_idle_stop_tick_protected();
+ tick_nohz_idle_stop_tick();
cpuhp_report_idle_dead();
arch_cpu_idle_dead();
}
- local_irq_disable();
arch_cpu_idle_enter();
/*
return HRTIMER_NORESTART;
}
- void play_idle(unsigned long duration_ms)
+ void play_idle(unsigned long duration_us)
{
struct idle_timer it;
WARN_ON_ONCE(current->nr_cpus_allowed != 1);
WARN_ON_ONCE(!(current->flags & PF_KTHREAD));
WARN_ON_ONCE(!(current->flags & PF_NO_SETAFFINITY));
- WARN_ON_ONCE(!duration_ms);
+ WARN_ON_ONCE(!duration_us);
rcu_sleep_check();
preempt_disable();
it.done = 0;
hrtimer_init_on_stack(&it.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
it.timer.function = idle_inject_timer_fn;
- hrtimer_start(&it.timer, ms_to_ktime(duration_ms), HRTIMER_MODE_REL_PINNED);
+ hrtimer_start(&it.timer, ns_to_ktime(duration_us * NSEC_PER_USEC),
+ HRTIMER_MODE_REL_PINNED);
while (!READ_ONCE(it.done))
do_idle();
resched_curr(rq);
}
-static struct task_struct *
-pick_next_task_idle(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
+static void put_prev_task_idle(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
+{
+}
+
+static void set_next_task_idle(struct rq *rq, struct task_struct *next)
{
- put_prev_task(rq, prev);
update_idle_core(rq);
schedstat_inc(rq->sched_goidle);
+}
+
+static struct task_struct *
+pick_next_task_idle(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
+{
+ struct task_struct *next = rq->idle;
- return rq->idle;
+ if (prev)
+ put_prev_task(rq, prev);
+
+ set_next_task_idle(rq, next);
+
+ return next;
}
/*
raw_spin_lock_irq(&rq->lock);
}
-static void put_prev_task_idle(struct rq *rq, struct task_struct *prev)
-{
-}
-
/*
* scheduler tick hitting a task of our scheduling class.
*
{
}
-static void set_curr_task_idle(struct rq *rq)
-{
-}
-
static void switched_to_idle(struct rq *rq, struct task_struct *p)
{
BUG();
.pick_next_task = pick_next_task_idle,
.put_prev_task = put_prev_task_idle,
+ .set_next_task = set_next_task_idle,
#ifdef CONFIG_SMP
.select_task_rq = select_task_rq_idle,
.set_cpus_allowed = set_cpus_allowed_common,
#endif
- .set_curr_task = set_curr_task_idle,
.task_tick = task_tick_idle,
.get_rr_interval = get_rr_interval_idle,
if (!device_may_wakeup(rtc->dev.parent))
return -1;
- __ws = wakeup_source_register("alarmtimer");
+ __ws = wakeup_source_register(dev, "alarmtimer");
spin_lock_irqsave(&rtcdev_lock, flags);
if (!rtcdev) {
int ret = alarm_try_to_cancel(alarm);
if (ret >= 0)
return ret;
- cpu_relax();
+ hrtimer_cancel_wait_running(&alarm->timer);
}
}
EXPORT_SYMBOL_GPL(alarm_cancel);
return alarm_try_to_cancel(&timr->it.alarm.alarmtimer);
}
+/**
+ * alarm_timer_wait_running - Posix timer callback to wait for a timer
+ * @timr: Pointer to the posixtimer data struct
+ *
+ * Called from the core code when timer cancel detected that the callback
+ * is running. @timr is unlocked and rcu read lock is held to prevent it
+ * from being freed.
+ */
+static void alarm_timer_wait_running(struct k_itimer *timr)
+{
+ hrtimer_cancel_wait_running(&timr->it.alarm.alarmtimer.timer);
+}
+
/**
* alarm_timer_arm - Posix timer callback to arm a timer
* @timr: Pointer to the posixtimer data struct
enum alarmtimer_type type;
if (!alarmtimer_get_rtcdev())
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
if (!capable(CAP_WAKE_ALARM))
return -EPERM;
int ret = 0;
if (!alarmtimer_get_rtcdev())
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
if (flags & ~TIMER_ABSTIME)
return -EINVAL;
.timer_forward = alarm_timer_forward,
.timer_remaining = alarm_timer_remaining,
.timer_try_to_cancel = alarm_timer_try_to_cancel,
+ .timer_wait_running = alarm_timer_wait_running,
.nsleep = alarm_timer_nsleep,
};
#endif /* CONFIG_POSIX_TIMERS */