F: include/linux/altera_uart.h
F: include/linux/altera_jtaguart.h
+AMAZON ETHERNET DRIVERS
+M: Netanel Belgazal <netanel@annapurnalabs.com>
+R: Saeed Bishara <saeed@annapurnalabs.com>
+R: Zorik Machulsky <zorik@annapurnalabs.com>
+L: netdev@vger.kernel.org
+S: Supported
+F: Documentation/networking/ena.txt
+F: drivers/net/ethernet/amazon/
+
AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER
M: Tom Lendacky <thomas.lendacky@amd.com>
M: Gary Hook <gary.hook@amd.com>
M: Sumit Semwal <sumit.semwal@linaro.org>
L: devel@driverdev.osuosl.org
S: Supported
+F: Documentation/devicetree/bindings/staging/ion/
F: drivers/staging/android/ion
F: drivers/staging/android/uapi/ion.h
F: drivers/staging/android/uapi/ion_test.h
S: Maintained
F: sound/aoa/
-APEX EMBEDDED SYSTEMS STX104 DAC DRIVER
+APEX EMBEDDED SYSTEMS STX104 IIO DRIVER
M: William Breathitt Gray <vilhelm.gray@gmail.com>
L: linux-iio@vger.kernel.org
S: Maintained
-F: drivers/iio/dac/stx104.c
+F: drivers/iio/adc/stx104.c
APM DRIVER
M: Jiri Kosina <jikos@kernel.org>
F: drivers/gpu/drm/arc/
F: Documentation/devicetree/bindings/display/snps,arcpgu.txt
+ARM ARCHITECTED TIMER DRIVER
+M: Mark Rutland <mark.rutland@arm.com>
+M: Marc Zyngier <marc.zyngier@arm.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/include/asm/arch_timer.h
+F: arch/arm64/include/asm/arch_timer.h
+F: drivers/clocksource/arm_arch_timer.c
+
ARM HDLCD DRM DRIVER
M: Liviu Dudau <liviu.dudau@arm.com>
S: Supported
ARM PMU PROFILING AND DEBUGGING
M: Will Deacon <will.deacon@arm.com>
-R: Mark Rutland <mark.rutland@arm.com>
+M: Mark Rutland <mark.rutland@arm.com>
S: Maintained
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
F: arch/arm*/kernel/perf_*
F: arch/arm/oprofile/common.c
F: arch/arm*/kernel/hw_breakpoint.c
F: arch/arm*/include/asm/hw_breakpoint.h
F: arch/arm*/include/asm/perf_event.h
-F: drivers/perf/arm_pmu.c
+F: drivers/perf/*
F: include/linux/perf/arm_pmu.h
+F: Documentation/devicetree/bindings/arm/pmu.txt
ARM PORT
M: Russell King <linux@armlinux.org.uk>
ARM/Annapurna Labs ALPINE ARCHITECTURE
M: Tsahee Zidenberg <tsahee@annapurnalabs.com>
M: Antoine Tenart <antoine.tenart@free-electrons.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-alpine/
F: arch/arm/boot/dts/alpine*
F: Documentation/trace/coresight.txt
F: Documentation/devicetree/bindings/arm/coresight.txt
F: Documentation/ABI/testing/sysfs-bus-coresight-devices-*
+F: tools/perf/arch/arm/util/pmu.c
+F: tools/perf/arch/arm/util/auxtrace.c
+F: tools/perf/arch/arm/util/cs-etm.c
+F: tools/perf/arch/arm/util/cs-etm.h
+F: tools/perf/util/cs-etm.h
ARM/CORGI MACHINE SUPPORT
M: Richard Purdie <rpurdie@rpsys.net>
ARM/SAMSUNG EXYNOS ARM ARCHITECTURES
M: Kukjin Kim <kgene@kernel.org>
-M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
+R: Javier Martinez Canillas <javier@osg.samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
S: Maintained
F: drivers/*/*s5pv210*
F: drivers/memory/samsung/*
F: drivers/soc/samsung/*
-F: drivers/spi/spi-s3c*
F: Documentation/arm/Samsung/
F: Documentation/devicetree/bindings/arm/samsung/
F: Documentation/devicetree/bindings/sram/samsung-sram.txt
ARM/UNIPHIER ARCHITECTURE
M: Masahiro Yamada <yamada.masahiro@socionext.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-uniphier.git
S: Maintained
F: arch/arm/boot/dts/uniphier*
F: arch/arm/include/asm/hardware/cache-uniphier.h
F: arch/arm/mm/cache-uniphier.c
F: arch/arm64/boot/dts/socionext/
F: drivers/bus/uniphier-system-bus.c
+F: drivers/clk/uniphier/
F: drivers/i2c/busses/i2c-uniphier*
F: drivers/pinctrl/uniphier/
F: drivers/tty/serial/8250/8250_uniphier.c
F: drivers/media/i2c/as3645a.c
F: include/media/i2c/as3645a.h
+ASAHI KASEI AK8974 DRIVER
+M: Linus Walleij <linus.walleij@linaro.org>
+L: linux-iio@vger.kernel.org
+W: http://www.akm.com/
+S: Supported
+F: drivers/iio/magnetometer/ak8974.c
+
ASC7621 HARDWARE MONITOR DRIVER
M: George Joseph <george.joseph@fairview5.com>
L: linux-hwmon@vger.kernel.org
S: Maintained
F: drivers/mmc/host/atmel-mci.c
-ATMEL AT91 / AT32 SERIAL DRIVER
-M: Nicolas Ferre <nicolas.ferre@atmel.com>
-S: Supported
-F: drivers/tty/serial/atmel_serial.c
-
ATMEL AT91 SAMA5D2-Compatible Shutdown Controller
M: Nicolas Ferre <nicolas.ferre@atmel.com>
S: Supported
BONDING DRIVER
M: Jay Vosburgh <j.vosburgh@gmail.com>
M: Veaceslav Falico <vfalico@gmail.com>
-M: Andy Gospodarek <gospo@cumulusnetworks.com>
+M: Andy Gospodarek <andy@greyhouse.net>
L: netdev@vger.kernel.org
W: http://sourceforge.net/projects/bonding/
S: Supported
F: kernel/bpf/
BROADCOM B44 10/100 ETHERNET DRIVER
-M: Gary Zambrano <zambrano@broadcom.com>
+M: Michael Chan <michael.chan@broadcom.com>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/broadcom/b44.*
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git misc
W: http://coccinelle.lip6.fr/
S: Supported
-F: Documentation/coccinelle.txt
+F: Documentation/dev-tools/coccinelle.rst
F: scripts/coccinelle/
F: scripts/coccicheck
M: Michael Turquette <mturquette@baylibre.com>
M: Stephen Boyd <sboyd@codeaurora.org>
L: linux-clk@vger.kernel.org
+Q: http://patchwork.kernel.org/project/linux-clk/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
S: Maintained
F: Documentation/devicetree/bindings/clock/
CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG)
M: Johannes Weiner <hannes@cmpxchg.org>
M: Michal Hocko <mhocko@kernel.org>
-M: Vladimir Davydov <vdavydov@virtuozzo.com>
+M: Vladimir Davydov <vdavydov.dev@gmail.com>
L: cgroups@vger.kernel.org
L: linux-mm@kvack.org
S: Maintained
F: drivers/net/wan/cosa*
CPMAC ETHERNET DRIVER
-M: Florian Fainelli <florian@openwrt.org>
+M: Florian Fainelli <f.fainelli@gmail.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/ti/cpmac.c
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
T: git git://git.linaro.org/people/vireshk/linux.git (For ARM Updates)
+F: Documentation/cpu-freq/
F: drivers/cpufreq/
F: include/linux/cpufreq.h
F: drivers/mfd/da903x.c
F: drivers/mfd/da90??-*.c
F: drivers/mfd/da91??-*.c
-F: drivers/power/da9052-battery.c
-F: drivers/power/da91??-*.c
+F: drivers/power/supply/da9052-battery.c
+F: drivers/power/supply/da91??-*.c
F: drivers/regulator/da903x.c
F: drivers/regulator/da9???-regulator.[ch]
F: drivers/rtc/rtc-da90??.c
F: include/sound/da[79]*.h
F: sound/soc/codecs/da[79]*.[ch]
+DIAMOND SYSTEMS GPIO-MM GPIO DRIVER
+M: William Breathitt Gray <vilhelm.gray@gmail.com>
+L: linux-gpio@vger.kernel.org
+S: Maintained
+F: drivers/gpio/gpio-gpio-mm.c
+
DIGI NEO AND CLASSIC PCI PRODUCTS
M: Lidza Louina <lidza.louina@gmail.com>
M: Mark Hounschell <markh@compro.net>
F: fs/ecryptfs/
EDAC-CORE
-M: Doug Thompson <dougthompson@xmission.com>
M: Borislav Petkov <bp@alien8.de>
M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
M: Mauro Carvalho Chehab <mchehab@kernel.org>
F: include/linux/edac.h
EDAC-AMD64
-M: Doug Thompson <dougthompson@xmission.com>
M: Borislav Petkov <bp@alien8.de>
L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/amd64_edac*
EDAC-CALXEDA
-M: Doug Thompson <dougthompson@xmission.com>
M: Robert Richter <rric@kernel.org>
L: linux-edac@vger.kernel.org
S: Maintained
EDAC-E752X
M: Mark Gross <mark.gross@intel.com>
-M: Doug Thompson <dougthompson@xmission.com>
L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/e752x_edac.c
EDAC-E7XXX
-M: Doug Thompson <dougthompson@xmission.com>
L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/e7xxx_edac.c
+EDAC-FSL_DDR
+M: York Sun <york.sun@nxp.com>
+L: linux-edac@vger.kernel.org
+S: Maintained
+F: drivers/edac/fsl_ddr_edac.*
+
EDAC-GHES
M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
M: Mauro Carvalho Chehab <mchehab@kernel.org>
F: drivers/edac/i82443bxgx_edac.c
EDAC-I3000
-M: Jason Uhlenkott <juhlenko@akamai.com>
L: linux-edac@vger.kernel.org
-S: Maintained
+S: Orphan
F: drivers/edac/i3000_edac.c
EDAC-I5000
-M: Doug Thompson <dougthompson@xmission.com>
L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/i5000_edac.c
S: Maintained
F: drivers/edac/sb_edac.c
+EDAC-SKYLAKE
+M: Tony Luck <tony.luck@intel.com>
+L: linux-edac@vger.kernel.org
+S: Maintained
+F: drivers/edac/skx_edac.c
+
EDAC-XGENE
APPLIED MICRO (APM) X-GENE SOC EDAC
M: Loc Ho <lho@apm.com>
S: Maintained
F: drivers/video/fbdev/efifb.c
+EFI TEST DRIVER
+L: linux-efi@vger.kernel.org
+M: Ivan Hu <ivan.hu@canonical.com>
+M: Matt Fleming <matt@codeblueprint.co.uk>
+S: Maintained
+F: drivers/firmware/efi/test/
+
EFS FILESYSTEM
W: http://aeschi.ch.eu.org/efs/
S: Orphan
FIRMWARE LOADER (request_firmware)
M: Ming Lei <ming.lei@canonical.com>
+M: Luis R. Rodriguez <mcgrof@kernel.org>
L: linux-kernel@vger.kernel.org
S: Maintained
F: Documentation/firmware_class/
F2FS FILE SYSTEM
M: Jaegeuk Kim <jaegeuk@kernel.org>
-M: Changman Lee <cm224.lee@samsung.com>
-R: Chao Yu <yuchao0@huawei.com>
+M: Chao Yu <yuchao0@huawei.com>
L: linux-f2fs-devel@lists.sourceforge.net
-W: http://en.wikipedia.org/wiki/F2FS
+W: https://f2fs.wiki.kernel.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git
S: Maintained
F: Documentation/filesystems/f2fs.txt
M: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
S: Maintained
F: kernel/gcov/
-F: Documentation/gcov.txt
+F: Documentation/dev-tools/gcov.rst
GDT SCSI DISK ARRAY CONTROLLER DRIVER
M: Achim Leubner <achim_leubner@adaptec.com>
S: Maintained
F: drivers/input/touchscreen/goodix.c
+GPIO MOCKUP DRIVER
+M: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
+L: linux-gpio@vger.kernel.org
+S: Maintained
+F: drivers/gpio/gpio-mockup.c
+F: tools/testing/selftests/gpio/
+
GPIO SUBSYSTEM
M: Linus Walleij <linus.walleij@linaro.org>
M: Alexandre Courbot <gnurou@gmail.com>
S: Maintained
F: drivers/net/ethernet/aeroflex/
+GREYBUS SUBSYSTEM
+M: Johan Hovold <johan@kernel.org>
+M: Alex Elder <elder@kernel.org>
+M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+S: Maintained
+F: drivers/staging/greybus/
+
+GREYBUS AUDIO PROTOCOLS DRIVERS
+M: Vaibhav Agarwal <vaibhav.sr@gmail.com>
+M: Mark Greer <mgreer@animalcreek.com>
+S: Maintained
+F: drivers/staging/greybus/audio_apbridgea.c
+F: drivers/staging/greybus/audio_apbridgea.h
+F: drivers/staging/greybus/audio_codec.c
+F: drivers/staging/greybus/audio_codec.h
+F: drivers/staging/greybus/audio_gb.c
+F: drivers/staging/greybus/audio_manager.c
+F: drivers/staging/greybus/audio_manager.h
+F: drivers/staging/greybus/audio_manager_module.c
+F: drivers/staging/greybus/audio_manager_private.h
+F: drivers/staging/greybus/audio_manager_sysfs.c
+F: drivers/staging/greybus/audio_module.c
+F: drivers/staging/greybus/audio_topology.c
+
+GREYBUS PROTOCOLS DRIVERS
+M: Rui Miguel Silva <rmfrfs@gmail.com>
+S: Maintained
+F: drivers/staging/greybus/sdio.c
+F: drivers/staging/greybus/light.c
+F: drivers/staging/greybus/gpio.c
+F: drivers/staging/greybus/power_supply.c
+F: drivers/staging/greybus/spi.c
+F: drivers/staging/greybus/spilib.c
+
+GREYBUS PROTOCOLS DRIVERS
+M: Bryan O'Donoghue <pure.logic@nexus-software.ie>
+S: Maintained
+F: drivers/staging/greybus/loopback.c
+F: drivers/staging/greybus/timesync.c
+F: drivers/staging/greybus/timesync_platform.c
+
+GREYBUS PROTOCOLS DRIVERS
+M: Viresh Kumar <vireshk@kernel.org>
+S: Maintained
+F: drivers/staging/greybus/authentication.c
+F: drivers/staging/greybus/bootrom.c
+F: drivers/staging/greybus/firmware.h
+F: drivers/staging/greybus/fw-core.c
+F: drivers/staging/greybus/fw-download.c
+F: drivers/staging/greybus/fw-managament.c
+F: drivers/staging/greybus/greybus_authentication.h
+F: drivers/staging/greybus/greybus_firmware.h
+F: drivers/staging/greybus/hid.c
+F: drivers/staging/greybus/i2c.c
+F: drivers/staging/greybus/spi.c
+F: drivers/staging/greybus/spilib.c
+F: drivers/staging/greybus/spilib.h
+
+GREYBUS PROTOCOLS DRIVERS
+M: David Lin <dtwlin@gmail.com>
+S: Maintained
+F: drivers/staging/greybus/uart.c
+F: drivers/staging/greybus/log.c
+
+GREYBUS PLATFORM DRIVERS
+M: Vaibhav Hiremath <hvaibhav.linux@gmail.com>
+S: Maintained
+F: drivers/staging/greybus/arche-platform.c
+F: drivers/staging/greybus/arche-apb-ctrl.c
+F: drivers/staging/greybus/arche_platform.h
+
GSPCA FINEPIX SUBDRIVER
M: Frank Zago <frank@zago.net>
L: linux-media@vger.kernel.org
HOST AP DRIVER
M: Jouni Malinen <j@w1.fi>
-L: hostap@shmoo.com (subscribers-only)
L: linux-wireless@vger.kernel.org
-W: http://hostap.epitest.fi/
-S: Maintained
+W: http://w1.fi/hostap-driver.html
+S: Obsolete
F: drivers/net/wireless/intersil/hostap/
HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi.git
S: Maintained
F: Documentation/ABI/testing/sysfs-bus-hsi
-F: Documentation/hsi.txt
+F: Documentation/device-drivers/serial-interfaces.rst
F: drivers/hsi/
F: include/linux/hsi/
F: include/uapi/linux/hsi/
F: drivers/cpufreq/intel_pstate.c
INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
-M: Maik Broemme <mbroemme@plusserver.de>
+M: Maik Broemme <mbroemme@libmpq.org>
L: linux-fbdev@vger.kernel.org
S: Maintained
F: Documentation/fb/intelfb.txt
S: Maintained
F: arch/*/include/asm/kasan.h
F: arch/*/mm/kasan_init*
-F: Documentation/kasan.txt
+F: Documentation/dev-tools/kasan.rst
F: include/linux/kasan*.h
F: lib/test_kasan.c
F: mm/kasan/
M: Vegard Nossum <vegardno@ifi.uio.no>
M: Pekka Enberg <penberg@kernel.org>
S: Maintained
-F: Documentation/kmemcheck.txt
+F: Documentation/dev-tools/kmemcheck.rst
F: arch/x86/include/asm/kmemcheck.h
F: arch/x86/mm/kmemcheck/
F: include/linux/kmemcheck.h
KMEMLEAK
M: Catalin Marinas <catalin.marinas@arm.com>
S: Maintained
-F: Documentation/kmemleak.txt
+F: Documentation/dev-tools/kmemleak.rst
F: include/linux/kmemleak.h
F: mm/kmemleak.c
F: mm/kmemleak-test.c
F: drivers/hwmon/max20751.c
MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
-M: "Hans J. Koch" <hjk@hansjkoch.de>
L: linux-hwmon@vger.kernel.org
-S: Maintained
+S: Orphan
F: Documentation/hwmon/max6650
F: drivers/hwmon/max6650.c
F: sound/soc/codecs/max9860.*
MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
-M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
+M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-pm@vger.kernel.org
S: Supported
-F: drivers/power/max14577_charger.c
-F: drivers/power/max77693_charger.c
+F: drivers/power/supply/max14577_charger.c
+F: drivers/power/supply/max77693_charger.c
MAXIM MAX77802 MULTIFUNCTION PMIC DEVICE DRIVERS
M: Javier Martinez Canillas <javier@osg.samsung.com>
MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS
M: Chanwoo Choi <cw00.choi@samsung.com>
-M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
+M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-kernel@vger.kernel.org
S: Supported
F: drivers/*/max14577*.c
S: Maintained
F: drivers/iio/potentiometer/mcp4531.c
+MEASUREMENT COMPUTING CIO-DAC IIO DRIVER
+M: William Breathitt Gray <vilhelm.gray@gmail.com>
+L: linux-iio@vger.kernel.org
+S: Maintained
+F: drivers/iio/dac/cio-dac.c
+
MEDIA DRIVERS FOR RENESAS - FCP
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
Q: http://patchwork.ozlabs.org/project/netdev/list/
F: drivers/net/ethernet/mellanox/mlxsw/
+MELLANOX MLXCPLD LED DRIVER
+M: Vadim Pasternak <vadimp@mellanox.com>
+L: linux-leds@vger.kernel.org
+S: Supported
+F: drivers/leds/leds-mlxcpld.c
+F: Documentation/leds/leds-mlxcpld.txt
+
+MELLANOX PLATFORM DRIVER
+M: Vadim Pasternak <vadimp@mellanox.com>
+L: platform-driver-x86@vger.kernel.org
+S: Supported
+F: arch/x86/platform/mellanox/mlx-platform.c
+
SOFT-ROCE DRIVER (rxe)
M: Moni Shoua <monis@mellanox.com>
L: linux-rdma@vger.kernel.org
S: Supported
W: https://github.com/SoftRoCE/rxe-dev/wiki/rxe-dev:-Home
Q: http://patchwork.kernel.org/project/linux-rdma/list/
-F: drivers/infiniband/hw/rxe/
+F: drivers/infiniband/sw/rxe/
F: include/uapi/rdma/rdma_user_rxe.h
MEMBARRIER SUPPORT
S: Supported
F: arch/microblaze/
+MICROCHIP / ATMEL AT91 / AT32 SERIAL DRIVER
+M: Richard Genoud <richard.genoud@gmail.com>
+S: Maintained
+F: drivers/tty/serial/atmel_serial.c
+F: include/linux/atmel_serial.h
+
MICROSOFT SURFACE PRO 3 BUTTON DRIVER
M: Chen Yu <yu.c.chen@intel.com>
L: platform-driver-x86@vger.kernel.org
S: Supported
F: drivers/iio/temperature/mlx90614.c
+MICROSEMI SMART ARRAY SMARTPQI DRIVER (smartpqi)
+M: Don Brace <don.brace@microsemi.com>
+L: esc.storagedev@microsemi.com
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/smartpqi/smartpqi*.[ch]
+F: drivers/scsi/smartpqi/Kconfig
+F: drivers/scsi/smartpqi/Makefile
+F: include/linux/cciss*.h
+F: include/uapi/linux/cciss*.h
+F: Documentation/scsi/smartpqi.txt
+
MN88472 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
M: Lee Jones <lee.jones@linaro.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
S: Supported
+F: Documentation/devicetree/bindings/mfd/
F: drivers/mfd/
F: include/linux/mfd/
L: linux-scsi@vger.kernel.org
S: Maintained
F: Documentation/scsi/g_NCR5380.txt
-F: Documentation/scsi/dtc3x80.txt
F: drivers/scsi/NCR5380.*
F: drivers/scsi/arm/cumana_1.c
F: drivers/scsi/arm/oak.c
F: drivers/scsi/atari_scsi.*
F: drivers/scsi/dmx3191d.c
-F: drivers/scsi/dtc.*
F: drivers/scsi/g_NCR5380.*
F: drivers/scsi/g_NCR5380_mmio.c
F: drivers/scsi/mac_scsi.*
-F: drivers/scsi/pas16.*
F: drivers/scsi/sun3_scsi.*
F: drivers/scsi/sun3_scsi_vme.c
-F: drivers/scsi/t128.*
NCR DUAL 700 SCSI DRIVER (MICROCHANNEL)
M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
W: https://fedorahosted.org/dropwatch/
F: net/core/drop_monitor.c
+NETWORKING [DSA]
+M: Andrew Lunn <andrew@lunn.ch>
+M: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+M: Florian Fainelli <f.fainelli@gmail.com>
+S: Maintained
+F: net/dsa/
+F: include/net/dsa.h
+F: drivers/net/dsa/
+
NETWORKING [GENERAL]
M: "David S. Miller" <davem@davemloft.net>
L: netdev@vger.kernel.org
F: include/linux/power/bq2415x_charger.h
F: include/linux/power/bq27xxx_battery.h
F: include/linux/power/isp1704_charger.h
-F: drivers/power/bq2415x_charger.c
-F: drivers/power/bq27xxx_battery.c
-F: drivers/power/bq27xxx_battery_i2c.c
-F: drivers/power/isp1704_charger.c
-F: drivers/power/rx51_battery.c
+F: drivers/power/supply/bq2415x_charger.c
+F: drivers/power/supply/bq27xxx_battery.c
+F: drivers/power/supply/bq27xxx_battery_i2c.c
+F: drivers/power/supply/isp1704_charger.c
+F: drivers/power/supply/rx51_battery.c
NTB DRIVER CORE
M: Jon Mason <jdmason@kudzu.us>
F: include/linux/oprofile.h
ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
-M: Mark Fasheh <mfasheh@suse.com>
+M: Mark Fasheh <mfasheh@versity.com>
M: Joel Becker <jlbec@evilplan.org>
L: ocfs2-devel@oss.oracle.com (moderated for non-subscribers)
W: http://ocfs2.wiki.kernel.org
F: Documentation/virtual/paravirt_ops.txt
F: arch/*/kernel/paravirt*
F: arch/*/include/asm/paravirt.h
+F: include/linux/hypervisor.h
PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES
M: Tim Waugh <tim@cyberelk.net>
F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
F: drivers/pci/host/pcie-hisi.c
+ PCIE DRIVER FOR ROCKCHIP
+ M: Shawn Lin <shawn.lin@rock-chips.com>
+ M: Wenrui Li <wenrui.li@rock-chips.com>
+ L: linux-pci@vger.kernel.org
+ L: linux-rockchip@lists.infradead.org
+ S: Maintained
+ F: Documentation/devicetree/bindings/pci/rockchip-pcie.txt
+ F: drivers/pci/host/pcie-rockchip.c
+
PCIE DRIVER FOR QUALCOMM MSM
M: Stanimir Varbanov <svarbanov@mm-sol.com>
L: linux-pci@vger.kernel.org
PIN CONTROLLER - SAMSUNG
M: Tomasz Figa <tomasz.figa@gmail.com>
-M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
M: Sebastian Reichel <sre@kernel.org>
-M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
-M: David Woodhouse <dwmw2@infradead.org>
L: linux-pm@vger.kernel.org
-T: git git://git.infradead.org/battery-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git
S: Maintained
-F: Documentation/devicetree/bindings/power/
-F: Documentation/devicetree/bindings/power_supply/
+F: Documentation/devicetree/bindings/power/supply/
F: include/linux/power_supply.h
-F: drivers/power/
-X: drivers/power/avs/
+F: drivers/power/supply/
POWER STATE COORDINATION INTERFACE (PSCI)
M: Mark Rutland <mark.rutland@arm.com>
S: Supported
F: drivers/net/wireless/ath/ath10k/
+QUALCOMM EMAC GIGABIT ETHERNET DRIVER
+M: Timur Tabi <timur@codeaurora.org>
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/ethernet/qualcomm/emac/
+
QUALCOMM HEXAGON ARCHITECTURE
M: Richard Kuo <rkuo@codeaurora.org>
L: linux-hexagon@vger.kernel.org
F: Documentation/rpmsg.txt
F: include/linux/rpmsg.h
+RENESAS CLOCK DRIVERS
+M: Geert Uytterhoeven <geert+renesas@glider.be>
+L: linux-renesas-soc@vger.kernel.org
+S: Supported
+F: drivers/clk/renesas/
+
RENESAS ETHERNET DRIVERS
R: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
L: netdev@vger.kernel.org
RHASHTABLE
M: Thomas Graf <tgraf@suug.ch>
+M: Herbert Xu <herbert@gondor.apana.org.au>
L: netdev@vger.kernel.org
S: Maintained
F: lib/rhashtable.c
F: drivers/s390/cio/
S390 DASD DRIVER
-M: Stefan Weinhuber <wein@de.ibm.com>
-M: Stefan Haberland <stefan.haberland@de.ibm.com>
+M: Stefan Haberland <sth@linux.vnet.ibm.com>
+M: Jan Hoeppner <hoeppner@linux.vnet.ibm.com>
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
F: drivers/platform/x86/samsung-laptop.c
SAMSUNG AUDIO (ASoC) DRIVERS
-M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
M: Sangbeom Kim <sbkim73@samsung.com>
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS
M: Sangbeom Kim <sbkim73@samsung.com>
-M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
+M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-kernel@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org
S: Supported
SAMSUNG SOC CLOCK DRIVERS
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
M: Tomasz Figa <tomasz.figa@gmail.com>
+M: Chanwoo Choi <cw00.choi@samsung.com>
S: Supported
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
F: drivers/clk/samsung/
+F: include/dt-bindings/clock/exynos*.h
+F: Documentation/devicetree/bindings/clock/exynos*.txt
+
+SAMSUNG SPI DRIVERS
+M: Kukjin Kim <kgene@kernel.org>
+M: Krzysztof Kozlowski <krzk@kernel.org>
+M: Andi Shyti <andi.shyti@samsung.com>
+L: linux-spi@vger.kernel.org
+L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/spi/spi-samsung.txt
+F: drivers/spi/spi-s3c*
+F: include/linux/platform_data/spi-s3c64xx.h
SAMSUNG SXGBE DRIVERS
M: Byungho An <bh74.an@samsung.com>
TI BQ27XXX POWER SUPPLY DRIVER
R: Andrew F. Davis <afd@ti.com>
F: include/linux/power/bq27xxx_battery.h
-F: drivers/power/bq27xxx_battery.c
-F: drivers/power/bq27xxx_battery_i2c.c
+F: drivers/power/supply/bq27xxx_battery.c
+F: drivers/power/supply/bq27xxx_battery_i2c.c
TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
M: John Stultz <john.stultz@linaro.org>
F: drivers/misc/phantom.c
F: include/uapi/linux/phantom.h
-SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER
-M: Jayamohan Kallickal <jayamohan.kallickal@avagotech.com>
-M: Ketan Mukadam <ketan.mukadam@avagotech.com>
-M: John Soni Jose <sony.john@avagotech.com>
+Emulex 10Gbps iSCSI - OneConnect DRIVER
+M: Subbu Seetharaman <subbu.seetharaman@broadcom.com>
+M: Ketan Mukadam <ketan.mukadam@broadcom.com>
+M: Jitendra Bhivare <jitendra.bhivare@broadcom.com>
L: linux-scsi@vger.kernel.org
-W: http://www.avagotech.com
+W: http://www.broadcom.com
S: Supported
F: drivers/scsi/be2iscsi/
F: drivers/spi/
F: include/linux/spi/
F: include/uapi/linux/spi/
+F: tools/spi/
SPIDERNET NETWORK DRIVER for CELL
M: Ishizaki Kou <kou.ishizaki@toshiba.co.jp>
STAGING - LUSTRE PARALLEL FILESYSTEM
M: Oleg Drokin <oleg.drokin@intel.com>
M: Andreas Dilger <andreas.dilger@intel.com>
+M: James Simmons <jsimmons@infradead.org>
L: lustre-devel@lists.lustre.org (moderated for non-subscribers)
W: http://wiki.lustre.org/
S: Maintained
S: Odd Fixes
F: drivers/staging/rtl8712/
-STAGING - REALTEK RTL8723U WIRELESS DRIVER
-M: Larry Finger <Larry.Finger@lwfinger.net>
-M: Jes Sorensen <Jes.Sorensen@redhat.com>
-L: linux-wireless@vger.kernel.org
-S: Maintained
-F: drivers/staging/rtl8723au/
-
STAGING - SILICON MOTION SM750 FRAME BUFFER DRIVER
M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
M: Teddy Wang <teddy.wang@siliconmotion.com>
F: drivers/staging/vt665?/
STAGING - WILC1000 WIFI DRIVER
-M: Johnny Kim <johnny.kim@atmel.com>
-M: Austin Shin <austin.shin@atmel.com>
-M: Chris Park <chris.park@atmel.com>
-M: Tony Cho <tony.cho@atmel.com>
-M: Glen Lee <glen.lee@atmel.com>
-M: Leo Kim <leo.kim@atmel.com>
+M: Aditya Shankar <aditya.shankar@microchip.com>
+M: Ganesh Krishna <ganesh.krishna@microchip.com>
L: linux-wireless@vger.kernel.org
S: Supported
F: drivers/staging/wilc1000/
S: Supported
F: drivers/mfd/syscon.c
+SYSTEM RESET/SHUTDOWN DRIVERS
+M: Sebastian Reichel <sre@kernel.org>
+L: linux-pm@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git
+S: Maintained
+F: Documentation/devicetree/bindings/power/reset/
+F: drivers/power/reset/
+
SYSV FILESYSTEM
M: Christoph Hellwig <hch@infradead.org>
S: Maintained
THERMAL/CPU_COOLING
M: Amit Daniel Kachhap <amit.kachhap@gmail.com>
M: Viresh Kumar <viresh.kumar@linaro.org>
-M: Javi Merino <javi.merino@arm.com>
+M: Javi Merino <javi.merino@kernel.org>
L: linux-pm@vger.kernel.org
S: Supported
F: Documentation/thermal/cpu-cooling-api.txt
TI LP8727 CHARGER DRIVER
M: Milo Kim <milo.kim@ti.com>
S: Maintained
-F: drivers/power/lp8727_charger.c
+F: drivers/power/supply/lp8727_charger.c
F: include/linux/platform_data/lp8727.h
TI LP8788 MFD DRIVER
F: drivers/iio/adc/lp8788_adc.c
F: drivers/leds/leds-lp8788.c
F: drivers/mfd/lp8788*.c
-F: drivers/power/lp8788-charger.c
+F: drivers/power/supply/lp8788-charger.c
F: drivers/regulator/lp8788-*.c
F: include/linux/mfd/lp8788*.h
F: drivers/tc/
F: include/linux/tc.h
-U14-34F SCSI DRIVER
-M: Dario Ballabio <ballabio_dario@emc.com>
-L: linux-scsi@vger.kernel.org
-S: Maintained
-F: drivers/scsi/u14-34f.c
-
UBI FILE SYSTEM (UBIFS)
M: Richard Weinberger <richard@nod.at>
M: Artem Bityutskiy <dedekind1@gmail.com>
F: drivers/net/usb/lan78xx.*
USB MASS STORAGE DRIVER
-M: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
+M: Alan Stern <stern@rowland.harvard.edu>
L: linux-usb@vger.kernel.org
L: usb-storage@lists.one-eyed-alien.net
S: Maintained
USB SERIAL SUBSYSTEM
M: Johan Hovold <johan@kernel.org>
L: linux-usb@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git
S: Maintained
F: Documentation/usb/usb-serial.txt
F: drivers/usb/serial/
USB SMSC95XX ETHERNET DRIVER
M: Steve Glendinning <steve.glendinning@shawell.net>
+M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/usb/smsc95xx.*
F: fs/hppfs/
USERSPACE I/O (UIO)
-M: "Hans J. Koch" <hjk@hansjkoch.de>
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
F: net/8021q/
VLYNQ BUS
-M: Florian Fainelli <florian@openwrt.org>
+M: Florian Fainelli <f.fainelli@gmail.com>
L: openwrt-devel@lists.openwrt.org (subscribers-only)
S: Maintained
F: drivers/vlynq/vlynq.c
F: include/linux/watchdog.h
F: include/uapi/linux/watchdog.h
-WD7000 SCSI DRIVER
-M: Miroslav Zagorac <zaga@fly.cc.fer.hr>
-L: linux-scsi@vger.kernel.org
-S: Maintained
-F: drivers/scsi/wd7000.c
-
WIIMOTE HID DRIVER
M: David Herrmann <dh.herrmann@googlemail.com>
L: linux-input@vger.kernel.org
F: drivers/mfd/arizona*
F: drivers/mfd/wm*.c
F: drivers/mfd/cs47l24*
-F: drivers/power/wm83*.c
+F: drivers/power/supply/wm83*.c
F: drivers/rtc/rtc-wm83*.c
F: drivers/regulator/wm8*.c
F: drivers/video/backlight/wm83*_bl.c
F: drivers/xen/*swiotlb*
XFS FILESYSTEM
-P: Silicon Graphics Inc
M: Dave Chinner <david@fromorbit.com>
-M: xfs@oss.sgi.com
-L: xfs@oss.sgi.com
-W: http://oss.sgi.com/projects/xfs
+M: linux-xfs@vger.kernel.org
+L: linux-xfs@vger.kernel.org
+W: http://xfs.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git
S: Supported
F: Documentation/filesystems/xfs.txt
select ARCH_DISCARD_MEMBLOCK
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
- select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FAST_MULTIPLIER
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_AOUT if X86_32
select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_ARCH_HARDENED_USERCOPY
select HAVE_ARCH_HUGE_VMAP if X86_64 || X86_PAE
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_KASAN if X86_64 && SPARSEMEM_VMEMMAP
select HAVE_ARCH_SOFT_DIRTY if X86_64
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
+ select HAVE_ARCH_WITHIN_STACK_FRAMES
select HAVE_EBPF_JIT if X86_64
+ select HAVE_ARCH_VMAP_STACK if X86_64
select HAVE_CC_STACKPROTECTOR
select HAVE_CMPXCHG_DOUBLE
select HAVE_CMPXCHG_LOCAL
select HAVE_EXIT_THREAD
select HAVE_FENTRY if X86_64
select HAVE_FTRACE_MCOUNT_RECORD
- select HAVE_FUNCTION_GRAPH_FP_TEST
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
select HAVE_GCC_PLUGINS
select SPARSE_IRQ
select SRCU
select SYSCTL_EXCEPTION_TRACE
+ select THREAD_INFO_IN_TASK
select USER_STACKTRACE_SUPPORT
select VIRT_TO_BUS
select X86_DEV_DMA_OPS if X86_64
Say Y here if you have a Quark based system such as the Arduino
compatible Intel Galileo.
+config MLX_PLATFORM
+ tristate "Mellanox Technologies platform support"
+ depends on X86_64
+ depends on X86_EXTENDED_PLATFORM
+ ---help---
+ This option enables system support for the Mellanox Technologies
+ platform.
+
+ Say Y here if you are building a kernel for Mellanox system.
+
+ Otherwise, say N.
+
config X86_INTEL_LPSS
bool "Intel Low Power Subsystem Support"
depends on X86 && ACPI
config PARAVIRT_SPINLOCKS
bool "Paravirtualization layer for spinlocks"
depends on PARAVIRT && SMP
- select UNINLINE_SPIN_UNLOCK if !QUEUED_SPINLOCKS
---help---
Paravirtualized spinlocks allow a pvops backend to replace the
spinlock implementation with something virtualization-friendly
config QUEUED_LOCK_STAT
bool "Paravirt queued spinlock statistics"
- depends on PARAVIRT_SPINLOCKS && DEBUG_FS && QUEUED_SPINLOCKS
+ depends on PARAVIRT_SPINLOCKS && DEBUG_FS
---help---
Enable the collection of statistical data on the slowpath
behavior of paravirtualized queued spinlocks and report
def_bool y
depends on PCI
- config VMD
- depends on PCI_MSI
- tristate "Volume Management Device Driver"
- default N
- ---help---
- Adds support for the Intel Volume Management Device (VMD). VMD is a
- secondary PCI host bridge that allows PCI Express root ports,
- and devices attached to them, to be removed from the default
- PCI domain and placed within the VMD domain. This provides
- more bus resources than are otherwise possible with a
- single domain. If you know your system provides one of these and
- has devices attached to it, say Y; if you are not sure, say N.
-
source "net/Kconfig"
source "drivers/Kconfig"
--- /dev/null
- list_del_rcu(&vmdirq->node);
- INIT_LIST_HEAD_RCU(&vmdirq->node);
+ /*
+ * Volume Management Device driver
+ * Copyright (c) 2015, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+ #include <linux/device.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/msi.h>
+ #include <linux/pci.h>
+ #include <linux/rculist.h>
+ #include <linux/rcupdate.h>
+
+ #include <asm/irqdomain.h>
+ #include <asm/device.h>
+ #include <asm/msi.h>
+ #include <asm/msidef.h>
+
+ #define VMD_CFGBAR 0
+ #define VMD_MEMBAR1 2
+ #define VMD_MEMBAR2 4
+
+ /*
+ * Lock for manipulating VMD IRQ lists.
+ */
+ static DEFINE_RAW_SPINLOCK(list_lock);
+
+ /**
+ * struct vmd_irq - private data to map driver IRQ to the VMD shared vector
+ * @node: list item for parent traversal.
+ * @rcu: RCU callback item for freeing.
+ * @irq: back pointer to parent.
++ * @enabled: true if driver enabled IRQ
+ * @virq: the virtual IRQ value provided to the requesting driver.
+ *
+ * Every MSI/MSI-X IRQ requested for a device in a VMD domain will be mapped to
+ * a VMD IRQ using this structure.
+ */
+ struct vmd_irq {
+ struct list_head node;
+ struct rcu_head rcu;
+ struct vmd_irq_list *irq;
++ bool enabled;
+ unsigned int virq;
+ };
+
+ /**
+ * struct vmd_irq_list - list of driver requested IRQs mapping to a VMD vector
+ * @irq_list: the list of irq's the VMD one demuxes to.
+ * @count: number of child IRQs assigned to this vector; used to track
+ * sharing.
+ */
+ struct vmd_irq_list {
+ struct list_head irq_list;
+ unsigned int count;
+ };
+
+ struct vmd_dev {
+ struct pci_dev *dev;
+
+ spinlock_t cfg_lock;
+ char __iomem *cfgbar;
+
+ int msix_count;
+ struct vmd_irq_list *irqs;
+
+ struct pci_sysdata sysdata;
+ struct resource resources[3];
+ struct irq_domain *irq_domain;
+ struct pci_bus *bus;
+
+ #ifdef CONFIG_X86_DEV_DMA_OPS
+ struct dma_map_ops dma_ops;
+ struct dma_domain dma_domain;
+ #endif
+ };
+
+ static inline struct vmd_dev *vmd_from_bus(struct pci_bus *bus)
+ {
+ return container_of(bus->sysdata, struct vmd_dev, sysdata);
+ }
+
+ static inline unsigned int index_from_irqs(struct vmd_dev *vmd,
+ struct vmd_irq_list *irqs)
+ {
+ return irqs - vmd->irqs;
+ }
+
+ /*
+ * Drivers managing a device in a VMD domain allocate their own IRQs as before,
+ * but the MSI entry for the hardware it's driving will be programmed with a
+ * destination ID for the VMD MSI-X table. The VMD muxes interrupts in its
+ * domain into one of its own, and the VMD driver de-muxes these for the
+ * handlers sharing that VMD IRQ. The vmd irq_domain provides the operations
+ * and irq_chip to set this up.
+ */
+ static void vmd_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ {
+ struct vmd_irq *vmdirq = data->chip_data;
+ struct vmd_irq_list *irq = vmdirq->irq;
+ struct vmd_dev *vmd = irq_data_get_irq_handler_data(data);
+
+ msg->address_hi = MSI_ADDR_BASE_HI;
+ msg->address_lo = MSI_ADDR_BASE_LO |
+ MSI_ADDR_DEST_ID(index_from_irqs(vmd, irq));
+ msg->data = 0;
+ }
+
+ /*
+ * We rely on MSI_FLAG_USE_DEF_CHIP_OPS to set the IRQ mask/unmask ops.
+ */
+ static void vmd_irq_enable(struct irq_data *data)
+ {
+ struct vmd_irq *vmdirq = data->chip_data;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&list_lock, flags);
++ WARN_ON(vmdirq->enabled);
+ list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list);
++ vmdirq->enabled = true;
+ raw_spin_unlock_irqrestore(&list_lock, flags);
+
+ data->chip->irq_unmask(data);
+ }
+
+ static void vmd_irq_disable(struct irq_data *data)
+ {
+ struct vmd_irq *vmdirq = data->chip_data;
+ unsigned long flags;
+
+ data->chip->irq_mask(data);
+
+ raw_spin_lock_irqsave(&list_lock, flags);
++ if (vmdirq->enabled) {
++ list_del_rcu(&vmdirq->node);
++ vmdirq->enabled = false;
++ }
+ raw_spin_unlock_irqrestore(&list_lock, flags);
+ }
+
+ /*
+ * XXX: Stubbed until we develop acceptable way to not create conflicts with
+ * other devices sharing the same vector.
+ */
+ static int vmd_irq_set_affinity(struct irq_data *data,
+ const struct cpumask *dest, bool force)
+ {
+ return -EINVAL;
+ }
+
+ static struct irq_chip vmd_msi_controller = {
+ .name = "VMD-MSI",
+ .irq_enable = vmd_irq_enable,
+ .irq_disable = vmd_irq_disable,
+ .irq_compose_msi_msg = vmd_compose_msi_msg,
+ .irq_set_affinity = vmd_irq_set_affinity,
+ };
+
+ static irq_hw_number_t vmd_get_hwirq(struct msi_domain_info *info,
+ msi_alloc_info_t *arg)
+ {
+ return 0;
+ }
+
+ /*
+ * XXX: We can be even smarter selecting the best IRQ once we solve the
+ * affinity problem.
+ */
+ static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd, struct msi_desc *desc)
+ {
+ int i, best = 1;
+ unsigned long flags;
+
+ if (!desc->msi_attrib.is_msix || vmd->msix_count == 1)
+ return &vmd->irqs[0];
+
+ raw_spin_lock_irqsave(&list_lock, flags);
+ for (i = 1; i < vmd->msix_count; i++)
+ if (vmd->irqs[i].count < vmd->irqs[best].count)
+ best = i;
+ vmd->irqs[best].count++;
+ raw_spin_unlock_irqrestore(&list_lock, flags);
+
+ return &vmd->irqs[best];
+ }
+
+ static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info,
+ unsigned int virq, irq_hw_number_t hwirq,
+ msi_alloc_info_t *arg)
+ {
+ struct msi_desc *desc = arg->desc;
+ struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(desc)->bus);
+ struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL);
+ unsigned int index, vector;
+
+ if (!vmdirq)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&vmdirq->node);
+ vmdirq->irq = vmd_next_irq(vmd, desc);
+ vmdirq->virq = virq;
+ index = index_from_irqs(vmd, vmdirq->irq);
+ vector = pci_irq_vector(vmd->dev, index);
+
+ irq_domain_set_info(domain, virq, vector, info->chip, vmdirq,
+ handle_untracked_irq, vmd, NULL);
+ return 0;
+ }
+
+ static void vmd_msi_free(struct irq_domain *domain,
+ struct msi_domain_info *info, unsigned int virq)
+ {
+ struct vmd_irq *vmdirq = irq_get_chip_data(virq);
+ unsigned long flags;
+
+ synchronize_rcu();
+
+ /* XXX: Potential optimization to rebalance */
+ raw_spin_lock_irqsave(&list_lock, flags);
+ vmdirq->irq->count--;
+ raw_spin_unlock_irqrestore(&list_lock, flags);
+
+ kfree_rcu(vmdirq, rcu);
+ }
+
+ static int vmd_msi_prepare(struct irq_domain *domain, struct device *dev,
+ int nvec, msi_alloc_info_t *arg)
+ {
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct vmd_dev *vmd = vmd_from_bus(pdev->bus);
+
+ if (nvec > vmd->msix_count)
+ return vmd->msix_count;
+
+ memset(arg, 0, sizeof(*arg));
+ return 0;
+ }
+
+ static void vmd_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+ {
+ arg->desc = desc;
+ }
+
+ static struct msi_domain_ops vmd_msi_domain_ops = {
+ .get_hwirq = vmd_get_hwirq,
+ .msi_init = vmd_msi_init,
+ .msi_free = vmd_msi_free,
+ .msi_prepare = vmd_msi_prepare,
+ .set_desc = vmd_set_desc,
+ };
+
+ static struct msi_domain_info vmd_msi_domain_info = {
+ .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+ MSI_FLAG_PCI_MSIX,
+ .ops = &vmd_msi_domain_ops,
+ .chip = &vmd_msi_controller,
+ };
+
+ #ifdef CONFIG_X86_DEV_DMA_OPS
+ /*
+ * VMD replaces the requester ID with its own. DMA mappings for devices in a
+ * VMD domain need to be mapped for the VMD, not the device requiring
+ * the mapping.
+ */
+ static struct device *to_vmd_dev(struct device *dev)
+ {
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct vmd_dev *vmd = vmd_from_bus(pdev->bus);
+
+ return &vmd->dev->dev;
+ }
+
+ static struct dma_map_ops *vmd_dma_ops(struct device *dev)
+ {
+ return get_dma_ops(to_vmd_dev(dev));
+ }
+
+ static void *vmd_alloc(struct device *dev, size_t size, dma_addr_t *addr,
+ gfp_t flag, unsigned long attrs)
+ {
+ return vmd_dma_ops(dev)->alloc(to_vmd_dev(dev), size, addr, flag,
+ attrs);
+ }
+
+ static void vmd_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t addr, unsigned long attrs)
+ {
+ return vmd_dma_ops(dev)->free(to_vmd_dev(dev), size, vaddr, addr,
+ attrs);
+ }
+
+ static int vmd_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t addr, size_t size,
+ unsigned long attrs)
+ {
+ return vmd_dma_ops(dev)->mmap(to_vmd_dev(dev), vma, cpu_addr, addr,
+ size, attrs);
+ }
+
+ static int vmd_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t addr, size_t size,
+ unsigned long attrs)
+ {
+ return vmd_dma_ops(dev)->get_sgtable(to_vmd_dev(dev), sgt, cpu_addr,
+ addr, size, attrs);
+ }
+
+ static dma_addr_t vmd_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ unsigned long attrs)
+ {
+ return vmd_dma_ops(dev)->map_page(to_vmd_dev(dev), page, offset, size,
+ dir, attrs);
+ }
+
+ static void vmd_unmap_page(struct device *dev, dma_addr_t addr, size_t size,
+ enum dma_data_direction dir, unsigned long attrs)
+ {
+ vmd_dma_ops(dev)->unmap_page(to_vmd_dev(dev), addr, size, dir, attrs);
+ }
+
+ static int vmd_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, unsigned long attrs)
+ {
+ return vmd_dma_ops(dev)->map_sg(to_vmd_dev(dev), sg, nents, dir, attrs);
+ }
+
+ static void vmd_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, unsigned long attrs)
+ {
+ vmd_dma_ops(dev)->unmap_sg(to_vmd_dev(dev), sg, nents, dir, attrs);
+ }
+
+ static void vmd_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir)
+ {
+ vmd_dma_ops(dev)->sync_single_for_cpu(to_vmd_dev(dev), addr, size, dir);
+ }
+
+ static void vmd_sync_single_for_device(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir)
+ {
+ vmd_dma_ops(dev)->sync_single_for_device(to_vmd_dev(dev), addr, size,
+ dir);
+ }
+
+ static void vmd_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+ {
+ vmd_dma_ops(dev)->sync_sg_for_cpu(to_vmd_dev(dev), sg, nents, dir);
+ }
+
+ static void vmd_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+ {
+ vmd_dma_ops(dev)->sync_sg_for_device(to_vmd_dev(dev), sg, nents, dir);
+ }
+
+ static int vmd_mapping_error(struct device *dev, dma_addr_t addr)
+ {
+ return vmd_dma_ops(dev)->mapping_error(to_vmd_dev(dev), addr);
+ }
+
+ static int vmd_dma_supported(struct device *dev, u64 mask)
+ {
+ return vmd_dma_ops(dev)->dma_supported(to_vmd_dev(dev), mask);
+ }
+
+ #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
+ static u64 vmd_get_required_mask(struct device *dev)
+ {
+ return vmd_dma_ops(dev)->get_required_mask(to_vmd_dev(dev));
+ }
+ #endif
+
+ static void vmd_teardown_dma_ops(struct vmd_dev *vmd)
+ {
+ struct dma_domain *domain = &vmd->dma_domain;
+
+ if (get_dma_ops(&vmd->dev->dev))
+ del_dma_domain(domain);
+ }
+
+ #define ASSIGN_VMD_DMA_OPS(source, dest, fn) \
+ do { \
+ if (source->fn) \
+ dest->fn = vmd_##fn; \
+ } while (0)
+
+ static void vmd_setup_dma_ops(struct vmd_dev *vmd)
+ {
+ const struct dma_map_ops *source = get_dma_ops(&vmd->dev->dev);
+ struct dma_map_ops *dest = &vmd->dma_ops;
+ struct dma_domain *domain = &vmd->dma_domain;
+
+ domain->domain_nr = vmd->sysdata.domain;
+ domain->dma_ops = dest;
+
+ if (!source)
+ return;
+ ASSIGN_VMD_DMA_OPS(source, dest, alloc);
+ ASSIGN_VMD_DMA_OPS(source, dest, free);
+ ASSIGN_VMD_DMA_OPS(source, dest, mmap);
+ ASSIGN_VMD_DMA_OPS(source, dest, get_sgtable);
+ ASSIGN_VMD_DMA_OPS(source, dest, map_page);
+ ASSIGN_VMD_DMA_OPS(source, dest, unmap_page);
+ ASSIGN_VMD_DMA_OPS(source, dest, map_sg);
+ ASSIGN_VMD_DMA_OPS(source, dest, unmap_sg);
+ ASSIGN_VMD_DMA_OPS(source, dest, sync_single_for_cpu);
+ ASSIGN_VMD_DMA_OPS(source, dest, sync_single_for_device);
+ ASSIGN_VMD_DMA_OPS(source, dest, sync_sg_for_cpu);
+ ASSIGN_VMD_DMA_OPS(source, dest, sync_sg_for_device);
+ ASSIGN_VMD_DMA_OPS(source, dest, mapping_error);
+ ASSIGN_VMD_DMA_OPS(source, dest, dma_supported);
+ #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
+ ASSIGN_VMD_DMA_OPS(source, dest, get_required_mask);
+ #endif
+ add_dma_domain(domain);
+ }
+ #undef ASSIGN_VMD_DMA_OPS
+ #else
+ static void vmd_teardown_dma_ops(struct vmd_dev *vmd) {}
+ static void vmd_setup_dma_ops(struct vmd_dev *vmd) {}
+ #endif
+
+ static char __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus,
+ unsigned int devfn, int reg, int len)
+ {
+ char __iomem *addr = vmd->cfgbar +
+ (bus->number << 20) + (devfn << 12) + reg;
+
+ if ((addr - vmd->cfgbar) + len >=
+ resource_size(&vmd->dev->resource[VMD_CFGBAR]))
+ return NULL;
+
+ return addr;
+ }
+
+ /*
+ * CPU may deadlock if config space is not serialized on some versions of this
+ * hardware, so all config space access is done under a spinlock.
+ */
+ static int vmd_pci_read(struct pci_bus *bus, unsigned int devfn, int reg,
+ int len, u32 *value)
+ {
+ struct vmd_dev *vmd = vmd_from_bus(bus);
+ char __iomem *addr = vmd_cfg_addr(vmd, bus, devfn, reg, len);
+ unsigned long flags;
+ int ret = 0;
+
+ if (!addr)
+ return -EFAULT;
+
+ spin_lock_irqsave(&vmd->cfg_lock, flags);
+ switch (len) {
+ case 1:
+ *value = readb(addr);
+ break;
+ case 2:
+ *value = readw(addr);
+ break;
+ case 4:
+ *value = readl(addr);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ spin_unlock_irqrestore(&vmd->cfg_lock, flags);
+ return ret;
+ }
+
+ /*
+ * VMD h/w converts non-posted config writes to posted memory writes. The
+ * read-back in this function forces the completion so it returns only after
+ * the config space was written, as expected.
+ */
+ static int vmd_pci_write(struct pci_bus *bus, unsigned int devfn, int reg,
+ int len, u32 value)
+ {
+ struct vmd_dev *vmd = vmd_from_bus(bus);
+ char __iomem *addr = vmd_cfg_addr(vmd, bus, devfn, reg, len);
+ unsigned long flags;
+ int ret = 0;
+
+ if (!addr)
+ return -EFAULT;
+
+ spin_lock_irqsave(&vmd->cfg_lock, flags);
+ switch (len) {
+ case 1:
+ writeb(value, addr);
+ readb(addr);
+ break;
+ case 2:
+ writew(value, addr);
+ readw(addr);
+ break;
+ case 4:
+ writel(value, addr);
+ readl(addr);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ spin_unlock_irqrestore(&vmd->cfg_lock, flags);
+ return ret;
+ }
+
+ static struct pci_ops vmd_ops = {
+ .read = vmd_pci_read,
+ .write = vmd_pci_write,
+ };
+
+ static void vmd_attach_resources(struct vmd_dev *vmd)
+ {
+ vmd->dev->resource[VMD_MEMBAR1].child = &vmd->resources[1];
+ vmd->dev->resource[VMD_MEMBAR2].child = &vmd->resources[2];
+ }
+
+ static void vmd_detach_resources(struct vmd_dev *vmd)
+ {
+ vmd->dev->resource[VMD_MEMBAR1].child = NULL;
+ vmd->dev->resource[VMD_MEMBAR2].child = NULL;
+ }
+
+ /*
+ * VMD domains start at 0x1000 to not clash with ACPI _SEG domains.
+ */
+ static int vmd_find_free_domain(void)
+ {
+ int domain = 0xffff;
+ struct pci_bus *bus = NULL;
+
+ while ((bus = pci_find_next_bus(bus)) != NULL)
+ domain = max_t(int, domain, pci_domain_nr(bus));
+ return domain + 1;
+ }
+
+ static int vmd_enable_domain(struct vmd_dev *vmd)
+ {
+ struct pci_sysdata *sd = &vmd->sysdata;
+ struct resource *res;
+ u32 upper_bits;
+ unsigned long flags;
+ LIST_HEAD(resources);
+
+ res = &vmd->dev->resource[VMD_CFGBAR];
+ vmd->resources[0] = (struct resource) {
+ .name = "VMD CFGBAR",
+ .start = 0,
+ .end = (resource_size(res) >> 20) - 1,
+ .flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED,
+ };
+
+ /*
+ * If the window is below 4GB, clear IORESOURCE_MEM_64 so we can
+ * put 32-bit resources in the window.
+ *
+ * There's no hardware reason why a 64-bit window *couldn't*
+ * contain a 32-bit resource, but pbus_size_mem() computes the
+ * bridge window size assuming a 64-bit window will contain no
+ * 32-bit resources. __pci_assign_resource() enforces that
+ * artificial restriction to make sure everything will fit.
+ *
+ * The only way we could use a 64-bit non-prefechable MEMBAR is
+ * if its address is <4GB so that we can convert it to a 32-bit
+ * resource. To be visible to the host OS, all VMD endpoints must
+ * be initially configured by platform BIOS, which includes setting
+ * up these resources. We can assume the device is configured
+ * according to the platform needs.
+ */
+ res = &vmd->dev->resource[VMD_MEMBAR1];
+ upper_bits = upper_32_bits(res->end);
+ flags = res->flags & ~IORESOURCE_SIZEALIGN;
+ if (!upper_bits)
+ flags &= ~IORESOURCE_MEM_64;
+ vmd->resources[1] = (struct resource) {
+ .name = "VMD MEMBAR1",
+ .start = res->start,
+ .end = res->end,
+ .flags = flags,
+ .parent = res,
+ };
+
+ res = &vmd->dev->resource[VMD_MEMBAR2];
+ upper_bits = upper_32_bits(res->end);
+ flags = res->flags & ~IORESOURCE_SIZEALIGN;
+ if (!upper_bits)
+ flags &= ~IORESOURCE_MEM_64;
+ vmd->resources[2] = (struct resource) {
+ .name = "VMD MEMBAR2",
+ .start = res->start + 0x2000,
+ .end = res->end,
+ .flags = flags,
+ .parent = res,
+ };
+
+ sd->vmd_domain = true;
+ sd->domain = vmd_find_free_domain();
+ if (sd->domain < 0)
+ return sd->domain;
+
+ sd->node = pcibus_to_node(vmd->dev->bus);
+
+ vmd->irq_domain = pci_msi_create_irq_domain(NULL, &vmd_msi_domain_info,
+ x86_vector_domain);
+ if (!vmd->irq_domain)
+ return -ENODEV;
+
+ pci_add_resource(&resources, &vmd->resources[0]);
+ pci_add_resource(&resources, &vmd->resources[1]);
+ pci_add_resource(&resources, &vmd->resources[2]);
+ vmd->bus = pci_create_root_bus(&vmd->dev->dev, 0, &vmd_ops, sd,
+ &resources);
+ if (!vmd->bus) {
+ pci_free_resource_list(&resources);
+ irq_domain_remove(vmd->irq_domain);
+ return -ENODEV;
+ }
+
+ vmd_attach_resources(vmd);
+ vmd_setup_dma_ops(vmd);
+ dev_set_msi_domain(&vmd->bus->dev, vmd->irq_domain);
+ pci_rescan_bus(vmd->bus);
+
+ WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj,
+ "domain"), "Can't create symlink to domain\n");
+ return 0;
+ }
+
+ static irqreturn_t vmd_irq(int irq, void *data)
+ {
+ struct vmd_irq_list *irqs = data;
+ struct vmd_irq *vmdirq;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(vmdirq, &irqs->irq_list, node)
+ generic_handle_irq(vmdirq->virq);
+ rcu_read_unlock();
+
+ return IRQ_HANDLED;
+ }
+
+ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ {
+ struct vmd_dev *vmd;
+ int i, err;
+
+ if (resource_size(&dev->resource[VMD_CFGBAR]) < (1 << 20))
+ return -ENOMEM;
+
+ vmd = devm_kzalloc(&dev->dev, sizeof(*vmd), GFP_KERNEL);
+ if (!vmd)
+ return -ENOMEM;
+
+ vmd->dev = dev;
+ err = pcim_enable_device(dev);
+ if (err < 0)
+ return err;
+
+ vmd->cfgbar = pcim_iomap(dev, VMD_CFGBAR, 0);
+ if (!vmd->cfgbar)
+ return -ENOMEM;
+
+ pci_set_master(dev);
+ if (dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(64)) &&
+ dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)))
+ return -ENODEV;
+
+ vmd->msix_count = pci_msix_vec_count(dev);
+ if (vmd->msix_count < 0)
+ return -ENODEV;
+
+ vmd->msix_count = pci_alloc_irq_vectors(dev, 1, vmd->msix_count,
+ PCI_IRQ_MSIX | PCI_IRQ_AFFINITY);
+ if (vmd->msix_count < 0)
+ return vmd->msix_count;
+
+ vmd->irqs = devm_kcalloc(&dev->dev, vmd->msix_count, sizeof(*vmd->irqs),
+ GFP_KERNEL);
+ if (!vmd->irqs)
+ return -ENOMEM;
+
+ for (i = 0; i < vmd->msix_count; i++) {
+ INIT_LIST_HEAD(&vmd->irqs[i].irq_list);
+ err = devm_request_irq(&dev->dev, pci_irq_vector(dev, i),
+ vmd_irq, 0, "vmd", &vmd->irqs[i]);
+ if (err)
+ return err;
+ }
+
+ spin_lock_init(&vmd->cfg_lock);
+ pci_set_drvdata(dev, vmd);
+ err = vmd_enable_domain(vmd);
+ if (err)
+ return err;
+
+ dev_info(&vmd->dev->dev, "Bound to PCI domain %04x\n",
+ vmd->sysdata.domain);
+ return 0;
+ }
+
+ static void vmd_remove(struct pci_dev *dev)
+ {
+ struct vmd_dev *vmd = pci_get_drvdata(dev);
+
+ vmd_detach_resources(vmd);
+ pci_set_drvdata(dev, NULL);
+ sysfs_remove_link(&vmd->dev->dev.kobj, "domain");
+ pci_stop_root_bus(vmd->bus);
+ pci_remove_root_bus(vmd->bus);
+ vmd_teardown_dma_ops(vmd);
+ irq_domain_remove(vmd->irq_domain);
+ }
+
+ #ifdef CONFIG_PM
+ static int vmd_suspend(struct device *dev)
+ {
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ pci_save_state(pdev);
+ return 0;
+ }
+
+ static int vmd_resume(struct device *dev)
+ {
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ pci_restore_state(pdev);
+ return 0;
+ }
+ #endif
+ static SIMPLE_DEV_PM_OPS(vmd_dev_pm_ops, vmd_suspend, vmd_resume);
+
+ static const struct pci_device_id vmd_ids[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x201d),},
+ {0,}
+ };
+ MODULE_DEVICE_TABLE(pci, vmd_ids);
+
+ static struct pci_driver vmd_drv = {
+ .name = "vmd",
+ .id_table = vmd_ids,
+ .probe = vmd_probe,
+ .remove = vmd_remove,
+ .driver = {
+ .pm = &vmd_dev_pm_ops,
+ },
+ };
+ module_pci_driver(vmd_drv);
+
+ MODULE_AUTHOR("Intel Corporation");
+ MODULE_LICENSE("GPL v2");
+ MODULE_VERSION("0.6");
}
EXPORT_SYMBOL(pci_find_parent_resource);
+/**
+ * pci_find_resource - Return matching PCI device resource
+ * @dev: PCI device to query
+ * @res: Resource to look for
+ *
+ * Goes over standard PCI resources (BARs) and checks if the given resource
+ * is partially or fully contained in any of them. In that case the
+ * matching resource is returned, %NULL otherwise.
+ */
+struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res)
+{
+ int i;
+
+ for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+ struct resource *r = &dev->resource[i];
+
+ if (r->start && resource_contains(r, res))
+ return r;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(pci_find_resource);
+
/**
* pci_find_pcie_root_port - return PCIe Root Port
* @dev: PCI device to query
int pci_set_platform_pm(const struct pci_platform_pm_ops *ops)
{
- if (!ops->is_manageable || !ops->set_state || !ops->choose_state ||
- !ops->sleep_wake || !ops->run_wake || !ops->need_resume)
+ if (!ops->is_manageable || !ops->set_state || !ops->get_state ||
+ !ops->choose_state || !ops->sleep_wake || !ops->run_wake ||
+ !ops->need_resume)
return -EINVAL;
pci_platform_pm = ops;
return 0;
return pci_platform_pm ? pci_platform_pm->set_state(dev, t) : -ENOSYS;
}
+ static inline pci_power_t platform_pci_get_power_state(struct pci_dev *dev)
+ {
+ return pci_platform_pm ? pci_platform_pm->get_state(dev) : PCI_UNKNOWN;
+ }
+
static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev)
{
return pci_platform_pm ?
}
/**
- * pci_update_current_state - Read PCI power state of given device from its
- * PCI PM registers and cache it
+ * pci_update_current_state - Read power state of given device and cache it
* @dev: PCI device to handle.
* @state: State to cache in case the device doesn't have the PM capability
+ *
+ * The power state is read from the PMCSR register, which however is
+ * inaccessible in D3cold. The platform firmware is therefore queried first
+ * to detect accessibility of the register. In case the platform firmware
+ * reports an incorrect state or the device isn't power manageable by the
+ * platform at all, we try to detect D3cold by testing accessibility of the
+ * vendor ID in config space.
*/
void pci_update_current_state(struct pci_dev *dev, pci_power_t state)
{
- if (dev->pm_cap) {
+ if (platform_pci_get_power_state(dev) == PCI_D3cold ||
+ !pci_device_is_present(dev)) {
+ dev->current_state = PCI_D3cold;
+ } else if (dev->pm_cap) {
u16 pmcsr;
- /*
- * Configuration space is not accessible for device in
- * D3cold, so just keep or set D3cold for safety
- */
- if (dev->current_state == PCI_D3cold)
- return;
- if (state == PCI_D3cold) {
- dev->current_state = PCI_D3cold;
- return;
- }
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
} else {
default:
target_state = state;
}
- } else if (!dev->pm_cap) {
+
+ return target_state;
+ }
+
+ if (!dev->pm_cap)
target_state = PCI_D0;
- } else if (device_may_wakeup(&dev->dev)) {
+
+ /*
+ * If the device is in D3cold even though it's not power-manageable by
+ * the platform, it may have been powered down by non-standard means.
+ * Best to let it slumber.
+ */
+ if (dev->current_state == PCI_D3cold)
+ target_state = PCI_D3cold;
+
+ if (device_may_wakeup(&dev->dev)) {
/*
* Find the deepest state from which the device can generate
* wake-up events, make it the target state and enable device
spin_lock(&resource_alignment_lock);
p = resource_alignment_param;
+ if (!*p)
+ goto out;
+ if (pci_has_flag(PCI_PROBE_ONLY)) {
+ pr_info_once("PCI: Ignoring requested alignments (PCI_PROBE_ONLY)\n");
+ goto out;
+ }
+
while (*p) {
count = 0;
if (sscanf(p, "%d%n", &align_order, &count) == 1 &&
}
p++;
}
+ out:
spin_unlock(&resource_alignment_lock);
return align;
}
resource_size_t align, size;
u16 command;
+ /*
+ * VF BARs are read-only zero according to SR-IOV spec r1.1, sec
+ * 3.4.1.11. Their resources are allocated from the space
+ * described by the VF BARx register in the PF's SR-IOV capability.
+ * We can't influence their alignment here.
+ */
+ if (dev->is_virtfn)
+ return;
+
/* check if specified PCI is target device to reassign */
align = pci_specified_resource_alignment(dev);
if (!align)
r = &dev->resource[i];
if (!(r->flags & IORESOURCE_MEM))
continue;
+ if (r->flags & IORESOURCE_PCI_FIXED) {
+ dev_info(&dev->dev, "Ignoring requested alignment for BAR%d: %pR\n",
+ i, r);
+ continue;
+ }
+
size = resource_size(r);
if (size < align) {
size = align;
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset);
static void quirk_no_pm_reset(struct pci_dev *dev)
{
if (nhi->vendor != PCI_VENDOR_ID_INTEL
|| (nhi->device != PCI_DEVICE_ID_INTEL_LIGHT_RIDGE &&
nhi->device != PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C &&
+ nhi->device != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI &&
nhi->device != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI)
- || nhi->subsystem_vendor != 0x2222
- || nhi->subsystem_device != 0x1111)
+ || nhi->class != PCI_CLASS_SYSTEM_OTHER << 8)
goto out;
dev_info(&dev->dev, "quirk: waiting for thunderbolt to reestablish PCI tunnels...\n");
device_pm_wait_for_dev(&dev->dev, &nhi->dev);
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C,
quirk_apple_wait_for_thunderbolt);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE,
+ quirk_apple_wait_for_thunderbolt);
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE,
quirk_apple_wait_for_thunderbolt);
}
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap);
+
+ /*
+ * VMD-enabled root ports will change the source ID for all messages
+ * to the VMD device. Rather than doing device matching with the source
+ * ID, the AER driver should traverse the child device tree, reading
+ * AER registers to find the faulting device.
+ */
+ static void quirk_no_aersid(struct pci_dev *pdev)
+ {
+ /* VMD Domain */
+ if (pdev->bus->sysdata && pci_domain_nr(pdev->bus) >= 0x10000)
+ pdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_AERSID;
+ }
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid);
typedef unsigned short __bitwise pci_bus_flags_t;
enum pci_bus_flags {
- PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
- PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,
+ PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
+ PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,
+ PCI_BUS_FLAGS_NO_AERSID = (__force pci_bus_flags_t) 4,
};
/* These values come from the PCI Express Spec */
unsigned int class; /* 3 bytes: (base,sub,prog-if) */
u8 revision; /* PCI revision, low byte of class word */
u8 hdr_type; /* PCI header type (`multi' flag masked out) */
+ #ifdef CONFIG_PCIEAER
+ u16 aer_cap; /* AER capability offset */
+ #endif
u8 pcie_cap; /* PCIe capability offset */
u8 msi_cap; /* MSI capability offset */
u8 msix_cap; /* MSI-X capability offset */
powered on/off by the
corresponding bridge */
unsigned int ignore_hotplug:1; /* Ignore hotplug events */
+ unsigned int hotplug_user_indicators:1; /* SlotCtl indicators
+ controlled exclusively by
+ user sysfs */
unsigned int d3_delay; /* D3->D0 transition time in ms */
unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */
int rom_attr_enabled; /* has display of the rom attribute been enabled? */
struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
+
+ #ifdef CONFIG_PCIE_PTM
+ unsigned int ptm_root:1;
+ unsigned int ptm_enabled:1;
+ u8 ptm_granularity;
+ #endif
#ifdef CONFIG_PCI_MSI
const struct attribute_group **msi_irq_groups;
#endif
#define to_pci_driver(drv) container_of(drv, struct pci_driver, driver)
-/**
- * DEFINE_PCI_DEVICE_TABLE - macro used to describe a pci device table
- * @_table: device table name
- *
- * This macro is deprecated and should not be used in new code.
- */
-#define DEFINE_PCI_DEVICE_TABLE(_table) \
- const struct pci_device_id _table[]
-
/**
* PCI_DEVICE - macro used to describe a specific pci device
* @vend: the 16 bit PCI Vendor ID
int pci_enable_resources(struct pci_dev *, int mask);
void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
int (*)(const struct pci_dev *, u8, u8));
+struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res);
#define HAVE_PCI_REQ_REGIONS 2
int __must_check pci_request_regions(struct pci_dev *, const char *);
int __must_check pci_request_regions_exclusive(struct pci_dev *, const char *);
unsigned int max_vecs, unsigned int flags);
void pci_free_irq_vectors(struct pci_dev *dev);
int pci_irq_vector(struct pci_dev *dev, unsigned int nr);
+const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, int vec);
#else
static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; }
return -EINVAL;
return dev->irq;
}
+static inline const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev,
+ int vec)
+{
+ return cpu_possible_mask;
+}
#endif
#ifdef CONFIG_PCIEPORTBUS
#ifdef CONFIG_PCIEAER
void pci_no_aer(void);
bool pci_aer_available(void);
+ int pci_aer_init(struct pci_dev *dev);
#else
static inline void pci_no_aer(void) { }
static inline bool pci_aer_available(void) { return false; }
+ static inline int pci_aer_init(struct pci_dev *d) { return -ENODEV; }
#endif
#ifdef CONFIG_PCIE_ECRC
static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; }
#endif
+ #ifdef CONFIG_PCIE_PTM
+ int pci_enable_ptm(struct pci_dev *dev, u8 *granularity);
+ #else
+ static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity)
+ { return -EINVAL; }
+ #endif
+
void pci_cfg_access_lock(struct pci_dev *dev);
bool pci_cfg_access_trylock(struct pci_dev *dev);
void pci_cfg_access_unlock(struct pci_dev *dev);
int enable)
{ return 0; }
+static inline struct resource *pci_find_resource(struct pci_dev *dev,
+ struct resource *res)
+{ return NULL; }
static inline int pci_request_regions(struct pci_dev *dev, const char *res_name)
{ return -EIO; }
static inline void pci_release_regions(struct pci_dev *dev) { }