Merge 5.6-rc6 into android-mainline
Linux 5.6-rc6 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I6c2d7aff44ad5a9b75030b72d34ca5dbd5ad3ceb
This commit is contained in:
@@ -86,6 +86,8 @@ ForEachMacros:
|
||||
- 'bio_for_each_segment_all'
|
||||
- 'bio_list_for_each'
|
||||
- 'bip_for_each_vec'
|
||||
- 'bitmap_for_each_clear_region'
|
||||
- 'bitmap_for_each_set_region'
|
||||
- 'blkg_for_each_descendant_post'
|
||||
- 'blkg_for_each_descendant_pre'
|
||||
- 'blk_queue_for_each_rl'
|
||||
@@ -115,6 +117,7 @@ ForEachMacros:
|
||||
- 'drm_client_for_each_connector_iter'
|
||||
- 'drm_client_for_each_modeset'
|
||||
- 'drm_connector_for_each_possible_encoder'
|
||||
- 'drm_for_each_bridge_in_chain'
|
||||
- 'drm_for_each_connector_iter'
|
||||
- 'drm_for_each_crtc'
|
||||
- 'drm_for_each_encoder'
|
||||
@@ -136,9 +139,10 @@ ForEachMacros:
|
||||
- 'for_each_bio'
|
||||
- 'for_each_board_func_rsrc'
|
||||
- 'for_each_bvec'
|
||||
- 'for_each_card_auxs'
|
||||
- 'for_each_card_auxs_safe'
|
||||
- 'for_each_card_components'
|
||||
- 'for_each_card_links'
|
||||
- 'for_each_card_links_safe'
|
||||
- 'for_each_card_pre_auxs'
|
||||
- 'for_each_card_prelinks'
|
||||
- 'for_each_card_rtds'
|
||||
- 'for_each_card_rtds_safe'
|
||||
@@ -166,6 +170,7 @@ ForEachMacros:
|
||||
- 'for_each_dpcm_fe'
|
||||
- 'for_each_drhd_unit'
|
||||
- 'for_each_dss_dev'
|
||||
- 'for_each_efi_handle'
|
||||
- 'for_each_efi_memory_desc'
|
||||
- 'for_each_efi_memory_desc_in_map'
|
||||
- 'for_each_element'
|
||||
@@ -190,6 +195,7 @@ ForEachMacros:
|
||||
- 'for_each_lru'
|
||||
- 'for_each_matching_node'
|
||||
- 'for_each_matching_node_and_match'
|
||||
- 'for_each_member'
|
||||
- 'for_each_memblock'
|
||||
- 'for_each_memblock_type'
|
||||
- 'for_each_memcg_cache_index'
|
||||
@@ -200,9 +206,11 @@ ForEachMacros:
|
||||
- 'for_each_msi_entry'
|
||||
- 'for_each_msi_entry_safe'
|
||||
- 'for_each_net'
|
||||
- 'for_each_net_continue_reverse'
|
||||
- 'for_each_netdev'
|
||||
- 'for_each_netdev_continue'
|
||||
- 'for_each_netdev_continue_rcu'
|
||||
- 'for_each_netdev_continue_reverse'
|
||||
- 'for_each_netdev_feature'
|
||||
- 'for_each_netdev_in_bond_rcu'
|
||||
- 'for_each_netdev_rcu'
|
||||
@@ -254,10 +262,10 @@ ForEachMacros:
|
||||
- 'for_each_reserved_mem_region'
|
||||
- 'for_each_rtd_codec_dai'
|
||||
- 'for_each_rtd_codec_dai_rollback'
|
||||
- 'for_each_rtdcom'
|
||||
- 'for_each_rtdcom_safe'
|
||||
- 'for_each_rtd_components'
|
||||
- 'for_each_set_bit'
|
||||
- 'for_each_set_bit_from'
|
||||
- 'for_each_set_clump8'
|
||||
- 'for_each_sg'
|
||||
- 'for_each_sg_dma_page'
|
||||
- 'for_each_sg_page'
|
||||
@@ -267,6 +275,7 @@ ForEachMacros:
|
||||
- 'for_each_subelement_id'
|
||||
- '__for_each_thread'
|
||||
- 'for_each_thread'
|
||||
- 'for_each_wakeup_source'
|
||||
- 'for_each_zone'
|
||||
- 'for_each_zone_zonelist'
|
||||
- 'for_each_zone_zonelist_nodemask'
|
||||
@@ -330,6 +339,7 @@ ForEachMacros:
|
||||
- 'list_for_each'
|
||||
- 'list_for_each_codec'
|
||||
- 'list_for_each_codec_safe'
|
||||
- 'list_for_each_continue'
|
||||
- 'list_for_each_entry'
|
||||
- 'list_for_each_entry_continue'
|
||||
- 'list_for_each_entry_continue_rcu'
|
||||
@@ -351,6 +361,7 @@ ForEachMacros:
|
||||
- 'llist_for_each_entry'
|
||||
- 'llist_for_each_entry_safe'
|
||||
- 'llist_for_each_safe'
|
||||
- 'mci_for_each_dimm'
|
||||
- 'media_device_for_each_entity'
|
||||
- 'media_device_for_each_intf'
|
||||
- 'media_device_for_each_link'
|
||||
@@ -444,10 +455,16 @@ ForEachMacros:
|
||||
- 'virtio_device_for_each_vq'
|
||||
- 'xa_for_each'
|
||||
- 'xa_for_each_marked'
|
||||
- 'xa_for_each_range'
|
||||
- 'xa_for_each_start'
|
||||
- 'xas_for_each'
|
||||
- 'xas_for_each_conflict'
|
||||
- 'xas_for_each_marked'
|
||||
- 'xbc_array_for_each_value'
|
||||
- 'xbc_for_each_key_value'
|
||||
- 'xbc_node_for_each_array_value'
|
||||
- 'xbc_node_for_each_child'
|
||||
- 'xbc_node_for_each_key_value'
|
||||
- 'zorro_for_each_dev'
|
||||
|
||||
#IncludeBlocks: Preserve # Unknown to clang-format-5.0
|
||||
|
@@ -110,6 +110,8 @@ stable kernels.
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Cavium | ThunderX GICv3 | #38539 | N/A |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Cavium | ThunderX Core | #30115 | CAVIUM_ERRATUM_30115 |
|
||||
|
@@ -110,6 +110,13 @@ PROPERTIES
|
||||
Usage: required
|
||||
Definition: See soc/fsl/qman.txt and soc/fsl/bman.txt
|
||||
|
||||
- fsl,erratum-a050385
|
||||
Usage: optional
|
||||
Value type: boolean
|
||||
Definition: A boolean property. Indicates the presence of the
|
||||
erratum A050385 which indicates that DMA transactions that are
|
||||
split can result in a FMan lock.
|
||||
|
||||
=============================================================================
|
||||
FMan MURAM Node
|
||||
|
||||
|
@@ -850,3 +850,11 @@ business doing so.
|
||||
d_alloc_pseudo() is internal-only; uses outside of alloc_file_pseudo() are
|
||||
very suspect (and won't work in modules). Such uses are very likely to
|
||||
be misspelled d_alloc_anon().
|
||||
|
||||
---
|
||||
|
||||
**mandatory**
|
||||
|
||||
[should've been added in 2016] stale comment in finish_open() nonwithstanding,
|
||||
failure exits in ->atomic_open() instances should *NOT* fput() the file,
|
||||
no matter what. Everything is handled by the caller.
|
||||
|
@@ -40,9 +40,6 @@ example usage
|
||||
# Delete a snapshot using:
|
||||
$ devlink region del pci/0000:00:05.0/cr-space snapshot 1
|
||||
|
||||
# Trigger (request) a snapshot be taken:
|
||||
$ devlink region trigger pci/0000:00:05.0/cr-space
|
||||
|
||||
# Dump a snapshot:
|
||||
$ devlink region dump pci/0000:00:05.0/fw-health snapshot 1
|
||||
0000000000000000 0014 95dc 0014 9514 0035 1670 0034 db30
|
||||
|
@@ -8,9 +8,9 @@ Overview
|
||||
========
|
||||
|
||||
The net_failover driver provides an automated failover mechanism via APIs
|
||||
to create and destroy a failover master netdev and mananges a primary and
|
||||
to create and destroy a failover master netdev and manages a primary and
|
||||
standby slave netdevs that get registered via the generic failover
|
||||
infrastructrure.
|
||||
infrastructure.
|
||||
|
||||
The failover netdev acts a master device and controls 2 slave devices. The
|
||||
original paravirtual interface is registered as 'standby' slave netdev and
|
||||
@@ -29,7 +29,7 @@ virtio-net accelerated datapath: STANDBY mode
|
||||
=============================================
|
||||
|
||||
net_failover enables hypervisor controlled accelerated datapath to virtio-net
|
||||
enabled VMs in a transparent manner with no/minimal guest userspace chanages.
|
||||
enabled VMs in a transparent manner with no/minimal guest userspace changes.
|
||||
|
||||
To support this, the hypervisor needs to enable VIRTIO_NET_F_STANDBY
|
||||
feature on the virtio-net interface and assign the same MAC address to both
|
||||
|
@@ -159,7 +159,7 @@ Socket Interface
|
||||
set SO_RDS_TRANSPORT on a socket for which the transport has
|
||||
been previously attached explicitly (by SO_RDS_TRANSPORT) or
|
||||
implicitly (via bind(2)) will return an error of EOPNOTSUPP.
|
||||
An attempt to set SO_RDS_TRANSPPORT to RDS_TRANS_NONE will
|
||||
An attempt to set SO_RDS_TRANSPORT to RDS_TRANS_NONE will
|
||||
always return EINVAL.
|
||||
|
||||
RDMA for RDS
|
||||
|
@@ -4073,7 +4073,6 @@ F: drivers/scsi/snic/
|
||||
CISCO VIC ETHERNET NIC DRIVER
|
||||
M: Christian Benvenuti <benve@cisco.com>
|
||||
M: Govindarajulu Varadarajan <_govind@gmx.com>
|
||||
M: Parvi Kaustubhi <pkaustub@cisco.com>
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/cisco/enic/
|
||||
|
||||
@@ -4572,7 +4571,7 @@ F: drivers/infiniband/hw/cxgb4/
|
||||
F: include/uapi/rdma/cxgb4-abi.h
|
||||
|
||||
CXGB4VF ETHERNET DRIVER (CXGB4VF)
|
||||
M: Casey Leedom <leedom@chelsio.com>
|
||||
M: Vishal Kulkarni <vishal@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
W: http://www.chelsio.com
|
||||
S: Supported
|
||||
@@ -6198,7 +6197,6 @@ S: Supported
|
||||
F: drivers/scsi/be2iscsi/
|
||||
|
||||
Emulex 10Gbps NIC BE2, BE3-R, Lancer, Skyhawk-R DRIVER (be2net)
|
||||
M: Sathya Perla <sathya.perla@broadcom.com>
|
||||
M: Ajit Khaparde <ajit.khaparde@broadcom.com>
|
||||
M: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
|
||||
M: Somnath Kotur <somnath.kotur@broadcom.com>
|
||||
@@ -11119,7 +11117,7 @@ M: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
L: linux-mips@vger.kernel.org
|
||||
W: http://www.linux-mips.org/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git
|
||||
Q: http://patchwork.linux-mips.org/project/linux-mips/list/
|
||||
Q: https://patchwork.kernel.org/project/linux-mips/list/
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/mips/
|
||||
F: Documentation/mips/
|
||||
|
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc6
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@@ -154,7 +154,7 @@ config ARC_CPU_HS
|
||||
help
|
||||
Support for ARC HS38x Cores based on ARCv2 ISA
|
||||
The notable features are:
|
||||
- SMP configurations of upto 4 core with coherency
|
||||
- SMP configurations of up to 4 cores with coherency
|
||||
- Optional L2 Cache and IO-Coherency
|
||||
- Revised Interrupt Architecture (multiple priorites, reg banks,
|
||||
auto stack switch, auto regfile save/restore)
|
||||
@@ -192,7 +192,7 @@ config ARC_SMP_HALT_ON_RESET
|
||||
help
|
||||
In SMP configuration cores can be configured as Halt-on-reset
|
||||
or they could all start at same time. For Halt-on-reset, non
|
||||
masters are parked until Master kicks them so they can start of
|
||||
masters are parked until Master kicks them so they can start off
|
||||
at designated entry point. For other case, all jump to common
|
||||
entry point and spin wait for Master's signal.
|
||||
|
||||
|
@@ -21,8 +21,6 @@ CONFIG_MODULES=y
|
||||
CONFIG_MODULE_FORCE_LOAD=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_ARC_PLAT_EZNPS=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_NR_CPUS=4096
|
||||
|
@@ -20,8 +20,6 @@ CONFIG_ISA_ARCOMPACT=y
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_MODULES=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci"
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_NET=y
|
||||
|
@@ -19,8 +19,6 @@ CONFIG_PERF_EVENTS=y
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_MODULES=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_ISA_ARCV2=y
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs"
|
||||
# CONFIG_COMPACTION is not set
|
||||
|
@@ -14,8 +14,6 @@ CONFIG_PERF_EVENTS=y
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_MODULES=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_ISA_ARCV2=y
|
||||
CONFIG_SMP=y
|
||||
# CONFIG_ARC_TIMERS_64BIT is not set
|
||||
|
@@ -43,6 +43,8 @@ extern void fpu_init_task(struct pt_regs *regs);
|
||||
|
||||
#endif /* !CONFIG_ISA_ARCOMPACT */
|
||||
|
||||
struct task_struct;
|
||||
|
||||
extern void fpu_save_restore(struct task_struct *p, struct task_struct *n);
|
||||
|
||||
#else /* !CONFIG_ARC_FPU_SAVE_RESTORE */
|
||||
|
@@ -29,6 +29,8 @@
|
||||
.endm
|
||||
|
||||
#define ASM_NL ` /* use '`' to mark new line in macro */
|
||||
#define __ALIGN .align 4
|
||||
#define __ALIGN_STR __stringify(__ALIGN)
|
||||
|
||||
/* annotation for data we want in DCCM - if enabled in .config */
|
||||
.macro ARCFP_DATA nm
|
||||
|
@@ -8,11 +8,11 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/root_dev.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/of_clk.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/cache.h>
|
||||
|
@@ -104,8 +104,7 @@ static void show_faulting_vma(unsigned long address)
|
||||
if (IS_ERR(nm))
|
||||
nm = "?";
|
||||
}
|
||||
pr_info(" @off 0x%lx in [%s]\n"
|
||||
" VMA: 0x%08lx to 0x%08lx\n",
|
||||
pr_info(" @off 0x%lx in [%s] VMA: 0x%08lx to 0x%08lx\n",
|
||||
vma->vm_start < TASK_UNMAPPED_BASE ?
|
||||
address : address - vma->vm_start,
|
||||
nm, vma->vm_start, vma->vm_end);
|
||||
@@ -120,8 +119,6 @@ static void show_ecr_verbose(struct pt_regs *regs)
|
||||
unsigned int vec, cause_code;
|
||||
unsigned long address;
|
||||
|
||||
pr_info("\n[ECR ]: 0x%08lx => ", regs->event);
|
||||
|
||||
/* For Data fault, this is data address not instruction addr */
|
||||
address = current->thread.fault_address;
|
||||
|
||||
@@ -130,10 +127,10 @@ static void show_ecr_verbose(struct pt_regs *regs)
|
||||
|
||||
/* For DTLB Miss or ProtV, display the memory involved too */
|
||||
if (vec == ECR_V_DTLB_MISS) {
|
||||
pr_cont("Invalid %s @ 0x%08lx by insn @ 0x%08lx\n",
|
||||
pr_cont("Invalid %s @ 0x%08lx by insn @ %pS\n",
|
||||
(cause_code == 0x01) ? "Read" :
|
||||
((cause_code == 0x02) ? "Write" : "EX"),
|
||||
address, regs->ret);
|
||||
address, (void *)regs->ret);
|
||||
} else if (vec == ECR_V_ITLB_MISS) {
|
||||
pr_cont("Insn could not be fetched\n");
|
||||
} else if (vec == ECR_V_MACH_CHK) {
|
||||
@@ -191,31 +188,31 @@ void show_regs(struct pt_regs *regs)
|
||||
|
||||
show_ecr_verbose(regs);
|
||||
|
||||
pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n",
|
||||
current->thread.fault_address,
|
||||
(void *)regs->blink, (void *)regs->ret);
|
||||
|
||||
if (user_mode(regs))
|
||||
show_faulting_vma(regs->ret); /* faulting code, not data */
|
||||
|
||||
pr_info("[STAT32]: 0x%08lx", regs->status32);
|
||||
pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\n",
|
||||
regs->event, current->thread.fault_address, regs->ret);
|
||||
|
||||
pr_info("STAT32: 0x%08lx", regs->status32);
|
||||
|
||||
#define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : ""
|
||||
|
||||
#ifdef CONFIG_ISA_ARCOMPACT
|
||||
pr_cont(" : %2s%2s%2s%2s%2s%2s%2s\n",
|
||||
pr_cont(" [%2s%2s%2s%2s%2s%2s%2s]",
|
||||
(regs->status32 & STATUS_U_MASK) ? "U " : "K ",
|
||||
STS_BIT(regs, DE), STS_BIT(regs, AE),
|
||||
STS_BIT(regs, A2), STS_BIT(regs, A1),
|
||||
STS_BIT(regs, E2), STS_BIT(regs, E1));
|
||||
#else
|
||||
pr_cont(" : %2s%2s%2s%2s\n",
|
||||
pr_cont(" [%2s%2s%2s%2s]",
|
||||
STS_BIT(regs, IE),
|
||||
(regs->status32 & STATUS_U_MASK) ? "U " : "K ",
|
||||
STS_BIT(regs, DE), STS_BIT(regs, AE));
|
||||
#endif
|
||||
pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n",
|
||||
regs->bta, regs->sp, regs->fp);
|
||||
pr_cont(" BTA: 0x%08lx\n", regs->bta);
|
||||
pr_info("BLK: %pS\n SP: 0x%08lx FP: 0x%08lx\n",
|
||||
(void *)regs->blink, regs->sp, regs->fp);
|
||||
pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n",
|
||||
regs->lp_start, regs->lp_end, regs->lp_count);
|
||||
|
||||
|
@@ -20,6 +20,8 @@
|
||||
};
|
||||
|
||||
&fman0 {
|
||||
fsl,erratum-a050385;
|
||||
|
||||
/* these aliases provide the FMan ports mapping */
|
||||
enet0: ethernet@e0000 {
|
||||
};
|
||||
|
@@ -4,6 +4,8 @@
|
||||
#include "jz4780.dtsi"
|
||||
#include <dt-bindings/clock/ingenic,tcu.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/regulator/active-semi,8865-regulator.h>
|
||||
|
||||
/ {
|
||||
compatible = "img,ci20", "ingenic,jz4780";
|
||||
@@ -163,63 +165,71 @@
|
||||
|
||||
regulators {
|
||||
vddcore: SUDCDC1 {
|
||||
regulator-name = "VDDCORE";
|
||||
regulator-name = "DCDC_REG1";
|
||||
regulator-min-microvolt = <1100000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
vddmem: SUDCDC2 {
|
||||
regulator-name = "VDDMEM";
|
||||
regulator-name = "DCDC_REG2";
|
||||
regulator-min-microvolt = <1500000>;
|
||||
regulator-max-microvolt = <1500000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
vcc_33: SUDCDC3 {
|
||||
regulator-name = "VCC33";
|
||||
regulator-name = "DCDC_REG3";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
vcc_50: SUDCDC4 {
|
||||
regulator-name = "VCC50";
|
||||
regulator-name = "SUDCDC_REG4";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
vcc_25: LDO_REG5 {
|
||||
regulator-name = "VCC25";
|
||||
regulator-name = "LDO_REG5";
|
||||
regulator-min-microvolt = <2500000>;
|
||||
regulator-max-microvolt = <2500000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
wifi_io: LDO_REG6 {
|
||||
regulator-name = "WIFIIO";
|
||||
regulator-name = "LDO_REG6";
|
||||
regulator-min-microvolt = <2500000>;
|
||||
regulator-max-microvolt = <2500000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
vcc_28: LDO_REG7 {
|
||||
regulator-name = "VCC28";
|
||||
regulator-name = "LDO_REG7";
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <2800000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
vcc_15: LDO_REG8 {
|
||||
regulator-name = "VCC15";
|
||||
regulator-name = "LDO_REG8";
|
||||
regulator-min-microvolt = <1500000>;
|
||||
regulator-max-microvolt = <1500000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
vcc_18: LDO_REG9 {
|
||||
regulator-name = "VCC18";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
vrtc_18: LDO_REG9 {
|
||||
regulator-name = "LDO_REG9";
|
||||
/* Despite the datasheet stating 3.3V
|
||||
* for REG9 and the driver expecting that,
|
||||
* REG9 outputs 1.8V.
|
||||
* Likely the CI20 uses a proprietary
|
||||
* factory programmed chip variant.
|
||||
* Since this is a simple on/off LDO the
|
||||
* exact values do not matter.
|
||||
*/
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
vcc_11: LDO_REG10 {
|
||||
regulator-name = "VCC11";
|
||||
regulator-min-microvolt = <1100000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
regulator-name = "LDO_REG10";
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
@@ -261,7 +271,9 @@
|
||||
rtc@51 {
|
||||
compatible = "nxp,pcf8563";
|
||||
reg = <0x51>;
|
||||
interrupts = <110>;
|
||||
|
||||
interrupt-parent = <&gpf>;
|
||||
interrupts = <30 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -605,7 +605,8 @@ static void __init bootcmdline_init(char **cmdline_p)
|
||||
* If we're configured to take boot arguments from DT, look for those
|
||||
* now.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB))
|
||||
if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) ||
|
||||
IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND))
|
||||
of_scan_flat_dt(bootcmdline_scan_chosen, &dt_bootargs);
|
||||
#endif
|
||||
|
||||
|
@@ -3268,7 +3268,10 @@ static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
|
||||
/* Initial reset is a superset of the normal reset */
|
||||
kvm_arch_vcpu_ioctl_normal_reset(vcpu);
|
||||
|
||||
/* this equals initial cpu reset in pop, but we don't switch to ESA */
|
||||
/*
|
||||
* This equals initial cpu reset in pop, but we don't switch to ESA.
|
||||
* We do not only reset the internal data, but also ...
|
||||
*/
|
||||
vcpu->arch.sie_block->gpsw.mask = 0;
|
||||
vcpu->arch.sie_block->gpsw.addr = 0;
|
||||
kvm_s390_set_prefix(vcpu, 0);
|
||||
@@ -3278,6 +3281,19 @@ static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
|
||||
memset(vcpu->arch.sie_block->gcr, 0, sizeof(vcpu->arch.sie_block->gcr));
|
||||
vcpu->arch.sie_block->gcr[0] = CR0_INITIAL_MASK;
|
||||
vcpu->arch.sie_block->gcr[14] = CR14_INITIAL_MASK;
|
||||
|
||||
/* ... the data in sync regs */
|
||||
memset(vcpu->run->s.regs.crs, 0, sizeof(vcpu->run->s.regs.crs));
|
||||
vcpu->run->s.regs.ckc = 0;
|
||||
vcpu->run->s.regs.crs[0] = CR0_INITIAL_MASK;
|
||||
vcpu->run->s.regs.crs[14] = CR14_INITIAL_MASK;
|
||||
vcpu->run->psw_addr = 0;
|
||||
vcpu->run->psw_mask = 0;
|
||||
vcpu->run->s.regs.todpr = 0;
|
||||
vcpu->run->s.regs.cputm = 0;
|
||||
vcpu->run->s.regs.ckc = 0;
|
||||
vcpu->run->s.regs.pp = 0;
|
||||
vcpu->run->s.regs.gbea = 1;
|
||||
vcpu->run->s.regs.fpc = 0;
|
||||
vcpu->arch.sie_block->gbea = 1;
|
||||
vcpu->arch.sie_block->pp = 0;
|
||||
|
@@ -194,9 +194,10 @@ avx2_instr :=$(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1)
|
||||
avx512_instr :=$(call as-instr,vpmovm2b %k1$(comma)%zmm5,-DCONFIG_AS_AVX512=1)
|
||||
sha1_ni_instr :=$(call as-instr,sha1msg1 %xmm0$(comma)%xmm1,-DCONFIG_AS_SHA1_NI=1)
|
||||
sha256_ni_instr :=$(call as-instr,sha256msg1 %xmm0$(comma)%xmm1,-DCONFIG_AS_SHA256_NI=1)
|
||||
adx_instr := $(call as-instr,adox %r10$(comma)%r10,-DCONFIG_AS_ADX=1)
|
||||
|
||||
KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr)
|
||||
KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr)
|
||||
KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr) $(adx_instr)
|
||||
KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr) $(adx_instr)
|
||||
|
||||
KBUILD_LDFLAGS := -m elf_$(UTS_MACHINE)
|
||||
|
||||
|
@@ -11,6 +11,7 @@ avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
|
||||
avx512_supported :=$(call as-instr,vpmovm2b %k1$(comma)%zmm5,yes,no)
|
||||
sha1_ni_supported :=$(call as-instr,sha1msg1 %xmm0$(comma)%xmm1,yes,no)
|
||||
sha256_ni_supported :=$(call as-instr,sha256msg1 %xmm0$(comma)%xmm1,yes,no)
|
||||
adx_supported := $(call as-instr,adox %r10$(comma)%r10,yes,no)
|
||||
|
||||
obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o
|
||||
|
||||
@@ -39,7 +40,11 @@ obj-$(CONFIG_CRYPTO_AEGIS128_AESNI_SSE2) += aegis128-aesni.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_NHPOLY1305_SSE2) += nhpoly1305-sse2.o
|
||||
obj-$(CONFIG_CRYPTO_NHPOLY1305_AVX2) += nhpoly1305-avx2.o
|
||||
obj-$(CONFIG_CRYPTO_CURVE25519_X86) += curve25519-x86_64.o
|
||||
|
||||
# These modules require the assembler to support ADX.
|
||||
ifeq ($(adx_supported),yes)
|
||||
obj-$(CONFIG_CRYPTO_CURVE25519_X86) += curve25519-x86_64.o
|
||||
endif
|
||||
|
||||
# These modules require assembler to support AVX.
|
||||
ifeq ($(avx_supported),yes)
|
||||
|
@@ -190,15 +190,12 @@ static int amd_uncore_event_init(struct perf_event *event)
|
||||
|
||||
/*
|
||||
* NB and Last level cache counters (MSRs) are shared across all cores
|
||||
* that share the same NB / Last level cache. Interrupts can be directed
|
||||
* to a single target core, however, event counts generated by processes
|
||||
* running on other cores cannot be masked out. So we do not support
|
||||
* sampling and per-thread events.
|
||||
* that share the same NB / Last level cache. On family 16h and below,
|
||||
* Interrupts can be directed to a single target core, however, event
|
||||
* counts generated by processes running on other cores cannot be masked
|
||||
* out. So we do not support sampling and per-thread events via
|
||||
* CAP_NO_INTERRUPT, and we do not enable counter overflow interrupts:
|
||||
*/
|
||||
if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
|
||||
return -EINVAL;
|
||||
|
||||
/* and we do not enable counter overflow interrupts */
|
||||
hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB;
|
||||
hwc->idx = -1;
|
||||
|
||||
@@ -306,7 +303,7 @@ static struct pmu amd_nb_pmu = {
|
||||
.start = amd_uncore_start,
|
||||
.stop = amd_uncore_stop,
|
||||
.read = amd_uncore_read,
|
||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
|
||||
};
|
||||
|
||||
static struct pmu amd_llc_pmu = {
|
||||
@@ -317,7 +314,7 @@ static struct pmu amd_llc_pmu = {
|
||||
.start = amd_uncore_start,
|
||||
.stop = amd_uncore_stop,
|
||||
.read = amd_uncore_read,
|
||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
|
||||
};
|
||||
|
||||
static struct amd_uncore *amd_uncore_alloc(unsigned int cpu)
|
||||
|
@@ -360,7 +360,6 @@ struct x86_emulate_ctxt {
|
||||
u64 d;
|
||||
unsigned long _eip;
|
||||
struct operand memop;
|
||||
/* Fields above regs are cleared together. */
|
||||
unsigned long _regs[NR_VCPU_REGS];
|
||||
struct operand *memopp;
|
||||
struct fetch_cache fetch;
|
||||
|
@@ -838,13 +838,15 @@ static void free_moved_vector(struct apic_chip_data *apicd)
|
||||
bool managed = apicd->is_managed;
|
||||
|
||||
/*
|
||||
* This should never happen. Managed interrupts are not
|
||||
* migrated except on CPU down, which does not involve the
|
||||
* cleanup vector. But try to keep the accounting correct
|
||||
* nevertheless.
|
||||
* Managed interrupts are usually not migrated away
|
||||
* from an online CPU, but CPU isolation 'managed_irq'
|
||||
* can make that happen.
|
||||
* 1) Activation does not take the isolation into account
|
||||
* to keep the code simple
|
||||
* 2) Migration away from an isolated CPU can happen when
|
||||
* a non-isolated CPU which is in the calculated
|
||||
* affinity mask comes online.
|
||||
*/
|
||||
WARN_ON_ONCE(managed);
|
||||
|
||||
trace_vector_free_moved(apicd->irq, cpu, vector, managed);
|
||||
irq_matrix_free(vector_matrix, cpu, vector, managed);
|
||||
per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
|
||||
|
@@ -493,17 +493,18 @@ static void intel_ppin_init(struct cpuinfo_x86 *c)
|
||||
return;
|
||||
|
||||
if ((val & 3UL) == 1UL) {
|
||||
/* PPIN available but disabled: */
|
||||
/* PPIN locked in disabled mode */
|
||||
return;
|
||||
}
|
||||
|
||||
/* If PPIN is disabled, but not locked, try to enable: */
|
||||
if (!(val & 3UL)) {
|
||||
/* If PPIN is disabled, try to enable */
|
||||
if (!(val & 2UL)) {
|
||||
wrmsrl_safe(MSR_PPIN_CTL, val | 2UL);
|
||||
rdmsrl_safe(MSR_PPIN_CTL, &val);
|
||||
}
|
||||
|
||||
if ((val & 3UL) == 2UL)
|
||||
/* Is the enable bit set? */
|
||||
if (val & 2UL)
|
||||
set_cpu_cap(c, X86_FEATURE_INTEL_PPIN);
|
||||
}
|
||||
}
|
||||
|
@@ -486,9 +486,14 @@ static int thermal_throttle_offline(unsigned int cpu)
|
||||
{
|
||||
struct thermal_state *state = &per_cpu(thermal_state, cpu);
|
||||
struct device *dev = get_cpu_device(cpu);
|
||||
u32 l;
|
||||
|
||||
cancel_delayed_work(&state->package_throttle.therm_work);
|
||||
cancel_delayed_work(&state->core_throttle.therm_work);
|
||||
/* Mask the thermal vector before draining evtl. pending work */
|
||||
l = apic_read(APIC_LVTTHMR);
|
||||
apic_write(APIC_LVTTHMR, l | APIC_LVT_MASKED);
|
||||
|
||||
cancel_delayed_work_sync(&state->package_throttle.therm_work);
|
||||
cancel_delayed_work_sync(&state->core_throttle.therm_work);
|
||||
|
||||
state->package_throttle.rate_control_active = false;
|
||||
state->core_throttle.rate_control_active = false;
|
||||
|
@@ -68,7 +68,7 @@ config KVM_WERROR
|
||||
depends on (X86_64 && !KASAN) || !COMPILE_TEST
|
||||
depends on EXPERT
|
||||
help
|
||||
Add -Werror to the build flags for (and only for) i915.ko.
|
||||
Add -Werror to the build flags for KVM.
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
|
@@ -5173,6 +5173,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
|
||||
ctxt->fetch.ptr = ctxt->fetch.data;
|
||||
ctxt->fetch.end = ctxt->fetch.data + insn_len;
|
||||
ctxt->opcode_len = 1;
|
||||
ctxt->intercept = x86_intercept_none;
|
||||
if (insn_len > 0)
|
||||
memcpy(ctxt->fetch.data, insn, insn_len);
|
||||
else {
|
||||
|
@@ -378,12 +378,15 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
|
||||
if (e->fields.delivery_mode == APIC_DM_FIXED) {
|
||||
struct kvm_lapic_irq irq;
|
||||
|
||||
irq.shorthand = APIC_DEST_NOSHORT;
|
||||
irq.vector = e->fields.vector;
|
||||
irq.delivery_mode = e->fields.delivery_mode << 8;
|
||||
irq.dest_id = e->fields.dest_id;
|
||||
irq.dest_mode =
|
||||
kvm_lapic_irq_dest_mode(!!e->fields.dest_mode);
|
||||
irq.level = false;
|
||||
irq.trig_mode = e->fields.trig_mode;
|
||||
irq.shorthand = APIC_DEST_NOSHORT;
|
||||
irq.dest_id = e->fields.dest_id;
|
||||
irq.msi_redir_hint = false;
|
||||
bitmap_zero(&vcpu_bitmap, 16);
|
||||
kvm_bitmap_or_dest_vcpus(ioapic->kvm, &irq,
|
||||
&vcpu_bitmap);
|
||||
|
@@ -6312,7 +6312,8 @@ static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu,
|
||||
enum exit_fastpath_completion *exit_fastpath)
|
||||
{
|
||||
if (!is_guest_mode(vcpu) &&
|
||||
to_svm(vcpu)->vmcb->control.exit_code == EXIT_REASON_MSR_WRITE)
|
||||
to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR &&
|
||||
to_svm(vcpu)->vmcb->control.exit_info_1)
|
||||
*exit_fastpath = handle_fastpath_set_msr_irqoff(vcpu);
|
||||
}
|
||||
|
||||
|
@@ -224,7 +224,7 @@ static inline void nested_release_evmcs(struct kvm_vcpu *vcpu)
|
||||
return;
|
||||
|
||||
kvm_vcpu_unmap(vcpu, &vmx->nested.hv_evmcs_map, true);
|
||||
vmx->nested.hv_evmcs_vmptr = -1ull;
|
||||
vmx->nested.hv_evmcs_vmptr = 0;
|
||||
vmx->nested.hv_evmcs = NULL;
|
||||
}
|
||||
|
||||
@@ -1923,7 +1923,8 @@ static int nested_vmx_handle_enlightened_vmptrld(struct kvm_vcpu *vcpu,
|
||||
if (!nested_enlightened_vmentry(vcpu, &evmcs_gpa))
|
||||
return 1;
|
||||
|
||||
if (unlikely(evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) {
|
||||
if (unlikely(!vmx->nested.hv_evmcs ||
|
||||
evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) {
|
||||
if (!vmx->nested.hv_evmcs)
|
||||
vmx->nested.current_vmptr = -1ull;
|
||||
|
||||
|
@@ -2338,6 +2338,17 @@ static void hardware_disable(void)
|
||||
kvm_cpu_vmxoff();
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no X86_FEATURE for SGX yet, but anyway we need to query CPUID
|
||||
* directly instead of going through cpu_has(), to ensure KVM is trapping
|
||||
* ENCLS whenever it's supported in hardware. It does not matter whether
|
||||
* the host OS supports or has enabled SGX.
|
||||
*/
|
||||
static bool cpu_has_sgx(void)
|
||||
{
|
||||
return cpuid_eax(0) >= 0x12 && (cpuid_eax(0x12) & BIT(0));
|
||||
}
|
||||
|
||||
static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
|
||||
u32 msr, u32 *result)
|
||||
{
|
||||
@@ -2418,8 +2429,9 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
|
||||
SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE |
|
||||
SECONDARY_EXEC_PT_USE_GPA |
|
||||
SECONDARY_EXEC_PT_CONCEAL_VMX |
|
||||
SECONDARY_EXEC_ENABLE_VMFUNC |
|
||||
SECONDARY_EXEC_ENCLS_EXITING;
|
||||
SECONDARY_EXEC_ENABLE_VMFUNC;
|
||||
if (cpu_has_sgx())
|
||||
opt2 |= SECONDARY_EXEC_ENCLS_EXITING;
|
||||
if (adjust_vmx_controls(min2, opt2,
|
||||
MSR_IA32_VMX_PROCBASED_CTLS2,
|
||||
&_cpu_based_2nd_exec_control) < 0)
|
||||
|
@@ -7195,10 +7195,12 @@ static void kvm_timer_init(void)
|
||||
|
||||
cpu = get_cpu();
|
||||
policy = cpufreq_cpu_get(cpu);
|
||||
if (policy && policy->cpuinfo.max_freq)
|
||||
max_tsc_khz = policy->cpuinfo.max_freq;
|
||||
if (policy) {
|
||||
if (policy->cpuinfo.max_freq)
|
||||
max_tsc_khz = policy->cpuinfo.max_freq;
|
||||
cpufreq_cpu_put(policy);
|
||||
}
|
||||
put_cpu();
|
||||
cpufreq_cpu_put(policy);
|
||||
#endif
|
||||
cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
|
@@ -106,6 +106,19 @@ static unsigned int __ioremap_check_encrypted(struct resource *res)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The EFI runtime services data area is not covered by walk_mem_res(), but must
|
||||
* be mapped encrypted when SEV is active.
|
||||
*/
|
||||
static void __ioremap_check_other(resource_size_t addr, struct ioremap_desc *desc)
|
||||
{
|
||||
if (!sev_active())
|
||||
return;
|
||||
|
||||
if (efi_mem_type(addr) == EFI_RUNTIME_SERVICES_DATA)
|
||||
desc->flags |= IORES_MAP_ENCRYPTED;
|
||||
}
|
||||
|
||||
static int __ioremap_collect_map_flags(struct resource *res, void *arg)
|
||||
{
|
||||
struct ioremap_desc *desc = arg;
|
||||
@@ -124,6 +137,9 @@ static int __ioremap_collect_map_flags(struct resource *res, void *arg)
|
||||
* To avoid multiple resource walks, this function walks resources marked as
|
||||
* IORESOURCE_MEM and IORESOURCE_BUSY and looking for system RAM and/or a
|
||||
* resource described not as IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES).
|
||||
*
|
||||
* After that, deal with misc other ranges in __ioremap_check_other() which do
|
||||
* not fall into the above category.
|
||||
*/
|
||||
static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
|
||||
struct ioremap_desc *desc)
|
||||
@@ -135,6 +151,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
|
||||
memset(desc, 0, sizeof(struct ioremap_desc));
|
||||
|
||||
walk_mem_res(start, end, desc, __ioremap_collect_map_flags);
|
||||
|
||||
__ioremap_check_other(addr, desc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -1318,7 +1318,7 @@ static bool iocg_is_idle(struct ioc_gq *iocg)
|
||||
return false;
|
||||
|
||||
/* is something in flight? */
|
||||
if (atomic64_read(&iocg->done_vtime) < atomic64_read(&iocg->vtime))
|
||||
if (atomic64_read(&iocg->done_vtime) != atomic64_read(&iocg->vtime))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@@ -398,6 +398,28 @@ void blk_mq_sched_insert_request(struct request *rq, bool at_head,
|
||||
WARN_ON(e && (rq->tag != -1));
|
||||
|
||||
if (blk_mq_sched_bypass_insert(hctx, !!e, rq)) {
|
||||
/*
|
||||
* Firstly normal IO request is inserted to scheduler queue or
|
||||
* sw queue, meantime we add flush request to dispatch queue(
|
||||
* hctx->dispatch) directly and there is at most one in-flight
|
||||
* flush request for each hw queue, so it doesn't matter to add
|
||||
* flush request to tail or front of the dispatch queue.
|
||||
*
|
||||
* Secondly in case of NCQ, flush request belongs to non-NCQ
|
||||
* command, and queueing it will fail when there is any
|
||||
* in-flight normal IO request(NCQ command). When adding flush
|
||||
* rq to the front of hctx->dispatch, it is easier to introduce
|
||||
* extra time to flush rq's latency because of S_SCHED_RESTART
|
||||
* compared with adding to the tail of dispatch queue, then
|
||||
* chance of flush merge is increased, and less flush requests
|
||||
* will be issued to controller. It is observed that ~10% time
|
||||
* is saved in blktests block/004 on disk attached to AHCI/NCQ
|
||||
* drive when adding flush rq to the front of hctx->dispatch.
|
||||
*
|
||||
* Simply queue flush rq to the front of hctx->dispatch so that
|
||||
* intensive flush workloads can benefit in case of NCQ HW.
|
||||
*/
|
||||
at_head = (rq->rq_flags & RQF_FLUSH_SEQ) ? true : at_head;
|
||||
blk_mq_request_bypass_insert(rq, at_head, false);
|
||||
goto run;
|
||||
}
|
||||
|
@@ -301,6 +301,42 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(disk_map_sector_rcu);
|
||||
|
||||
/**
|
||||
* disk_has_partitions
|
||||
* @disk: gendisk of interest
|
||||
*
|
||||
* Walk through the partition table and check if valid partition exists.
|
||||
*
|
||||
* CONTEXT:
|
||||
* Don't care.
|
||||
*
|
||||
* RETURNS:
|
||||
* True if the gendisk has at least one valid non-zero size partition.
|
||||
* Otherwise false.
|
||||
*/
|
||||
bool disk_has_partitions(struct gendisk *disk)
|
||||
{
|
||||
struct disk_part_tbl *ptbl;
|
||||
int i;
|
||||
bool ret = false;
|
||||
|
||||
rcu_read_lock();
|
||||
ptbl = rcu_dereference(disk->part_tbl);
|
||||
|
||||
/* Iterate partitions skipping the whole device at index 0 */
|
||||
for (i = 1; i < ptbl->len; i++) {
|
||||
if (rcu_dereference(ptbl->part[i])) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(disk_has_partitions);
|
||||
|
||||
/*
|
||||
* Can be deleted altogether. Later.
|
||||
*
|
||||
|
@@ -91,7 +91,7 @@
|
||||
#ifdef GENERAL_DEBUG
|
||||
#define PRINTK(args...) printk(args)
|
||||
#else
|
||||
#define PRINTK(args...)
|
||||
#define PRINTK(args...) do {} while (0)
|
||||
#endif /* GENERAL_DEBUG */
|
||||
|
||||
#ifdef EXTRA_DEBUG
|
||||
|
@@ -111,7 +111,7 @@ config CFAG12864B
|
||||
If unsure, say N.
|
||||
|
||||
config CFAG12864B_RATE
|
||||
int "Refresh rate (hertz)"
|
||||
int "Refresh rate (hertz)"
|
||||
depends on CFAG12864B
|
||||
default "20"
|
||||
---help---
|
||||
@@ -329,7 +329,7 @@ config PANEL_LCD_PROTO
|
||||
|
||||
config PANEL_LCD_PIN_E
|
||||
depends on PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO="0"
|
||||
int "Parallel port pin number & polarity connected to the LCD E signal (-17...17) "
|
||||
int "Parallel port pin number & polarity connected to the LCD E signal (-17...17) "
|
||||
range -17 17
|
||||
default 14
|
||||
---help---
|
||||
@@ -344,7 +344,7 @@ config PANEL_LCD_PIN_E
|
||||
|
||||
config PANEL_LCD_PIN_RS
|
||||
depends on PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO="0"
|
||||
int "Parallel port pin number & polarity connected to the LCD RS signal (-17...17) "
|
||||
int "Parallel port pin number & polarity connected to the LCD RS signal (-17...17) "
|
||||
range -17 17
|
||||
default 17
|
||||
---help---
|
||||
@@ -359,7 +359,7 @@ config PANEL_LCD_PIN_RS
|
||||
|
||||
config PANEL_LCD_PIN_RW
|
||||
depends on PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO="0"
|
||||
int "Parallel port pin number & polarity connected to the LCD RW signal (-17...17) "
|
||||
int "Parallel port pin number & polarity connected to the LCD RW signal (-17...17) "
|
||||
range -17 17
|
||||
default 16
|
||||
---help---
|
||||
@@ -374,7 +374,7 @@ config PANEL_LCD_PIN_RW
|
||||
|
||||
config PANEL_LCD_PIN_SCL
|
||||
depends on PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO!="0"
|
||||
int "Parallel port pin number & polarity connected to the LCD SCL signal (-17...17) "
|
||||
int "Parallel port pin number & polarity connected to the LCD SCL signal (-17...17) "
|
||||
range -17 17
|
||||
default 1
|
||||
---help---
|
||||
@@ -389,7 +389,7 @@ config PANEL_LCD_PIN_SCL
|
||||
|
||||
config PANEL_LCD_PIN_SDA
|
||||
depends on PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO!="0"
|
||||
int "Parallel port pin number & polarity connected to the LCD SDA signal (-17...17) "
|
||||
int "Parallel port pin number & polarity connected to the LCD SDA signal (-17...17) "
|
||||
range -17 17
|
||||
default 2
|
||||
---help---
|
||||
@@ -404,12 +404,12 @@ config PANEL_LCD_PIN_SDA
|
||||
|
||||
config PANEL_LCD_PIN_BL
|
||||
depends on PANEL_PROFILE="0" && PANEL_LCD="1"
|
||||
int "Parallel port pin number & polarity connected to the LCD backlight signal (-17...17) "
|
||||
int "Parallel port pin number & polarity connected to the LCD backlight signal (-17...17) "
|
||||
range -17 17
|
||||
default 0
|
||||
---help---
|
||||
This describes the number of the parallel port pin to which the LCD 'BL' signal
|
||||
has been connected. It can be :
|
||||
has been connected. It can be :
|
||||
|
||||
0 : no connection (eg: connected to ground)
|
||||
1..17 : directly connected to any of these pins on the DB25 plug
|
||||
|
@@ -88,7 +88,7 @@ struct charlcd_priv {
|
||||
int len;
|
||||
} esc_seq;
|
||||
|
||||
unsigned long long drvdata[0];
|
||||
unsigned long long drvdata[];
|
||||
};
|
||||
|
||||
#define charlcd_to_priv(p) container_of(p, struct charlcd_priv, lcd)
|
||||
|
@@ -356,7 +356,6 @@ static int img_ascii_lcd_probe(struct platform_device *pdev)
|
||||
const struct of_device_id *match;
|
||||
const struct img_ascii_lcd_config *cfg;
|
||||
struct img_ascii_lcd_ctx *ctx;
|
||||
struct resource *res;
|
||||
int err;
|
||||
|
||||
match = of_match_device(img_ascii_lcd_matches, &pdev->dev);
|
||||
@@ -378,8 +377,7 @@ static int img_ascii_lcd_probe(struct platform_device *pdev)
|
||||
&ctx->offset))
|
||||
return -EINVAL;
|
||||
} else {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ctx->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
ctx->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(ctx->base))
|
||||
return PTR_ERR(ctx->base);
|
||||
}
|
||||
|
@@ -363,10 +363,10 @@ static void setup_pdev_dma_masks(struct platform_device *pdev)
|
||||
{
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
if (!pdev->dma_mask)
|
||||
pdev->dma_mask = DMA_BIT_MASK(32);
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &pdev->dma_mask;
|
||||
if (!pdev->dev.dma_mask) {
|
||||
pdev->platform_dma_mask = DMA_BIT_MASK(32);
|
||||
pdev->dev.dma_mask = &pdev->platform_dma_mask;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -662,20 +662,8 @@ struct platform_device *platform_device_register_full(
|
||||
pdev->dev.of_node_reused = pdevinfo->of_node_reused;
|
||||
|
||||
if (pdevinfo->dma_mask) {
|
||||
/*
|
||||
* This memory isn't freed when the device is put,
|
||||
* I don't have a nice idea for that though. Conceptually
|
||||
* dma_mask in struct device should not be a pointer.
|
||||
* See http://thread.gmane.org/gmane.linux.kernel.pci/9081
|
||||
*/
|
||||
pdev->dev.dma_mask =
|
||||
kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
|
||||
if (!pdev->dev.dma_mask)
|
||||
goto err;
|
||||
|
||||
kmemleak_ignore(pdev->dev.dma_mask);
|
||||
|
||||
*pdev->dev.dma_mask = pdevinfo->dma_mask;
|
||||
pdev->platform_dma_mask = pdevinfo->dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->platform_dma_mask;
|
||||
pdev->dev.coherent_dma_mask = pdevinfo->dma_mask;
|
||||
}
|
||||
|
||||
@@ -700,7 +688,6 @@ struct platform_device *platform_device_register_full(
|
||||
if (ret) {
|
||||
err:
|
||||
ACPI_COMPANION_SET(&pdev->dev, NULL);
|
||||
kfree(pdev->dev.dma_mask);
|
||||
platform_device_put(pdev);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
@@ -247,13 +247,20 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);
|
||||
if (err) {
|
||||
virtqueue_kick(vblk->vqs[qid].vq);
|
||||
blk_mq_stop_hw_queue(hctx);
|
||||
/* Don't stop the queue if -ENOMEM: we may have failed to
|
||||
* bounce the buffer due to global resource outage.
|
||||
*/
|
||||
if (err == -ENOSPC)
|
||||
blk_mq_stop_hw_queue(hctx);
|
||||
spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
|
||||
/* Out of mem doesn't actually happen, since we fall back
|
||||
* to direct descriptors */
|
||||
if (err == -ENOMEM || err == -ENOSPC)
|
||||
switch (err) {
|
||||
case -ENOSPC:
|
||||
return BLK_STS_DEV_RESOURCE;
|
||||
return BLK_STS_IOERR;
|
||||
case -ENOMEM:
|
||||
return BLK_STS_RESOURCE;
|
||||
default:
|
||||
return BLK_STS_IOERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq))
|
||||
|
@@ -194,7 +194,7 @@ static int platform_ipmi_probe(struct platform_device *pdev)
|
||||
else
|
||||
io.slave_addr = slave_addr;
|
||||
|
||||
io.irq = platform_get_irq(pdev, 0);
|
||||
io.irq = platform_get_irq_optional(pdev, 0);
|
||||
if (io.irq > 0)
|
||||
io.irq_setup = ipmi_std_irq_setup;
|
||||
else
|
||||
@@ -378,7 +378,7 @@ static int acpi_ipmi_probe(struct platform_device *pdev)
|
||||
io.irq = tmp;
|
||||
io.irq_setup = acpi_gpe_irq_setup;
|
||||
} else {
|
||||
int irq = platform_get_irq(pdev, 0);
|
||||
int irq = platform_get_irq_optional(pdev, 0);
|
||||
|
||||
if (irq > 0) {
|
||||
io.irq = irq;
|
||||
|
@@ -4796,7 +4796,7 @@ EXPORT_SYMBOL(of_clk_get_by_name);
|
||||
*
|
||||
* Returns: The number of clocks that are possible parents of this node
|
||||
*/
|
||||
unsigned int of_clk_get_parent_count(struct device_node *np)
|
||||
unsigned int of_clk_get_parent_count(const struct device_node *np)
|
||||
{
|
||||
int count;
|
||||
|
||||
@@ -4808,7 +4808,7 @@ unsigned int of_clk_get_parent_count(struct device_node *np)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_clk_get_parent_count);
|
||||
|
||||
const char *of_clk_get_parent_name(struct device_node *np, int index)
|
||||
const char *of_clk_get_parent_name(const struct device_node *np, int index)
|
||||
{
|
||||
struct of_phandle_args clkspec;
|
||||
struct property *prop;
|
||||
|
@@ -592,24 +592,6 @@ static struct clk_branch disp_cc_mdss_rot_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
|
||||
.halt_reg = 0x400c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x400c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_rscc_ahb_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
|
||||
.halt_reg = 0x4008,
|
||||
.halt_check = BRANCH_HALT,
|
||||
@@ -687,7 +669,6 @@ static struct clk_regmap *disp_cc_sc7180_clocks[] = {
|
||||
[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
|
||||
[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
|
||||
[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
|
||||
[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
|
||||
[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
|
||||
[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
|
||||
[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
|
||||
|
@@ -97,7 +97,7 @@ static struct clk_branch video_cc_vcodec0_axi_clk = {
|
||||
|
||||
static struct clk_branch video_cc_vcodec0_core_clk = {
|
||||
.halt_reg = 0x890,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x890,
|
||||
.enable_mask = BIT(0),
|
||||
|
@@ -83,13 +83,16 @@ static ssize_t
|
||||
efivar_attr_read(struct efivar_entry *entry, char *buf)
|
||||
{
|
||||
struct efi_variable *var = &entry->var;
|
||||
unsigned long size = sizeof(var->Data);
|
||||
char *str = buf;
|
||||
int ret;
|
||||
|
||||
if (!entry || !buf)
|
||||
return -EINVAL;
|
||||
|
||||
var->DataSize = 1024;
|
||||
if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
|
||||
ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
|
||||
var->DataSize = size;
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
if (var->Attributes & EFI_VARIABLE_NON_VOLATILE)
|
||||
@@ -116,13 +119,16 @@ static ssize_t
|
||||
efivar_size_read(struct efivar_entry *entry, char *buf)
|
||||
{
|
||||
struct efi_variable *var = &entry->var;
|
||||
unsigned long size = sizeof(var->Data);
|
||||
char *str = buf;
|
||||
int ret;
|
||||
|
||||
if (!entry || !buf)
|
||||
return -EINVAL;
|
||||
|
||||
var->DataSize = 1024;
|
||||
if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
|
||||
ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
|
||||
var->DataSize = size;
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
str += sprintf(str, "0x%lx\n", var->DataSize);
|
||||
@@ -133,12 +139,15 @@ static ssize_t
|
||||
efivar_data_read(struct efivar_entry *entry, char *buf)
|
||||
{
|
||||
struct efi_variable *var = &entry->var;
|
||||
unsigned long size = sizeof(var->Data);
|
||||
int ret;
|
||||
|
||||
if (!entry || !buf)
|
||||
return -EINVAL;
|
||||
|
||||
var->DataSize = 1024;
|
||||
if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
|
||||
ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
|
||||
var->DataSize = size;
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
memcpy(buf, var->Data, var->DataSize);
|
||||
@@ -199,6 +208,9 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
|
||||
u8 *data;
|
||||
int err;
|
||||
|
||||
if (!entry || !buf)
|
||||
return -EINVAL;
|
||||
|
||||
if (in_compat_syscall()) {
|
||||
struct compat_efi_variable *compat;
|
||||
|
||||
@@ -250,14 +262,16 @@ efivar_show_raw(struct efivar_entry *entry, char *buf)
|
||||
{
|
||||
struct efi_variable *var = &entry->var;
|
||||
struct compat_efi_variable *compat;
|
||||
unsigned long datasize = sizeof(var->Data);
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
if (!entry || !buf)
|
||||
return 0;
|
||||
|
||||
var->DataSize = 1024;
|
||||
if (efivar_entry_get(entry, &entry->var.Attributes,
|
||||
&entry->var.DataSize, entry->var.Data))
|
||||
ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data);
|
||||
var->DataSize = datasize;
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
if (in_compat_syscall()) {
|
||||
|
@@ -89,6 +89,13 @@
|
||||
#define HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK 0x00010000L
|
||||
#define HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK 0x00020000L
|
||||
#define mmHDP_MEM_POWER_CTRL_BASE_IDX 0
|
||||
|
||||
/* for Vega20/arcturus regiter offset change */
|
||||
#define mmROM_INDEX_VG20 0x00e4
|
||||
#define mmROM_INDEX_VG20_BASE_IDX 0
|
||||
#define mmROM_DATA_VG20 0x00e5
|
||||
#define mmROM_DATA_VG20_BASE_IDX 0
|
||||
|
||||
/*
|
||||
* Indirect registers accessor
|
||||
*/
|
||||
@@ -309,6 +316,8 @@ static bool soc15_read_bios_from_rom(struct amdgpu_device *adev,
|
||||
{
|
||||
u32 *dw_ptr;
|
||||
u32 i, length_dw;
|
||||
uint32_t rom_index_offset;
|
||||
uint32_t rom_data_offset;
|
||||
|
||||
if (bios == NULL)
|
||||
return false;
|
||||
@@ -321,11 +330,23 @@ static bool soc15_read_bios_from_rom(struct amdgpu_device *adev,
|
||||
dw_ptr = (u32 *)bios;
|
||||
length_dw = ALIGN(length_bytes, 4) / 4;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_ARCTURUS:
|
||||
rom_index_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX_VG20);
|
||||
rom_data_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA_VG20);
|
||||
break;
|
||||
default:
|
||||
rom_index_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX);
|
||||
rom_data_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA);
|
||||
break;
|
||||
}
|
||||
|
||||
/* set rom index to 0 */
|
||||
WREG32(SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX), 0);
|
||||
WREG32(rom_index_offset, 0);
|
||||
/* read out the rom data */
|
||||
for (i = 0; i < length_dw; i++)
|
||||
dw_ptr[i] = RREG32(SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA));
|
||||
dw_ptr[i] = RREG32(rom_data_offset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -335,6 +335,117 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {
|
||||
.use_urgent_burst_bw = 0
|
||||
};
|
||||
|
||||
struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = {
|
||||
.clock_limits = {
|
||||
{
|
||||
.state = 0,
|
||||
.dcfclk_mhz = 560.0,
|
||||
.fabricclk_mhz = 560.0,
|
||||
.dispclk_mhz = 513.0,
|
||||
.dppclk_mhz = 513.0,
|
||||
.phyclk_mhz = 540.0,
|
||||
.socclk_mhz = 560.0,
|
||||
.dscclk_mhz = 171.0,
|
||||
.dram_speed_mts = 8960.0,
|
||||
},
|
||||
{
|
||||
.state = 1,
|
||||
.dcfclk_mhz = 694.0,
|
||||
.fabricclk_mhz = 694.0,
|
||||
.dispclk_mhz = 642.0,
|
||||
.dppclk_mhz = 642.0,
|
||||
.phyclk_mhz = 600.0,
|
||||
.socclk_mhz = 694.0,
|
||||
.dscclk_mhz = 214.0,
|
||||
.dram_speed_mts = 11104.0,
|
||||
},
|
||||
{
|
||||
.state = 2,
|
||||
.dcfclk_mhz = 875.0,
|
||||
.fabricclk_mhz = 875.0,
|
||||
.dispclk_mhz = 734.0,
|
||||
.dppclk_mhz = 734.0,
|
||||
.phyclk_mhz = 810.0,
|
||||
.socclk_mhz = 875.0,
|
||||
.dscclk_mhz = 245.0,
|
||||
.dram_speed_mts = 14000.0,
|
||||
},
|
||||
{
|
||||
.state = 3,
|
||||
.dcfclk_mhz = 1000.0,
|
||||
.fabricclk_mhz = 1000.0,
|
||||
.dispclk_mhz = 1100.0,
|
||||
.dppclk_mhz = 1100.0,
|
||||
.phyclk_mhz = 810.0,
|
||||
.socclk_mhz = 1000.0,
|
||||
.dscclk_mhz = 367.0,
|
||||
.dram_speed_mts = 16000.0,
|
||||
},
|
||||
{
|
||||
.state = 4,
|
||||
.dcfclk_mhz = 1200.0,
|
||||
.fabricclk_mhz = 1200.0,
|
||||
.dispclk_mhz = 1284.0,
|
||||
.dppclk_mhz = 1284.0,
|
||||
.phyclk_mhz = 810.0,
|
||||
.socclk_mhz = 1200.0,
|
||||
.dscclk_mhz = 428.0,
|
||||
.dram_speed_mts = 16000.0,
|
||||
},
|
||||
/*Extra state, no dispclk ramping*/
|
||||
{
|
||||
.state = 5,
|
||||
.dcfclk_mhz = 1200.0,
|
||||
.fabricclk_mhz = 1200.0,
|
||||
.dispclk_mhz = 1284.0,
|
||||
.dppclk_mhz = 1284.0,
|
||||
.phyclk_mhz = 810.0,
|
||||
.socclk_mhz = 1200.0,
|
||||
.dscclk_mhz = 428.0,
|
||||
.dram_speed_mts = 16000.0,
|
||||
},
|
||||
},
|
||||
.num_states = 5,
|
||||
.sr_exit_time_us = 8.6,
|
||||
.sr_enter_plus_exit_time_us = 10.9,
|
||||
.urgent_latency_us = 4.0,
|
||||
.urgent_latency_pixel_data_only_us = 4.0,
|
||||
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
|
||||
.urgent_latency_vm_data_only_us = 4.0,
|
||||
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
|
||||
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
|
||||
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
|
||||
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,
|
||||
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,
|
||||
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
|
||||
.max_avg_sdp_bw_use_normal_percent = 40.0,
|
||||
.max_avg_dram_bw_use_normal_percent = 40.0,
|
||||
.writeback_latency_us = 12.0,
|
||||
.ideal_dram_bw_after_urgent_percent = 40.0,
|
||||
.max_request_size_bytes = 256,
|
||||
.dram_channel_width_bytes = 2,
|
||||
.fabric_datapath_to_dcn_data_return_bytes = 64,
|
||||
.dcn_downspread_percent = 0.5,
|
||||
.downspread_percent = 0.38,
|
||||
.dram_page_open_time_ns = 50.0,
|
||||
.dram_rw_turnaround_time_ns = 17.5,
|
||||
.dram_return_buffer_per_channel_bytes = 8192,
|
||||
.round_trip_ping_latency_dcfclk_cycles = 131,
|
||||
.urgent_out_of_order_return_per_channel_bytes = 256,
|
||||
.channel_interleave_bytes = 256,
|
||||
.num_banks = 8,
|
||||
.num_chans = 8,
|
||||
.vmm_page_size_bytes = 4096,
|
||||
.dram_clock_change_latency_us = 404.0,
|
||||
.dummy_pstate_latency_us = 5.0,
|
||||
.writeback_dram_clock_change_latency_us = 23.0,
|
||||
.return_bus_width_bytes = 64,
|
||||
.dispclk_dppclk_vco_speed_mhz = 3850,
|
||||
.xfc_bus_transport_time_us = 20,
|
||||
.xfc_xbuf_latency_tolerance_us = 4,
|
||||
.use_urgent_burst_bw = 0
|
||||
};
|
||||
|
||||
struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 };
|
||||
|
||||
#ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
|
||||
@@ -3291,6 +3402,9 @@ void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st
|
||||
static struct _vcs_dpi_soc_bounding_box_st *get_asic_rev_soc_bb(
|
||||
uint32_t hw_internal_rev)
|
||||
{
|
||||
if (ASICREV_IS_NAVI14_M(hw_internal_rev))
|
||||
return &dcn2_0_nv14_soc;
|
||||
|
||||
if (ASICREV_IS_NAVI12_P(hw_internal_rev))
|
||||
return &dcn2_0_nv12_soc;
|
||||
|
||||
|
@@ -2006,8 +2006,11 @@ int smu_set_watermarks_for_clock_ranges(struct smu_context *smu,
|
||||
smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) &&
|
||||
smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
|
||||
smu_set_watermarks_table(smu, table, clock_ranges);
|
||||
smu->watermarks_bitmap |= WATERMARKS_EXIST;
|
||||
smu->watermarks_bitmap &= ~WATERMARKS_LOADED;
|
||||
|
||||
if (!(smu->watermarks_bitmap & WATERMARKS_EXIST)) {
|
||||
smu->watermarks_bitmap |= WATERMARKS_EXIST;
|
||||
smu->watermarks_bitmap &= ~WATERMARKS_LOADED;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&smu->mutex);
|
||||
|
@@ -1062,15 +1062,6 @@ static int navi10_display_config_changed(struct smu_context *smu)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
|
||||
!(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
|
||||
ret = smu_write_watermarks_table(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
smu->watermarks_bitmap |= WATERMARKS_LOADED;
|
||||
}
|
||||
|
||||
if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
|
||||
smu_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) &&
|
||||
smu_feature_is_supported(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
|
||||
@@ -1493,6 +1484,7 @@ static int navi10_set_watermarks_table(struct smu_context *smu,
|
||||
*clock_ranges)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
Watermarks_t *table = watermarks;
|
||||
|
||||
if (!table || !clock_ranges)
|
||||
@@ -1544,6 +1536,18 @@ static int navi10_set_watermarks_table(struct smu_context *smu,
|
||||
clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
|
||||
}
|
||||
|
||||
smu->watermarks_bitmap |= WATERMARKS_EXIST;
|
||||
|
||||
/* pass data to smu controller */
|
||||
if (!(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
|
||||
ret = smu_write_watermarks_table(smu);
|
||||
if (ret) {
|
||||
pr_err("Failed to update WMTABLE!");
|
||||
return ret;
|
||||
}
|
||||
smu->watermarks_bitmap |= WATERMARKS_LOADED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -806,9 +806,10 @@ static int renoir_set_watermarks_table(
|
||||
clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
|
||||
}
|
||||
|
||||
smu->watermarks_bitmap |= WATERMARKS_EXIST;
|
||||
|
||||
/* pass data to smu controller */
|
||||
if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
|
||||
!(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
|
||||
if (!(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
|
||||
ret = smu_write_watermarks_table(smu);
|
||||
if (ret) {
|
||||
pr_err("Failed to update WMTABLE!");
|
||||
|
@@ -1935,7 +1935,7 @@ static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,
|
||||
return parent_lct + 1;
|
||||
}
|
||||
|
||||
static bool drm_dp_mst_is_dp_mst_end_device(u8 pdt, bool mcs)
|
||||
static bool drm_dp_mst_is_end_device(u8 pdt, bool mcs)
|
||||
{
|
||||
switch (pdt) {
|
||||
case DP_PEER_DEVICE_DP_LEGACY_CONV:
|
||||
@@ -1965,13 +1965,13 @@ drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt,
|
||||
|
||||
/* Teardown the old pdt, if there is one */
|
||||
if (port->pdt != DP_PEER_DEVICE_NONE) {
|
||||
if (drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) {
|
||||
if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
|
||||
/*
|
||||
* If the new PDT would also have an i2c bus,
|
||||
* don't bother with reregistering it
|
||||
*/
|
||||
if (new_pdt != DP_PEER_DEVICE_NONE &&
|
||||
drm_dp_mst_is_dp_mst_end_device(new_pdt, new_mcs)) {
|
||||
drm_dp_mst_is_end_device(new_pdt, new_mcs)) {
|
||||
port->pdt = new_pdt;
|
||||
port->mcs = new_mcs;
|
||||
return 0;
|
||||
@@ -1991,7 +1991,7 @@ drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt,
|
||||
port->mcs = new_mcs;
|
||||
|
||||
if (port->pdt != DP_PEER_DEVICE_NONE) {
|
||||
if (drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) {
|
||||
if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
|
||||
/* add i2c over sideband */
|
||||
ret = drm_dp_mst_register_i2c_bus(&port->aux);
|
||||
} else {
|
||||
@@ -2172,7 +2172,7 @@ drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb,
|
||||
}
|
||||
|
||||
if (port->pdt != DP_PEER_DEVICE_NONE &&
|
||||
drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) {
|
||||
drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
|
||||
port->cached_edid = drm_get_edid(port->connector,
|
||||
&port->aux.ddc);
|
||||
drm_connector_set_tile_property(port->connector);
|
||||
@@ -2302,14 +2302,18 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
|
||||
mutex_unlock(&mgr->lock);
|
||||
}
|
||||
|
||||
if (old_ddps != port->ddps) {
|
||||
if (port->ddps) {
|
||||
if (!port->input) {
|
||||
drm_dp_send_enum_path_resources(mgr, mstb,
|
||||
port);
|
||||
}
|
||||
/*
|
||||
* Reprobe PBN caps on both hotplug, and when re-probing the link
|
||||
* for our parent mstb
|
||||
*/
|
||||
if (old_ddps != port->ddps || !created) {
|
||||
if (port->ddps && !port->input) {
|
||||
ret = drm_dp_send_enum_path_resources(mgr, mstb,
|
||||
port);
|
||||
if (ret == 1)
|
||||
changed = true;
|
||||
} else {
|
||||
port->available_pbn = 0;
|
||||
port->full_pbn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2401,11 +2405,10 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
|
||||
port->ddps = conn_stat->displayport_device_plug_status;
|
||||
|
||||
if (old_ddps != port->ddps) {
|
||||
if (port->ddps) {
|
||||
dowork = true;
|
||||
} else {
|
||||
port->available_pbn = 0;
|
||||
}
|
||||
if (port->ddps && !port->input)
|
||||
drm_dp_send_enum_path_resources(mgr, mstb, port);
|
||||
else
|
||||
port->full_pbn = 0;
|
||||
}
|
||||
|
||||
new_pdt = port->input ? DP_PEER_DEVICE_NONE : conn_stat->peer_device_type;
|
||||
@@ -2556,13 +2559,6 @@ static int drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mg
|
||||
if (port->input || !port->ddps)
|
||||
continue;
|
||||
|
||||
if (!port->available_pbn) {
|
||||
drm_modeset_lock(&mgr->base.lock, NULL);
|
||||
drm_dp_send_enum_path_resources(mgr, mstb, port);
|
||||
drm_modeset_unlock(&mgr->base.lock);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (port->mstb)
|
||||
mstb_child = drm_dp_mst_topology_get_mstb_validated(
|
||||
mgr, port->mstb);
|
||||
@@ -2990,6 +2986,7 @@ drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
|
||||
|
||||
ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
|
||||
if (ret > 0) {
|
||||
ret = 0;
|
||||
path_res = &txmsg->reply.u.path_resources;
|
||||
|
||||
if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
|
||||
@@ -3002,14 +2999,22 @@ drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
|
||||
path_res->port_number,
|
||||
path_res->full_payload_bw_number,
|
||||
path_res->avail_payload_bw_number);
|
||||
port->available_pbn =
|
||||
path_res->avail_payload_bw_number;
|
||||
|
||||
/*
|
||||
* If something changed, make sure we send a
|
||||
* hotplug
|
||||
*/
|
||||
if (port->full_pbn != path_res->full_payload_bw_number ||
|
||||
port->fec_capable != path_res->fec_capable)
|
||||
ret = 1;
|
||||
|
||||
port->full_pbn = path_res->full_payload_bw_number;
|
||||
port->fec_capable = path_res->fec_capable;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(txmsg);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct drm_dp_mst_port *drm_dp_get_last_connected_port_to_mstb(struct drm_dp_mst_branch *mstb)
|
||||
@@ -3596,13 +3601,9 @@ drm_dp_mst_topology_mgr_invalidate_mstb(struct drm_dp_mst_branch *mstb)
|
||||
/* The link address will need to be re-sent on resume */
|
||||
mstb->link_address_sent = false;
|
||||
|
||||
list_for_each_entry(port, &mstb->ports, next) {
|
||||
/* The PBN for each port will also need to be re-probed */
|
||||
port->available_pbn = 0;
|
||||
|
||||
list_for_each_entry(port, &mstb->ports, next)
|
||||
if (port->mstb)
|
||||
drm_dp_mst_topology_mgr_invalidate_mstb(port->mstb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4829,41 +4830,102 @@ static bool drm_dp_mst_port_downstream_of_branch(struct drm_dp_mst_port *port,
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline
|
||||
int drm_dp_mst_atomic_check_bw_limit(struct drm_dp_mst_branch *branch,
|
||||
struct drm_dp_mst_topology_state *mst_state)
|
||||
static int
|
||||
drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
|
||||
struct drm_dp_mst_topology_state *state);
|
||||
|
||||
static int
|
||||
drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb,
|
||||
struct drm_dp_mst_topology_state *state)
|
||||
{
|
||||
struct drm_dp_mst_port *port;
|
||||
struct drm_dp_vcpi_allocation *vcpi;
|
||||
int pbn_limit = 0, pbn_used = 0;
|
||||
struct drm_dp_mst_port *port;
|
||||
int pbn_used = 0, ret;
|
||||
bool found = false;
|
||||
|
||||
list_for_each_entry(port, &branch->ports, next) {
|
||||
if (port->mstb)
|
||||
if (drm_dp_mst_atomic_check_bw_limit(port->mstb, mst_state))
|
||||
return -ENOSPC;
|
||||
|
||||
if (port->available_pbn > 0)
|
||||
pbn_limit = port->available_pbn;
|
||||
}
|
||||
DRM_DEBUG_ATOMIC("[MST BRANCH:%p] branch has %d PBN available\n",
|
||||
branch, pbn_limit);
|
||||
|
||||
list_for_each_entry(vcpi, &mst_state->vcpis, next) {
|
||||
if (!vcpi->pbn)
|
||||
/* Check that we have at least one port in our state that's downstream
|
||||
* of this branch, otherwise we can skip this branch
|
||||
*/
|
||||
list_for_each_entry(vcpi, &state->vcpis, next) {
|
||||
if (!vcpi->pbn ||
|
||||
!drm_dp_mst_port_downstream_of_branch(vcpi->port, mstb))
|
||||
continue;
|
||||
|
||||
if (drm_dp_mst_port_downstream_of_branch(vcpi->port, branch))
|
||||
pbn_used += vcpi->pbn;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
DRM_DEBUG_ATOMIC("[MST BRANCH:%p] branch used %d PBN\n",
|
||||
branch, pbn_used);
|
||||
if (!found)
|
||||
return 0;
|
||||
|
||||
if (pbn_used > pbn_limit) {
|
||||
DRM_DEBUG_ATOMIC("[MST BRANCH:%p] No available bandwidth\n",
|
||||
branch);
|
||||
if (mstb->port_parent)
|
||||
DRM_DEBUG_ATOMIC("[MSTB:%p] [MST PORT:%p] Checking bandwidth limits on [MSTB:%p]\n",
|
||||
mstb->port_parent->parent, mstb->port_parent,
|
||||
mstb);
|
||||
else
|
||||
DRM_DEBUG_ATOMIC("[MSTB:%p] Checking bandwidth limits\n",
|
||||
mstb);
|
||||
|
||||
list_for_each_entry(port, &mstb->ports, next) {
|
||||
ret = drm_dp_mst_atomic_check_port_bw_limit(port, state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
pbn_used += ret;
|
||||
}
|
||||
|
||||
return pbn_used;
|
||||
}
|
||||
|
||||
static int
|
||||
drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
|
||||
struct drm_dp_mst_topology_state *state)
|
||||
{
|
||||
struct drm_dp_vcpi_allocation *vcpi;
|
||||
int pbn_used = 0;
|
||||
|
||||
if (port->pdt == DP_PEER_DEVICE_NONE)
|
||||
return 0;
|
||||
|
||||
if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
|
||||
bool found = false;
|
||||
|
||||
list_for_each_entry(vcpi, &state->vcpis, next) {
|
||||
if (vcpi->port != port)
|
||||
continue;
|
||||
if (!vcpi->pbn)
|
||||
return 0;
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
return 0;
|
||||
|
||||
/* This should never happen, as it means we tried to
|
||||
* set a mode before querying the full_pbn
|
||||
*/
|
||||
if (WARN_ON(!port->full_pbn))
|
||||
return -EINVAL;
|
||||
|
||||
pbn_used = vcpi->pbn;
|
||||
} else {
|
||||
pbn_used = drm_dp_mst_atomic_check_mstb_bw_limit(port->mstb,
|
||||
state);
|
||||
if (pbn_used <= 0)
|
||||
return pbn_used;
|
||||
}
|
||||
|
||||
if (pbn_used > port->full_pbn) {
|
||||
DRM_DEBUG_ATOMIC("[MSTB:%p] [MST PORT:%p] required PBN of %d exceeds port limit of %d\n",
|
||||
port->parent, port, pbn_used,
|
||||
port->full_pbn);
|
||||
return -ENOSPC;
|
||||
}
|
||||
return 0;
|
||||
|
||||
DRM_DEBUG_ATOMIC("[MSTB:%p] [MST PORT:%p] uses %d out of %d PBN\n",
|
||||
port->parent, port, pbn_used, port->full_pbn);
|
||||
|
||||
return pbn_used;
|
||||
}
|
||||
|
||||
static inline int
|
||||
@@ -5061,9 +5123,15 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state *state)
|
||||
ret = drm_dp_mst_atomic_check_vcpi_alloc_limit(mgr, mst_state);
|
||||
if (ret)
|
||||
break;
|
||||
ret = drm_dp_mst_atomic_check_bw_limit(mgr->mst_primary, mst_state);
|
||||
if (ret)
|
||||
|
||||
mutex_lock(&mgr->lock);
|
||||
ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,
|
||||
mst_state);
|
||||
mutex_unlock(&mgr->lock);
|
||||
if (ret < 0)
|
||||
break;
|
||||
else
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@@ -55,6 +55,7 @@ static const char * const decon_clks_name[] = {
|
||||
struct decon_context {
|
||||
struct device *dev;
|
||||
struct drm_device *drm_dev;
|
||||
void *dma_priv;
|
||||
struct exynos_drm_crtc *crtc;
|
||||
struct exynos_drm_plane planes[WINDOWS_NR];
|
||||
struct exynos_drm_plane_config configs[WINDOWS_NR];
|
||||
@@ -644,7 +645,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
|
||||
|
||||
decon_clear_channels(ctx->crtc);
|
||||
|
||||
return exynos_drm_register_dma(drm_dev, dev);
|
||||
return exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv);
|
||||
}
|
||||
|
||||
static void decon_unbind(struct device *dev, struct device *master, void *data)
|
||||
@@ -654,7 +655,7 @@ static void decon_unbind(struct device *dev, struct device *master, void *data)
|
||||
decon_atomic_disable(ctx->crtc);
|
||||
|
||||
/* detach this sub driver from iommu mapping if supported. */
|
||||
exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev);
|
||||
exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv);
|
||||
}
|
||||
|
||||
static const struct component_ops decon_component_ops = {
|
||||
|
@@ -40,6 +40,7 @@
|
||||
struct decon_context {
|
||||
struct device *dev;
|
||||
struct drm_device *drm_dev;
|
||||
void *dma_priv;
|
||||
struct exynos_drm_crtc *crtc;
|
||||
struct exynos_drm_plane planes[WINDOWS_NR];
|
||||
struct exynos_drm_plane_config configs[WINDOWS_NR];
|
||||
@@ -127,13 +128,13 @@ static int decon_ctx_initialize(struct decon_context *ctx,
|
||||
|
||||
decon_clear_channels(ctx->crtc);
|
||||
|
||||
return exynos_drm_register_dma(drm_dev, ctx->dev);
|
||||
return exynos_drm_register_dma(drm_dev, ctx->dev, &ctx->dma_priv);
|
||||
}
|
||||
|
||||
static void decon_ctx_remove(struct decon_context *ctx)
|
||||
{
|
||||
/* detach this sub driver from iommu mapping if supported. */
|
||||
exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev);
|
||||
exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv);
|
||||
}
|
||||
|
||||
static u32 decon_calc_clkdiv(struct decon_context *ctx,
|
||||
|
@@ -58,7 +58,7 @@ static inline void clear_dma_max_seg_size(struct device *dev)
|
||||
* mapping.
|
||||
*/
|
||||
static int drm_iommu_attach_device(struct drm_device *drm_dev,
|
||||
struct device *subdrv_dev)
|
||||
struct device *subdrv_dev, void **dma_priv)
|
||||
{
|
||||
struct exynos_drm_private *priv = drm_dev->dev_private;
|
||||
int ret;
|
||||
@@ -74,7 +74,14 @@ static int drm_iommu_attach_device(struct drm_device *drm_dev,
|
||||
return ret;
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
|
||||
if (to_dma_iommu_mapping(subdrv_dev))
|
||||
/*
|
||||
* Keep the original DMA mapping of the sub-device and
|
||||
* restore it on Exynos DRM detach, otherwise the DMA
|
||||
* framework considers it as IOMMU-less during the next
|
||||
* probe (in case of deferred probe or modular build)
|
||||
*/
|
||||
*dma_priv = to_dma_iommu_mapping(subdrv_dev);
|
||||
if (*dma_priv)
|
||||
arm_iommu_detach_device(subdrv_dev);
|
||||
|
||||
ret = arm_iommu_attach_device(subdrv_dev, priv->mapping);
|
||||
@@ -98,19 +105,21 @@ static int drm_iommu_attach_device(struct drm_device *drm_dev,
|
||||
* mapping
|
||||
*/
|
||||
static void drm_iommu_detach_device(struct drm_device *drm_dev,
|
||||
struct device *subdrv_dev)
|
||||
struct device *subdrv_dev, void **dma_priv)
|
||||
{
|
||||
struct exynos_drm_private *priv = drm_dev->dev_private;
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU))
|
||||
if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
|
||||
arm_iommu_detach_device(subdrv_dev);
|
||||
else if (IS_ENABLED(CONFIG_IOMMU_DMA))
|
||||
arm_iommu_attach_device(subdrv_dev, *dma_priv);
|
||||
} else if (IS_ENABLED(CONFIG_IOMMU_DMA))
|
||||
iommu_detach_device(priv->mapping, subdrv_dev);
|
||||
|
||||
clear_dma_max_seg_size(subdrv_dev);
|
||||
}
|
||||
|
||||
int exynos_drm_register_dma(struct drm_device *drm, struct device *dev)
|
||||
int exynos_drm_register_dma(struct drm_device *drm, struct device *dev,
|
||||
void **dma_priv)
|
||||
{
|
||||
struct exynos_drm_private *priv = drm->dev_private;
|
||||
|
||||
@@ -137,13 +146,14 @@ int exynos_drm_register_dma(struct drm_device *drm, struct device *dev)
|
||||
priv->mapping = mapping;
|
||||
}
|
||||
|
||||
return drm_iommu_attach_device(drm, dev);
|
||||
return drm_iommu_attach_device(drm, dev, dma_priv);
|
||||
}
|
||||
|
||||
void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev)
|
||||
void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev,
|
||||
void **dma_priv)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_EXYNOS_IOMMU))
|
||||
drm_iommu_detach_device(drm, dev);
|
||||
drm_iommu_detach_device(drm, dev, dma_priv);
|
||||
}
|
||||
|
||||
void exynos_drm_cleanup_dma(struct drm_device *drm)
|
||||
|
@@ -223,8 +223,10 @@ static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
|
||||
return priv->mapping ? true : false;
|
||||
}
|
||||
|
||||
int exynos_drm_register_dma(struct drm_device *drm, struct device *dev);
|
||||
void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev);
|
||||
int exynos_drm_register_dma(struct drm_device *drm, struct device *dev,
|
||||
void **dma_priv);
|
||||
void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev,
|
||||
void **dma_priv);
|
||||
void exynos_drm_cleanup_dma(struct drm_device *drm);
|
||||
|
||||
#ifdef CONFIG_DRM_EXYNOS_DPI
|
||||
|
@@ -97,6 +97,7 @@ struct fimc_scaler {
|
||||
struct fimc_context {
|
||||
struct exynos_drm_ipp ipp;
|
||||
struct drm_device *drm_dev;
|
||||
void *dma_priv;
|
||||
struct device *dev;
|
||||
struct exynos_drm_ipp_task *task;
|
||||
struct exynos_drm_ipp_formats *formats;
|
||||
@@ -1133,7 +1134,7 @@ static int fimc_bind(struct device *dev, struct device *master, void *data)
|
||||
|
||||
ctx->drm_dev = drm_dev;
|
||||
ipp->drm_dev = drm_dev;
|
||||
exynos_drm_register_dma(drm_dev, dev);
|
||||
exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv);
|
||||
|
||||
exynos_drm_ipp_register(dev, ipp, &ipp_funcs,
|
||||
DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
|
||||
@@ -1153,7 +1154,7 @@ static void fimc_unbind(struct device *dev, struct device *master,
|
||||
struct exynos_drm_ipp *ipp = &ctx->ipp;
|
||||
|
||||
exynos_drm_ipp_unregister(dev, ipp);
|
||||
exynos_drm_unregister_dma(drm_dev, dev);
|
||||
exynos_drm_unregister_dma(drm_dev, dev, &ctx->dma_priv);
|
||||
}
|
||||
|
||||
static const struct component_ops fimc_component_ops = {
|
||||
|
@@ -167,6 +167,7 @@ static struct fimd_driver_data exynos5420_fimd_driver_data = {
|
||||
struct fimd_context {
|
||||
struct device *dev;
|
||||
struct drm_device *drm_dev;
|
||||
void *dma_priv;
|
||||
struct exynos_drm_crtc *crtc;
|
||||
struct exynos_drm_plane planes[WINDOWS_NR];
|
||||
struct exynos_drm_plane_config configs[WINDOWS_NR];
|
||||
@@ -1090,7 +1091,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
|
||||
if (is_drm_iommu_supported(drm_dev))
|
||||
fimd_clear_channels(ctx->crtc);
|
||||
|
||||
return exynos_drm_register_dma(drm_dev, dev);
|
||||
return exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv);
|
||||
}
|
||||
|
||||
static void fimd_unbind(struct device *dev, struct device *master,
|
||||
@@ -1100,7 +1101,7 @@ static void fimd_unbind(struct device *dev, struct device *master,
|
||||
|
||||
fimd_atomic_disable(ctx->crtc);
|
||||
|
||||
exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev);
|
||||
exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv);
|
||||
|
||||
if (ctx->encoder)
|
||||
exynos_dpi_remove(ctx->encoder);
|
||||
|
@@ -232,6 +232,7 @@ struct g2d_runqueue_node {
|
||||
|
||||
struct g2d_data {
|
||||
struct device *dev;
|
||||
void *dma_priv;
|
||||
struct clk *gate_clk;
|
||||
void __iomem *regs;
|
||||
int irq;
|
||||
@@ -1409,7 +1410,7 @@ static int g2d_bind(struct device *dev, struct device *master, void *data)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = exynos_drm_register_dma(drm_dev, dev);
|
||||
ret = exynos_drm_register_dma(drm_dev, dev, &g2d->dma_priv);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to enable iommu.\n");
|
||||
g2d_fini_cmdlist(g2d);
|
||||
@@ -1434,7 +1435,7 @@ static void g2d_unbind(struct device *dev, struct device *master, void *data)
|
||||
priv->g2d_dev = NULL;
|
||||
|
||||
cancel_work_sync(&g2d->runqueue_work);
|
||||
exynos_drm_unregister_dma(g2d->drm_dev, dev);
|
||||
exynos_drm_unregister_dma(g2d->drm_dev, dev, &g2d->dma_priv);
|
||||
}
|
||||
|
||||
static const struct component_ops g2d_component_ops = {
|
||||
|
@@ -97,6 +97,7 @@ struct gsc_scaler {
|
||||
struct gsc_context {
|
||||
struct exynos_drm_ipp ipp;
|
||||
struct drm_device *drm_dev;
|
||||
void *dma_priv;
|
||||
struct device *dev;
|
||||
struct exynos_drm_ipp_task *task;
|
||||
struct exynos_drm_ipp_formats *formats;
|
||||
@@ -1169,7 +1170,7 @@ static int gsc_bind(struct device *dev, struct device *master, void *data)
|
||||
|
||||
ctx->drm_dev = drm_dev;
|
||||
ctx->drm_dev = drm_dev;
|
||||
exynos_drm_register_dma(drm_dev, dev);
|
||||
exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv);
|
||||
|
||||
exynos_drm_ipp_register(dev, ipp, &ipp_funcs,
|
||||
DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
|
||||
@@ -1189,7 +1190,7 @@ static void gsc_unbind(struct device *dev, struct device *master,
|
||||
struct exynos_drm_ipp *ipp = &ctx->ipp;
|
||||
|
||||
exynos_drm_ipp_unregister(dev, ipp);
|
||||
exynos_drm_unregister_dma(drm_dev, dev);
|
||||
exynos_drm_unregister_dma(drm_dev, dev, &ctx->dma_priv);
|
||||
}
|
||||
|
||||
static const struct component_ops gsc_component_ops = {
|
||||
|
@@ -56,6 +56,7 @@ struct rot_variant {
|
||||
struct rot_context {
|
||||
struct exynos_drm_ipp ipp;
|
||||
struct drm_device *drm_dev;
|
||||
void *dma_priv;
|
||||
struct device *dev;
|
||||
void __iomem *regs;
|
||||
struct clk *clock;
|
||||
@@ -243,7 +244,7 @@ static int rotator_bind(struct device *dev, struct device *master, void *data)
|
||||
|
||||
rot->drm_dev = drm_dev;
|
||||
ipp->drm_dev = drm_dev;
|
||||
exynos_drm_register_dma(drm_dev, dev);
|
||||
exynos_drm_register_dma(drm_dev, dev, &rot->dma_priv);
|
||||
|
||||
exynos_drm_ipp_register(dev, ipp, &ipp_funcs,
|
||||
DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE,
|
||||
@@ -261,7 +262,7 @@ static void rotator_unbind(struct device *dev, struct device *master,
|
||||
struct exynos_drm_ipp *ipp = &rot->ipp;
|
||||
|
||||
exynos_drm_ipp_unregister(dev, ipp);
|
||||
exynos_drm_unregister_dma(rot->drm_dev, rot->dev);
|
||||
exynos_drm_unregister_dma(rot->drm_dev, rot->dev, &rot->dma_priv);
|
||||
}
|
||||
|
||||
static const struct component_ops rotator_component_ops = {
|
||||
|
@@ -39,6 +39,7 @@ struct scaler_data {
|
||||
struct scaler_context {
|
||||
struct exynos_drm_ipp ipp;
|
||||
struct drm_device *drm_dev;
|
||||
void *dma_priv;
|
||||
struct device *dev;
|
||||
void __iomem *regs;
|
||||
struct clk *clock[SCALER_MAX_CLK];
|
||||
@@ -450,7 +451,7 @@ static int scaler_bind(struct device *dev, struct device *master, void *data)
|
||||
|
||||
scaler->drm_dev = drm_dev;
|
||||
ipp->drm_dev = drm_dev;
|
||||
exynos_drm_register_dma(drm_dev, dev);
|
||||
exynos_drm_register_dma(drm_dev, dev, &scaler->dma_priv);
|
||||
|
||||
exynos_drm_ipp_register(dev, ipp, &ipp_funcs,
|
||||
DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
|
||||
@@ -470,7 +471,8 @@ static void scaler_unbind(struct device *dev, struct device *master,
|
||||
struct exynos_drm_ipp *ipp = &scaler->ipp;
|
||||
|
||||
exynos_drm_ipp_unregister(dev, ipp);
|
||||
exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev);
|
||||
exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev,
|
||||
&scaler->dma_priv);
|
||||
}
|
||||
|
||||
static const struct component_ops scaler_component_ops = {
|
||||
|
@@ -94,6 +94,7 @@ struct mixer_context {
|
||||
struct platform_device *pdev;
|
||||
struct device *dev;
|
||||
struct drm_device *drm_dev;
|
||||
void *dma_priv;
|
||||
struct exynos_drm_crtc *crtc;
|
||||
struct exynos_drm_plane planes[MIXER_WIN_NR];
|
||||
unsigned long flags;
|
||||
@@ -894,12 +895,14 @@ static int mixer_initialize(struct mixer_context *mixer_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
return exynos_drm_register_dma(drm_dev, mixer_ctx->dev);
|
||||
return exynos_drm_register_dma(drm_dev, mixer_ctx->dev,
|
||||
&mixer_ctx->dma_priv);
|
||||
}
|
||||
|
||||
static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
|
||||
{
|
||||
exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev);
|
||||
exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev,
|
||||
&mixer_ctx->dma_priv);
|
||||
}
|
||||
|
||||
static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
|
||||
|
@@ -423,7 +423,8 @@ eb_validate_vma(struct i915_execbuffer *eb,
|
||||
if (unlikely(entry->flags & eb->invalid_flags))
|
||||
return -EINVAL;
|
||||
|
||||
if (unlikely(entry->alignment && !is_power_of_2(entry->alignment)))
|
||||
if (unlikely(entry->alignment &&
|
||||
!is_power_of_2_u64(entry->alignment)))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
|
@@ -1679,11 +1679,9 @@ need_timeslice(struct intel_engine_cs *engine, const struct i915_request *rq)
|
||||
if (!intel_engine_has_timeslices(engine))
|
||||
return false;
|
||||
|
||||
if (list_is_last(&rq->sched.link, &engine->active.requests))
|
||||
return false;
|
||||
|
||||
hint = max(rq_prio(list_next_entry(rq, sched.link)),
|
||||
engine->execlists.queue_priority_hint);
|
||||
hint = engine->execlists.queue_priority_hint;
|
||||
if (!list_is_last(&rq->sched.link, &engine->active.requests))
|
||||
hint = max(hint, rq_prio(list_next_entry(rq, sched.link)));
|
||||
|
||||
return hint >= effective_prio(rq);
|
||||
}
|
||||
@@ -1725,6 +1723,18 @@ static void set_timeslice(struct intel_engine_cs *engine)
|
||||
set_timer_ms(&engine->execlists.timer, active_timeslice(engine));
|
||||
}
|
||||
|
||||
static void start_timeslice(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct intel_engine_execlists *execlists = &engine->execlists;
|
||||
|
||||
execlists->switch_priority_hint = execlists->queue_priority_hint;
|
||||
|
||||
if (timer_pending(&execlists->timer))
|
||||
return;
|
||||
|
||||
set_timer_ms(&execlists->timer, timeslice(engine));
|
||||
}
|
||||
|
||||
static void record_preemption(struct intel_engine_execlists *execlists)
|
||||
{
|
||||
(void)I915_SELFTEST_ONLY(execlists->preempt_hang.count++);
|
||||
@@ -1888,11 +1898,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
|
||||
* Even if ELSP[1] is occupied and not worthy
|
||||
* of timeslices, our queue might be.
|
||||
*/
|
||||
if (!execlists->timer.expires &&
|
||||
need_timeslice(engine, last))
|
||||
set_timer_ms(&execlists->timer,
|
||||
timeslice(engine));
|
||||
|
||||
start_timeslice(engine);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1927,7 +1933,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
|
||||
|
||||
if (last && !can_merge_rq(last, rq)) {
|
||||
spin_unlock(&ve->base.active.lock);
|
||||
return; /* leave this for another */
|
||||
start_timeslice(engine);
|
||||
return; /* leave this for another sibling */
|
||||
}
|
||||
|
||||
ENGINE_TRACE(engine,
|
||||
|
@@ -192,11 +192,15 @@ static void cacheline_release(struct intel_timeline_cacheline *cl)
|
||||
|
||||
static void cacheline_free(struct intel_timeline_cacheline *cl)
|
||||
{
|
||||
if (!i915_active_acquire_if_busy(&cl->active)) {
|
||||
__idle_cacheline_free(cl);
|
||||
return;
|
||||
}
|
||||
|
||||
GEM_BUG_ON(ptr_test_bit(cl->vaddr, CACHELINE_FREE));
|
||||
cl->vaddr = ptr_set_bit(cl->vaddr, CACHELINE_FREE);
|
||||
|
||||
if (i915_active_is_idle(&cl->active))
|
||||
__idle_cacheline_free(cl);
|
||||
i915_active_release(&cl->active);
|
||||
}
|
||||
|
||||
int intel_timeline_init(struct intel_timeline *timeline,
|
||||
|
@@ -457,7 +457,8 @@ void intel_vgpu_emulate_hotplug(struct intel_vgpu *vgpu, bool connected)
|
||||
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
|
||||
|
||||
/* TODO: add more platforms support */
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) ||
|
||||
IS_COFFEELAKE(dev_priv)) {
|
||||
if (connected) {
|
||||
vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
|
||||
SFUSE_STRAP_DDID_DETECTED;
|
||||
|
@@ -147,15 +147,14 @@ static void virt_vbt_generation(struct vbt *v)
|
||||
/* there's features depending on version! */
|
||||
v->header.version = 155;
|
||||
v->header.header_size = sizeof(v->header);
|
||||
v->header.vbt_size = sizeof(struct vbt) - sizeof(v->header);
|
||||
v->header.vbt_size = sizeof(struct vbt);
|
||||
v->header.bdb_offset = offsetof(struct vbt, bdb_header);
|
||||
|
||||
strcpy(&v->bdb_header.signature[0], "BIOS_DATA_BLOCK");
|
||||
v->bdb_header.version = 186; /* child_dev_size = 33 */
|
||||
v->bdb_header.header_size = sizeof(v->bdb_header);
|
||||
|
||||
v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header)
|
||||
- sizeof(struct bdb_header);
|
||||
v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header);
|
||||
|
||||
/* general features */
|
||||
v->general_features_header.id = BDB_GENERAL_FEATURES;
|
||||
|
@@ -272,10 +272,17 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
|
||||
{
|
||||
struct intel_gvt *gvt = vgpu->gvt;
|
||||
|
||||
mutex_lock(&vgpu->vgpu_lock);
|
||||
|
||||
WARN(vgpu->active, "vGPU is still active!\n");
|
||||
|
||||
/*
|
||||
* remove idr first so later clean can judge if need to stop
|
||||
* service if no active vgpu.
|
||||
*/
|
||||
mutex_lock(&gvt->lock);
|
||||
idr_remove(&gvt->vgpu_idr, vgpu->id);
|
||||
mutex_unlock(&gvt->lock);
|
||||
|
||||
mutex_lock(&vgpu->vgpu_lock);
|
||||
intel_gvt_debugfs_remove_vgpu(vgpu);
|
||||
intel_vgpu_clean_sched_policy(vgpu);
|
||||
intel_vgpu_clean_submission(vgpu);
|
||||
@@ -290,7 +297,6 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
|
||||
mutex_unlock(&vgpu->vgpu_lock);
|
||||
|
||||
mutex_lock(&gvt->lock);
|
||||
idr_remove(&gvt->vgpu_idr, vgpu->id);
|
||||
if (idr_is_empty(&gvt->vgpu_idr))
|
||||
intel_gvt_clean_irq(gvt);
|
||||
intel_gvt_update_vgpu_types(gvt);
|
||||
|
@@ -527,19 +527,31 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static void irq_semaphore_cb(struct irq_work *wrk)
|
||||
{
|
||||
struct i915_request *rq =
|
||||
container_of(wrk, typeof(*rq), semaphore_work);
|
||||
|
||||
i915_schedule_bump_priority(rq, I915_PRIORITY_NOSEMAPHORE);
|
||||
i915_request_put(rq);
|
||||
}
|
||||
|
||||
static int __i915_sw_fence_call
|
||||
semaphore_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
|
||||
{
|
||||
struct i915_request *request =
|
||||
container_of(fence, typeof(*request), semaphore);
|
||||
struct i915_request *rq = container_of(fence, typeof(*rq), semaphore);
|
||||
|
||||
switch (state) {
|
||||
case FENCE_COMPLETE:
|
||||
i915_schedule_bump_priority(request, I915_PRIORITY_NOSEMAPHORE);
|
||||
if (!(READ_ONCE(rq->sched.attr.priority) & I915_PRIORITY_NOSEMAPHORE)) {
|
||||
i915_request_get(rq);
|
||||
init_irq_work(&rq->semaphore_work, irq_semaphore_cb);
|
||||
irq_work_queue(&rq->semaphore_work);
|
||||
}
|
||||
break;
|
||||
|
||||
case FENCE_FREE:
|
||||
i915_request_put(request);
|
||||
i915_request_put(rq);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -776,8 +788,8 @@ i915_request_await_start(struct i915_request *rq, struct i915_request *signal)
|
||||
struct dma_fence *fence;
|
||||
int err;
|
||||
|
||||
GEM_BUG_ON(i915_request_timeline(rq) ==
|
||||
rcu_access_pointer(signal->timeline));
|
||||
if (i915_request_timeline(rq) == rcu_access_pointer(signal->timeline))
|
||||
return 0;
|
||||
|
||||
if (i915_request_started(signal))
|
||||
return 0;
|
||||
@@ -821,7 +833,7 @@ i915_request_await_start(struct i915_request *rq, struct i915_request *signal)
|
||||
return 0;
|
||||
|
||||
err = 0;
|
||||
if (intel_timeline_sync_is_later(i915_request_timeline(rq), fence))
|
||||
if (!intel_timeline_sync_is_later(i915_request_timeline(rq), fence))
|
||||
err = i915_sw_fence_await_dma_fence(&rq->submit,
|
||||
fence, 0,
|
||||
I915_FENCE_GFP);
|
||||
@@ -1318,9 +1330,9 @@ void __i915_request_queue(struct i915_request *rq,
|
||||
* decide whether to preempt the entire chain so that it is ready to
|
||||
* run at the earliest possible convenience.
|
||||
*/
|
||||
i915_sw_fence_commit(&rq->semaphore);
|
||||
if (attr && rq->engine->schedule)
|
||||
rq->engine->schedule(rq, attr);
|
||||
i915_sw_fence_commit(&rq->semaphore);
|
||||
i915_sw_fence_commit(&rq->submit);
|
||||
}
|
||||
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#define I915_REQUEST_H
|
||||
|
||||
#include <linux/dma-fence.h>
|
||||
#include <linux/irq_work.h>
|
||||
#include <linux/lockdep.h>
|
||||
|
||||
#include "gem/i915_gem_context_types.h"
|
||||
@@ -208,6 +209,7 @@ struct i915_request {
|
||||
};
|
||||
struct list_head execute_cb;
|
||||
struct i915_sw_fence semaphore;
|
||||
struct irq_work semaphore_work;
|
||||
|
||||
/*
|
||||
* A list of everyone we wait upon, and everyone who waits upon us.
|
||||
|
@@ -234,6 +234,11 @@ static inline u64 ptr_to_u64(const void *ptr)
|
||||
__idx; \
|
||||
})
|
||||
|
||||
static inline bool is_power_of_2_u64(u64 n)
|
||||
{
|
||||
return (n != 0 && ((n & (n - 1)) == 0));
|
||||
}
|
||||
|
||||
static inline void __list_del_many(struct list_head *head,
|
||||
struct list_head *first)
|
||||
{
|
||||
|
@@ -313,6 +313,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev)
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
|
||||
i2c_del_adapter(&dev->adapter);
|
||||
devm_free_irq(&pdev->dev, dev->irq, dev);
|
||||
pci_free_irq_vectors(pdev);
|
||||
}
|
||||
|
||||
|
@@ -348,7 +348,7 @@ static struct gpio_desc *i2c_gpio_get_desc(struct device *dev,
|
||||
if (ret == -ENOENT)
|
||||
retdesc = ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
if (ret != -EPROBE_DEFER)
|
||||
if (PTR_ERR(retdesc) != -EPROBE_DEFER)
|
||||
dev_err(dev, "error trying to get descriptor: %d\n", ret);
|
||||
|
||||
return retdesc;
|
||||
|
@@ -132,11 +132,6 @@
|
||||
#define TCOBASE 0x050
|
||||
#define TCOCTL 0x054
|
||||
|
||||
#define ACPIBASE 0x040
|
||||
#define ACPIBASE_SMI_OFF 0x030
|
||||
#define ACPICTRL 0x044
|
||||
#define ACPICTRL_EN 0x080
|
||||
|
||||
#define SBREG_BAR 0x10
|
||||
#define SBREG_SMBCTRL 0xc6000c
|
||||
#define SBREG_SMBCTRL_DNV 0xcf000c
|
||||
@@ -1553,7 +1548,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev,
|
||||
pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden);
|
||||
spin_unlock(&p2sb_spinlock);
|
||||
|
||||
res = &tco_res[ICH_RES_MEM_OFF];
|
||||
res = &tco_res[1];
|
||||
if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS)
|
||||
res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL_DNV;
|
||||
else
|
||||
@@ -1563,7 +1558,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev,
|
||||
res->flags = IORESOURCE_MEM;
|
||||
|
||||
return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1,
|
||||
tco_res, 3, &spt_tco_platform_data,
|
||||
tco_res, 2, &spt_tco_platform_data,
|
||||
sizeof(spt_tco_platform_data));
|
||||
}
|
||||
|
||||
@@ -1576,17 +1571,16 @@ static struct platform_device *
|
||||
i801_add_tco_cnl(struct i801_priv *priv, struct pci_dev *pci_dev,
|
||||
struct resource *tco_res)
|
||||
{
|
||||
return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1,
|
||||
tco_res, 2, &cnl_tco_platform_data,
|
||||
sizeof(cnl_tco_platform_data));
|
||||
return platform_device_register_resndata(&pci_dev->dev,
|
||||
"iTCO_wdt", -1, tco_res, 1, &cnl_tco_platform_data,
|
||||
sizeof(cnl_tco_platform_data));
|
||||
}
|
||||
|
||||
static void i801_add_tco(struct i801_priv *priv)
|
||||
{
|
||||
u32 base_addr, tco_base, tco_ctl, ctrl_val;
|
||||
struct pci_dev *pci_dev = priv->pci_dev;
|
||||
struct resource tco_res[3], *res;
|
||||
unsigned int devfn;
|
||||
struct resource tco_res[2], *res;
|
||||
u32 tco_base, tco_ctl;
|
||||
|
||||
/* If we have ACPI based watchdog use that instead */
|
||||
if (acpi_has_watchdog())
|
||||
@@ -1601,30 +1595,15 @@ static void i801_add_tco(struct i801_priv *priv)
|
||||
return;
|
||||
|
||||
memset(tco_res, 0, sizeof(tco_res));
|
||||
|
||||
res = &tco_res[ICH_RES_IO_TCO];
|
||||
/*
|
||||
* Always populate the main iTCO IO resource here. The second entry
|
||||
* for NO_REBOOT MMIO is filled by the SPT specific function.
|
||||
*/
|
||||
res = &tco_res[0];
|
||||
res->start = tco_base & ~1;
|
||||
res->end = res->start + 32 - 1;
|
||||
res->flags = IORESOURCE_IO;
|
||||
|
||||
/*
|
||||
* Power Management registers.
|
||||
*/
|
||||
devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 2);
|
||||
pci_bus_read_config_dword(pci_dev->bus, devfn, ACPIBASE, &base_addr);
|
||||
|
||||
res = &tco_res[ICH_RES_IO_SMI];
|
||||
res->start = (base_addr & ~1) + ACPIBASE_SMI_OFF;
|
||||
res->end = res->start + 3;
|
||||
res->flags = IORESOURCE_IO;
|
||||
|
||||
/*
|
||||
* Enable the ACPI I/O space.
|
||||
*/
|
||||
pci_bus_read_config_dword(pci_dev->bus, devfn, ACPICTRL, &ctrl_val);
|
||||
ctrl_val |= ACPICTRL_EN;
|
||||
pci_bus_write_config_dword(pci_dev->bus, devfn, ACPICTRL, ctrl_val);
|
||||
|
||||
if (priv->features & FEATURE_TCO_CNL)
|
||||
priv->tco_pdev = i801_add_tco_cnl(priv, pci_dev, tco_res);
|
||||
else
|
||||
|
@@ -394,9 +394,17 @@ EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle);
|
||||
static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
|
||||
{
|
||||
struct device *dev;
|
||||
struct i2c_client *client;
|
||||
|
||||
dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev);
|
||||
return dev ? i2c_verify_client(dev) : NULL;
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
client = i2c_verify_client(dev);
|
||||
if (!client)
|
||||
put_device(dev);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
|
||||
|
@@ -3826,7 +3826,7 @@ int amd_iommu_activate_guest_mode(void *data)
|
||||
entry->lo.fields_vapic.ga_tag = ir_data->ga_tag;
|
||||
|
||||
return modify_irte_ga(ir_data->irq_2_irte.devid,
|
||||
ir_data->irq_2_irte.index, entry, NULL);
|
||||
ir_data->irq_2_irte.index, entry, ir_data);
|
||||
}
|
||||
EXPORT_SYMBOL(amd_iommu_activate_guest_mode);
|
||||
|
||||
@@ -3852,7 +3852,7 @@ int amd_iommu_deactivate_guest_mode(void *data)
|
||||
APICID_TO_IRTE_DEST_HI(cfg->dest_apicid);
|
||||
|
||||
return modify_irte_ga(ir_data->irq_2_irte.devid,
|
||||
ir_data->irq_2_irte.index, entry, NULL);
|
||||
ir_data->irq_2_irte.index, entry, ir_data);
|
||||
}
|
||||
EXPORT_SYMBOL(amd_iommu_deactivate_guest_mode);
|
||||
|
||||
|
@@ -177,15 +177,15 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie,
|
||||
start -= iova_offset(iovad, start);
|
||||
num_pages = iova_align(iovad, end - start) >> iova_shift(iovad);
|
||||
|
||||
msi_page = kcalloc(num_pages, sizeof(*msi_page), GFP_KERNEL);
|
||||
if (!msi_page)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num_pages; i++) {
|
||||
msi_page[i].phys = start;
|
||||
msi_page[i].iova = start;
|
||||
INIT_LIST_HEAD(&msi_page[i].list);
|
||||
list_add(&msi_page[i].list, &cookie->msi_page_list);
|
||||
msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL);
|
||||
if (!msi_page)
|
||||
return -ENOMEM;
|
||||
|
||||
msi_page->phys = start;
|
||||
msi_page->iova = start;
|
||||
INIT_LIST_HEAD(&msi_page->list);
|
||||
list_add(&msi_page->list, &cookie->msi_page_list);
|
||||
start += iovad->granule;
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/numa.h>
|
||||
#include <linux/limits.h>
|
||||
#include <asm/irq_remapping.h>
|
||||
#include <asm/iommu_table.h>
|
||||
|
||||
@@ -128,6 +129,13 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event)
|
||||
|
||||
BUG_ON(dev->is_virtfn);
|
||||
|
||||
/*
|
||||
* Ignore devices that have a domain number higher than what can
|
||||
* be looked up in DMAR, e.g. VMD subdevices with domain 0x10000
|
||||
*/
|
||||
if (pci_domain_nr(dev->bus) > U16_MAX)
|
||||
return NULL;
|
||||
|
||||
/* Only generate path[] for device addition event */
|
||||
if (event == BUS_NOTIFY_ADD_DEVICE)
|
||||
for (tmp = dev; tmp; tmp = tmp->bus->self)
|
||||
@@ -363,7 +371,8 @@ dmar_find_dmaru(struct acpi_dmar_hardware_unit *drhd)
|
||||
{
|
||||
struct dmar_drhd_unit *dmaru;
|
||||
|
||||
list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list)
|
||||
list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list,
|
||||
dmar_rcu_check())
|
||||
if (dmaru->segment == drhd->segment &&
|
||||
dmaru->reg_base_addr == drhd->address)
|
||||
return dmaru;
|
||||
@@ -440,12 +449,13 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header,
|
||||
|
||||
/* Check for NUL termination within the designated length */
|
||||
if (strnlen(andd->device_name, header->length - 8) == header->length - 8) {
|
||||
WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
|
||||
pr_warn(FW_BUG
|
||||
"Your BIOS is broken; ANDD object name is not NUL-terminated\n"
|
||||
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
|
||||
dmi_get_system_info(DMI_BIOS_VENDOR),
|
||||
dmi_get_system_info(DMI_BIOS_VERSION),
|
||||
dmi_get_system_info(DMI_PRODUCT_VERSION));
|
||||
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
|
||||
return -EINVAL;
|
||||
}
|
||||
pr_info("ANDD device: %x name: %s\n", andd->device_number,
|
||||
@@ -471,14 +481,14 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
WARN_TAINT(
|
||||
1, TAINT_FIRMWARE_WORKAROUND,
|
||||
pr_warn(FW_BUG
|
||||
"Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n"
|
||||
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
|
||||
drhd->reg_base_addr,
|
||||
rhsa->base_address,
|
||||
dmi_get_system_info(DMI_BIOS_VENDOR),
|
||||
dmi_get_system_info(DMI_BIOS_VERSION),
|
||||
dmi_get_system_info(DMI_PRODUCT_VERSION));
|
||||
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -827,14 +837,14 @@ int __init dmar_table_init(void)
|
||||
|
||||
static void warn_invalid_dmar(u64 addr, const char *message)
|
||||
{
|
||||
WARN_TAINT_ONCE(
|
||||
1, TAINT_FIRMWARE_WORKAROUND,
|
||||
pr_warn_once(FW_BUG
|
||||
"Your BIOS is broken; DMAR reported at address %llx%s!\n"
|
||||
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
|
||||
addr, message,
|
||||
dmi_get_system_info(DMI_BIOS_VENDOR),
|
||||
dmi_get_system_info(DMI_BIOS_VERSION),
|
||||
dmi_get_system_info(DMI_PRODUCT_VERSION));
|
||||
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
|
||||
}
|
||||
|
||||
static int __ref
|
||||
|
@@ -33,38 +33,42 @@ struct iommu_regset {
|
||||
|
||||
#define IOMMU_REGSET_ENTRY(_reg_) \
|
||||
{ DMAR_##_reg_##_REG, __stringify(_reg_) }
|
||||
static const struct iommu_regset iommu_regs[] = {
|
||||
|
||||
static const struct iommu_regset iommu_regs_32[] = {
|
||||
IOMMU_REGSET_ENTRY(VER),
|
||||
IOMMU_REGSET_ENTRY(CAP),
|
||||
IOMMU_REGSET_ENTRY(ECAP),
|
||||
IOMMU_REGSET_ENTRY(GCMD),
|
||||
IOMMU_REGSET_ENTRY(GSTS),
|
||||
IOMMU_REGSET_ENTRY(RTADDR),
|
||||
IOMMU_REGSET_ENTRY(CCMD),
|
||||
IOMMU_REGSET_ENTRY(FSTS),
|
||||
IOMMU_REGSET_ENTRY(FECTL),
|
||||
IOMMU_REGSET_ENTRY(FEDATA),
|
||||
IOMMU_REGSET_ENTRY(FEADDR),
|
||||
IOMMU_REGSET_ENTRY(FEUADDR),
|
||||
IOMMU_REGSET_ENTRY(AFLOG),
|
||||
IOMMU_REGSET_ENTRY(PMEN),
|
||||
IOMMU_REGSET_ENTRY(PLMBASE),
|
||||
IOMMU_REGSET_ENTRY(PLMLIMIT),
|
||||
IOMMU_REGSET_ENTRY(PHMBASE),
|
||||
IOMMU_REGSET_ENTRY(PHMLIMIT),
|
||||
IOMMU_REGSET_ENTRY(IQH),
|
||||
IOMMU_REGSET_ENTRY(IQT),
|
||||
IOMMU_REGSET_ENTRY(IQA),
|
||||
IOMMU_REGSET_ENTRY(ICS),
|
||||
IOMMU_REGSET_ENTRY(IRTA),
|
||||
IOMMU_REGSET_ENTRY(PQH),
|
||||
IOMMU_REGSET_ENTRY(PQT),
|
||||
IOMMU_REGSET_ENTRY(PQA),
|
||||
IOMMU_REGSET_ENTRY(PRS),
|
||||
IOMMU_REGSET_ENTRY(PECTL),
|
||||
IOMMU_REGSET_ENTRY(PEDATA),
|
||||
IOMMU_REGSET_ENTRY(PEADDR),
|
||||
IOMMU_REGSET_ENTRY(PEUADDR),
|
||||
};
|
||||
|
||||
static const struct iommu_regset iommu_regs_64[] = {
|
||||
IOMMU_REGSET_ENTRY(CAP),
|
||||
IOMMU_REGSET_ENTRY(ECAP),
|
||||
IOMMU_REGSET_ENTRY(RTADDR),
|
||||
IOMMU_REGSET_ENTRY(CCMD),
|
||||
IOMMU_REGSET_ENTRY(AFLOG),
|
||||
IOMMU_REGSET_ENTRY(PHMBASE),
|
||||
IOMMU_REGSET_ENTRY(PHMLIMIT),
|
||||
IOMMU_REGSET_ENTRY(IQH),
|
||||
IOMMU_REGSET_ENTRY(IQT),
|
||||
IOMMU_REGSET_ENTRY(IQA),
|
||||
IOMMU_REGSET_ENTRY(IRTA),
|
||||
IOMMU_REGSET_ENTRY(PQH),
|
||||
IOMMU_REGSET_ENTRY(PQT),
|
||||
IOMMU_REGSET_ENTRY(PQA),
|
||||
IOMMU_REGSET_ENTRY(MTRRCAP),
|
||||
IOMMU_REGSET_ENTRY(MTRRDEF),
|
||||
IOMMU_REGSET_ENTRY(MTRR_FIX64K_00000),
|
||||
@@ -127,10 +131,16 @@ static int iommu_regset_show(struct seq_file *m, void *unused)
|
||||
* by adding the offset to the pointer (virtual address).
|
||||
*/
|
||||
raw_spin_lock_irqsave(&iommu->register_lock, flag);
|
||||
for (i = 0 ; i < ARRAY_SIZE(iommu_regs); i++) {
|
||||
value = dmar_readq(iommu->reg + iommu_regs[i].offset);
|
||||
for (i = 0 ; i < ARRAY_SIZE(iommu_regs_32); i++) {
|
||||
value = dmar_readl(iommu->reg + iommu_regs_32[i].offset);
|
||||
seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n",
|
||||
iommu_regs[i].regs, iommu_regs[i].offset,
|
||||
iommu_regs_32[i].regs, iommu_regs_32[i].offset,
|
||||
value);
|
||||
}
|
||||
for (i = 0 ; i < ARRAY_SIZE(iommu_regs_64); i++) {
|
||||
value = dmar_readq(iommu->reg + iommu_regs_64[i].offset);
|
||||
seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n",
|
||||
iommu_regs_64[i].regs, iommu_regs_64[i].offset,
|
||||
value);
|
||||
}
|
||||
raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
|
||||
@@ -272,9 +282,16 @@ static int dmar_translation_struct_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct dmar_drhd_unit *drhd;
|
||||
struct intel_iommu *iommu;
|
||||
u32 sts;
|
||||
|
||||
rcu_read_lock();
|
||||
for_each_active_iommu(iommu, drhd) {
|
||||
sts = dmar_readl(iommu->reg + DMAR_GSTS_REG);
|
||||
if (!(sts & DMA_GSTS_TES)) {
|
||||
seq_printf(m, "DMA Remapping is not enabled on %s\n",
|
||||
iommu->name);
|
||||
continue;
|
||||
}
|
||||
root_tbl_walk(m, iommu);
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
@@ -415,6 +432,7 @@ static int ir_translation_struct_show(struct seq_file *m, void *unused)
|
||||
struct dmar_drhd_unit *drhd;
|
||||
struct intel_iommu *iommu;
|
||||
u64 irta;
|
||||
u32 sts;
|
||||
|
||||
rcu_read_lock();
|
||||
for_each_active_iommu(iommu, drhd) {
|
||||
@@ -424,7 +442,8 @@ static int ir_translation_struct_show(struct seq_file *m, void *unused)
|
||||
seq_printf(m, "Remapped Interrupt supported on IOMMU: %s\n",
|
||||
iommu->name);
|
||||
|
||||
if (iommu->ir_table) {
|
||||
sts = dmar_readl(iommu->reg + DMAR_GSTS_REG);
|
||||
if (iommu->ir_table && (sts & DMA_GSTS_IRES)) {
|
||||
irta = virt_to_phys(iommu->ir_table->base);
|
||||
seq_printf(m, " IR table address:%llx\n", irta);
|
||||
ir_tbl_remap_entry_show(m, iommu);
|
||||
|
@@ -4261,10 +4261,11 @@ static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
|
||||
|
||||
/* we know that the this iommu should be at offset 0xa000 from vtbar */
|
||||
drhd = dmar_find_matched_drhd_unit(pdev);
|
||||
if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
|
||||
TAINT_FIRMWARE_WORKAROUND,
|
||||
"BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
|
||||
if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) {
|
||||
pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n");
|
||||
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
|
||||
pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
|
||||
|
||||
@@ -4460,14 +4461,16 @@ int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
|
||||
struct dmar_rmrr_unit *rmrru;
|
||||
|
||||
rmrr = (struct acpi_dmar_reserved_memory *)header;
|
||||
if (rmrr_sanity_check(rmrr))
|
||||
WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
|
||||
if (rmrr_sanity_check(rmrr)) {
|
||||
pr_warn(FW_BUG
|
||||
"Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n"
|
||||
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
|
||||
rmrr->base_address, rmrr->end_address,
|
||||
dmi_get_system_info(DMI_BIOS_VENDOR),
|
||||
dmi_get_system_info(DMI_BIOS_VERSION),
|
||||
dmi_get_system_info(DMI_PRODUCT_VERSION));
|
||||
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
|
||||
}
|
||||
|
||||
rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
|
||||
if (!rmrru)
|
||||
@@ -5130,6 +5133,9 @@ int __init intel_iommu_init(void)
|
||||
|
||||
down_write(&dmar_global_lock);
|
||||
|
||||
if (!no_iommu)
|
||||
intel_iommu_debugfs_init();
|
||||
|
||||
if (no_iommu || dmar_disabled) {
|
||||
/*
|
||||
* We exit the function here to ensure IOMMU's remapping and
|
||||
@@ -5193,6 +5199,7 @@ int __init intel_iommu_init(void)
|
||||
|
||||
init_iommu_pm_ops();
|
||||
|
||||
down_read(&dmar_global_lock);
|
||||
for_each_active_iommu(iommu, drhd) {
|
||||
iommu_device_sysfs_add(&iommu->iommu, NULL,
|
||||
intel_iommu_groups,
|
||||
@@ -5200,6 +5207,7 @@ int __init intel_iommu_init(void)
|
||||
iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
|
||||
iommu_device_register(&iommu->iommu);
|
||||
}
|
||||
up_read(&dmar_global_lock);
|
||||
|
||||
bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
|
||||
if (si_domain && !hw_pass_through)
|
||||
@@ -5210,7 +5218,6 @@ int __init intel_iommu_init(void)
|
||||
down_read(&dmar_global_lock);
|
||||
if (probe_acpi_namespace_devices())
|
||||
pr_warn("ACPI name space devices didn't probe correctly\n");
|
||||
up_read(&dmar_global_lock);
|
||||
|
||||
/* Finally, we enable the DMA remapping hardware. */
|
||||
for_each_iommu(iommu, drhd) {
|
||||
@@ -5219,10 +5226,11 @@ int __init intel_iommu_init(void)
|
||||
|
||||
iommu_disable_protect_mem_regions(iommu);
|
||||
}
|
||||
up_read(&dmar_global_lock);
|
||||
|
||||
pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
|
||||
|
||||
intel_iommu_enabled = 1;
|
||||
intel_iommu_debugfs_init();
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -5700,8 +5708,10 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
|
||||
u64 phys = 0;
|
||||
|
||||
pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
|
||||
if (pte)
|
||||
phys = dma_pte_addr(pte);
|
||||
if (pte && dma_pte_present(pte))
|
||||
phys = dma_pte_addr(pte) +
|
||||
(iova & (BIT_MASK(level_to_offset_bits(level) +
|
||||
VTD_PAGE_SHIFT) - 1));
|
||||
|
||||
return phys;
|
||||
}
|
||||
|
@@ -468,7 +468,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
|
||||
arm_lpae_iopte *ptep = data->pgd;
|
||||
int ret, lvl = data->start_level;
|
||||
arm_lpae_iopte prot;
|
||||
long iaext = (long)iova >> cfg->ias;
|
||||
long iaext = (s64)iova >> cfg->ias;
|
||||
|
||||
/* If no access, then nothing to do */
|
||||
if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
|
||||
@@ -645,7 +645,7 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
|
||||
struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
|
||||
struct io_pgtable_cfg *cfg = &data->iop.cfg;
|
||||
arm_lpae_iopte *ptep = data->pgd;
|
||||
long iaext = (long)iova >> cfg->ias;
|
||||
long iaext = (s64)iova >> cfg->ias;
|
||||
|
||||
if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size))
|
||||
return 0;
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#define GICD_INT_NMI_PRI (GICD_INT_DEF_PRI & ~0x80)
|
||||
|
||||
#define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0)
|
||||
#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1)
|
||||
|
||||
struct redist_region {
|
||||
void __iomem *redist_base;
|
||||
@@ -1464,6 +1465,15 @@ static bool gic_enable_quirk_msm8996(void *data)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gic_enable_quirk_cavium_38539(void *data)
|
||||
{
|
||||
struct gic_chip_data *d = data;
|
||||
|
||||
d->flags |= FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gic_enable_quirk_hip06_07(void *data)
|
||||
{
|
||||
struct gic_chip_data *d = data;
|
||||
@@ -1502,6 +1512,19 @@ static const struct gic_quirk gic_quirks[] = {
|
||||
.mask = 0xffffffff,
|
||||
.init = gic_enable_quirk_hip06_07,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Reserved register accesses generate a Synchronous
|
||||
* External Abort. This erratum applies to:
|
||||
* - ThunderX: CN88xx
|
||||
* - OCTEON TX: CN83xx, CN81xx
|
||||
* - OCTEON TX2: CN93xx, CN96xx, CN98xx, CNF95xx*
|
||||
*/
|
||||
.desc = "GICv3: Cavium erratum 38539",
|
||||
.iidr = 0xa000034c,
|
||||
.mask = 0xe8f00fff,
|
||||
.init = gic_enable_quirk_cavium_38539,
|
||||
},
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -1577,7 +1600,12 @@ static int __init gic_init_bases(void __iomem *dist_base,
|
||||
pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32);
|
||||
pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR);
|
||||
|
||||
gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2);
|
||||
/*
|
||||
* ThunderX1 explodes on reading GICD_TYPER2, in violation of the
|
||||
* architecture spec (which says that reserved registers are RES0).
|
||||
*/
|
||||
if (!(gic_data.flags & FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539))
|
||||
gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2);
|
||||
|
||||
gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
|
||||
&gic_data);
|
||||
|
@@ -312,9 +312,16 @@ static const struct i2c_device_id wf_ad7417_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_ad7417_id);
|
||||
|
||||
static const struct of_device_id wf_ad7417_of_id[] = {
|
||||
{ .compatible = "ad7417", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_ad7417_of_id);
|
||||
|
||||
static struct i2c_driver wf_ad7417_driver = {
|
||||
.driver = {
|
||||
.name = "wf_ad7417",
|
||||
.of_match_table = wf_ad7417_of_id,
|
||||
},
|
||||
.probe = wf_ad7417_probe,
|
||||
.remove = wf_ad7417_remove,
|
||||
|
@@ -580,9 +580,16 @@ static const struct i2c_device_id wf_fcu_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_fcu_id);
|
||||
|
||||
static const struct of_device_id wf_fcu_of_id[] = {
|
||||
{ .compatible = "fcu", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_fcu_of_id);
|
||||
|
||||
static struct i2c_driver wf_fcu_driver = {
|
||||
.driver = {
|
||||
.name = "wf_fcu",
|
||||
.of_match_table = wf_fcu_of_id,
|
||||
},
|
||||
.probe = wf_fcu_probe,
|
||||
.remove = wf_fcu_remove,
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/io.h>
|
||||
@@ -91,9 +92,14 @@ static int wf_lm75_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct wf_lm75_sensor *lm;
|
||||
int rc, ds1775 = id->driver_data;
|
||||
int rc, ds1775;
|
||||
const char *name, *loc;
|
||||
|
||||
if (id)
|
||||
ds1775 = id->driver_data;
|
||||
else
|
||||
ds1775 = !!of_device_get_match_data(&client->dev);
|
||||
|
||||
DBG("wf_lm75: creating %s device at address 0x%02x\n",
|
||||
ds1775 ? "ds1775" : "lm75", client->addr);
|
||||
|
||||
@@ -164,9 +170,17 @@ static const struct i2c_device_id wf_lm75_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_lm75_id);
|
||||
|
||||
static const struct of_device_id wf_lm75_of_id[] = {
|
||||
{ .compatible = "lm75", .data = (void *)0},
|
||||
{ .compatible = "ds1775", .data = (void *)1 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_lm75_of_id);
|
||||
|
||||
static struct i2c_driver wf_lm75_driver = {
|
||||
.driver = {
|
||||
.name = "wf_lm75",
|
||||
.of_match_table = wf_lm75_of_id,
|
||||
},
|
||||
.probe = wf_lm75_probe,
|
||||
.remove = wf_lm75_remove,
|
||||
|
@@ -166,9 +166,16 @@ static const struct i2c_device_id wf_lm87_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_lm87_id);
|
||||
|
||||
static const struct of_device_id wf_lm87_of_id[] = {
|
||||
{ .compatible = "lm87cimt", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_lm87_of_id);
|
||||
|
||||
static struct i2c_driver wf_lm87_driver = {
|
||||
.driver = {
|
||||
.name = "wf_lm87",
|
||||
.of_match_table = wf_lm87_of_id,
|
||||
},
|
||||
.probe = wf_lm87_probe,
|
||||
.remove = wf_lm87_remove,
|
||||
|
@@ -120,9 +120,16 @@ static const struct i2c_device_id wf_max6690_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_max6690_id);
|
||||
|
||||
static const struct of_device_id wf_max6690_of_id[] = {
|
||||
{ .compatible = "max6690", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_max6690_of_id);
|
||||
|
||||
static struct i2c_driver wf_max6690_driver = {
|
||||
.driver = {
|
||||
.name = "wf_max6690",
|
||||
.of_match_table = wf_max6690_of_id,
|
||||
},
|
||||
.probe = wf_max6690_probe,
|
||||
.remove = wf_max6690_remove,
|
||||
|
@@ -341,9 +341,16 @@ static const struct i2c_device_id wf_sat_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_sat_id);
|
||||
|
||||
static const struct of_device_id wf_sat_of_id[] = {
|
||||
{ .compatible = "smu-sat", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_sat_of_id);
|
||||
|
||||
static struct i2c_driver wf_sat_driver = {
|
||||
.driver = {
|
||||
.name = "wf_smu_sat",
|
||||
.of_match_table = wf_sat_of_id,
|
||||
},
|
||||
.probe = wf_sat_probe,
|
||||
.remove = wf_sat_remove,
|
||||
|
@@ -712,13 +712,14 @@ static int at24_probe(struct i2c_client *client)
|
||||
* chip is functional.
|
||||
*/
|
||||
err = at24_read(at24, 0, &test_byte, 1);
|
||||
pm_runtime_idle(dev);
|
||||
if (err) {
|
||||
pm_runtime_disable(dev);
|
||||
regulator_disable(at24->vcc_reg);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pm_runtime_idle(dev);
|
||||
|
||||
if (writable)
|
||||
dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n",
|
||||
byte_len, client->name, at24->write_max);
|
||||
|
@@ -1732,8 +1732,11 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
|
||||
* the erase operation does not exceed the max_busy_timeout, we should
|
||||
* use R1B response. Or we need to prevent the host from doing hw busy
|
||||
* detection, which is done by converting to a R1 response instead.
|
||||
* Note, some hosts requires R1B, which also means they are on their own
|
||||
* when it comes to deal with the busy timeout.
|
||||
*/
|
||||
if (card->host->max_busy_timeout &&
|
||||
if (!(card->host->caps & MMC_CAP_NEED_RSP_BUSY) &&
|
||||
card->host->max_busy_timeout &&
|
||||
busy_timeout > card->host->max_busy_timeout) {
|
||||
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
|
||||
} else {
|
||||
|
@@ -1910,9 +1910,12 @@ static int mmc_sleep(struct mmc_host *host)
|
||||
* If the max_busy_timeout of the host is specified, validate it against
|
||||
* the sleep cmd timeout. A failure means we need to prevent the host
|
||||
* from doing hw busy detection, which is done by converting to a R1
|
||||
* response instead of a R1B.
|
||||
* response instead of a R1B. Note, some hosts requires R1B, which also
|
||||
* means they are on their own when it comes to deal with the busy
|
||||
* timeout.
|
||||
*/
|
||||
if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) {
|
||||
if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout &&
|
||||
(timeout_ms > host->max_busy_timeout)) {
|
||||
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
|
||||
} else {
|
||||
cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
|
||||
|
@@ -542,9 +542,11 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
|
||||
* If the max_busy_timeout of the host is specified, make sure it's
|
||||
* enough to fit the used timeout_ms. In case it's not, let's instruct
|
||||
* the host to avoid HW busy detection, by converting to a R1 response
|
||||
* instead of a R1B.
|
||||
* instead of a R1B. Note, some hosts requires R1B, which also means
|
||||
* they are on their own when it comes to deal with the busy timeout.
|
||||
*/
|
||||
if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout))
|
||||
if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout &&
|
||||
(timeout_ms > host->max_busy_timeout))
|
||||
use_r1b_resp = false;
|
||||
|
||||
cmd.opcode = MMC_SWITCH;
|
||||
|
@@ -1590,7 +1590,7 @@ static u32 sdhci_msm_cqe_irq(struct sdhci_host *host, u32 intmask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery)
|
||||
static void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery)
|
||||
{
|
||||
struct sdhci_host *host = mmc_priv(mmc);
|
||||
unsigned long flags;
|
||||
|
@@ -1192,6 +1192,9 @@ static int sdhci_omap_probe(struct platform_device *pdev)
|
||||
if (of_find_property(dev->of_node, "dmas", NULL))
|
||||
sdhci_switch_external_dma(host, true);
|
||||
|
||||
/* R1B responses is required to properly manage HW busy detection. */
|
||||
mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
|
||||
|
||||
ret = sdhci_setup_host(host);
|
||||
if (ret)
|
||||
goto err_put_sync;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user