mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 12:00:22 +09:00
Merge 5.15.124 into android14-5.15-lts
Changes in 5.15.124
jbd2: Fix wrongly judgement for buffer head removing while doing checkpoint
KVM: s390: pv: fix index value of replaced ASCE
io_uring: don't audit the capability check in io_uring_create()
gpio: tps68470: Make tps68470_gpio_output() always set the initial value
pwm: Add a stub for devm_pwmchip_add()
gpio: mvebu: Make use of devm_pwmchip_add
gpio: mvebu: fix irq domain leak
btrfs: fix race between quota disable and relocation
i2c: Delete error messages for failed memory allocations
i2c: Improve size determinations
i2c: nomadik: Remove unnecessary goto label
i2c: nomadik: Use devm_clk_get_enabled()
i2c: nomadik: Remove a useless call in the remove function
PCI/ASPM: Return 0 or -ETIMEDOUT from pcie_retrain_link()
PCI/ASPM: Factor out pcie_wait_for_retrain()
PCI/ASPM: Avoid link retraining race
PCI: rockchip: Remove writes to unused registers
PCI: rockchip: Fix window mapping and address translation for endpoint
PCI: rockchip: Don't advertise MSI-X in PCIe capabilities
dlm: cleanup plock_op vs plock_xop
dlm: rearrange async condition return
fs: dlm: interrupt posix locks only when process is killed
drm/ttm: Don't print error message if eviction was interrupted
drm/ttm: Don't leak a resource on eviction error
n_tty: Rename tail to old_tail in n_tty_read()
tty: fix hang on tty device with no_room set
drm/ttm: never consider pinned BOs for eviction&swap
cifs: missing directory in MAINTAINERS file
cifs: use fs_context for automounts
ksmbd: remove internal.h include
cifs: if deferred close is disabled then close files immediately
pwm: meson: Simplify duplicated per-channel tracking
pwm: meson: fix handling of period/duty if greater than UINT_MAX
tracing/probes: Add symstr type for dynamic events
tracing/probes: Fix to avoid double count of the string length on the array
tracing: Allow synthetic events to pass around stacktraces
Revert "tracing: Add "(fault)" name injection to kernel probes"
tracing/probes: Fix to record 0-length data_loc in fetch_store_string*() if fails
scsi: qla2xxx: Remove unused declarations for qla2xxx
scsi: qla2xxx: Multi-que support for TMF
scsi: qla2xxx: Fix task management cmd failure
scsi: qla2xxx: Fix task management cmd fail due to unavailable resource
scsi: qla2xxx: Add debug prints in the device remove path
scsi: qla2xxx: Fix hang in task management
drm/amdgpu: fix vkms crtc settings
drm/amdgpu/vkms: relax timer deactivation by hrtimer_try_to_cancel
phy: qcom-snps: Use dev_err_probe() to simplify code
phy: qcom-snps: correct struct qcom_snps_hsphy kerneldoc
phy: qcom-snps-femto-v2: keep cfg_ahb_clk enabled during runtime suspend
phy: qcom-snps-femto-v2: properly enable ref clock
soundwire: qcom: update status correctly with mask
media: staging: atomisp: select V4L2_FWNODE
i40e: Fix an NULL vs IS_ERR() bug for debugfs_create_dir()
iavf: fix potential deadlock on allocation failure
iavf: check for removal state before IAVF_FLAG_PF_COMMS_FAILED
net: phy: marvell10g: fix 88x3310 power up
net: hns3: fix wrong tc bandwidth weight data issue
net: hns3: fix wrong bw weight of disabled tc issue
vxlan: move to its own directory
vxlan: calculate correct header length for GPE
phy: hisilicon: Fix an out of bounds check in hisi_inno_phy_probe()
ethernet: atheros: fix return value check in atl1e_tso_csum()
ipv6 addrconf: fix bug where deleting a mngtmpaddr can create a new temporary address
tcp: Reduce chance of collisions in inet6_hashfn().
ice: Fix memory management in ice_ethtool_fdir.c
bonding: reset bond's flags when down link is P2P device
team: reset team's flags when down link is P2P device
net: stmmac: Apply redundant write work around on 4.xx too
platform/x86: msi-laptop: Fix rfkill out-of-sync on MSI Wind U100
igc: Fix Kernel Panic during ndo_tx_timeout callback
netfilter: nft_set_rbtree: fix overlap expiration walk
netfilter: nf_tables: skip immediate deactivate in _PREPARE_ERROR
netfilter: nf_tables: disallow rule addition to bound chain via NFTA_RULE_CHAIN_ID
net/sched: mqprio: refactor nlattr parsing to a separate function
net/sched: mqprio: add extack to mqprio_parse_nlattr()
net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64
benet: fix return value check in be_lancer_xmit_workarounds()
tipc: check return value of pskb_trim()
tipc: stop tipc crypto on failure in tipc_node_create
RDMA/mlx4: Make check for invalid flags stricter
drm/msm/dpu: drop enum dpu_core_perf_data_bus_id
drm/msm/adreno: Fix snapshot BINDLESS_DATA size
RDMA/irdma: Add missing read barriers
RDMA/irdma: Fix data race on CQP completion stats
RDMA/irdma: Fix data race on CQP request done
RDMA/mthca: Fix crash when polling CQ for shared QPs
RDMA/bnxt_re: Prevent handling any completions after qp destroy
drm/msm: Fix IS_ERR_OR_NULL() vs NULL check in a5xx_submit_in_rb()
ASoC: fsl_spdif: Silence output on stop
block: Fix a source code comment in include/uapi/linux/blkzoned.h
dm raid: fix missing reconfig_mutex unlock in raid_ctr() error paths
dm raid: clean up four equivalent goto tags in raid_ctr()
dm raid: protect md_stop() with 'reconfig_mutex'
drm/amd: Fix an error handling mistake in psp_sw_init()
RDMA/irdma: Report correct WC error
ata: pata_ns87415: mark ns87560_tf_read static
ring-buffer: Fix wrong stat of cpu_buffer->read
tracing: Fix warning in trace_buffered_event_disable()
Revert "usb: gadget: tegra-xudc: Fix error check in tegra_xudc_powerdomain_init()"
usb: gadget: call usb_gadget_check_config() to verify UDC capability
USB: gadget: Fix the memory leak in raw_gadget driver
KVM: Grab a reference to KVM for VM and vCPU stats file descriptors
KVM: VMX: Don't fudge CR0 and CR4 for restricted L2 guest
serial: qcom-geni: drop bogus runtime pm state update
serial: 8250_dw: Preserve original value of DLF register
serial: sifive: Fix sifive_serial_console_setup() section
USB: serial: option: support Quectel EM060K_128
USB: serial: option: add Quectel EC200A module support
USB: serial: simple: add Kaufmann RKS+CAN VCP
USB: serial: simple: sort driver entries
can: gs_usb: gs_can_close(): add missing set of CAN state to CAN_STATE_STOPPED
Revert "usb: dwc3: core: Enable AutoRetry feature in the controller"
usb: dwc3: pci: skip BYT GPIO lookup table for hardwired phy
usb: dwc3: don't reset device side if dwc3 was configured as host-only
usb: ohci-at91: Fix the unhandle interrupt when resume
USB: quirks: add quirk for Focusrite Scarlett
usb: cdns3: fix incorrect calculation of ep_buf_size when more than one config
usb: xhci-mtk: set the dma max_seg_size
Revert "usb: xhci: tegra: Fix error check"
Documentation: security-bugs.rst: update preferences when dealing with the linux-distros group
Documentation: security-bugs.rst: clarify CVE handling
staging: r8712: Fix memory leak in _r8712_init_xmit_priv()
staging: ks7010: potential buffer overflow in ks_wlan_set_encode_ext()
tty: n_gsm: fix UAF in gsm_cleanup_mux
Revert "xhci: add quirk for host controllers that don't update endpoint DCS"
ALSA: hda/relatek: Enable Mute LED on HP 250 G8
hwmon: (k10temp) Enable AMD3255 Proc to show negative temperature
hwmon: (nct7802) Fix for temp6 (PECI1) processed even if PECI1 disabled
btrfs: check if the transaction was aborted at btrfs_wait_for_commit()
btrfs: check for commit error at btrfs_attach_transaction_barrier()
file: always lock position for FMODE_ATOMIC_POS
nfsd: Remove incorrect check in nfsd4_validate_stateid
tpm_tis: Explicitly check for error code
irq-bcm6345-l1: Do not assume a fixed block to cpu mapping
irqchip/gic-v4.1: Properly lock VPEs when doing a directLPI invalidation
locking/rtmutex: Fix task->pi_waiters integrity
KVM: x86: Disallow KVM_SET_SREGS{2} if incoming CR0 is invalid
virtio-net: fix race between set queues and probe
s390/dasd: fix hanging device after quiesce/resume
ASoC: wm8904: Fill the cache for WM8904_ADC_TEST_0 register
ceph: never send metrics if disable_send_metrics is set
dm cache policy smq: ensure IO doesn't prevent cleaner policy progress
rbd: make get_lock_owner_info() return a single locker or NULL
rbd: harden get_lock_owner_info() a bit
rbd: retrieve and check lock owner twice before blocklisting
tracing: Fix trace_event_raw_event_synth() if else statement
ACPI: processor: perflib: Use the "no limit" frequency QoS
ACPI: processor: perflib: Avoid updating frequency QoS unnecessarily
cpufreq: intel_pstate: Drop ACPI _PSS states table patching
selftests: mptcp: sockopt: use 'iptables-legacy' if available
io_uring: treat -EAGAIN for REQ_F_NOWAIT as final for io-wq
ASoC: cs42l51: fix driver to properly autoload with automatic module loading
selftests: mptcp: join: only check for ip6tables if needed
Linux 5.15.124
Change-Id: Ifeb2357cc7522671aff42c1408cc917a0f1aa905
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -63,31 +63,28 @@ information submitted to the security list and any followup discussions
|
||||
of the report are treated confidentially even after the embargo has been
|
||||
lifted, in perpetuity.
|
||||
|
||||
Coordination
|
||||
------------
|
||||
Coordination with other groups
|
||||
------------------------------
|
||||
|
||||
Fixes for sensitive bugs, such as those that might lead to privilege
|
||||
escalations, may need to be coordinated with the private
|
||||
<linux-distros@vs.openwall.org> mailing list so that distribution vendors
|
||||
are well prepared to issue a fixed kernel upon public disclosure of the
|
||||
upstream fix. Distros will need some time to test the proposed patch and
|
||||
will generally request at least a few days of embargo, and vendor update
|
||||
publication prefers to happen Tuesday through Thursday. When appropriate,
|
||||
the security team can assist with this coordination, or the reporter can
|
||||
include linux-distros from the start. In this case, remember to prefix
|
||||
the email Subject line with "[vs]" as described in the linux-distros wiki:
|
||||
<http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists>
|
||||
The kernel security team strongly recommends that reporters of potential
|
||||
security issues NEVER contact the "linux-distros" mailing list until
|
||||
AFTER discussing it with the kernel security team. Do not Cc: both
|
||||
lists at once. You may contact the linux-distros mailing list after a
|
||||
fix has been agreed on and you fully understand the requirements that
|
||||
doing so will impose on you and the kernel community.
|
||||
|
||||
The different lists have different goals and the linux-distros rules do
|
||||
not contribute to actually fixing any potential security problems.
|
||||
|
||||
CVE assignment
|
||||
--------------
|
||||
|
||||
The security team does not normally assign CVEs, nor do we require them
|
||||
for reports or fixes, as this can needlessly complicate the process and
|
||||
may delay the bug handling. If a reporter wishes to have a CVE identifier
|
||||
assigned ahead of public disclosure, they will need to contact the private
|
||||
linux-distros list, described above. When such a CVE identifier is known
|
||||
before a patch is provided, it is desirable to mention it in the commit
|
||||
message if the reporter agrees.
|
||||
The security team does not assign CVEs, nor do we require them for
|
||||
reports or fixes, as this can needlessly complicate the process and may
|
||||
delay the bug handling. If a reporter wishes to have a CVE identifier
|
||||
assigned, they should find one by themselves, for example by contacting
|
||||
MITRE directly. However under no circumstances will a patch inclusion
|
||||
be delayed to wait for a CVE identifier to arrive.
|
||||
|
||||
Non-disclosure agreements
|
||||
-------------------------
|
||||
|
||||
@@ -58,8 +58,8 @@ Synopsis of kprobe_events
|
||||
NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
|
||||
FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
|
||||
(u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
|
||||
(x8/x16/x32/x64), "string", "ustring" and bitfield
|
||||
are supported.
|
||||
(x8/x16/x32/x64), "string", "ustring", "symbol", "symstr"
|
||||
and bitfield are supported.
|
||||
|
||||
(\*1) only for the probe on function entry (offs == 0).
|
||||
(\*2) only for return probe.
|
||||
@@ -96,6 +96,10 @@ offset, and container-size (usually 32). The syntax is::
|
||||
|
||||
Symbol type('symbol') is an alias of u32 or u64 type (depends on BITS_PER_LONG)
|
||||
which shows given pointer in "symbol+offset" style.
|
||||
On the other hand, symbol-string type ('symstr') converts the given address to
|
||||
"symbol+offset/symbolsize" style and stores it as a null-terminated string.
|
||||
With 'symstr' type, you can filter the event with wildcard pattern of the
|
||||
symbols, and you don't need to solve symbol name by yourself.
|
||||
For $comm, the default type is "string"; any other type is invalid.
|
||||
|
||||
.. _user_mem_access:
|
||||
|
||||
@@ -4666,6 +4666,7 @@ T: git git://git.samba.org/sfrench/cifs-2.6.git
|
||||
F: Documentation/admin-guide/cifs/
|
||||
F: fs/cifs/
|
||||
F: fs/smbfs_common/
|
||||
F: include/uapi/linux/cifs
|
||||
|
||||
COMPACTPCI HOTPLUG CORE
|
||||
M: Scott Murray <scott@spiteful.org>
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 123
|
||||
SUBLEVEL = 124
|
||||
EXTRAVERSION =
|
||||
NAME = Trick or Treat
|
||||
|
||||
|
||||
@@ -2791,6 +2791,7 @@ int s390_replace_asce(struct gmap *gmap)
|
||||
page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER);
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
page->index = 0;
|
||||
table = page_to_virt(page);
|
||||
memcpy(table, gmap->table, 1UL << (CRST_ALLOC_ORDER + PAGE_SHIFT));
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ KVM_X86_OP(get_segment)
|
||||
KVM_X86_OP(get_cpl)
|
||||
KVM_X86_OP(set_segment)
|
||||
KVM_X86_OP_NULL(get_cs_db_l_bits)
|
||||
KVM_X86_OP(is_valid_cr0)
|
||||
KVM_X86_OP(set_cr0)
|
||||
KVM_X86_OP(is_valid_cr4)
|
||||
KVM_X86_OP(set_cr4)
|
||||
|
||||
@@ -1334,8 +1334,9 @@ struct kvm_x86_ops {
|
||||
void (*set_segment)(struct kvm_vcpu *vcpu,
|
||||
struct kvm_segment *var, int seg);
|
||||
void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l);
|
||||
bool (*is_valid_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0);
|
||||
void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0);
|
||||
bool (*is_valid_cr4)(struct kvm_vcpu *vcpu, unsigned long cr0);
|
||||
bool (*is_valid_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4);
|
||||
void (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4);
|
||||
int (*set_efer)(struct kvm_vcpu *vcpu, u64 efer);
|
||||
void (*get_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt);
|
||||
|
||||
@@ -1734,6 +1734,11 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
|
||||
vmcb_mark_dirty(svm->vmcb, VMCB_DT);
|
||||
}
|
||||
|
||||
static bool svm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
||||
{
|
||||
struct vcpu_svm *svm = to_svm(vcpu);
|
||||
@@ -4596,6 +4601,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
|
||||
.set_segment = svm_set_segment,
|
||||
.get_cpl = svm_get_cpl,
|
||||
.get_cs_db_l_bits = kvm_get_cs_db_l_bits,
|
||||
.is_valid_cr0 = svm_is_valid_cr0,
|
||||
.set_cr0 = svm_set_cr0,
|
||||
.is_valid_cr4 = svm_is_valid_cr4,
|
||||
.set_cr4 = svm_set_cr4,
|
||||
|
||||
@@ -1416,6 +1416,11 @@ void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
unsigned long old_rflags;
|
||||
|
||||
/*
|
||||
* Unlike CR0 and CR4, RFLAGS handling requires checking if the vCPU
|
||||
* is an unrestricted guest in order to mark L2 as needing emulation
|
||||
* if L1 runs L2 as a restricted guest.
|
||||
*/
|
||||
if (is_unrestricted_guest(vcpu)) {
|
||||
kvm_register_mark_available(vcpu, VCPU_EXREG_RFLAGS);
|
||||
vmx->rflags = rflags;
|
||||
@@ -2889,6 +2894,15 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
struct kvm_vmx *kvm_vmx = to_kvm_vmx(vcpu->kvm);
|
||||
|
||||
/*
|
||||
* KVM should never use VM86 to virtualize Real Mode when L2 is active,
|
||||
* as using VM86 is unnecessary if unrestricted guest is enabled, and
|
||||
* if unrestricted guest is disabled, VM-Enter (from L1) with CR0.PG=0
|
||||
* should VM-Fail and KVM should reject userspace attempts to stuff
|
||||
* CR0.PG=0 when L2 is active.
|
||||
*/
|
||||
WARN_ON_ONCE(is_guest_mode(vcpu));
|
||||
|
||||
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR);
|
||||
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_ES], VCPU_SREG_ES);
|
||||
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_DS], VCPU_SREG_DS);
|
||||
@@ -3079,6 +3093,17 @@ void ept_save_pdptrs(struct kvm_vcpu *vcpu)
|
||||
#define CR3_EXITING_BITS (CPU_BASED_CR3_LOAD_EXITING | \
|
||||
CPU_BASED_CR3_STORE_EXITING)
|
||||
|
||||
static bool vmx_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
||||
{
|
||||
if (is_guest_mode(vcpu))
|
||||
return nested_guest_cr0_valid(vcpu, cr0);
|
||||
|
||||
if (to_vmx(vcpu)->nested.vmxon)
|
||||
return nested_host_cr0_valid(vcpu, cr0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
@@ -3088,7 +3113,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
||||
old_cr0_pg = kvm_read_cr0_bits(vcpu, X86_CR0_PG);
|
||||
|
||||
hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF);
|
||||
if (is_unrestricted_guest(vcpu))
|
||||
if (enable_unrestricted_guest)
|
||||
hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST;
|
||||
else {
|
||||
hw_cr0 |= KVM_VM_CR0_ALWAYS_ON;
|
||||
@@ -3116,7 +3141,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (enable_ept && !is_unrestricted_guest(vcpu)) {
|
||||
if (enable_ept && !enable_unrestricted_guest) {
|
||||
/*
|
||||
* Ensure KVM has an up-to-date snapshot of the guest's CR3. If
|
||||
* the below code _enables_ CR3 exiting, vmx_cache_reg() will
|
||||
@@ -3239,7 +3264,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
|
||||
unsigned long hw_cr4;
|
||||
|
||||
hw_cr4 = (cr4_read_shadow() & X86_CR4_MCE) | (cr4 & ~X86_CR4_MCE);
|
||||
if (is_unrestricted_guest(vcpu))
|
||||
if (enable_unrestricted_guest)
|
||||
hw_cr4 |= KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST;
|
||||
else if (vmx->rmode.vm86_active)
|
||||
hw_cr4 |= KVM_RMODE_VM_CR4_ALWAYS_ON;
|
||||
@@ -3259,7 +3284,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
|
||||
vcpu->arch.cr4 = cr4;
|
||||
kvm_register_mark_available(vcpu, VCPU_EXREG_CR4);
|
||||
|
||||
if (!is_unrestricted_guest(vcpu)) {
|
||||
if (!enable_unrestricted_guest) {
|
||||
if (enable_ept) {
|
||||
if (!is_paging(vcpu)) {
|
||||
hw_cr4 &= ~X86_CR4_PAE;
|
||||
@@ -5022,18 +5047,11 @@ static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val)
|
||||
val = (val & ~vmcs12->cr0_guest_host_mask) |
|
||||
(vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask);
|
||||
|
||||
if (!nested_guest_cr0_valid(vcpu, val))
|
||||
return 1;
|
||||
|
||||
if (kvm_set_cr0(vcpu, val))
|
||||
return 1;
|
||||
vmcs_writel(CR0_READ_SHADOW, orig_val);
|
||||
return 0;
|
||||
} else {
|
||||
if (to_vmx(vcpu)->nested.vmxon &&
|
||||
!nested_host_cr0_valid(vcpu, val))
|
||||
return 1;
|
||||
|
||||
return kvm_set_cr0(vcpu, val);
|
||||
}
|
||||
}
|
||||
@@ -7741,6 +7759,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
|
||||
.set_segment = vmx_set_segment,
|
||||
.get_cpl = vmx_get_cpl,
|
||||
.get_cs_db_l_bits = vmx_get_cs_db_l_bits,
|
||||
.is_valid_cr0 = vmx_is_valid_cr0,
|
||||
.set_cr0 = vmx_set_cr0,
|
||||
.is_valid_cr4 = vmx_is_valid_cr4,
|
||||
.set_cr4 = vmx_set_cr4,
|
||||
|
||||
@@ -876,6 +876,22 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(load_pdptrs);
|
||||
|
||||
static bool kvm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
||||
{
|
||||
#ifdef CONFIG_X86_64
|
||||
if (cr0 & 0xffffffff00000000UL)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD))
|
||||
return false;
|
||||
|
||||
if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE))
|
||||
return false;
|
||||
|
||||
return static_call(kvm_x86_is_valid_cr0)(vcpu, cr0);
|
||||
}
|
||||
|
||||
void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0)
|
||||
{
|
||||
if ((cr0 ^ old_cr0) & X86_CR0_PG) {
|
||||
@@ -898,21 +914,14 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
||||
unsigned long old_cr0 = kvm_read_cr0(vcpu);
|
||||
unsigned long pdptr_bits = X86_CR0_CD | X86_CR0_NW | X86_CR0_PG;
|
||||
|
||||
if (!kvm_is_valid_cr0(vcpu, cr0))
|
||||
return 1;
|
||||
|
||||
cr0 |= X86_CR0_ET;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
if (cr0 & 0xffffffff00000000UL)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
/* Write to CR0 reserved bits are ignored, even on Intel. */
|
||||
cr0 &= ~CR0_RESERVED_BITS;
|
||||
|
||||
if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD))
|
||||
return 1;
|
||||
|
||||
if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE))
|
||||
return 1;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
if ((vcpu->arch.efer & EFER_LME) && !is_paging(vcpu) &&
|
||||
(cr0 & X86_CR0_PG)) {
|
||||
@@ -10598,7 +10607,8 @@ static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
|
||||
return false;
|
||||
}
|
||||
|
||||
return kvm_is_valid_cr4(vcpu, sregs->cr4);
|
||||
return kvm_is_valid_cr4(vcpu, sregs->cr4) &&
|
||||
kvm_is_valid_cr0(vcpu, sregs->cr0);
|
||||
}
|
||||
|
||||
static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs,
|
||||
|
||||
@@ -53,6 +53,8 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
|
||||
{
|
||||
acpi_status status = 0;
|
||||
unsigned long long ppc = 0;
|
||||
s32 qos_value;
|
||||
int index;
|
||||
int ret;
|
||||
|
||||
if (!pr)
|
||||
@@ -72,17 +74,30 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
|
||||
}
|
||||
}
|
||||
|
||||
pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
|
||||
(int)ppc, ppc ? "" : "not");
|
||||
index = ppc;
|
||||
|
||||
pr->performance_platform_limit = (int)ppc;
|
||||
|
||||
if (ppc >= pr->performance->state_count ||
|
||||
unlikely(!freq_qos_request_active(&pr->perflib_req)))
|
||||
if (pr->performance_platform_limit == index ||
|
||||
ppc >= pr->performance->state_count)
|
||||
return 0;
|
||||
|
||||
ret = freq_qos_update_request(&pr->perflib_req,
|
||||
pr->performance->states[ppc].core_frequency * 1000);
|
||||
pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
|
||||
index, index ? "is" : "is not");
|
||||
|
||||
pr->performance_platform_limit = index;
|
||||
|
||||
if (unlikely(!freq_qos_request_active(&pr->perflib_req)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If _PPC returns 0, it means that all of the available states can be
|
||||
* used ("no limit").
|
||||
*/
|
||||
if (index == 0)
|
||||
qos_value = FREQ_QOS_MAX_DEFAULT_VALUE;
|
||||
else
|
||||
qos_value = pr->performance->states[index].core_frequency * 1000;
|
||||
|
||||
ret = freq_qos_update_request(&pr->perflib_req, qos_value);
|
||||
if (ret < 0) {
|
||||
pr_warn("Failed to update perflib freq constraint: CPU%d (%d)\n",
|
||||
pr->id, ret);
|
||||
@@ -165,9 +180,16 @@ void acpi_processor_ppc_init(struct cpufreq_policy *policy)
|
||||
if (!pr)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Reset performance_platform_limit in case there is a stale
|
||||
* value in it, so as to make it match the "no limit" QoS value
|
||||
* below.
|
||||
*/
|
||||
pr->performance_platform_limit = 0;
|
||||
|
||||
ret = freq_qos_add_request(&policy->constraints,
|
||||
&pr->perflib_req,
|
||||
FREQ_QOS_MAX, INT_MAX);
|
||||
&pr->perflib_req, FREQ_QOS_MAX,
|
||||
FREQ_QOS_MAX_DEFAULT_VALUE);
|
||||
if (ret < 0)
|
||||
pr_err("Failed to add freq constraint for CPU%d (%d)\n",
|
||||
cpu, ret);
|
||||
|
||||
@@ -260,7 +260,7 @@ static u8 ns87560_check_status(struct ata_port *ap)
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
static void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
|
||||
@@ -3851,51 +3851,82 @@ static void wake_lock_waiters(struct rbd_device *rbd_dev, int result)
|
||||
list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list);
|
||||
}
|
||||
|
||||
static int get_lock_owner_info(struct rbd_device *rbd_dev,
|
||||
struct ceph_locker **lockers, u32 *num_lockers)
|
||||
static bool locker_equal(const struct ceph_locker *lhs,
|
||||
const struct ceph_locker *rhs)
|
||||
{
|
||||
return lhs->id.name.type == rhs->id.name.type &&
|
||||
lhs->id.name.num == rhs->id.name.num &&
|
||||
!strcmp(lhs->id.cookie, rhs->id.cookie) &&
|
||||
ceph_addr_equal_no_type(&lhs->info.addr, &rhs->info.addr);
|
||||
}
|
||||
|
||||
static void free_locker(struct ceph_locker *locker)
|
||||
{
|
||||
if (locker)
|
||||
ceph_free_lockers(locker, 1);
|
||||
}
|
||||
|
||||
static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev)
|
||||
{
|
||||
struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
|
||||
struct ceph_locker *lockers;
|
||||
u32 num_lockers;
|
||||
u8 lock_type;
|
||||
char *lock_tag;
|
||||
u64 handle;
|
||||
int ret;
|
||||
|
||||
dout("%s rbd_dev %p\n", __func__, rbd_dev);
|
||||
|
||||
ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid,
|
||||
&rbd_dev->header_oloc, RBD_LOCK_NAME,
|
||||
&lock_type, &lock_tag, lockers, num_lockers);
|
||||
if (ret)
|
||||
return ret;
|
||||
&lock_type, &lock_tag, &lockers, &num_lockers);
|
||||
if (ret) {
|
||||
rbd_warn(rbd_dev, "failed to retrieve lockers: %d", ret);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
if (*num_lockers == 0) {
|
||||
if (num_lockers == 0) {
|
||||
dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev);
|
||||
lockers = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp(lock_tag, RBD_LOCK_TAG)) {
|
||||
rbd_warn(rbd_dev, "locked by external mechanism, tag %s",
|
||||
lock_tag);
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
goto err_busy;
|
||||
}
|
||||
|
||||
if (lock_type == CEPH_CLS_LOCK_SHARED) {
|
||||
rbd_warn(rbd_dev, "shared lock type detected");
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
if (lock_type != CEPH_CLS_LOCK_EXCLUSIVE) {
|
||||
rbd_warn(rbd_dev, "incompatible lock type detected");
|
||||
goto err_busy;
|
||||
}
|
||||
|
||||
if (strncmp((*lockers)[0].id.cookie, RBD_LOCK_COOKIE_PREFIX,
|
||||
strlen(RBD_LOCK_COOKIE_PREFIX))) {
|
||||
WARN_ON(num_lockers != 1);
|
||||
ret = sscanf(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu",
|
||||
&handle);
|
||||
if (ret != 1) {
|
||||
rbd_warn(rbd_dev, "locked by external mechanism, cookie %s",
|
||||
(*lockers)[0].id.cookie);
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
lockers[0].id.cookie);
|
||||
goto err_busy;
|
||||
}
|
||||
if (ceph_addr_is_blank(&lockers[0].info.addr)) {
|
||||
rbd_warn(rbd_dev, "locker has a blank address");
|
||||
goto err_busy;
|
||||
}
|
||||
|
||||
dout("%s rbd_dev %p got locker %s%llu@%pISpc/%u handle %llu\n",
|
||||
__func__, rbd_dev, ENTITY_NAME(lockers[0].id.name),
|
||||
&lockers[0].info.addr.in_addr,
|
||||
le32_to_cpu(lockers[0].info.addr.nonce), handle);
|
||||
|
||||
out:
|
||||
kfree(lock_tag);
|
||||
return ret;
|
||||
return lockers;
|
||||
|
||||
err_busy:
|
||||
kfree(lock_tag);
|
||||
ceph_free_lockers(lockers, num_lockers);
|
||||
return ERR_PTR(-EBUSY);
|
||||
}
|
||||
|
||||
static int find_watcher(struct rbd_device *rbd_dev,
|
||||
@@ -3949,51 +3980,68 @@ out:
|
||||
static int rbd_try_lock(struct rbd_device *rbd_dev)
|
||||
{
|
||||
struct ceph_client *client = rbd_dev->rbd_client->client;
|
||||
struct ceph_locker *lockers;
|
||||
u32 num_lockers;
|
||||
struct ceph_locker *locker, *refreshed_locker;
|
||||
int ret;
|
||||
|
||||
for (;;) {
|
||||
locker = refreshed_locker = NULL;
|
||||
|
||||
ret = rbd_lock(rbd_dev);
|
||||
if (ret != -EBUSY)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
/* determine if the current lock holder is still alive */
|
||||
ret = get_lock_owner_info(rbd_dev, &lockers, &num_lockers);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (num_lockers == 0)
|
||||
locker = get_lock_owner_info(rbd_dev);
|
||||
if (IS_ERR(locker)) {
|
||||
ret = PTR_ERR(locker);
|
||||
locker = NULL;
|
||||
goto out;
|
||||
}
|
||||
if (!locker)
|
||||
goto again;
|
||||
|
||||
ret = find_watcher(rbd_dev, lockers);
|
||||
ret = find_watcher(rbd_dev, locker);
|
||||
if (ret)
|
||||
goto out; /* request lock or error */
|
||||
|
||||
refreshed_locker = get_lock_owner_info(rbd_dev);
|
||||
if (IS_ERR(refreshed_locker)) {
|
||||
ret = PTR_ERR(refreshed_locker);
|
||||
refreshed_locker = NULL;
|
||||
goto out;
|
||||
}
|
||||
if (!refreshed_locker ||
|
||||
!locker_equal(locker, refreshed_locker))
|
||||
goto again;
|
||||
|
||||
rbd_warn(rbd_dev, "breaking header lock owned by %s%llu",
|
||||
ENTITY_NAME(lockers[0].id.name));
|
||||
ENTITY_NAME(locker->id.name));
|
||||
|
||||
ret = ceph_monc_blocklist_add(&client->monc,
|
||||
&lockers[0].info.addr);
|
||||
&locker->info.addr);
|
||||
if (ret) {
|
||||
rbd_warn(rbd_dev, "blocklist of %s%llu failed: %d",
|
||||
ENTITY_NAME(lockers[0].id.name), ret);
|
||||
rbd_warn(rbd_dev, "failed to blocklist %s%llu: %d",
|
||||
ENTITY_NAME(locker->id.name), ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid,
|
||||
&rbd_dev->header_oloc, RBD_LOCK_NAME,
|
||||
lockers[0].id.cookie,
|
||||
&lockers[0].id.name);
|
||||
if (ret && ret != -ENOENT)
|
||||
locker->id.cookie, &locker->id.name);
|
||||
if (ret && ret != -ENOENT) {
|
||||
rbd_warn(rbd_dev, "failed to break header lock: %d",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
again:
|
||||
ceph_free_lockers(lockers, num_lockers);
|
||||
free_locker(refreshed_locker);
|
||||
free_locker(locker);
|
||||
}
|
||||
|
||||
out:
|
||||
ceph_free_lockers(lockers, num_lockers);
|
||||
free_locker(refreshed_locker);
|
||||
free_locker(locker);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -314,6 +314,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
int size = 0;
|
||||
int status;
|
||||
u32 expected;
|
||||
int rc;
|
||||
|
||||
if (count < TPM_HEADER_SIZE) {
|
||||
size = -EIO;
|
||||
@@ -333,8 +334,13 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
goto out;
|
||||
}
|
||||
|
||||
size += recv_data(chip, &buf[TPM_HEADER_SIZE],
|
||||
expected - TPM_HEADER_SIZE);
|
||||
rc = recv_data(chip, &buf[TPM_HEADER_SIZE],
|
||||
expected - TPM_HEADER_SIZE);
|
||||
if (rc < 0) {
|
||||
size = rc;
|
||||
goto out;
|
||||
}
|
||||
size += rc;
|
||||
if (size < expected) {
|
||||
dev_err(&chip->dev, "Unable to read remainder of result\n");
|
||||
size = -ETIME;
|
||||
|
||||
@@ -448,20 +448,6 @@ static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy)
|
||||
(u32) cpu->acpi_perf_data.states[i].control);
|
||||
}
|
||||
|
||||
/*
|
||||
* The _PSS table doesn't contain whole turbo frequency range.
|
||||
* This just contains +1 MHZ above the max non turbo frequency,
|
||||
* with control value corresponding to max turbo ratio. But
|
||||
* when cpufreq set policy is called, it will call with this
|
||||
* max frequency, which will cause a reduced performance as
|
||||
* this driver uses real max turbo frequency as the max
|
||||
* frequency. So correct this frequency in _PSS table to
|
||||
* correct max turbo frequency based on the turbo state.
|
||||
* Also need to convert to MHz as _PSS freq is in MHz.
|
||||
*/
|
||||
if (!global.turbo_disabled)
|
||||
cpu->acpi_perf_data.states[0].core_frequency =
|
||||
policy->cpuinfo.max_freq / 1000;
|
||||
cpu->valid_pss_table = true;
|
||||
pr_debug("_PPC limits will be enforced\n");
|
||||
|
||||
|
||||
@@ -874,7 +874,7 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
|
||||
|
||||
spin_lock_init(&mvpwm->lock);
|
||||
|
||||
return pwmchip_add(&mvpwm->chip);
|
||||
return devm_pwmchip_add(dev, &mvpwm->chip);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
@@ -1112,6 +1112,13 @@ static int mvebu_gpio_probe_syscon(struct platform_device *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mvebu_gpio_remove_irq_domain(void *data)
|
||||
{
|
||||
struct irq_domain *domain = data;
|
||||
|
||||
irq_domain_remove(domain);
|
||||
}
|
||||
|
||||
static int mvebu_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mvebu_gpio_chip *mvchip;
|
||||
@@ -1244,17 +1251,21 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
|
||||
if (!mvchip->domain) {
|
||||
dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n",
|
||||
mvchip->chip.label);
|
||||
err = -ENODEV;
|
||||
goto err_pwm;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = devm_add_action_or_reset(&pdev->dev, mvebu_gpio_remove_irq_domain,
|
||||
mvchip->domain);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = irq_alloc_domain_generic_chips(
|
||||
mvchip->domain, ngpios, 2, np->name, handle_level_irq,
|
||||
IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_LEVEL, 0, 0);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "couldn't allocate irq chips %s (DT).\n",
|
||||
mvchip->chip.label);
|
||||
goto err_domain;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1294,13 +1305,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_domain:
|
||||
irq_domain_remove(mvchip->domain);
|
||||
err_pwm:
|
||||
pwmchip_remove(&mvchip->mvpwm->chip);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct platform_driver mvebu_gpio_driver = {
|
||||
|
||||
@@ -91,13 +91,13 @@ static int tps68470_gpio_output(struct gpio_chip *gc, unsigned int offset,
|
||||
struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
|
||||
struct regmap *regmap = tps68470_gpio->tps68470_regmap;
|
||||
|
||||
/* Set the initial value */
|
||||
tps68470_gpio_set(gc, offset, value);
|
||||
|
||||
/* rest are always outputs */
|
||||
if (offset >= TPS68470_N_REGULAR_GPIO)
|
||||
return 0;
|
||||
|
||||
/* Set the initial value */
|
||||
tps68470_gpio_set(gc, offset, value);
|
||||
|
||||
return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset),
|
||||
TPS68470_GPIO_MODE_MASK,
|
||||
TPS68470_GPIO_MODE_OUT_CMOS);
|
||||
|
||||
@@ -341,11 +341,11 @@ static int psp_sw_init(void *handle)
|
||||
return 0;
|
||||
|
||||
failed2:
|
||||
amdgpu_bo_free_kernel(&psp->fw_pri_bo,
|
||||
&psp->fw_pri_mc_addr, &psp->fw_pri_buf);
|
||||
failed1:
|
||||
amdgpu_bo_free_kernel(&psp->fence_buf_bo,
|
||||
&psp->fence_buf_mc_addr, &psp->fence_buf);
|
||||
failed1:
|
||||
amdgpu_bo_free_kernel(&psp->fw_pri_bo,
|
||||
&psp->fw_pri_mc_addr, &psp->fw_pri_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "ivsrcid/ivsrcid_vislands30.h"
|
||||
#include "amdgpu_vkms.h"
|
||||
#include "amdgpu_display.h"
|
||||
#include "atom.h"
|
||||
#include "amdgpu_irq.h"
|
||||
|
||||
/**
|
||||
* DOC: amdgpu_vkms
|
||||
@@ -41,20 +43,20 @@ static const u32 amdgpu_vkms_formats[] = {
|
||||
|
||||
static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer)
|
||||
{
|
||||
struct amdgpu_vkms_output *output = container_of(timer,
|
||||
struct amdgpu_vkms_output,
|
||||
vblank_hrtimer);
|
||||
struct drm_crtc *crtc = &output->crtc;
|
||||
struct amdgpu_crtc *amdgpu_crtc = container_of(timer, struct amdgpu_crtc, vblank_timer);
|
||||
struct drm_crtc *crtc = &amdgpu_crtc->base;
|
||||
struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
|
||||
u64 ret_overrun;
|
||||
bool ret;
|
||||
|
||||
ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
|
||||
ret_overrun = hrtimer_forward_now(&amdgpu_crtc->vblank_timer,
|
||||
output->period_ns);
|
||||
WARN_ON(ret_overrun != 1);
|
||||
|
||||
ret = drm_crtc_handle_vblank(crtc);
|
||||
/* Don't queue timer again when vblank is disabled. */
|
||||
if (!ret)
|
||||
DRM_ERROR("amdgpu_vkms failure on handling vblank");
|
||||
return HRTIMER_NORESTART;
|
||||
|
||||
return HRTIMER_RESTART;
|
||||
}
|
||||
@@ -65,22 +67,21 @@ static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc)
|
||||
unsigned int pipe = drm_crtc_index(crtc);
|
||||
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
|
||||
struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
drm_calc_timestamping_constants(crtc, &crtc->mode);
|
||||
|
||||
hrtimer_init(&out->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
out->vblank_hrtimer.function = &amdgpu_vkms_vblank_simulate;
|
||||
out->period_ns = ktime_set(0, vblank->framedur_ns);
|
||||
hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL);
|
||||
hrtimer_start(&amdgpu_crtc->vblank_timer, out->period_ns, HRTIMER_MODE_REL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
hrtimer_cancel(&out->vblank_hrtimer);
|
||||
hrtimer_try_to_cancel(&amdgpu_crtc->vblank_timer);
|
||||
}
|
||||
|
||||
static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
|
||||
@@ -92,13 +93,14 @@ static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
|
||||
unsigned int pipe = crtc->index;
|
||||
struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
|
||||
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
if (!READ_ONCE(vblank->enabled)) {
|
||||
*vblank_time = ktime_get();
|
||||
return true;
|
||||
}
|
||||
|
||||
*vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
|
||||
*vblank_time = READ_ONCE(amdgpu_crtc->vblank_timer.node.expires);
|
||||
|
||||
if (WARN_ON(*vblank_time == vblank->time))
|
||||
return true;
|
||||
@@ -166,6 +168,8 @@ static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {
|
||||
static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
|
||||
struct drm_plane *primary, struct drm_plane *cursor)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
int ret;
|
||||
|
||||
ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
|
||||
@@ -177,6 +181,17 @@ static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
|
||||
|
||||
drm_crtc_helper_add(crtc, &amdgpu_vkms_crtc_helper_funcs);
|
||||
|
||||
amdgpu_crtc->crtc_id = drm_crtc_index(crtc);
|
||||
adev->mode_info.crtcs[drm_crtc_index(crtc)] = amdgpu_crtc;
|
||||
|
||||
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
amdgpu_crtc->encoder = NULL;
|
||||
amdgpu_crtc->connector = NULL;
|
||||
amdgpu_crtc->vsync_timer_enabled = AMDGPU_IRQ_STATE_DISABLE;
|
||||
|
||||
hrtimer_init(&amdgpu_crtc->vblank_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
amdgpu_crtc->vblank_timer.function = &amdgpu_vkms_vblank_simulate;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -402,7 +417,7 @@ int amdgpu_vkms_output_init(struct drm_device *dev,
|
||||
{
|
||||
struct drm_connector *connector = &output->connector;
|
||||
struct drm_encoder *encoder = &output->encoder;
|
||||
struct drm_crtc *crtc = &output->crtc;
|
||||
struct drm_crtc *crtc = &output->crtc.base;
|
||||
struct drm_plane *primary, *cursor = NULL;
|
||||
int ret;
|
||||
|
||||
@@ -505,8 +520,8 @@ static int amdgpu_vkms_sw_fini(void *handle)
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < adev->mode_info.num_crtc; i++)
|
||||
if (adev->amdgpu_vkms_output[i].vblank_hrtimer.function)
|
||||
hrtimer_cancel(&adev->amdgpu_vkms_output[i].vblank_hrtimer);
|
||||
if (adev->mode_info.crtcs[i])
|
||||
hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
|
||||
|
||||
kfree(adev->mode_info.bios_hardcoded_edid);
|
||||
kfree(adev->amdgpu_vkms_output);
|
||||
|
||||
@@ -10,15 +10,14 @@
|
||||
#define YRES_MAX 16384
|
||||
|
||||
#define drm_crtc_to_amdgpu_vkms_output(target) \
|
||||
container_of(target, struct amdgpu_vkms_output, crtc)
|
||||
container_of(target, struct amdgpu_vkms_output, crtc.base)
|
||||
|
||||
extern const struct amdgpu_ip_block_version amdgpu_vkms_ip_block;
|
||||
|
||||
struct amdgpu_vkms_output {
|
||||
struct drm_crtc crtc;
|
||||
struct amdgpu_crtc crtc;
|
||||
struct drm_encoder encoder;
|
||||
struct drm_connector connector;
|
||||
struct hrtimer vblank_hrtimer;
|
||||
ktime_t period_ns;
|
||||
struct drm_pending_vblank_event *event;
|
||||
};
|
||||
|
||||
@@ -90,7 +90,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit
|
||||
* since we've already mapped it once in
|
||||
* submit_reloc()
|
||||
*/
|
||||
if (WARN_ON(!ptr))
|
||||
if (WARN_ON(IS_ERR_OR_NULL(ptr)))
|
||||
return;
|
||||
|
||||
for (i = 0; i < dwords; i++) {
|
||||
|
||||
@@ -200,7 +200,7 @@ static const struct a6xx_shader_block {
|
||||
SHADER(A6XX_SP_LB_3_DATA, 0x800),
|
||||
SHADER(A6XX_SP_LB_4_DATA, 0x800),
|
||||
SHADER(A6XX_SP_LB_5_DATA, 0x200),
|
||||
SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x2000),
|
||||
SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x800),
|
||||
SHADER(A6XX_SP_CB_LEGACY_DATA, 0x280),
|
||||
SHADER(A6XX_SP_UAV_DATA, 0x80),
|
||||
SHADER(A6XX_SP_INST_TAG, 0x80),
|
||||
|
||||
@@ -14,19 +14,6 @@
|
||||
|
||||
#define DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE 412500000
|
||||
|
||||
/**
|
||||
* enum dpu_core_perf_data_bus_id - data bus identifier
|
||||
* @DPU_CORE_PERF_DATA_BUS_ID_MNOC: DPU/MNOC data bus
|
||||
* @DPU_CORE_PERF_DATA_BUS_ID_LLCC: MNOC/LLCC data bus
|
||||
* @DPU_CORE_PERF_DATA_BUS_ID_EBI: LLCC/EBI data bus
|
||||
*/
|
||||
enum dpu_core_perf_data_bus_id {
|
||||
DPU_CORE_PERF_DATA_BUS_ID_MNOC,
|
||||
DPU_CORE_PERF_DATA_BUS_ID_LLCC,
|
||||
DPU_CORE_PERF_DATA_BUS_ID_EBI,
|
||||
DPU_CORE_PERF_DATA_BUS_ID_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dpu_core_perf_params - definition of performance parameters
|
||||
* @max_per_pipe_ib: maximum instantaneous bandwidth request
|
||||
|
||||
@@ -552,17 +552,18 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo,
|
||||
goto out;
|
||||
}
|
||||
|
||||
bounce:
|
||||
ret = ttm_bo_handle_move_mem(bo, evict_mem, true, ctx, &hop);
|
||||
if (ret == -EMULTIHOP) {
|
||||
do {
|
||||
ret = ttm_bo_handle_move_mem(bo, evict_mem, true, ctx, &hop);
|
||||
if (ret != -EMULTIHOP)
|
||||
break;
|
||||
|
||||
ret = ttm_bo_bounce_temp_buffer(bo, &evict_mem, ctx, &hop);
|
||||
if (ret) {
|
||||
} while (!ret);
|
||||
|
||||
if (ret) {
|
||||
ttm_resource_free(bo, &evict_mem);
|
||||
if (ret != -ERESTARTSYS && ret != -EINTR)
|
||||
pr_err("Buffer eviction failed\n");
|
||||
ttm_resource_free(bo, &evict_mem);
|
||||
goto out;
|
||||
}
|
||||
/* try and move to final place now. */
|
||||
goto bounce;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
@@ -603,6 +604,12 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (bo->pin_count) {
|
||||
*locked = false;
|
||||
*busy = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bo->base.resv == ctx->resv) {
|
||||
dma_resv_assert_held(bo->base.resv);
|
||||
if (ctx->allow_res_evict)
|
||||
|
||||
@@ -97,6 +97,13 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
|
||||
#define F19H_M01H_CFACTOR_ICORE 1000000 /* 1A / LSB */
|
||||
#define F19H_M01H_CFACTOR_ISOC 310000 /* 0.31A / LSB */
|
||||
|
||||
/*
|
||||
* AMD's Industrial processor 3255 supports temperature from -40 deg to 105 deg Celsius.
|
||||
* Use the model name to identify 3255 CPUs and set a flag to display negative temperature.
|
||||
* Do not round off to zero for negative Tctl or Tdie values if the flag is set
|
||||
*/
|
||||
#define AMD_I3255_STR "3255"
|
||||
|
||||
struct k10temp_data {
|
||||
struct pci_dev *pdev;
|
||||
void (*read_htcreg)(struct pci_dev *pdev, u32 *regval);
|
||||
@@ -106,6 +113,7 @@ struct k10temp_data {
|
||||
u32 show_temp;
|
||||
bool is_zen;
|
||||
u32 ccd_offset;
|
||||
bool disp_negative;
|
||||
};
|
||||
|
||||
#define TCTL_BIT 0
|
||||
@@ -220,12 +228,12 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
|
||||
switch (channel) {
|
||||
case 0: /* Tctl */
|
||||
*val = get_raw_temp(data);
|
||||
if (*val < 0)
|
||||
if (*val < 0 && !data->disp_negative)
|
||||
*val = 0;
|
||||
break;
|
||||
case 1: /* Tdie */
|
||||
*val = get_raw_temp(data) - data->temp_offset;
|
||||
if (*val < 0)
|
||||
if (*val < 0 && !data->disp_negative)
|
||||
*val = 0;
|
||||
break;
|
||||
case 2 ... 9: /* Tccd{1-8} */
|
||||
@@ -417,6 +425,11 @@ static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
data->pdev = pdev;
|
||||
data->show_temp |= BIT(TCTL_BIT); /* Always show Tctl */
|
||||
|
||||
if (boot_cpu_data.x86 == 0x17 &&
|
||||
strstr(boot_cpu_data.x86_model_id, AMD_I3255_STR)) {
|
||||
data->disp_negative = true;
|
||||
}
|
||||
|
||||
if (boot_cpu_data.x86 == 0x15 &&
|
||||
((boot_cpu_data.x86_model & 0xf0) == 0x60 ||
|
||||
(boot_cpu_data.x86_model & 0xf0) == 0x70)) {
|
||||
|
||||
@@ -708,7 +708,7 @@ static umode_t nct7802_temp_is_visible(struct kobject *kobj,
|
||||
if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */
|
||||
return 0;
|
||||
|
||||
if (index >= 0x46 && (!(reg & 0x02))) /* PECI 1 */
|
||||
if (index >= 46 && !(reg & 0x02)) /* PECI 1 */
|
||||
return 0;
|
||||
|
||||
return attr->mode;
|
||||
|
||||
@@ -694,10 +694,8 @@ static int iic_probe(struct platform_device *ofdev)
|
||||
int ret;
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev) {
|
||||
dev_err(&ofdev->dev, "failed to allocate device data\n");
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
platform_set_drvdata(ofdev, dev);
|
||||
|
||||
|
||||
@@ -970,12 +970,10 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
struct i2c_vendor_data *vendor = id->data;
|
||||
u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1;
|
||||
|
||||
dev = devm_kzalloc(&adev->dev, sizeof(struct nmk_i2c_dev), GFP_KERNEL);
|
||||
if (!dev) {
|
||||
dev_err(&adev->dev, "cannot allocate memory\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_no_mem;
|
||||
}
|
||||
dev = devm_kzalloc(&adev->dev, sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
dev->vendor = vendor;
|
||||
dev->adev = adev;
|
||||
nmk_i2c_of_probe(np, dev);
|
||||
@@ -996,30 +994,21 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
|
||||
dev->virtbase = devm_ioremap(&adev->dev, adev->res.start,
|
||||
resource_size(&adev->res));
|
||||
if (!dev->virtbase) {
|
||||
ret = -ENOMEM;
|
||||
goto err_no_mem;
|
||||
}
|
||||
if (!dev->virtbase)
|
||||
return -ENOMEM;
|
||||
|
||||
dev->irq = adev->irq[0];
|
||||
ret = devm_request_irq(&adev->dev, dev->irq, i2c_irq_handler, 0,
|
||||
DRIVER_NAME, dev);
|
||||
if (ret) {
|
||||
dev_err(&adev->dev, "cannot claim the irq %d\n", dev->irq);
|
||||
goto err_no_mem;
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev->clk = devm_clk_get(&adev->dev, NULL);
|
||||
dev->clk = devm_clk_get_enabled(&adev->dev, NULL);
|
||||
if (IS_ERR(dev->clk)) {
|
||||
dev_err(&adev->dev, "could not get i2c clock\n");
|
||||
ret = PTR_ERR(dev->clk);
|
||||
goto err_no_mem;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dev->clk);
|
||||
if (ret) {
|
||||
dev_err(&adev->dev, "can't prepare_enable clock\n");
|
||||
goto err_no_mem;
|
||||
dev_err(&adev->dev, "could enable i2c clock\n");
|
||||
return PTR_ERR(dev->clk);
|
||||
}
|
||||
|
||||
init_hw(dev);
|
||||
@@ -1042,22 +1031,15 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
|
||||
ret = i2c_add_adapter(adap);
|
||||
if (ret)
|
||||
goto err_no_adap;
|
||||
return ret;
|
||||
|
||||
pm_runtime_put(&adev->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_no_adap:
|
||||
clk_disable_unprepare(dev->clk);
|
||||
err_no_mem:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nmk_i2c_remove(struct amba_device *adev)
|
||||
{
|
||||
struct resource *res = &adev->res;
|
||||
struct nmk_i2c_dev *dev = amba_get_drvdata(adev);
|
||||
|
||||
i2c_del_adapter(&dev->adap);
|
||||
@@ -1066,8 +1048,6 @@ static void nmk_i2c_remove(struct amba_device *adev)
|
||||
clear_all_interrupts(dev);
|
||||
/* disable the controller */
|
||||
i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
|
||||
clk_disable_unprepare(dev->clk);
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
}
|
||||
|
||||
static struct i2c_vendor_data vendor_stn8815 = {
|
||||
|
||||
@@ -443,9 +443,8 @@ static int sh7760_i2c_probe(struct platform_device *pdev)
|
||||
goto out0;
|
||||
}
|
||||
|
||||
id = kzalloc(sizeof(struct cami2c), GFP_KERNEL);
|
||||
id = kzalloc(sizeof(*id), GFP_KERNEL);
|
||||
if (!id) {
|
||||
dev_err(&pdev->dev, "no mem for private data\n");
|
||||
ret = -ENOMEM;
|
||||
goto out0;
|
||||
}
|
||||
|
||||
@@ -226,10 +226,8 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface,
|
||||
|
||||
/* allocate memory for our device state and initialize it */
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (dev == NULL) {
|
||||
dev_err(&interface->dev, "Out of memory\n");
|
||||
if (!dev)
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
|
||||
dev->interface = interface;
|
||||
|
||||
@@ -792,7 +792,10 @@ fail:
|
||||
int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
|
||||
{
|
||||
struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp);
|
||||
struct bnxt_qplib_qp *qplib_qp = &qp->qplib_qp;
|
||||
struct bnxt_re_dev *rdev = qp->rdev;
|
||||
struct bnxt_qplib_nq *scq_nq = NULL;
|
||||
struct bnxt_qplib_nq *rcq_nq = NULL;
|
||||
unsigned int flags;
|
||||
int rc;
|
||||
|
||||
@@ -826,6 +829,15 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
|
||||
ib_umem_release(qp->rumem);
|
||||
ib_umem_release(qp->sumem);
|
||||
|
||||
/* Flush all the entries of notification queue associated with
|
||||
* given qp.
|
||||
*/
|
||||
scq_nq = qplib_qp->scq->nq;
|
||||
rcq_nq = qplib_qp->rcq->nq;
|
||||
bnxt_re_synchronize_nq(scq_nq);
|
||||
if (scq_nq != rcq_nq)
|
||||
bnxt_re_synchronize_nq(rcq_nq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -386,6 +386,24 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t)
|
||||
spin_unlock_bh(&hwq->lock);
|
||||
}
|
||||
|
||||
/* bnxt_re_synchronize_nq - self polling notification queue.
|
||||
* @nq - notification queue pointer
|
||||
*
|
||||
* This function will start polling entries of a given notification queue
|
||||
* for all pending entries.
|
||||
* This function is useful to synchronize notification entries while resources
|
||||
* are going away.
|
||||
*/
|
||||
|
||||
void bnxt_re_synchronize_nq(struct bnxt_qplib_nq *nq)
|
||||
{
|
||||
int budget = nq->budget;
|
||||
|
||||
nq->budget = nq->hwq.max_elements;
|
||||
bnxt_qplib_service_nq(&nq->nq_tasklet);
|
||||
nq->budget = budget;
|
||||
}
|
||||
|
||||
static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
|
||||
{
|
||||
struct bnxt_qplib_nq *nq = dev_instance;
|
||||
|
||||
@@ -548,6 +548,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq,
|
||||
struct bnxt_qplib_cqe *cqe,
|
||||
int num_cqes);
|
||||
void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp);
|
||||
void bnxt_re_synchronize_nq(struct bnxt_qplib_nq *nq);
|
||||
|
||||
static inline void *bnxt_qplib_get_swqe(struct bnxt_qplib_q *que, u32 *swq_idx)
|
||||
{
|
||||
|
||||
@@ -2741,13 +2741,13 @@ irdma_sc_cq_modify(struct irdma_sc_cq *cq, struct irdma_modify_cq_info *info,
|
||||
*/
|
||||
void irdma_check_cqp_progress(struct irdma_cqp_timeout *timeout, struct irdma_sc_dev *dev)
|
||||
{
|
||||
if (timeout->compl_cqp_cmds != dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]) {
|
||||
timeout->compl_cqp_cmds = dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS];
|
||||
u64 completed_ops = atomic64_read(&dev->cqp->completed_ops);
|
||||
|
||||
if (timeout->compl_cqp_cmds != completed_ops) {
|
||||
timeout->compl_cqp_cmds = completed_ops;
|
||||
timeout->count = 0;
|
||||
} else {
|
||||
if (dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS] !=
|
||||
timeout->compl_cqp_cmds)
|
||||
timeout->count++;
|
||||
} else if (timeout->compl_cqp_cmds != dev->cqp->requested_ops) {
|
||||
timeout->count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2790,7 +2790,7 @@ static enum irdma_status_code irdma_cqp_poll_registers(struct irdma_sc_cqp *cqp,
|
||||
if (newtail != tail) {
|
||||
/* SUCCESS */
|
||||
IRDMA_RING_MOVE_TAIL(cqp->sq_ring);
|
||||
cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]++;
|
||||
atomic64_inc(&cqp->completed_ops);
|
||||
return 0;
|
||||
}
|
||||
udelay(cqp->dev->hw_attrs.max_sleep_count);
|
||||
@@ -3152,8 +3152,8 @@ enum irdma_status_code irdma_sc_cqp_init(struct irdma_sc_cqp *cqp,
|
||||
info->dev->cqp = cqp;
|
||||
|
||||
IRDMA_RING_INIT(cqp->sq_ring, cqp->sq_size);
|
||||
cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS] = 0;
|
||||
cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS] = 0;
|
||||
cqp->requested_ops = 0;
|
||||
atomic64_set(&cqp->completed_ops, 0);
|
||||
/* for the cqp commands backlog. */
|
||||
INIT_LIST_HEAD(&cqp->dev->cqp_cmd_head);
|
||||
|
||||
@@ -3306,7 +3306,7 @@ __le64 *irdma_sc_cqp_get_next_send_wqe_idx(struct irdma_sc_cqp *cqp, u64 scratch
|
||||
if (ret_code)
|
||||
return NULL;
|
||||
|
||||
cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS]++;
|
||||
cqp->requested_ops++;
|
||||
if (!*wqe_idx)
|
||||
cqp->polarity = !cqp->polarity;
|
||||
wqe = cqp->sq_base[*wqe_idx].elem;
|
||||
@@ -3395,6 +3395,9 @@ enum irdma_status_code irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq,
|
||||
if (polarity != ccq->cq_uk.polarity)
|
||||
return IRDMA_ERR_Q_EMPTY;
|
||||
|
||||
/* Ensure CEQE contents are read after valid bit is checked */
|
||||
dma_rmb();
|
||||
|
||||
get_64bit_val(cqe, 8, &qp_ctx);
|
||||
cqp = (struct irdma_sc_cqp *)(unsigned long)qp_ctx;
|
||||
info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, temp);
|
||||
@@ -3429,7 +3432,7 @@ enum irdma_status_code irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq,
|
||||
dma_wmb(); /* make sure shadow area is updated before moving tail */
|
||||
|
||||
IRDMA_RING_MOVE_TAIL(cqp->sq_ring);
|
||||
ccq->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]++;
|
||||
atomic64_inc(&cqp->completed_ops);
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
@@ -4046,13 +4049,17 @@ enum irdma_status_code irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq,
|
||||
u8 polarity;
|
||||
|
||||
aeqe = IRDMA_GET_CURRENT_AEQ_ELEM(aeq);
|
||||
get_64bit_val(aeqe, 0, &compl_ctx);
|
||||
get_64bit_val(aeqe, 8, &temp);
|
||||
polarity = (u8)FIELD_GET(IRDMA_AEQE_VALID, temp);
|
||||
|
||||
if (aeq->polarity != polarity)
|
||||
return IRDMA_ERR_Q_EMPTY;
|
||||
|
||||
/* Ensure AEQE contents are read after valid bit is checked */
|
||||
dma_rmb();
|
||||
|
||||
get_64bit_val(aeqe, 0, &compl_ctx);
|
||||
|
||||
print_hex_dump_debug("WQE: AEQ_ENTRY WQE", DUMP_PREFIX_OFFSET, 16, 8,
|
||||
aeqe, 16, false);
|
||||
|
||||
|
||||
@@ -190,32 +190,30 @@ enum irdma_cqp_op_type {
|
||||
IRDMA_OP_MANAGE_VF_PBLE_BP = 25,
|
||||
IRDMA_OP_QUERY_FPM_VAL = 26,
|
||||
IRDMA_OP_COMMIT_FPM_VAL = 27,
|
||||
IRDMA_OP_REQ_CMDS = 28,
|
||||
IRDMA_OP_CMPL_CMDS = 29,
|
||||
IRDMA_OP_AH_CREATE = 30,
|
||||
IRDMA_OP_AH_MODIFY = 31,
|
||||
IRDMA_OP_AH_DESTROY = 32,
|
||||
IRDMA_OP_MC_CREATE = 33,
|
||||
IRDMA_OP_MC_DESTROY = 34,
|
||||
IRDMA_OP_MC_MODIFY = 35,
|
||||
IRDMA_OP_STATS_ALLOCATE = 36,
|
||||
IRDMA_OP_STATS_FREE = 37,
|
||||
IRDMA_OP_STATS_GATHER = 38,
|
||||
IRDMA_OP_WS_ADD_NODE = 39,
|
||||
IRDMA_OP_WS_MODIFY_NODE = 40,
|
||||
IRDMA_OP_WS_DELETE_NODE = 41,
|
||||
IRDMA_OP_WS_FAILOVER_START = 42,
|
||||
IRDMA_OP_WS_FAILOVER_COMPLETE = 43,
|
||||
IRDMA_OP_SET_UP_MAP = 44,
|
||||
IRDMA_OP_GEN_AE = 45,
|
||||
IRDMA_OP_QUERY_RDMA_FEATURES = 46,
|
||||
IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY = 47,
|
||||
IRDMA_OP_ADD_LOCAL_MAC_ENTRY = 48,
|
||||
IRDMA_OP_DELETE_LOCAL_MAC_ENTRY = 49,
|
||||
IRDMA_OP_CQ_MODIFY = 50,
|
||||
IRDMA_OP_AH_CREATE = 28,
|
||||
IRDMA_OP_AH_MODIFY = 29,
|
||||
IRDMA_OP_AH_DESTROY = 30,
|
||||
IRDMA_OP_MC_CREATE = 31,
|
||||
IRDMA_OP_MC_DESTROY = 32,
|
||||
IRDMA_OP_MC_MODIFY = 33,
|
||||
IRDMA_OP_STATS_ALLOCATE = 34,
|
||||
IRDMA_OP_STATS_FREE = 35,
|
||||
IRDMA_OP_STATS_GATHER = 36,
|
||||
IRDMA_OP_WS_ADD_NODE = 37,
|
||||
IRDMA_OP_WS_MODIFY_NODE = 38,
|
||||
IRDMA_OP_WS_DELETE_NODE = 39,
|
||||
IRDMA_OP_WS_FAILOVER_START = 40,
|
||||
IRDMA_OP_WS_FAILOVER_COMPLETE = 41,
|
||||
IRDMA_OP_SET_UP_MAP = 42,
|
||||
IRDMA_OP_GEN_AE = 43,
|
||||
IRDMA_OP_QUERY_RDMA_FEATURES = 44,
|
||||
IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY = 45,
|
||||
IRDMA_OP_ADD_LOCAL_MAC_ENTRY = 46,
|
||||
IRDMA_OP_DELETE_LOCAL_MAC_ENTRY = 47,
|
||||
IRDMA_OP_CQ_MODIFY = 48,
|
||||
|
||||
/* Must be last entry*/
|
||||
IRDMA_MAX_CQP_OPS = 51,
|
||||
IRDMA_MAX_CQP_OPS = 49,
|
||||
};
|
||||
|
||||
/* CQP SQ WQES */
|
||||
|
||||
@@ -191,6 +191,7 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp,
|
||||
case IRDMA_AE_AMP_MWBIND_INVALID_RIGHTS:
|
||||
case IRDMA_AE_AMP_MWBIND_BIND_DISABLED:
|
||||
case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS:
|
||||
case IRDMA_AE_AMP_MWBIND_VALID_STAG:
|
||||
qp->flush_code = FLUSH_MW_BIND_ERR;
|
||||
qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
|
||||
break;
|
||||
@@ -2084,7 +2085,7 @@ void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq)
|
||||
cqp_request->compl_info.error = info.error;
|
||||
|
||||
if (cqp_request->waiting) {
|
||||
cqp_request->request_done = true;
|
||||
WRITE_ONCE(cqp_request->request_done, true);
|
||||
wake_up(&cqp_request->waitq);
|
||||
irdma_put_cqp_request(&rf->cqp, cqp_request);
|
||||
} else {
|
||||
|
||||
@@ -160,8 +160,8 @@ struct irdma_cqp_request {
|
||||
void (*callback_fcn)(struct irdma_cqp_request *cqp_request);
|
||||
void *param;
|
||||
struct irdma_cqp_compl_info compl_info;
|
||||
bool request_done; /* READ/WRITE_ONCE macros operate on it */
|
||||
bool waiting:1;
|
||||
bool request_done:1;
|
||||
bool dynamic:1;
|
||||
};
|
||||
|
||||
|
||||
@@ -235,6 +235,9 @@ irdma_puda_poll_info(struct irdma_sc_cq *cq, struct irdma_puda_cmpl_info *info)
|
||||
if (valid_bit != cq_uk->polarity)
|
||||
return IRDMA_ERR_Q_EMPTY;
|
||||
|
||||
/* Ensure CQE contents are read after valid bit is checked */
|
||||
dma_rmb();
|
||||
|
||||
if (cq->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2)
|
||||
ext_valid = (bool)FIELD_GET(IRDMA_CQ_EXTCQE, qword3);
|
||||
|
||||
@@ -248,6 +251,9 @@ irdma_puda_poll_info(struct irdma_sc_cq *cq, struct irdma_puda_cmpl_info *info)
|
||||
if (polarity != cq_uk->polarity)
|
||||
return IRDMA_ERR_Q_EMPTY;
|
||||
|
||||
/* Ensure ext CQE contents are read after ext valid bit is checked */
|
||||
dma_rmb();
|
||||
|
||||
IRDMA_RING_MOVE_HEAD_NOCHECK(cq_uk->cq_ring);
|
||||
if (!IRDMA_RING_CURRENT_HEAD(cq_uk->cq_ring))
|
||||
cq_uk->polarity = !cq_uk->polarity;
|
||||
|
||||
@@ -411,6 +411,8 @@ struct irdma_sc_cqp {
|
||||
struct irdma_dcqcn_cc_params dcqcn_params;
|
||||
__le64 *host_ctx;
|
||||
u64 *scratch_array;
|
||||
u64 requested_ops;
|
||||
atomic64_t completed_ops;
|
||||
u32 cqp_id;
|
||||
u32 sq_size;
|
||||
u32 hw_sq_size;
|
||||
|
||||
@@ -1549,6 +1549,9 @@ void irdma_uk_clean_cq(void *q, struct irdma_cq_uk *cq)
|
||||
if (polarity != temp)
|
||||
break;
|
||||
|
||||
/* Ensure CQE contents are read after valid bit is checked */
|
||||
dma_rmb();
|
||||
|
||||
get_64bit_val(cqe, 8, &comp_ctx);
|
||||
if ((void *)(unsigned long)comp_ctx == q)
|
||||
set_64bit_val(cqe, 8, 0);
|
||||
|
||||
@@ -481,7 +481,7 @@ void irdma_free_cqp_request(struct irdma_cqp *cqp,
|
||||
if (cqp_request->dynamic) {
|
||||
kfree(cqp_request);
|
||||
} else {
|
||||
cqp_request->request_done = false;
|
||||
WRITE_ONCE(cqp_request->request_done, false);
|
||||
cqp_request->callback_fcn = NULL;
|
||||
cqp_request->waiting = false;
|
||||
|
||||
@@ -515,7 +515,7 @@ irdma_free_pending_cqp_request(struct irdma_cqp *cqp,
|
||||
{
|
||||
if (cqp_request->waiting) {
|
||||
cqp_request->compl_info.error = true;
|
||||
cqp_request->request_done = true;
|
||||
WRITE_ONCE(cqp_request->request_done, true);
|
||||
wake_up(&cqp_request->waitq);
|
||||
}
|
||||
wait_event_timeout(cqp->remove_wq,
|
||||
@@ -567,11 +567,11 @@ static enum irdma_status_code irdma_wait_event(struct irdma_pci_f *rf,
|
||||
bool cqp_error = false;
|
||||
enum irdma_status_code err_code = 0;
|
||||
|
||||
cqp_timeout.compl_cqp_cmds = rf->sc_dev.cqp_cmd_stats[IRDMA_OP_CMPL_CMDS];
|
||||
cqp_timeout.compl_cqp_cmds = atomic64_read(&rf->sc_dev.cqp->completed_ops);
|
||||
do {
|
||||
irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq);
|
||||
if (wait_event_timeout(cqp_request->waitq,
|
||||
cqp_request->request_done,
|
||||
READ_ONCE(cqp_request->request_done),
|
||||
msecs_to_jiffies(CQP_COMPL_WAIT_TIME_MS)))
|
||||
break;
|
||||
|
||||
|
||||
@@ -530,15 +530,15 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx,
|
||||
return (-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 |
|
||||
MLX4_IB_RX_HASH_DST_IPV4 |
|
||||
MLX4_IB_RX_HASH_SRC_IPV6 |
|
||||
MLX4_IB_RX_HASH_DST_IPV6 |
|
||||
MLX4_IB_RX_HASH_SRC_PORT_TCP |
|
||||
MLX4_IB_RX_HASH_DST_PORT_TCP |
|
||||
MLX4_IB_RX_HASH_SRC_PORT_UDP |
|
||||
MLX4_IB_RX_HASH_DST_PORT_UDP |
|
||||
MLX4_IB_RX_HASH_INNER)) {
|
||||
if (ucmd->rx_hash_fields_mask & ~(u64)(MLX4_IB_RX_HASH_SRC_IPV4 |
|
||||
MLX4_IB_RX_HASH_DST_IPV4 |
|
||||
MLX4_IB_RX_HASH_SRC_IPV6 |
|
||||
MLX4_IB_RX_HASH_DST_IPV6 |
|
||||
MLX4_IB_RX_HASH_SRC_PORT_TCP |
|
||||
MLX4_IB_RX_HASH_DST_PORT_TCP |
|
||||
MLX4_IB_RX_HASH_SRC_PORT_UDP |
|
||||
MLX4_IB_RX_HASH_DST_PORT_UDP |
|
||||
MLX4_IB_RX_HASH_INNER)) {
|
||||
pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n",
|
||||
ucmd->rx_hash_fields_mask);
|
||||
return (-EOPNOTSUPP);
|
||||
|
||||
@@ -1393,7 +1393,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev,
|
||||
if (mthca_array_get(&dev->qp_table.qp, mqpn))
|
||||
err = -EBUSY;
|
||||
else
|
||||
mthca_array_set(&dev->qp_table.qp, mqpn, qp->sqp);
|
||||
mthca_array_set(&dev->qp_table.qp, mqpn, qp);
|
||||
spin_unlock_irq(&dev->qp_table.lock);
|
||||
|
||||
if (err)
|
||||
|
||||
@@ -82,6 +82,7 @@ struct bcm6345_l1_chip {
|
||||
};
|
||||
|
||||
struct bcm6345_l1_cpu {
|
||||
struct bcm6345_l1_chip *intc;
|
||||
void __iomem *map_base;
|
||||
unsigned int parent_irq;
|
||||
u32 enable_cache[];
|
||||
@@ -115,17 +116,11 @@ static inline unsigned int cpu_for_irq(struct bcm6345_l1_chip *intc,
|
||||
|
||||
static void bcm6345_l1_irq_handle(struct irq_desc *desc)
|
||||
{
|
||||
struct bcm6345_l1_chip *intc = irq_desc_get_handler_data(desc);
|
||||
struct bcm6345_l1_cpu *cpu;
|
||||
struct bcm6345_l1_cpu *cpu = irq_desc_get_handler_data(desc);
|
||||
struct bcm6345_l1_chip *intc = cpu->intc;
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
unsigned int idx;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cpu = intc->cpus[cpu_logical_map(smp_processor_id())];
|
||||
#else
|
||||
cpu = intc->cpus[0];
|
||||
#endif
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
||||
for (idx = 0; idx < intc->n_words; idx++) {
|
||||
@@ -257,6 +252,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn,
|
||||
if (!cpu)
|
||||
return -ENOMEM;
|
||||
|
||||
cpu->intc = intc;
|
||||
cpu->map_base = ioremap(res.start, sz);
|
||||
if (!cpu->map_base)
|
||||
return -ENOMEM;
|
||||
@@ -272,7 +268,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn,
|
||||
return -EINVAL;
|
||||
}
|
||||
irq_set_chained_handler_and_data(cpu->parent_irq,
|
||||
bcm6345_l1_irq_handle, intc);
|
||||
bcm6345_l1_irq_handle, cpu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -267,13 +267,23 @@ static void vpe_to_cpuid_unlock(struct its_vpe *vpe, unsigned long flags)
|
||||
raw_spin_unlock_irqrestore(&vpe->vpe_lock, flags);
|
||||
}
|
||||
|
||||
static struct irq_chip its_vpe_irq_chip;
|
||||
|
||||
static int irq_to_cpuid_lock(struct irq_data *d, unsigned long *flags)
|
||||
{
|
||||
struct its_vlpi_map *map = get_vlpi_map(d);
|
||||
struct its_vpe *vpe = NULL;
|
||||
int cpu;
|
||||
|
||||
if (map) {
|
||||
cpu = vpe_to_cpuid_lock(map->vpe, flags);
|
||||
if (d->chip == &its_vpe_irq_chip) {
|
||||
vpe = irq_data_get_irq_chip_data(d);
|
||||
} else {
|
||||
struct its_vlpi_map *map = get_vlpi_map(d);
|
||||
if (map)
|
||||
vpe = map->vpe;
|
||||
}
|
||||
|
||||
if (vpe) {
|
||||
cpu = vpe_to_cpuid_lock(vpe, flags);
|
||||
} else {
|
||||
/* Physical LPIs are already locked via the irq_desc lock */
|
||||
struct its_device *its_dev = irq_data_get_irq_chip_data(d);
|
||||
@@ -287,10 +297,18 @@ static int irq_to_cpuid_lock(struct irq_data *d, unsigned long *flags)
|
||||
|
||||
static void irq_to_cpuid_unlock(struct irq_data *d, unsigned long flags)
|
||||
{
|
||||
struct its_vlpi_map *map = get_vlpi_map(d);
|
||||
struct its_vpe *vpe = NULL;
|
||||
|
||||
if (map)
|
||||
vpe_to_cpuid_unlock(map->vpe, flags);
|
||||
if (d->chip == &its_vpe_irq_chip) {
|
||||
vpe = irq_data_get_irq_chip_data(d);
|
||||
} else {
|
||||
struct its_vlpi_map *map = get_vlpi_map(d);
|
||||
if (map)
|
||||
vpe = map->vpe;
|
||||
}
|
||||
|
||||
if (vpe)
|
||||
vpe_to_cpuid_unlock(vpe, flags);
|
||||
}
|
||||
|
||||
static struct its_collection *valid_col(struct its_collection *col)
|
||||
@@ -1427,13 +1445,28 @@ static void wait_for_syncr(void __iomem *rdbase)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
static void __direct_lpi_inv(struct irq_data *d, u64 val)
|
||||
{
|
||||
void __iomem *rdbase;
|
||||
unsigned long flags;
|
||||
int cpu;
|
||||
|
||||
/* Target the redistributor this LPI is currently routed to */
|
||||
cpu = irq_to_cpuid_lock(d, &flags);
|
||||
raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock);
|
||||
|
||||
rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
|
||||
gic_write_lpir(val, rdbase + GICR_INVLPIR);
|
||||
wait_for_syncr(rdbase);
|
||||
|
||||
raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock);
|
||||
irq_to_cpuid_unlock(d, flags);
|
||||
}
|
||||
|
||||
static void direct_lpi_inv(struct irq_data *d)
|
||||
{
|
||||
struct its_vlpi_map *map = get_vlpi_map(d);
|
||||
void __iomem *rdbase;
|
||||
unsigned long flags;
|
||||
u64 val;
|
||||
int cpu;
|
||||
|
||||
if (map) {
|
||||
struct its_device *its_dev = irq_data_get_irq_chip_data(d);
|
||||
@@ -1447,15 +1480,7 @@ static void direct_lpi_inv(struct irq_data *d)
|
||||
val = d->hwirq;
|
||||
}
|
||||
|
||||
/* Target the redistributor this LPI is currently routed to */
|
||||
cpu = irq_to_cpuid_lock(d, &flags);
|
||||
raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock);
|
||||
rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
|
||||
gic_write_lpir(val, rdbase + GICR_INVLPIR);
|
||||
|
||||
wait_for_syncr(rdbase);
|
||||
raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock);
|
||||
irq_to_cpuid_unlock(d, flags);
|
||||
__direct_lpi_inv(d, val);
|
||||
}
|
||||
|
||||
static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
|
||||
@@ -3936,18 +3961,10 @@ static void its_vpe_send_inv(struct irq_data *d)
|
||||
{
|
||||
struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
|
||||
|
||||
if (gic_rdists->has_direct_lpi) {
|
||||
void __iomem *rdbase;
|
||||
|
||||
/* Target the redistributor this VPE is currently known on */
|
||||
raw_spin_lock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock);
|
||||
rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base;
|
||||
gic_write_lpir(d->parent_data->hwirq, rdbase + GICR_INVLPIR);
|
||||
wait_for_syncr(rdbase);
|
||||
raw_spin_unlock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock);
|
||||
} else {
|
||||
if (gic_rdists->has_direct_lpi)
|
||||
__direct_lpi_inv(d, d->parent_data->hwirq);
|
||||
else
|
||||
its_vpe_send_cmd(vpe, its_send_inv);
|
||||
}
|
||||
}
|
||||
|
||||
static void its_vpe_mask_irq(struct irq_data *d)
|
||||
|
||||
@@ -854,7 +854,13 @@ struct smq_policy {
|
||||
|
||||
struct background_tracker *bg_work;
|
||||
|
||||
bool migrations_allowed;
|
||||
bool migrations_allowed:1;
|
||||
|
||||
/*
|
||||
* If this is set the policy will try and clean the whole cache
|
||||
* even if the device is not idle.
|
||||
*/
|
||||
bool cleaner:1;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
@@ -1133,7 +1139,7 @@ static bool clean_target_met(struct smq_policy *mq, bool idle)
|
||||
* Cache entries may not be populated. So we cannot rely on the
|
||||
* size of the clean queue.
|
||||
*/
|
||||
if (idle) {
|
||||
if (idle || mq->cleaner) {
|
||||
/*
|
||||
* We'd like to clean everything.
|
||||
*/
|
||||
@@ -1716,11 +1722,9 @@ static void calc_hotspot_params(sector_t origin_size,
|
||||
*hotspot_block_size /= 2u;
|
||||
}
|
||||
|
||||
static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size,
|
||||
sector_t origin_size,
|
||||
sector_t cache_block_size,
|
||||
bool mimic_mq,
|
||||
bool migrations_allowed)
|
||||
static struct dm_cache_policy *
|
||||
__smq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size,
|
||||
bool mimic_mq, bool migrations_allowed, bool cleaner)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned nr_sentinels_per_queue = 2u * NR_CACHE_LEVELS;
|
||||
@@ -1807,6 +1811,7 @@ static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size,
|
||||
goto bad_btracker;
|
||||
|
||||
mq->migrations_allowed = migrations_allowed;
|
||||
mq->cleaner = cleaner;
|
||||
|
||||
return &mq->policy;
|
||||
|
||||
@@ -1830,21 +1835,24 @@ static struct dm_cache_policy *smq_create(dm_cblock_t cache_size,
|
||||
sector_t origin_size,
|
||||
sector_t cache_block_size)
|
||||
{
|
||||
return __smq_create(cache_size, origin_size, cache_block_size, false, true);
|
||||
return __smq_create(cache_size, origin_size, cache_block_size,
|
||||
false, true, false);
|
||||
}
|
||||
|
||||
static struct dm_cache_policy *mq_create(dm_cblock_t cache_size,
|
||||
sector_t origin_size,
|
||||
sector_t cache_block_size)
|
||||
{
|
||||
return __smq_create(cache_size, origin_size, cache_block_size, true, true);
|
||||
return __smq_create(cache_size, origin_size, cache_block_size,
|
||||
true, true, false);
|
||||
}
|
||||
|
||||
static struct dm_cache_policy *cleaner_create(dm_cblock_t cache_size,
|
||||
sector_t origin_size,
|
||||
sector_t cache_block_size)
|
||||
{
|
||||
return __smq_create(cache_size, origin_size, cache_block_size, false, false);
|
||||
return __smq_create(cache_size, origin_size, cache_block_size,
|
||||
false, false, true);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
@@ -3258,8 +3258,7 @@ size_check:
|
||||
r = md_start(&rs->md);
|
||||
if (r) {
|
||||
ti->error = "Failed to start raid array";
|
||||
mddev_unlock(&rs->md);
|
||||
goto bad_md_start;
|
||||
goto bad_unlock;
|
||||
}
|
||||
|
||||
/* If raid4/5/6 journal mode explicitly requested (only possible with journal dev) -> set it */
|
||||
@@ -3267,8 +3266,7 @@ size_check:
|
||||
r = r5c_journal_mode_set(&rs->md, rs->journal_dev.mode);
|
||||
if (r) {
|
||||
ti->error = "Failed to set raid4/5/6 journal mode";
|
||||
mddev_unlock(&rs->md);
|
||||
goto bad_journal_mode_set;
|
||||
goto bad_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3279,14 +3277,14 @@ size_check:
|
||||
if (rs_is_raid456(rs)) {
|
||||
r = rs_set_raid456_stripe_cache(rs);
|
||||
if (r)
|
||||
goto bad_stripe_cache;
|
||||
goto bad_unlock;
|
||||
}
|
||||
|
||||
/* Now do an early reshape check */
|
||||
if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
|
||||
r = rs_check_reshape(rs);
|
||||
if (r)
|
||||
goto bad_check_reshape;
|
||||
goto bad_unlock;
|
||||
|
||||
/* Restore new, ctr requested layout to perform check */
|
||||
rs_config_restore(rs, &rs_layout);
|
||||
@@ -3295,7 +3293,7 @@ size_check:
|
||||
r = rs->md.pers->check_reshape(&rs->md);
|
||||
if (r) {
|
||||
ti->error = "Reshape check failed";
|
||||
goto bad_check_reshape;
|
||||
goto bad_unlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3306,11 +3304,9 @@ size_check:
|
||||
mddev_unlock(&rs->md);
|
||||
return 0;
|
||||
|
||||
bad_md_start:
|
||||
bad_journal_mode_set:
|
||||
bad_stripe_cache:
|
||||
bad_check_reshape:
|
||||
bad_unlock:
|
||||
md_stop(&rs->md);
|
||||
mddev_unlock(&rs->md);
|
||||
bad:
|
||||
raid_set_free(rs);
|
||||
|
||||
@@ -3321,7 +3317,9 @@ static void raid_dtr(struct dm_target *ti)
|
||||
{
|
||||
struct raid_set *rs = ti->private;
|
||||
|
||||
mddev_lock_nointr(&rs->md);
|
||||
md_stop(&rs->md);
|
||||
mddev_unlock(&rs->md);
|
||||
raid_set_free(rs);
|
||||
}
|
||||
|
||||
|
||||
@@ -6281,6 +6281,8 @@ static void __md_stop(struct mddev *mddev)
|
||||
|
||||
void md_stop(struct mddev *mddev)
|
||||
{
|
||||
lockdep_assert_held(&mddev->reconfig_mutex);
|
||||
|
||||
/* stop the array and free an attached data structures.
|
||||
* This is called from dm-raid
|
||||
*/
|
||||
|
||||
@@ -30,7 +30,7 @@ obj-$(CONFIG_TUN) += tun.o
|
||||
obj-$(CONFIG_TAP) += tap.o
|
||||
obj-$(CONFIG_VETH) += veth.o
|
||||
obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
|
||||
obj-$(CONFIG_VXLAN) += vxlan.o
|
||||
obj-$(CONFIG_VXLAN) += vxlan/
|
||||
obj-$(CONFIG_GENEVE) += geneve.o
|
||||
obj-$(CONFIG_BAREUDP) += bareudp.o
|
||||
obj-$(CONFIG_GTP) += gtp.o
|
||||
|
||||
@@ -1482,6 +1482,11 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
|
||||
|
||||
memcpy(bond_dev->broadcast, slave_dev->broadcast,
|
||||
slave_dev->addr_len);
|
||||
|
||||
if (slave_dev->flags & IFF_POINTOPOINT) {
|
||||
bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
|
||||
bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP);
|
||||
}
|
||||
}
|
||||
|
||||
/* On bonding slaves other than the currently active slave, suppress
|
||||
|
||||
@@ -734,6 +734,8 @@ static int gs_can_close(struct net_device *netdev)
|
||||
usb_kill_anchored_urbs(&dev->tx_submitted);
|
||||
atomic_set(&dev->active_tx_urbs, 0);
|
||||
|
||||
dev->can.state = CAN_STATE_STOPPED;
|
||||
|
||||
/* reset the device */
|
||||
rc = gs_cmd_reset(dev);
|
||||
if (rc < 0)
|
||||
|
||||
@@ -1642,8 +1642,11 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter,
|
||||
real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
|
||||
+ ntohs(ip_hdr(skb)->tot_len));
|
||||
|
||||
if (real_len < skb->len)
|
||||
pskb_trim(skb, real_len);
|
||||
if (real_len < skb->len) {
|
||||
err = pskb_trim(skb, real_len);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
|
||||
if (unlikely(skb->len == hdr_len)) {
|
||||
|
||||
@@ -1139,7 +1139,8 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter,
|
||||
(lancer_chip(adapter) || BE3_chip(adapter) ||
|
||||
skb_vlan_tag_present(skb)) && is_ipv4_pkt(skb)) {
|
||||
ip = (struct iphdr *)ip_hdr(skb);
|
||||
pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len));
|
||||
if (unlikely(pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len))))
|
||||
goto tx_drop;
|
||||
}
|
||||
|
||||
/* If vlan tag is already inlined in the packet, skip HW VLAN
|
||||
|
||||
@@ -52,7 +52,10 @@ static void hclge_tm_info_to_ieee_ets(struct hclge_dev *hdev,
|
||||
|
||||
for (i = 0; i < HNAE3_MAX_TC; i++) {
|
||||
ets->prio_tc[i] = hdev->tm_info.prio_tc[i];
|
||||
ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i];
|
||||
if (i < hdev->tm_info.num_tc)
|
||||
ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i];
|
||||
else
|
||||
ets->tc_tx_bw[i] = 0;
|
||||
|
||||
if (hdev->tm_info.tc_info[i].tc_sch_mode ==
|
||||
HCLGE_SCH_MODE_SP)
|
||||
@@ -123,7 +126,8 @@ static u8 hclge_ets_tc_changed(struct hclge_dev *hdev, struct ieee_ets *ets,
|
||||
}
|
||||
|
||||
static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev,
|
||||
struct ieee_ets *ets, bool *changed)
|
||||
struct ieee_ets *ets, bool *changed,
|
||||
u8 tc_num)
|
||||
{
|
||||
bool has_ets_tc = false;
|
||||
u32 total_ets_bw = 0;
|
||||
@@ -137,6 +141,13 @@ static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev,
|
||||
*changed = true;
|
||||
break;
|
||||
case IEEE_8021QAZ_TSA_ETS:
|
||||
if (i >= tc_num) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"tc%u is disabled, cannot set ets bw\n",
|
||||
i);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* The hardware will switch to sp mode if bandwidth is
|
||||
* 0, so limit ets bandwidth must be greater than 0.
|
||||
*/
|
||||
@@ -176,7 +187,7 @@ static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = hclge_ets_sch_mode_validate(hdev, ets, changed);
|
||||
ret = hclge_ets_sch_mode_validate(hdev, ets, changed, tc_num);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -677,8 +677,7 @@ static int hclge_dbg_dump_tc(struct hclge_dev *hdev, char *buf, int len)
|
||||
for (i = 0; i < HNAE3_MAX_TC; i++) {
|
||||
sch_mode_str = ets_weight->tc_weight[i] ? "dwrr" : "sp";
|
||||
pos += scnprintf(buf + pos, len - pos, "%u %4s %3u\n",
|
||||
i, sch_mode_str,
|
||||
hdev->tm_info.pg_info[0].tc_dwrr[i]);
|
||||
i, sch_mode_str, ets_weight->tc_weight[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -732,6 +732,7 @@ static void hclge_tm_tc_info_init(struct hclge_dev *hdev)
|
||||
static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
|
||||
{
|
||||
#define BW_PERCENT 100
|
||||
#define DEFAULT_BW_WEIGHT 1
|
||||
|
||||
u8 i;
|
||||
|
||||
@@ -753,7 +754,7 @@ static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
|
||||
for (k = 0; k < hdev->tm_info.num_tc; k++)
|
||||
hdev->tm_info.pg_info[i].tc_dwrr[k] = BW_PERCENT;
|
||||
for (; k < HNAE3_MAX_TC; k++)
|
||||
hdev->tm_info.pg_info[i].tc_dwrr[k] = 0;
|
||||
hdev->tm_info.pg_info[i].tc_dwrr[k] = DEFAULT_BW_WEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1839,7 +1839,7 @@ void i40e_dbg_pf_exit(struct i40e_pf *pf)
|
||||
void i40e_dbg_init(void)
|
||||
{
|
||||
i40e_dbg_root = debugfs_create_dir(i40e_driver_name, NULL);
|
||||
if (!i40e_dbg_root)
|
||||
if (IS_ERR(i40e_dbg_root))
|
||||
pr_info("init of debugfs failed\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -2532,9 +2532,6 @@ static void iavf_adminq_task(struct work_struct *work)
|
||||
u32 val, oldval;
|
||||
u16 pending;
|
||||
|
||||
if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
|
||||
goto out;
|
||||
|
||||
if (!mutex_trylock(&adapter->crit_lock)) {
|
||||
if (adapter->state == __IAVF_REMOVE)
|
||||
return;
|
||||
@@ -2543,10 +2540,13 @@ static void iavf_adminq_task(struct work_struct *work)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
|
||||
goto unlock;
|
||||
|
||||
event.buf_len = IAVF_MAX_AQ_BUF_SIZE;
|
||||
event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
|
||||
if (!event.msg_buf)
|
||||
goto out;
|
||||
goto unlock;
|
||||
|
||||
do {
|
||||
ret = iavf_clean_arq_element(hw, &event, &pending);
|
||||
@@ -2561,7 +2561,6 @@ static void iavf_adminq_task(struct work_struct *work)
|
||||
if (pending != 0)
|
||||
memset(event.msg_buf, 0, IAVF_MAX_AQ_BUF_SIZE);
|
||||
} while (pending);
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
|
||||
if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES)) {
|
||||
if (adapter->netdev_registered ||
|
||||
@@ -2619,6 +2618,8 @@ static void iavf_adminq_task(struct work_struct *work)
|
||||
|
||||
freedom:
|
||||
kfree(event.msg_buf);
|
||||
unlock:
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
out:
|
||||
/* re-enable Admin queue interrupt cause */
|
||||
iavf_misc_irq_enable(adapter);
|
||||
|
||||
@@ -1135,16 +1135,21 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp,
|
||||
ICE_FLOW_FLD_OFF_INVAL);
|
||||
}
|
||||
|
||||
/* add filter for outer headers */
|
||||
fltr_idx = ice_ethtool_flow_to_fltr(fsp->flow_type & ~FLOW_EXT);
|
||||
|
||||
assign_bit(fltr_idx, hw->fdir_perfect_fltr, perfect_filter);
|
||||
|
||||
/* add filter for outer headers */
|
||||
ret = ice_fdir_set_hw_fltr_rule(pf, seg, fltr_idx,
|
||||
ICE_FD_HW_SEG_NON_TUN);
|
||||
if (ret == -EEXIST)
|
||||
/* Rule already exists, free memory and continue */
|
||||
devm_kfree(dev, seg);
|
||||
else if (ret)
|
||||
if (ret == -EEXIST) {
|
||||
/* Rule already exists, free memory and count as success */
|
||||
ret = 0;
|
||||
goto err_exit;
|
||||
} else if (ret) {
|
||||
/* could not write filter, free memory */
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
/* make tunneled filter HW entries if possible */
|
||||
memcpy(&tun_seg[1], seg, sizeof(*seg));
|
||||
@@ -1159,18 +1164,13 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp,
|
||||
devm_kfree(dev, tun_seg);
|
||||
}
|
||||
|
||||
if (perfect_filter)
|
||||
set_bit(fltr_idx, hw->fdir_perfect_fltr);
|
||||
else
|
||||
clear_bit(fltr_idx, hw->fdir_perfect_fltr);
|
||||
|
||||
return ret;
|
||||
|
||||
err_exit:
|
||||
devm_kfree(dev, tun_seg);
|
||||
devm_kfree(dev, seg);
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1684,7 +1684,9 @@ int ice_add_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd)
|
||||
input->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL;
|
||||
|
||||
/* input struct is added to the HW filter list */
|
||||
ice_fdir_update_list_entry(pf, input, fsp->location);
|
||||
ret = ice_fdir_update_list_entry(pf, input, fsp->location);
|
||||
if (ret)
|
||||
goto release_lock;
|
||||
|
||||
ret = ice_fdir_write_all_fltr(pf, input, true);
|
||||
if (ret)
|
||||
|
||||
@@ -316,6 +316,33 @@ static void igc_clean_all_tx_rings(struct igc_adapter *adapter)
|
||||
igc_clean_tx_ring(adapter->tx_ring[i]);
|
||||
}
|
||||
|
||||
static void igc_disable_tx_ring_hw(struct igc_ring *ring)
|
||||
{
|
||||
struct igc_hw *hw = &ring->q_vector->adapter->hw;
|
||||
u8 idx = ring->reg_idx;
|
||||
u32 txdctl;
|
||||
|
||||
txdctl = rd32(IGC_TXDCTL(idx));
|
||||
txdctl &= ~IGC_TXDCTL_QUEUE_ENABLE;
|
||||
txdctl |= IGC_TXDCTL_SWFLUSH;
|
||||
wr32(IGC_TXDCTL(idx), txdctl);
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_disable_all_tx_rings_hw - Disable all transmit queue operation
|
||||
* @adapter: board private structure
|
||||
*/
|
||||
static void igc_disable_all_tx_rings_hw(struct igc_adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adapter->num_tx_queues; i++) {
|
||||
struct igc_ring *tx_ring = adapter->tx_ring[i];
|
||||
|
||||
igc_disable_tx_ring_hw(tx_ring);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* igc_setup_tx_resources - allocate Tx resources (Descriptors)
|
||||
* @tx_ring: tx descriptor ring (for a specific queue) to setup
|
||||
@@ -4975,6 +5002,7 @@ void igc_down(struct igc_adapter *adapter)
|
||||
/* clear VLAN promisc flag so VFTA will be updated if necessary */
|
||||
adapter->flags &= ~IGC_FLAG_VLAN_PROMISC;
|
||||
|
||||
igc_disable_all_tx_rings_hw(adapter);
|
||||
igc_clean_all_tx_rings(adapter);
|
||||
igc_clean_all_rx_rings(adapter);
|
||||
}
|
||||
@@ -7124,18 +7152,6 @@ void igc_enable_rx_ring(struct igc_ring *ring)
|
||||
igc_alloc_rx_buffers(ring, igc_desc_unused(ring));
|
||||
}
|
||||
|
||||
static void igc_disable_tx_ring_hw(struct igc_ring *ring)
|
||||
{
|
||||
struct igc_hw *hw = &ring->q_vector->adapter->hw;
|
||||
u8 idx = ring->reg_idx;
|
||||
u32 txdctl;
|
||||
|
||||
txdctl = rd32(IGC_TXDCTL(idx));
|
||||
txdctl &= ~IGC_TXDCTL_QUEUE_ENABLE;
|
||||
txdctl |= IGC_TXDCTL_SWFLUSH;
|
||||
wr32(IGC_TXDCTL(idx), txdctl);
|
||||
}
|
||||
|
||||
void igc_disable_tx_ring(struct igc_ring *ring)
|
||||
{
|
||||
igc_disable_tx_ring_hw(ring);
|
||||
|
||||
@@ -8398,7 +8398,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
|
||||
struct ixgbe_adapter *adapter = q_vector->adapter;
|
||||
|
||||
if (unlikely(skb_tail_pointer(skb) < hdr.network +
|
||||
VXLAN_HEADROOM))
|
||||
vxlan_headroom(0)))
|
||||
return;
|
||||
|
||||
/* verify the port is recognized as VXLAN */
|
||||
|
||||
@@ -207,13 +207,15 @@ void stmmac_dwmac4_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
|
||||
void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable)
|
||||
{
|
||||
u32 value = readl(ioaddr + GMAC_CONFIG);
|
||||
u32 old_val = value;
|
||||
|
||||
if (enable)
|
||||
value |= GMAC_CONFIG_RE | GMAC_CONFIG_TE;
|
||||
else
|
||||
value &= ~(GMAC_CONFIG_TE | GMAC_CONFIG_RE);
|
||||
|
||||
writel(value, ioaddr + GMAC_CONFIG);
|
||||
if (value != old_val)
|
||||
writel(value, ioaddr + GMAC_CONFIG);
|
||||
}
|
||||
|
||||
void stmmac_dwmac4_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
|
||||
|
||||
@@ -307,6 +307,13 @@ static int mv3310_power_up(struct phy_device *phydev)
|
||||
ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
|
||||
MV_V2_PORT_CTRL_PWRDOWN);
|
||||
|
||||
/* Sometimes, the power down bit doesn't clear immediately, and
|
||||
* a read of this register causes the bit not to clear. Delay
|
||||
* 100us to allow the PHY to come out of power down mode before
|
||||
* the next access.
|
||||
*/
|
||||
udelay(100);
|
||||
|
||||
if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310 ||
|
||||
priv->firmware_ver < 0x00030000)
|
||||
return ret;
|
||||
|
||||
@@ -2130,6 +2130,15 @@ static void team_setup_by_port(struct net_device *dev,
|
||||
dev->mtu = port_dev->mtu;
|
||||
memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len);
|
||||
eth_hw_addr_inherit(dev, port_dev);
|
||||
|
||||
if (port_dev->flags & IFF_POINTOPOINT) {
|
||||
dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
|
||||
dev->flags |= (IFF_POINTOPOINT | IFF_NOARP);
|
||||
} else if ((port_dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) ==
|
||||
(IFF_BROADCAST | IFF_MULTICAST)) {
|
||||
dev->flags |= (IFF_BROADCAST | IFF_MULTICAST);
|
||||
dev->flags &= ~(IFF_POINTOPOINT | IFF_NOARP);
|
||||
}
|
||||
}
|
||||
|
||||
static int team_dev_type_check_change(struct net_device *dev,
|
||||
|
||||
@@ -3319,6 +3319,8 @@ static int virtnet_probe(struct virtio_device *vdev)
|
||||
}
|
||||
}
|
||||
|
||||
_virtnet_set_queues(vi, vi->curr_queue_pairs);
|
||||
|
||||
/* serialize netdev register + virtio_device_ready() with ndo_open() */
|
||||
rtnl_lock();
|
||||
|
||||
@@ -3339,8 +3341,6 @@ static int virtnet_probe(struct virtio_device *vdev)
|
||||
goto free_unregister_netdev;
|
||||
}
|
||||
|
||||
virtnet_set_queues(vi, vi->curr_queue_pairs);
|
||||
|
||||
/* Assume link up if device can't report link status,
|
||||
otherwise get link status from config. */
|
||||
netif_carrier_off(dev);
|
||||
|
||||
7
drivers/net/vxlan/Makefile
Normal file
7
drivers/net/vxlan/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Makefile for the vxlan driver
|
||||
#
|
||||
|
||||
obj-$(CONFIG_VXLAN) += vxlan.o
|
||||
|
||||
vxlan-objs := vxlan_core.o
|
||||
@@ -2721,7 +2721,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
|
||||
}
|
||||
|
||||
ndst = &rt->dst;
|
||||
err = skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM,
|
||||
err = skb_tunnel_check_pmtu(skb, ndst, vxlan_headroom(flags & VXLAN_F_GPE),
|
||||
netif_is_any_bridge_port(dev));
|
||||
if (err < 0) {
|
||||
goto tx_error;
|
||||
@@ -2782,7 +2782,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
err = skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM,
|
||||
err = skb_tunnel_check_pmtu(skb, ndst,
|
||||
vxlan_headroom((flags & VXLAN_F_GPE) | VXLAN_F_IPV6),
|
||||
netif_is_any_bridge_port(dev));
|
||||
if (err < 0) {
|
||||
goto tx_error;
|
||||
@@ -3159,14 +3160,12 @@ static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
|
||||
struct vxlan_rdst *dst = &vxlan->default_dst;
|
||||
struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
|
||||
dst->remote_ifindex);
|
||||
bool use_ipv6 = !!(vxlan->cfg.flags & VXLAN_F_IPV6);
|
||||
|
||||
/* This check is different than dev->max_mtu, because it looks at
|
||||
* the lowerdev->mtu, rather than the static dev->max_mtu
|
||||
*/
|
||||
if (lowerdev) {
|
||||
int max_mtu = lowerdev->mtu -
|
||||
(use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
|
||||
int max_mtu = lowerdev->mtu - vxlan_headroom(vxlan->cfg.flags);
|
||||
if (new_mtu > max_mtu)
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -3788,11 +3787,11 @@ static void vxlan_config_apply(struct net_device *dev,
|
||||
struct vxlan_dev *vxlan = netdev_priv(dev);
|
||||
struct vxlan_rdst *dst = &vxlan->default_dst;
|
||||
unsigned short needed_headroom = ETH_HLEN;
|
||||
bool use_ipv6 = !!(conf->flags & VXLAN_F_IPV6);
|
||||
int max_mtu = ETH_MAX_MTU;
|
||||
u32 flags = conf->flags;
|
||||
|
||||
if (!changelink) {
|
||||
if (conf->flags & VXLAN_F_GPE)
|
||||
if (flags & VXLAN_F_GPE)
|
||||
vxlan_raw_setup(dev);
|
||||
else
|
||||
vxlan_ether_setup(dev);
|
||||
@@ -3818,8 +3817,7 @@ static void vxlan_config_apply(struct net_device *dev,
|
||||
|
||||
dev->needed_tailroom = lowerdev->needed_tailroom;
|
||||
|
||||
max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM :
|
||||
VXLAN_HEADROOM);
|
||||
max_mtu = lowerdev->mtu - vxlan_headroom(flags);
|
||||
if (max_mtu < ETH_MIN_MTU)
|
||||
max_mtu = ETH_MIN_MTU;
|
||||
|
||||
@@ -3830,10 +3828,9 @@ static void vxlan_config_apply(struct net_device *dev,
|
||||
if (dev->mtu > max_mtu)
|
||||
dev->mtu = max_mtu;
|
||||
|
||||
if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)
|
||||
needed_headroom += VXLAN6_HEADROOM;
|
||||
else
|
||||
needed_headroom += VXLAN_HEADROOM;
|
||||
if (flags & VXLAN_F_COLLECT_METADATA)
|
||||
flags |= VXLAN_F_IPV6;
|
||||
needed_headroom += vxlan_headroom(flags);
|
||||
dev->needed_headroom = needed_headroom;
|
||||
|
||||
memcpy(&vxlan->cfg, conf, sizeof(*conf));
|
||||
@@ -61,65 +61,32 @@ static void rockchip_pcie_clear_ep_ob_atu(struct rockchip_pcie *rockchip,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_DESC0(region));
|
||||
rockchip_pcie_write(rockchip, 0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_DESC1(region));
|
||||
rockchip_pcie_write(rockchip, 0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0(region));
|
||||
rockchip_pcie_write(rockchip, 0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(region));
|
||||
}
|
||||
|
||||
static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn,
|
||||
u32 r, u32 type, u64 cpu_addr,
|
||||
u64 pci_addr, size_t size)
|
||||
u32 r, u64 cpu_addr, u64 pci_addr,
|
||||
size_t size)
|
||||
{
|
||||
u64 sz = 1ULL << fls64(size - 1);
|
||||
int num_pass_bits = ilog2(sz);
|
||||
u32 addr0, addr1, desc0, desc1;
|
||||
bool is_nor_msg = (type == AXI_WRAPPER_NOR_MSG);
|
||||
int num_pass_bits = fls64(size - 1);
|
||||
u32 addr0, addr1, desc0;
|
||||
|
||||
/* The minimal region size is 1MB */
|
||||
if (num_pass_bits < 8)
|
||||
num_pass_bits = 8;
|
||||
|
||||
cpu_addr -= rockchip->mem_res->start;
|
||||
addr0 = ((is_nor_msg ? 0x10 : (num_pass_bits - 1)) &
|
||||
PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) |
|
||||
(lower_32_bits(cpu_addr) & PCIE_CORE_OB_REGION_ADDR0_LO_ADDR);
|
||||
addr1 = upper_32_bits(is_nor_msg ? cpu_addr : pci_addr);
|
||||
desc0 = ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN(fn) | type;
|
||||
desc1 = 0;
|
||||
addr0 = ((num_pass_bits - 1) & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) |
|
||||
(lower_32_bits(pci_addr) & PCIE_CORE_OB_REGION_ADDR0_LO_ADDR);
|
||||
addr1 = upper_32_bits(pci_addr);
|
||||
desc0 = ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN(fn) | AXI_WRAPPER_MEM_WRITE;
|
||||
|
||||
if (is_nor_msg) {
|
||||
rockchip_pcie_write(rockchip, 0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r));
|
||||
rockchip_pcie_write(rockchip, 0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r));
|
||||
rockchip_pcie_write(rockchip, desc0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r));
|
||||
rockchip_pcie_write(rockchip, desc1,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r));
|
||||
} else {
|
||||
/* PCI bus address region */
|
||||
rockchip_pcie_write(rockchip, addr0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r));
|
||||
rockchip_pcie_write(rockchip, addr1,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r));
|
||||
rockchip_pcie_write(rockchip, desc0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r));
|
||||
rockchip_pcie_write(rockchip, desc1,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r));
|
||||
|
||||
addr0 =
|
||||
((num_pass_bits - 1) & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) |
|
||||
(lower_32_bits(cpu_addr) &
|
||||
PCIE_CORE_OB_REGION_ADDR0_LO_ADDR);
|
||||
addr1 = upper_32_bits(cpu_addr);
|
||||
}
|
||||
|
||||
/* CPU bus address region */
|
||||
/* PCI bus address region */
|
||||
rockchip_pcie_write(rockchip, addr0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0(r));
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r));
|
||||
rockchip_pcie_write(rockchip, addr1,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(r));
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r));
|
||||
rockchip_pcie_write(rockchip, desc0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r));
|
||||
rockchip_pcie_write(rockchip, 0,
|
||||
ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r));
|
||||
}
|
||||
|
||||
static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
|
||||
@@ -258,26 +225,20 @@ static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
|
||||
ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar));
|
||||
}
|
||||
|
||||
static inline u32 rockchip_ob_region(phys_addr_t addr)
|
||||
{
|
||||
return (addr >> ilog2(SZ_1M)) & 0x1f;
|
||||
}
|
||||
|
||||
static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
|
||||
phys_addr_t addr, u64 pci_addr,
|
||||
size_t size)
|
||||
{
|
||||
struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
|
||||
struct rockchip_pcie *pcie = &ep->rockchip;
|
||||
u32 r;
|
||||
u32 r = rockchip_ob_region(addr);
|
||||
|
||||
r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG);
|
||||
/*
|
||||
* Region 0 is reserved for configuration space and shouldn't
|
||||
* be used elsewhere per TRM, so leave it out.
|
||||
*/
|
||||
if (r >= ep->max_regions - 1) {
|
||||
dev_err(&epc->dev, "no free outbound region\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rockchip_pcie_prog_ep_ob_atu(pcie, fn, r, AXI_WRAPPER_MEM_WRITE, addr,
|
||||
pci_addr, size);
|
||||
rockchip_pcie_prog_ep_ob_atu(pcie, fn, r, addr, pci_addr, size);
|
||||
|
||||
set_bit(r, &ep->ob_region_map);
|
||||
ep->ob_addr[r] = addr;
|
||||
@@ -292,15 +253,11 @@ static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
|
||||
struct rockchip_pcie *rockchip = &ep->rockchip;
|
||||
u32 r;
|
||||
|
||||
for (r = 0; r < ep->max_regions - 1; r++)
|
||||
for (r = 0; r < ep->max_regions; r++)
|
||||
if (ep->ob_addr[r] == addr)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Region 0 is reserved for configuration space and shouldn't
|
||||
* be used elsewhere per TRM, so leave it out.
|
||||
*/
|
||||
if (r == ep->max_regions - 1)
|
||||
if (r == ep->max_regions)
|
||||
return;
|
||||
|
||||
rockchip_pcie_clear_ep_ob_atu(rockchip, r);
|
||||
@@ -397,7 +354,8 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
|
||||
struct rockchip_pcie *rockchip = &ep->rockchip;
|
||||
u32 flags, mme, data, data_mask;
|
||||
u8 msi_count;
|
||||
u64 pci_addr, pci_addr_mask = 0xff;
|
||||
u64 pci_addr;
|
||||
u32 r;
|
||||
|
||||
/* Check MSI enable bit */
|
||||
flags = rockchip_pcie_read(&ep->rockchip,
|
||||
@@ -431,21 +389,20 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
|
||||
ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
|
||||
ROCKCHIP_PCIE_EP_MSI_CTRL_REG +
|
||||
PCI_MSI_ADDRESS_LO);
|
||||
pci_addr &= GENMASK_ULL(63, 2);
|
||||
|
||||
/* Set the outbound region if needed. */
|
||||
if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
|
||||
if (unlikely(ep->irq_pci_addr != (pci_addr & PCIE_ADDR_MASK) ||
|
||||
ep->irq_pci_fn != fn)) {
|
||||
rockchip_pcie_prog_ep_ob_atu(rockchip, fn, ep->max_regions - 1,
|
||||
AXI_WRAPPER_MEM_WRITE,
|
||||
r = rockchip_ob_region(ep->irq_phys_addr);
|
||||
rockchip_pcie_prog_ep_ob_atu(rockchip, fn, r,
|
||||
ep->irq_phys_addr,
|
||||
pci_addr & ~pci_addr_mask,
|
||||
pci_addr_mask + 1);
|
||||
ep->irq_pci_addr = (pci_addr & ~pci_addr_mask);
|
||||
pci_addr & PCIE_ADDR_MASK,
|
||||
~PCIE_ADDR_MASK + 1);
|
||||
ep->irq_pci_addr = (pci_addr & PCIE_ADDR_MASK);
|
||||
ep->irq_pci_fn = fn;
|
||||
}
|
||||
|
||||
writew(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask));
|
||||
writew(data, ep->irq_cpu_addr + (pci_addr & ~PCIE_ADDR_MASK));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -527,6 +484,8 @@ static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip,
|
||||
if (err < 0 || ep->max_regions > MAX_REGION_LIMIT)
|
||||
ep->max_regions = MAX_REGION_LIMIT;
|
||||
|
||||
ep->ob_region_map = 0;
|
||||
|
||||
err = of_property_read_u8(dev->of_node, "max-functions",
|
||||
&ep->epc->max_functions);
|
||||
if (err < 0)
|
||||
@@ -547,7 +506,9 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
|
||||
struct rockchip_pcie *rockchip;
|
||||
struct pci_epc *epc;
|
||||
size_t max_regions;
|
||||
int err;
|
||||
struct pci_epc_mem_window *windows = NULL;
|
||||
int err, i;
|
||||
u32 cfg_msi, cfg_msix_cp;
|
||||
|
||||
ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
|
||||
if (!ep)
|
||||
@@ -594,15 +555,27 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
|
||||
/* Only enable function 0 by default */
|
||||
rockchip_pcie_write(rockchip, BIT(0), PCIE_CORE_PHY_FUNC_CFG);
|
||||
|
||||
err = pci_epc_mem_init(epc, rockchip->mem_res->start,
|
||||
resource_size(rockchip->mem_res), PAGE_SIZE);
|
||||
windows = devm_kcalloc(dev, ep->max_regions,
|
||||
sizeof(struct pci_epc_mem_window), GFP_KERNEL);
|
||||
if (!windows) {
|
||||
err = -ENOMEM;
|
||||
goto err_uninit_port;
|
||||
}
|
||||
for (i = 0; i < ep->max_regions; i++) {
|
||||
windows[i].phys_base = rockchip->mem_res->start + (SZ_1M * i);
|
||||
windows[i].size = SZ_1M;
|
||||
windows[i].page_size = SZ_1M;
|
||||
}
|
||||
err = pci_epc_multi_mem_init(epc, windows, ep->max_regions);
|
||||
devm_kfree(dev, windows);
|
||||
|
||||
if (err < 0) {
|
||||
dev_err(dev, "failed to initialize the memory space\n");
|
||||
goto err_uninit_port;
|
||||
}
|
||||
|
||||
ep->irq_cpu_addr = pci_epc_mem_alloc_addr(epc, &ep->irq_phys_addr,
|
||||
SZ_128K);
|
||||
SZ_1M);
|
||||
if (!ep->irq_cpu_addr) {
|
||||
dev_err(dev, "failed to reserve memory space for MSI\n");
|
||||
err = -ENOMEM;
|
||||
@@ -611,6 +584,29 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
|
||||
|
||||
ep->irq_pci_addr = ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR;
|
||||
|
||||
/*
|
||||
* MSI-X is not supported but the controller still advertises the MSI-X
|
||||
* capability by default, which can lead to the Root Complex side
|
||||
* allocating MSI-X vectors which cannot be used. Avoid this by skipping
|
||||
* the MSI-X capability entry in the PCIe capabilities linked-list: get
|
||||
* the next pointer from the MSI-X entry and set that in the MSI
|
||||
* capability entry (which is the previous entry). This way the MSI-X
|
||||
* entry is skipped (left out of the linked-list) and not advertised.
|
||||
*/
|
||||
cfg_msi = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_BASE +
|
||||
ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
|
||||
|
||||
cfg_msi &= ~ROCKCHIP_PCIE_EP_MSI_CP1_MASK;
|
||||
|
||||
cfg_msix_cp = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_BASE +
|
||||
ROCKCHIP_PCIE_EP_MSIX_CAP_REG) &
|
||||
ROCKCHIP_PCIE_EP_MSIX_CAP_CP_MASK;
|
||||
|
||||
cfg_msi |= cfg_msix_cp;
|
||||
|
||||
rockchip_pcie_write(rockchip, cfg_msi,
|
||||
PCIE_EP_CONFIG_BASE + ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
|
||||
|
||||
rockchip_pcie_write(rockchip, PCIE_CLIENT_CONF_ENABLE,
|
||||
PCIE_CLIENT_CONFIG);
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
|
||||
#define PCIE_RC_RP_ATS_BASE 0x400000
|
||||
#define PCIE_RC_CONFIG_NORMAL_BASE 0x800000
|
||||
#define PCIE_EP_PF_CONFIG_REGS_BASE 0x800000
|
||||
#define PCIE_RC_CONFIG_BASE 0xa00000
|
||||
#define PCIE_EP_CONFIG_BASE 0xa00000
|
||||
#define PCIE_EP_CONFIG_DID_VID (PCIE_EP_CONFIG_BASE + 0x00)
|
||||
@@ -158,10 +159,11 @@
|
||||
#define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274)
|
||||
#define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20)
|
||||
|
||||
#define PCIE_ADDR_MASK 0xffffff00
|
||||
#define PCIE_CORE_AXI_CONF_BASE 0xc00000
|
||||
#define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0)
|
||||
#define PCIE_CORE_OB_REGION_ADDR0_NUM_BITS 0x3f
|
||||
#define PCIE_CORE_OB_REGION_ADDR0_LO_ADDR 0xffffff00
|
||||
#define PCIE_CORE_OB_REGION_ADDR0_LO_ADDR PCIE_ADDR_MASK
|
||||
#define PCIE_CORE_OB_REGION_ADDR1 (PCIE_CORE_AXI_CONF_BASE + 0x4)
|
||||
#define PCIE_CORE_OB_REGION_DESC0 (PCIE_CORE_AXI_CONF_BASE + 0x8)
|
||||
#define PCIE_CORE_OB_REGION_DESC1 (PCIE_CORE_AXI_CONF_BASE + 0xc)
|
||||
@@ -169,7 +171,7 @@
|
||||
#define PCIE_CORE_AXI_INBOUND_BASE 0xc00800
|
||||
#define PCIE_RP_IB_ADDR0 (PCIE_CORE_AXI_INBOUND_BASE + 0x0)
|
||||
#define PCIE_CORE_IB_REGION_ADDR0_NUM_BITS 0x3f
|
||||
#define PCIE_CORE_IB_REGION_ADDR0_LO_ADDR 0xffffff00
|
||||
#define PCIE_CORE_IB_REGION_ADDR0_LO_ADDR PCIE_ADDR_MASK
|
||||
#define PCIE_RP_IB_ADDR1 (PCIE_CORE_AXI_INBOUND_BASE + 0x4)
|
||||
|
||||
/* Size of one AXI Region (not Region 0) */
|
||||
@@ -226,6 +228,8 @@
|
||||
#define ROCKCHIP_PCIE_EP_CMD_STATUS 0x4
|
||||
#define ROCKCHIP_PCIE_EP_CMD_STATUS_IS BIT(19)
|
||||
#define ROCKCHIP_PCIE_EP_MSI_CTRL_REG 0x90
|
||||
#define ROCKCHIP_PCIE_EP_MSI_CP1_OFFSET 8
|
||||
#define ROCKCHIP_PCIE_EP_MSI_CP1_MASK GENMASK(15, 8)
|
||||
#define ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET 16
|
||||
#define ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET 17
|
||||
#define ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK GENMASK(19, 17)
|
||||
@@ -233,14 +237,19 @@
|
||||
#define ROCKCHIP_PCIE_EP_MSI_CTRL_MME_MASK GENMASK(22, 20)
|
||||
#define ROCKCHIP_PCIE_EP_MSI_CTRL_ME BIT(16)
|
||||
#define ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP BIT(24)
|
||||
#define ROCKCHIP_PCIE_EP_MSIX_CAP_REG 0xb0
|
||||
#define ROCKCHIP_PCIE_EP_MSIX_CAP_CP_OFFSET 8
|
||||
#define ROCKCHIP_PCIE_EP_MSIX_CAP_CP_MASK GENMASK(15, 8)
|
||||
#define ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR 0x1
|
||||
#define ROCKCHIP_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12))
|
||||
#define ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR 0x3
|
||||
#define ROCKCHIP_PCIE_EP_FUNC_BASE(fn) \
|
||||
(PCIE_EP_PF_CONFIG_REGS_BASE + (((fn) << 12) & GENMASK(19, 12)))
|
||||
#define ROCKCHIP_PCIE_EP_VIRT_FUNC_BASE(fn) \
|
||||
(PCIE_EP_PF_CONFIG_REGS_BASE + 0x10000 + (((fn) << 12) & GENMASK(19, 12)))
|
||||
#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
|
||||
(PCIE_RC_RP_ATS_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008)
|
||||
(PCIE_CORE_AXI_CONF_BASE + 0x0828 + (fn) * 0x0040 + (bar) * 0x0008)
|
||||
#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \
|
||||
(PCIE_RC_RP_ATS_BASE + 0x0844 + (fn) * 0x0040 + (bar) * 0x0008)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
|
||||
(PCIE_RC_RP_ATS_BASE + 0x0000 + ((r) & 0x1f) * 0x0020)
|
||||
(PCIE_CORE_AXI_CONF_BASE + 0x082c + (fn) * 0x0040 + (bar) * 0x0008)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK GENMASK(19, 12)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \
|
||||
(((devfn) << 12) & \
|
||||
@@ -248,20 +257,21 @@
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK GENMASK(27, 20)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(bus) \
|
||||
(((bus) << 20) & ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK)
|
||||
#define PCIE_RC_EP_ATR_OB_REGIONS_1_32 (PCIE_CORE_AXI_CONF_BASE + 0x0020)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
|
||||
(PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0000 + ((r) & 0x1f) * 0x0020)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r) \
|
||||
(PCIE_RC_RP_ATS_BASE + 0x0004 + ((r) & 0x1f) * 0x0020)
|
||||
(PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0004 + ((r) & 0x1f) * 0x0020)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID BIT(23)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK GENMASK(31, 24)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN(devfn) \
|
||||
(((devfn) << 24) & ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r) \
|
||||
(PCIE_RC_RP_ATS_BASE + 0x0008 + ((r) & 0x1f) * 0x0020)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r) \
|
||||
(PCIE_RC_RP_ATS_BASE + 0x000c + ((r) & 0x1f) * 0x0020)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0(r) \
|
||||
(PCIE_RC_RP_ATS_BASE + 0x0018 + ((r) & 0x1f) * 0x0020)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(r) \
|
||||
(PCIE_RC_RP_ATS_BASE + 0x001c + ((r) & 0x1f) * 0x0020)
|
||||
(PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0008 + ((r) & 0x1f) * 0x0020)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r) \
|
||||
(PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x000c + ((r) & 0x1f) * 0x0020)
|
||||
#define ROCKCHIP_PCIE_AT_OB_REGION_DESC2(r) \
|
||||
(PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0010 + ((r) & 0x1f) * 0x0020)
|
||||
|
||||
#define ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG0(fn) \
|
||||
(PCIE_CORE_CTRL_MGMT_BASE + 0x0240 + (fn) * 0x0008)
|
||||
|
||||
@@ -192,12 +192,39 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
|
||||
link->clkpm_disable = blacklist ? 1 : 0;
|
||||
}
|
||||
|
||||
static bool pcie_retrain_link(struct pcie_link_state *link)
|
||||
static int pcie_wait_for_retrain(struct pci_dev *pdev)
|
||||
{
|
||||
struct pci_dev *parent = link->pdev;
|
||||
unsigned long end_jiffies;
|
||||
u16 reg16;
|
||||
|
||||
/* Wait for Link Training to be cleared by hardware */
|
||||
end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
|
||||
do {
|
||||
pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, ®16);
|
||||
if (!(reg16 & PCI_EXP_LNKSTA_LT))
|
||||
return 0;
|
||||
msleep(1);
|
||||
} while (time_before(jiffies, end_jiffies));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int pcie_retrain_link(struct pcie_link_state *link)
|
||||
{
|
||||
struct pci_dev *parent = link->pdev;
|
||||
int rc;
|
||||
u16 reg16;
|
||||
|
||||
/*
|
||||
* Ensure the updated LNKCTL parameters are used during link
|
||||
* training by checking that there is no ongoing link training to
|
||||
* avoid LTSSM race as recommended in Implementation Note at the
|
||||
* end of PCIe r6.0.1 sec 7.5.3.7.
|
||||
*/
|
||||
rc = pcie_wait_for_retrain(parent);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16);
|
||||
reg16 |= PCI_EXP_LNKCTL_RL;
|
||||
pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);
|
||||
@@ -211,15 +238,7 @@ static bool pcie_retrain_link(struct pcie_link_state *link)
|
||||
pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);
|
||||
}
|
||||
|
||||
/* Wait for link training end. Break out after waiting for timeout */
|
||||
end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
|
||||
do {
|
||||
pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16);
|
||||
if (!(reg16 & PCI_EXP_LNKSTA_LT))
|
||||
break;
|
||||
msleep(1);
|
||||
} while (time_before(jiffies, end_jiffies));
|
||||
return !(reg16 & PCI_EXP_LNKSTA_LT);
|
||||
return pcie_wait_for_retrain(parent);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -288,15 +307,15 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
|
||||
reg16 &= ~PCI_EXP_LNKCTL_CCC;
|
||||
pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);
|
||||
|
||||
if (pcie_retrain_link(link))
|
||||
return;
|
||||
if (pcie_retrain_link(link)) {
|
||||
|
||||
/* Training failed. Restore common clock configurations */
|
||||
pci_err(parent, "ASPM: Could not configure common clock\n");
|
||||
list_for_each_entry(child, &linkbus->devices, bus_list)
|
||||
pcie_capability_write_word(child, PCI_EXP_LNKCTL,
|
||||
/* Training failed. Restore common clock configurations */
|
||||
pci_err(parent, "ASPM: Could not configure common clock\n");
|
||||
list_for_each_entry(child, &linkbus->devices, bus_list)
|
||||
pcie_capability_write_word(child, PCI_EXP_LNKCTL,
|
||||
child_reg[PCI_FUNC(child->devfn)]);
|
||||
pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg);
|
||||
pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert L0s latency encoding to ns */
|
||||
|
||||
@@ -153,7 +153,7 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)
|
||||
phy_set_drvdata(phy, &priv->ports[i]);
|
||||
i++;
|
||||
|
||||
if (i > INNO_PHY_PORT_NUM) {
|
||||
if (i >= INNO_PHY_PORT_NUM) {
|
||||
dev_warn(dev, "Support %d ports in maximum\n", i);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -68,23 +68,27 @@ static const char * const qcom_snps_hsphy_vreg_names[] = {
|
||||
/**
|
||||
* struct qcom_snps_hsphy - snps hs phy attributes
|
||||
*
|
||||
* @dev: device structure
|
||||
*
|
||||
* @phy: generic phy
|
||||
* @base: iomapped memory space for snps hs phy
|
||||
*
|
||||
* @cfg_ahb_clk: AHB2PHY interface clock
|
||||
* @ref_clk: phy reference clock
|
||||
* @iface_clk: phy interface clock
|
||||
* @num_clks: number of clocks
|
||||
* @clks: array of clocks
|
||||
* @phy_reset: phy reset control
|
||||
* @vregs: regulator supplies bulk data
|
||||
* @phy_initialized: if PHY has been initialized correctly
|
||||
* @mode: contains the current mode the PHY is in
|
||||
* @update_seq_cfg: tuning parameters for phy init
|
||||
*/
|
||||
struct qcom_snps_hsphy {
|
||||
struct device *dev;
|
||||
|
||||
struct phy *phy;
|
||||
void __iomem *base;
|
||||
|
||||
struct clk *cfg_ahb_clk;
|
||||
struct clk *ref_clk;
|
||||
int num_clks;
|
||||
struct clk_bulk_data *clks;
|
||||
struct reset_control *phy_reset;
|
||||
struct regulator_bulk_data vregs[SNPS_HS_NUM_VREGS];
|
||||
|
||||
@@ -92,6 +96,34 @@ struct qcom_snps_hsphy {
|
||||
enum phy_mode mode;
|
||||
};
|
||||
|
||||
static int qcom_snps_hsphy_clk_init(struct qcom_snps_hsphy *hsphy)
|
||||
{
|
||||
struct device *dev = hsphy->dev;
|
||||
|
||||
hsphy->num_clks = 2;
|
||||
hsphy->clks = devm_kcalloc(dev, hsphy->num_clks, sizeof(*hsphy->clks), GFP_KERNEL);
|
||||
if (!hsphy->clks)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* TODO: Currently no device tree instantiation of the PHY is using the clock.
|
||||
* This needs to be fixed in order for this code to be able to use devm_clk_bulk_get().
|
||||
*/
|
||||
hsphy->clks[0].id = "cfg_ahb";
|
||||
hsphy->clks[0].clk = devm_clk_get_optional(dev, "cfg_ahb");
|
||||
if (IS_ERR(hsphy->clks[0].clk))
|
||||
return dev_err_probe(dev, PTR_ERR(hsphy->clks[0].clk),
|
||||
"failed to get cfg_ahb clk\n");
|
||||
|
||||
hsphy->clks[1].id = "ref";
|
||||
hsphy->clks[1].clk = devm_clk_get(dev, "ref");
|
||||
if (IS_ERR(hsphy->clks[1].clk))
|
||||
return dev_err_probe(dev, PTR_ERR(hsphy->clks[1].clk),
|
||||
"failed to get ref clk\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void qcom_snps_hsphy_write_mask(void __iomem *base, u32 offset,
|
||||
u32 mask, u32 val)
|
||||
{
|
||||
@@ -122,22 +154,13 @@ static int qcom_snps_hsphy_suspend(struct qcom_snps_hsphy *hsphy)
|
||||
0, USB2_AUTO_RESUME);
|
||||
}
|
||||
|
||||
clk_disable_unprepare(hsphy->cfg_ahb_clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_snps_hsphy_resume(struct qcom_snps_hsphy *hsphy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dev_dbg(&hsphy->phy->dev, "Resume QCOM SNPS PHY, mode\n");
|
||||
|
||||
ret = clk_prepare_enable(hsphy->cfg_ahb_clk);
|
||||
if (ret) {
|
||||
dev_err(&hsphy->phy->dev, "failed to enable cfg ahb clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -183,16 +206,16 @@ static int qcom_snps_hsphy_init(struct phy *phy)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(hsphy->cfg_ahb_clk);
|
||||
ret = clk_bulk_prepare_enable(hsphy->num_clks, hsphy->clks);
|
||||
if (ret) {
|
||||
dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret);
|
||||
dev_err(&phy->dev, "failed to enable clocks, %d\n", ret);
|
||||
goto poweroff_phy;
|
||||
}
|
||||
|
||||
ret = reset_control_assert(hsphy->phy_reset);
|
||||
if (ret) {
|
||||
dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret);
|
||||
goto disable_ahb_clk;
|
||||
goto disable_clks;
|
||||
}
|
||||
|
||||
usleep_range(100, 150);
|
||||
@@ -200,7 +223,7 @@ static int qcom_snps_hsphy_init(struct phy *phy)
|
||||
ret = reset_control_deassert(hsphy->phy_reset);
|
||||
if (ret) {
|
||||
dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret);
|
||||
goto disable_ahb_clk;
|
||||
goto disable_clks;
|
||||
}
|
||||
|
||||
qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0,
|
||||
@@ -246,8 +269,8 @@ static int qcom_snps_hsphy_init(struct phy *phy)
|
||||
|
||||
return 0;
|
||||
|
||||
disable_ahb_clk:
|
||||
clk_disable_unprepare(hsphy->cfg_ahb_clk);
|
||||
disable_clks:
|
||||
clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks);
|
||||
poweroff_phy:
|
||||
regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs);
|
||||
|
||||
@@ -259,7 +282,7 @@ static int qcom_snps_hsphy_exit(struct phy *phy)
|
||||
struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy);
|
||||
|
||||
reset_control_assert(hsphy->phy_reset);
|
||||
clk_disable_unprepare(hsphy->cfg_ahb_clk);
|
||||
clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks);
|
||||
regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs);
|
||||
hsphy->phy_initialized = false;
|
||||
|
||||
@@ -299,17 +322,15 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
|
||||
if (!hsphy)
|
||||
return -ENOMEM;
|
||||
|
||||
hsphy->dev = dev;
|
||||
|
||||
hsphy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(hsphy->base))
|
||||
return PTR_ERR(hsphy->base);
|
||||
|
||||
hsphy->ref_clk = devm_clk_get(dev, "ref");
|
||||
if (IS_ERR(hsphy->ref_clk)) {
|
||||
ret = PTR_ERR(hsphy->ref_clk);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "failed to get ref clk, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = qcom_snps_hsphy_clk_init(hsphy);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to initialize clocks\n");
|
||||
|
||||
hsphy->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||
if (IS_ERR(hsphy->phy_reset)) {
|
||||
@@ -322,12 +343,9 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
|
||||
hsphy->vregs[i].supply = qcom_snps_hsphy_vreg_names[i];
|
||||
|
||||
ret = devm_regulator_bulk_get(dev, num, hsphy->vregs);
|
||||
if (ret) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "failed to get regulator supplies: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to get regulator supplies\n");
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
@@ -210,7 +210,7 @@ static ssize_t set_device_state(const char *buf, size_t count, u8 mask)
|
||||
return -EINVAL;
|
||||
|
||||
if (quirks->ec_read_only)
|
||||
return -EOPNOTSUPP;
|
||||
return 0;
|
||||
|
||||
/* read current device state */
|
||||
result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
|
||||
@@ -841,15 +841,15 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
|
||||
static void msi_init_rfkill(struct work_struct *ignored)
|
||||
{
|
||||
if (rfk_wlan) {
|
||||
rfkill_set_sw_state(rfk_wlan, !wlan_s);
|
||||
msi_rfkill_set_state(rfk_wlan, !wlan_s);
|
||||
rfkill_wlan_set(NULL, !wlan_s);
|
||||
}
|
||||
if (rfk_bluetooth) {
|
||||
rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s);
|
||||
msi_rfkill_set_state(rfk_bluetooth, !bluetooth_s);
|
||||
rfkill_bluetooth_set(NULL, !bluetooth_s);
|
||||
}
|
||||
if (rfk_threeg) {
|
||||
rfkill_set_sw_state(rfk_threeg, !threeg_s);
|
||||
msi_rfkill_set_state(rfk_threeg, !threeg_s);
|
||||
rfkill_threeg_set(NULL, !threeg_s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,12 +147,13 @@ static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
return err;
|
||||
}
|
||||
|
||||
return pwm_set_chip_data(pwm, channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
{
|
||||
struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
|
||||
struct meson_pwm *meson = to_meson_pwm(chip);
|
||||
struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
|
||||
|
||||
if (channel)
|
||||
clk_disable_unprepare(channel->clk);
|
||||
@@ -161,9 +162,10 @@ static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
|
||||
const struct pwm_state *state)
|
||||
{
|
||||
struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
|
||||
unsigned int duty, period, pre_div, cnt, duty_cnt;
|
||||
struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
|
||||
unsigned int pre_div, cnt, duty_cnt;
|
||||
unsigned long fin_freq;
|
||||
u64 duty, period;
|
||||
|
||||
duty = state->duty_cycle;
|
||||
period = state->period;
|
||||
@@ -185,19 +187,19 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
|
||||
|
||||
dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq);
|
||||
|
||||
pre_div = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * 0xffffLL);
|
||||
pre_div = div64_u64(fin_freq * period, NSEC_PER_SEC * 0xffffLL);
|
||||
if (pre_div > MISC_CLK_DIV_MASK) {
|
||||
dev_err(meson->chip.dev, "unable to get period pre_div\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cnt = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * (pre_div + 1));
|
||||
cnt = div64_u64(fin_freq * period, NSEC_PER_SEC * (pre_div + 1));
|
||||
if (cnt > 0xffff) {
|
||||
dev_err(meson->chip.dev, "unable to get period cnt\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(meson->chip.dev, "period=%u pre_div=%u cnt=%u\n", period,
|
||||
dev_dbg(meson->chip.dev, "period=%llu pre_div=%u cnt=%u\n", period,
|
||||
pre_div, cnt);
|
||||
|
||||
if (duty == period) {
|
||||
@@ -210,14 +212,13 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
|
||||
channel->lo = cnt;
|
||||
} else {
|
||||
/* Then check is we can have the duty with the same pre_div */
|
||||
duty_cnt = div64_u64(fin_freq * (u64)duty,
|
||||
NSEC_PER_SEC * (pre_div + 1));
|
||||
duty_cnt = div64_u64(fin_freq * duty, NSEC_PER_SEC * (pre_div + 1));
|
||||
if (duty_cnt > 0xffff) {
|
||||
dev_err(meson->chip.dev, "unable to get duty cycle\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(meson->chip.dev, "duty=%u pre_div=%u duty_cnt=%u\n",
|
||||
dev_dbg(meson->chip.dev, "duty=%llu pre_div=%u duty_cnt=%u\n",
|
||||
duty, pre_div, duty_cnt);
|
||||
|
||||
channel->pre_div = pre_div;
|
||||
@@ -230,7 +231,7 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
|
||||
|
||||
static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
|
||||
{
|
||||
struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
|
||||
struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
|
||||
struct meson_pwm_channel_data *channel_data;
|
||||
unsigned long flags;
|
||||
u32 value;
|
||||
@@ -273,8 +274,8 @@ static void meson_pwm_disable(struct meson_pwm *meson, struct pwm_device *pwm)
|
||||
static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
const struct pwm_state *state)
|
||||
{
|
||||
struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
|
||||
struct meson_pwm *meson = to_meson_pwm(chip);
|
||||
struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
|
||||
int err = 0;
|
||||
|
||||
if (!state)
|
||||
|
||||
@@ -131,6 +131,7 @@ static int dasd_ioctl_resume(struct dasd_block *block)
|
||||
spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
|
||||
|
||||
dasd_schedule_block_bh(block);
|
||||
dasd_schedule_device_bh(base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2705,6 +2705,9 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
|
||||
if (!fcport)
|
||||
return;
|
||||
|
||||
ql_dbg(ql_dbg_async, fcport->vha, 0x5101,
|
||||
DBG_FCPORT_PRFMT(fcport, "dev_loss_tmo expiry, rport_state=%d",
|
||||
rport->port_state));
|
||||
|
||||
/*
|
||||
* Now that the rport has been deleted, set the fcport state to
|
||||
|
||||
@@ -452,6 +452,15 @@ static inline be_id_t port_id_to_be_id(port_id_t port_id)
|
||||
return res;
|
||||
}
|
||||
|
||||
struct tmf_arg {
|
||||
struct qla_qpair *qpair;
|
||||
struct fc_port *fcport;
|
||||
struct scsi_qla_host *vha;
|
||||
u64 lun;
|
||||
u32 flags;
|
||||
uint8_t modifier;
|
||||
};
|
||||
|
||||
struct els_logo_payload {
|
||||
uint8_t opcode;
|
||||
uint8_t rsvd[3];
|
||||
@@ -531,6 +540,10 @@ struct srb_iocb {
|
||||
uint32_t data;
|
||||
struct completion comp;
|
||||
__le16 comp_status;
|
||||
|
||||
uint8_t modifier;
|
||||
uint8_t vp_index;
|
||||
uint16_t loop_id;
|
||||
} tmf;
|
||||
struct {
|
||||
#define SRB_FXDISC_REQ_DMA_VALID BIT_0
|
||||
@@ -634,6 +647,7 @@ struct srb_iocb {
|
||||
#define SRB_SA_UPDATE 25
|
||||
#define SRB_ELS_CMD_HST_NOLOGIN 26
|
||||
#define SRB_SA_REPLACE 27
|
||||
#define SRB_MARKER 28
|
||||
|
||||
struct qla_els_pt_arg {
|
||||
u8 els_opcode;
|
||||
@@ -2509,6 +2523,7 @@ enum rscn_addr_format {
|
||||
typedef struct fc_port {
|
||||
struct list_head list;
|
||||
struct scsi_qla_host *vha;
|
||||
struct list_head tmf_pending;
|
||||
|
||||
unsigned int conf_compl_supported:1;
|
||||
unsigned int deleted:2;
|
||||
@@ -2529,6 +2544,8 @@ typedef struct fc_port {
|
||||
unsigned int do_prli_nvme:1;
|
||||
|
||||
uint8_t nvme_flag;
|
||||
uint8_t active_tmf;
|
||||
#define MAX_ACTIVE_TMF 8
|
||||
|
||||
uint8_t node_name[WWN_SIZE];
|
||||
uint8_t port_name[WWN_SIZE];
|
||||
@@ -5458,4 +5475,14 @@ struct ql_vnd_tgt_stats_resp {
|
||||
#define IS_SESSION_DELETED(_fcport) (_fcport->disc_state == DSC_DELETE_PEND || \
|
||||
_fcport->disc_state == DSC_DELETED)
|
||||
|
||||
#define DBG_FCPORT_PRFMT(_fp, _fmt, _args...) \
|
||||
"%s: %8phC: " _fmt " (state=%d disc_state=%d scan_state=%d loopid=0x%x deleted=%d flags=0x%x)\n", \
|
||||
__func__, _fp->port_name, ##_args, atomic_read(&_fp->state), \
|
||||
_fp->disc_state, _fp->scan_state, _fp->loop_id, _fp->deleted, \
|
||||
_fp->flags
|
||||
|
||||
#define TMF_NOT_READY(_fcport) \
|
||||
(!_fcport || IS_SESSION_DELETED(_fcport) || atomic_read(&_fcport->state) != FCS_ONLINE || \
|
||||
!_fcport->vha->hw->flags.fw_started)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -69,9 +69,7 @@ extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *);
|
||||
extern int qla2x00_async_prlo(struct scsi_qla_host *, fc_port_t *);
|
||||
extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t);
|
||||
extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint64_t, uint32_t);
|
||||
struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *,
|
||||
enum qla_work_type);
|
||||
extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *);
|
||||
@@ -278,7 +276,6 @@ extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *);
|
||||
extern scsi_qla_host_t *qla24xx_create_vhost(struct fc_vport *);
|
||||
|
||||
extern void qla2x00_sp_free_dma(srb_t *sp);
|
||||
extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);
|
||||
|
||||
extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int);
|
||||
extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *);
|
||||
@@ -611,7 +608,6 @@ void __qla_consume_iocb(struct scsi_qla_host *vha, void **pkt, struct rsp_que **
|
||||
/*
|
||||
* Global Function Prototypes in qla_sup.c source file.
|
||||
*/
|
||||
extern void qla2x00_release_nvram_protection(scsi_qla_host_t *);
|
||||
extern int qla24xx_read_flash_data(scsi_qla_host_t *, uint32_t *,
|
||||
uint32_t, uint32_t);
|
||||
extern uint8_t *qla2x00_read_nvram_data(scsi_qla_host_t *, void *, uint32_t,
|
||||
@@ -781,12 +777,6 @@ extern void qla2x00_init_response_q_entries(struct rsp_que *);
|
||||
extern int qla25xx_delete_req_que(struct scsi_qla_host *, struct req_que *);
|
||||
extern int qla25xx_delete_rsp_que(struct scsi_qla_host *, struct rsp_que *);
|
||||
extern int qla25xx_delete_queues(struct scsi_qla_host *);
|
||||
extern uint16_t qla24xx_rd_req_reg(struct qla_hw_data *, uint16_t);
|
||||
extern uint16_t qla25xx_rd_req_reg(struct qla_hw_data *, uint16_t);
|
||||
extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t);
|
||||
extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t);
|
||||
extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
|
||||
extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
|
||||
|
||||
/* qlafx00 related functions */
|
||||
extern int qlafx00_pci_config(struct scsi_qla_host *);
|
||||
@@ -871,8 +861,6 @@ extern void qla82xx_init_flags(struct qla_hw_data *);
|
||||
extern void qla82xx_set_drv_active(scsi_qla_host_t *);
|
||||
extern int qla82xx_wr_32(struct qla_hw_data *, ulong, u32);
|
||||
extern int qla82xx_rd_32(struct qla_hw_data *, ulong);
|
||||
extern int qla82xx_rdmem(struct qla_hw_data *, u64, void *, int);
|
||||
extern int qla82xx_wrmem(struct qla_hw_data *, u64, void *, int);
|
||||
|
||||
/* ISP 8021 IDC */
|
||||
extern void qla82xx_clear_drv_active(struct qla_hw_data *);
|
||||
|
||||
@@ -1998,6 +1998,11 @@ qla2x00_tmf_iocb_timeout(void *data)
|
||||
int rc, h;
|
||||
unsigned long flags;
|
||||
|
||||
if (sp->type == SRB_MARKER) {
|
||||
complete(&tmf->u.tmf.comp);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = qla24xx_async_abort_cmd(sp, false);
|
||||
if (rc) {
|
||||
spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
|
||||
@@ -2015,24 +2020,131 @@ qla2x00_tmf_iocb_timeout(void *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void qla_marker_sp_done(srb_t *sp, int res)
|
||||
{
|
||||
struct srb_iocb *tmf = &sp->u.iocb_cmd;
|
||||
|
||||
if (res != QLA_SUCCESS)
|
||||
ql_dbg(ql_dbg_taskm, sp->vha, 0x8004,
|
||||
"Async-marker fail hdl=%x portid=%06x ctrl=%x lun=%lld qp=%d.\n",
|
||||
sp->handle, sp->fcport->d_id.b24, sp->u.iocb_cmd.u.tmf.flags,
|
||||
sp->u.iocb_cmd.u.tmf.lun, sp->qpair->id);
|
||||
|
||||
sp->u.iocb_cmd.u.tmf.data = res;
|
||||
complete(&tmf->u.tmf.comp);
|
||||
}
|
||||
|
||||
#define START_SP_W_RETRIES(_sp, _rval) \
|
||||
{\
|
||||
int cnt = 5; \
|
||||
do { \
|
||||
_rval = qla2x00_start_sp(_sp); \
|
||||
if (_rval == EAGAIN) \
|
||||
msleep(1); \
|
||||
else \
|
||||
break; \
|
||||
cnt--; \
|
||||
} while (cnt); \
|
||||
}
|
||||
|
||||
/**
|
||||
* qla26xx_marker: send marker IOCB and wait for the completion of it.
|
||||
* @arg: pointer to argument list.
|
||||
* It is assume caller will provide an fcport pointer and modifier
|
||||
*/
|
||||
static int
|
||||
qla26xx_marker(struct tmf_arg *arg)
|
||||
{
|
||||
struct scsi_qla_host *vha = arg->vha;
|
||||
struct srb_iocb *tm_iocb;
|
||||
srb_t *sp;
|
||||
int rval = QLA_FUNCTION_FAILED;
|
||||
fc_port_t *fcport = arg->fcport;
|
||||
|
||||
if (TMF_NOT_READY(arg->fcport)) {
|
||||
ql_dbg(ql_dbg_taskm, vha, 0x8039,
|
||||
"FC port not ready for marker loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d.\n",
|
||||
fcport->loop_id, fcport->d_id.b24,
|
||||
arg->modifier, arg->lun, arg->qpair->id);
|
||||
return QLA_SUSPENDED;
|
||||
}
|
||||
|
||||
/* ref: INIT */
|
||||
sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL);
|
||||
if (!sp)
|
||||
goto done;
|
||||
|
||||
sp->type = SRB_MARKER;
|
||||
sp->name = "marker";
|
||||
qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha), qla_marker_sp_done);
|
||||
sp->u.iocb_cmd.timeout = qla2x00_tmf_iocb_timeout;
|
||||
|
||||
tm_iocb = &sp->u.iocb_cmd;
|
||||
init_completion(&tm_iocb->u.tmf.comp);
|
||||
tm_iocb->u.tmf.modifier = arg->modifier;
|
||||
tm_iocb->u.tmf.lun = arg->lun;
|
||||
tm_iocb->u.tmf.loop_id = fcport->loop_id;
|
||||
tm_iocb->u.tmf.vp_index = vha->vp_idx;
|
||||
|
||||
START_SP_W_RETRIES(sp, rval);
|
||||
|
||||
ql_dbg(ql_dbg_taskm, vha, 0x8006,
|
||||
"Async-marker hdl=%x loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d rval %d.\n",
|
||||
sp->handle, fcport->loop_id, fcport->d_id.b24,
|
||||
arg->modifier, arg->lun, sp->qpair->id, rval);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x8031,
|
||||
"Marker IOCB send failure (%x).\n", rval);
|
||||
goto done_free_sp;
|
||||
}
|
||||
|
||||
wait_for_completion(&tm_iocb->u.tmf.comp);
|
||||
rval = tm_iocb->u.tmf.data;
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x8019,
|
||||
"Marker failed hdl=%x loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d rval %d.\n",
|
||||
sp->handle, fcport->loop_id, fcport->d_id.b24,
|
||||
arg->modifier, arg->lun, sp->qpair->id, rval);
|
||||
}
|
||||
|
||||
done_free_sp:
|
||||
/* ref: INIT */
|
||||
kref_put(&sp->cmd_kref, qla2x00_sp_release);
|
||||
done:
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void qla2x00_tmf_sp_done(srb_t *sp, int res)
|
||||
{
|
||||
struct srb_iocb *tmf = &sp->u.iocb_cmd;
|
||||
|
||||
if (res)
|
||||
tmf->u.tmf.data = res;
|
||||
complete(&tmf->u.tmf.comp);
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
|
||||
uint32_t tag)
|
||||
static int
|
||||
__qla2x00_async_tm_cmd(struct tmf_arg *arg)
|
||||
{
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
struct scsi_qla_host *vha = arg->vha;
|
||||
struct srb_iocb *tm_iocb;
|
||||
srb_t *sp;
|
||||
int rval = QLA_FUNCTION_FAILED;
|
||||
|
||||
fc_port_t *fcport = arg->fcport;
|
||||
|
||||
if (TMF_NOT_READY(arg->fcport)) {
|
||||
ql_dbg(ql_dbg_taskm, vha, 0x8032,
|
||||
"FC port not ready for TM command loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d.\n",
|
||||
fcport->loop_id, fcport->d_id.b24,
|
||||
arg->modifier, arg->lun, arg->qpair->id);
|
||||
return QLA_SUSPENDED;
|
||||
}
|
||||
|
||||
/* ref: INIT */
|
||||
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
|
||||
sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL);
|
||||
if (!sp)
|
||||
goto done;
|
||||
|
||||
@@ -2045,15 +2157,16 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
|
||||
|
||||
tm_iocb = &sp->u.iocb_cmd;
|
||||
init_completion(&tm_iocb->u.tmf.comp);
|
||||
tm_iocb->u.tmf.flags = flags;
|
||||
tm_iocb->u.tmf.lun = lun;
|
||||
tm_iocb->u.tmf.flags = arg->flags;
|
||||
tm_iocb->u.tmf.lun = arg->lun;
|
||||
|
||||
START_SP_W_RETRIES(sp, rval);
|
||||
|
||||
ql_dbg(ql_dbg_taskm, vha, 0x802f,
|
||||
"Async-tmf hdl=%x loop-id=%x portid=%02x%02x%02x.\n",
|
||||
sp->handle, fcport->loop_id, fcport->d_id.b.domain,
|
||||
fcport->d_id.b.area, fcport->d_id.b.al_pa);
|
||||
"Async-tmf hdl=%x loop-id=%x portid=%06x ctrl=%x lun=%lld qp=%d rval=%x.\n",
|
||||
sp->handle, fcport->loop_id, fcport->d_id.b24,
|
||||
arg->flags, arg->lun, sp->qpair->id, rval);
|
||||
|
||||
rval = qla2x00_start_sp(sp);
|
||||
if (rval != QLA_SUCCESS)
|
||||
goto done_free_sp;
|
||||
wait_for_completion(&tm_iocb->u.tmf.comp);
|
||||
@@ -2065,15 +2178,8 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
|
||||
"TM IOCB failed (%x).\n", rval);
|
||||
}
|
||||
|
||||
if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) {
|
||||
flags = tm_iocb->u.tmf.flags;
|
||||
lun = (uint16_t)tm_iocb->u.tmf.lun;
|
||||
|
||||
/* Issue Marker IOCB */
|
||||
qla2x00_marker(vha, vha->hw->base_qpair,
|
||||
fcport->loop_id, lun,
|
||||
flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
|
||||
}
|
||||
if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw))
|
||||
rval = qla26xx_marker(arg);
|
||||
|
||||
done_free_sp:
|
||||
/* ref: INIT */
|
||||
@@ -2082,6 +2188,115 @@ done:
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void qla_put_tmf(fc_port_t *fcport)
|
||||
{
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
fcport->active_tmf--;
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
}
|
||||
|
||||
static
|
||||
int qla_get_tmf(fc_port_t *fcport)
|
||||
{
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
unsigned long flags;
|
||||
int rc = 0;
|
||||
LIST_HEAD(tmf_elem);
|
||||
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
list_add_tail(&tmf_elem, &fcport->tmf_pending);
|
||||
|
||||
while (fcport->active_tmf >= MAX_ACTIVE_TMF) {
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
|
||||
msleep(1);
|
||||
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
if (TMF_NOT_READY(fcport)) {
|
||||
ql_log(ql_log_warn, vha, 0x802c,
|
||||
"Unable to acquire TM resource due to disruption.\n");
|
||||
rc = EIO;
|
||||
break;
|
||||
}
|
||||
if (fcport->active_tmf < MAX_ACTIVE_TMF &&
|
||||
list_is_first(&tmf_elem, &fcport->tmf_pending))
|
||||
break;
|
||||
}
|
||||
|
||||
list_del(&tmf_elem);
|
||||
|
||||
if (!rc)
|
||||
fcport->active_tmf++;
|
||||
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
|
||||
uint32_t tag)
|
||||
{
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
struct qla_qpair *qpair;
|
||||
struct tmf_arg a;
|
||||
int i, rval = QLA_SUCCESS;
|
||||
|
||||
if (TMF_NOT_READY(fcport))
|
||||
return QLA_SUSPENDED;
|
||||
|
||||
a.vha = fcport->vha;
|
||||
a.fcport = fcport;
|
||||
a.lun = lun;
|
||||
if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) {
|
||||
a.modifier = MK_SYNC_ID_LUN;
|
||||
|
||||
if (qla_get_tmf(fcport))
|
||||
return QLA_FUNCTION_FAILED;
|
||||
} else {
|
||||
a.modifier = MK_SYNC_ID;
|
||||
}
|
||||
|
||||
if (vha->hw->mqenable) {
|
||||
for (i = 0; i < vha->hw->num_qpairs; i++) {
|
||||
qpair = vha->hw->queue_pair_map[i];
|
||||
if (!qpair)
|
||||
continue;
|
||||
|
||||
if (TMF_NOT_READY(fcport)) {
|
||||
ql_log(ql_log_warn, vha, 0x8026,
|
||||
"Unable to send TM due to disruption.\n");
|
||||
rval = QLA_SUSPENDED;
|
||||
break;
|
||||
}
|
||||
|
||||
a.qpair = qpair;
|
||||
a.flags = flags|TCF_NOTMCMD_TO_TARGET;
|
||||
rval = __qla2x00_async_tm_cmd(&a);
|
||||
if (rval)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rval)
|
||||
goto bailout;
|
||||
|
||||
a.qpair = vha->hw->base_qpair;
|
||||
a.flags = flags;
|
||||
rval = __qla2x00_async_tm_cmd(&a);
|
||||
|
||||
bailout:
|
||||
if (a.modifier == MK_SYNC_ID_LUN)
|
||||
qla_put_tmf(fcport);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla24xx_async_abort_command(srb_t *sp)
|
||||
{
|
||||
@@ -5314,6 +5529,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
|
||||
INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
|
||||
INIT_LIST_HEAD(&fcport->gnl_entry);
|
||||
INIT_LIST_HEAD(&fcport->list);
|
||||
INIT_LIST_HEAD(&fcport->tmf_pending);
|
||||
|
||||
INIT_LIST_HEAD(&fcport->sess_cmd_list);
|
||||
spin_lock_init(&fcport->sess_cmd_lock);
|
||||
|
||||
@@ -522,21 +522,25 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct qla_qpair *qpair,
|
||||
return (QLA_FUNCTION_FAILED);
|
||||
}
|
||||
|
||||
mrk24 = (struct mrk_entry_24xx *)mrk;
|
||||
|
||||
mrk->entry_type = MARKER_TYPE;
|
||||
mrk->modifier = type;
|
||||
if (type != MK_SYNC_ALL) {
|
||||
if (IS_FWI2_CAPABLE(ha)) {
|
||||
mrk24 = (struct mrk_entry_24xx *) mrk;
|
||||
mrk24->nport_handle = cpu_to_le16(loop_id);
|
||||
int_to_scsilun(lun, (struct scsi_lun *)&mrk24->lun);
|
||||
host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun));
|
||||
mrk24->vp_index = vha->vp_idx;
|
||||
mrk24->handle = make_handle(req->id, mrk24->handle);
|
||||
} else {
|
||||
SET_TARGET_ID(ha, mrk->target, loop_id);
|
||||
mrk->lun = cpu_to_le16((uint16_t)lun);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_FWI2_CAPABLE(ha))
|
||||
mrk24->handle = QLA_SKIP_HANDLE;
|
||||
|
||||
wmb();
|
||||
|
||||
qla2x00_start_iocbs(vha, req);
|
||||
@@ -2542,7 +2546,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
|
||||
scsi_qla_host_t *vha = fcport->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct srb_iocb *iocb = &sp->u.iocb_cmd;
|
||||
struct req_que *req = vha->req;
|
||||
struct req_que *req = sp->qpair->req;
|
||||
|
||||
flags = iocb->u.tmf.flags;
|
||||
lun = iocb->u.tmf.lun;
|
||||
@@ -2558,7 +2562,8 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
|
||||
tsk->port_id[2] = fcport->d_id.b.domain;
|
||||
tsk->vp_index = fcport->vha->vp_idx;
|
||||
|
||||
if (flags == TCF_LUN_RESET) {
|
||||
if (flags & (TCF_LUN_RESET | TCF_ABORT_TASK_SET|
|
||||
TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) {
|
||||
int_to_scsilun(lun, &tsk->lun);
|
||||
host_to_fcp_swap((uint8_t *)&tsk->lun,
|
||||
sizeof(tsk->lun));
|
||||
@@ -3859,9 +3864,9 @@ int qla_get_iocbs_resource(struct srb *sp)
|
||||
case SRB_NACK_LOGO:
|
||||
case SRB_LOGOUT_CMD:
|
||||
case SRB_CTRL_VP:
|
||||
push_it_through = true;
|
||||
fallthrough;
|
||||
case SRB_MARKER:
|
||||
default:
|
||||
push_it_through = true;
|
||||
get_exch = false;
|
||||
}
|
||||
|
||||
@@ -3877,6 +3882,19 @@ int qla_get_iocbs_resource(struct srb *sp)
|
||||
return qla_get_fw_resources(sp->qpair, &sp->iores);
|
||||
}
|
||||
|
||||
static void
|
||||
qla_marker_iocb(srb_t *sp, struct mrk_entry_24xx *mrk)
|
||||
{
|
||||
mrk->entry_type = MARKER_TYPE;
|
||||
mrk->modifier = sp->u.iocb_cmd.u.tmf.modifier;
|
||||
if (sp->u.iocb_cmd.u.tmf.modifier != MK_SYNC_ALL) {
|
||||
mrk->nport_handle = cpu_to_le16(sp->u.iocb_cmd.u.tmf.loop_id);
|
||||
int_to_scsilun(sp->u.iocb_cmd.u.tmf.lun, (struct scsi_lun *)&mrk->lun);
|
||||
host_to_fcp_swap(mrk->lun, sizeof(mrk->lun));
|
||||
mrk->vp_index = sp->u.iocb_cmd.u.tmf.vp_index;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_start_sp(srb_t *sp)
|
||||
{
|
||||
@@ -3980,6 +3998,9 @@ qla2x00_start_sp(srb_t *sp)
|
||||
case SRB_SA_REPLACE:
|
||||
qla24xx_sa_replace_iocb(sp, pkt);
|
||||
break;
|
||||
case SRB_MARKER:
|
||||
qla_marker_iocb(sp, pkt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3737,6 +3737,28 @@ static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void qla_marker_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
struct mrk_entry_24xx *pkt)
|
||||
{
|
||||
const char func[] = "MRK-IOCB";
|
||||
srb_t *sp;
|
||||
int res = QLA_SUCCESS;
|
||||
|
||||
if (!IS_FWI2_CAPABLE(vha->hw))
|
||||
return;
|
||||
|
||||
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
|
||||
if (!sp)
|
||||
return;
|
||||
|
||||
if (pkt->entry_status) {
|
||||
ql_dbg(ql_dbg_taskm, vha, 0x8025, "marker failure.\n");
|
||||
res = QLA_COMMAND_ERROR;
|
||||
}
|
||||
sp->u.iocb_cmd.u.tmf.data = res;
|
||||
sp->done(sp, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* qla24xx_process_response_queue() - Process response queue entries.
|
||||
* @vha: SCSI driver HA context
|
||||
@@ -3858,9 +3880,7 @@ process_err:
|
||||
(struct nack_to_isp *)pkt);
|
||||
break;
|
||||
case MARKER_TYPE:
|
||||
/* Do nothing in this case, this check is to prevent it
|
||||
* from falling into default case
|
||||
*/
|
||||
qla_marker_iocb_entry(vha, rsp->req, (struct mrk_entry_24xx *)pkt);
|
||||
break;
|
||||
case ABORT_IOCB_TYPE:
|
||||
qla24xx_abort_iocb_entry(vha, rsp->req,
|
||||
|
||||
@@ -1080,8 +1080,6 @@ extern void qlt_81xx_config_nvram_stage2(struct scsi_qla_host *,
|
||||
struct init_cb_81xx *);
|
||||
extern void qlt_81xx_config_nvram_stage1(struct scsi_qla_host *,
|
||||
struct nvram_81xx *);
|
||||
extern int qlt_24xx_process_response_error(struct scsi_qla_host *,
|
||||
struct sts_entry_24xx *);
|
||||
extern void qlt_modify_vp_config(struct scsi_qla_host *,
|
||||
struct vp_config_entry_24xx *);
|
||||
extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *);
|
||||
|
||||
@@ -405,7 +405,7 @@ static int qcom_swrm_get_alert_slave_dev_num(struct qcom_swrm_ctrl *ctrl)
|
||||
status = (val >> (dev_num * SWRM_MCP_SLV_STATUS_SZ));
|
||||
|
||||
if ((status & SWRM_MCP_SLV_STATUS_MASK) == SDW_SLAVE_ALERT) {
|
||||
ctrl->status[dev_num] = status;
|
||||
ctrl->status[dev_num] = status & SWRM_MCP_SLV_STATUS_MASK;
|
||||
return dev_num;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1584,8 +1584,10 @@ static int ks_wlan_set_encode_ext(struct net_device *dev,
|
||||
commit |= SME_WEP_FLAG;
|
||||
}
|
||||
if (enc->key_len) {
|
||||
memcpy(&key->key_val[0], &enc->key[0], enc->key_len);
|
||||
key->key_len = enc->key_len;
|
||||
int key_len = clamp_val(enc->key_len, 0, IW_ENCODING_TOKEN_MAX);
|
||||
|
||||
memcpy(&key->key_val[0], &enc->key[0], key_len);
|
||||
key->key_len = key_len;
|
||||
commit |= (SME_WEP_VAL1 << index);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -13,6 +13,7 @@ config VIDEO_ATOMISP
|
||||
tristate "Intel Atom Image Signal Processor Driver"
|
||||
depends on VIDEO_V4L2 && INTEL_ATOMISP
|
||||
depends on PMIC_OPREGION
|
||||
select V4L2_FWNODE
|
||||
select IOSF_MBI
|
||||
select VIDEOBUF_VMALLOC
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "osdep_intf.h"
|
||||
#include "usb_ops.h"
|
||||
|
||||
#include <linux/usb.h>
|
||||
#include <linux/ieee80211.h>
|
||||
|
||||
static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
|
||||
@@ -55,6 +56,7 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
|
||||
sint i;
|
||||
struct xmit_buf *pxmitbuf;
|
||||
struct xmit_frame *pxframe;
|
||||
int j;
|
||||
|
||||
memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
|
||||
spin_lock_init(&pxmitpriv->lock);
|
||||
@@ -117,11 +119,8 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
|
||||
_init_queue(&pxmitpriv->pending_xmitbuf_queue);
|
||||
pxmitpriv->pallocated_xmitbuf =
|
||||
kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC);
|
||||
if (!pxmitpriv->pallocated_xmitbuf) {
|
||||
kfree(pxmitpriv->pallocated_frame_buf);
|
||||
pxmitpriv->pallocated_frame_buf = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!pxmitpriv->pallocated_xmitbuf)
|
||||
goto clean_up_frame_buf;
|
||||
pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
|
||||
((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
|
||||
pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
|
||||
@@ -129,13 +128,17 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
|
||||
INIT_LIST_HEAD(&pxmitbuf->list);
|
||||
pxmitbuf->pallocated_buf =
|
||||
kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC);
|
||||
if (!pxmitbuf->pallocated_buf)
|
||||
return -ENOMEM;
|
||||
if (!pxmitbuf->pallocated_buf) {
|
||||
j = 0;
|
||||
goto clean_up_alloc_buf;
|
||||
}
|
||||
pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
|
||||
((addr_t) (pxmitbuf->pallocated_buf) &
|
||||
(XMITBUF_ALIGN_SZ - 1));
|
||||
if (r8712_xmit_resource_alloc(padapter, pxmitbuf))
|
||||
return -ENOMEM;
|
||||
if (r8712_xmit_resource_alloc(padapter, pxmitbuf)) {
|
||||
j = 1;
|
||||
goto clean_up_alloc_buf;
|
||||
}
|
||||
list_add_tail(&pxmitbuf->list,
|
||||
&(pxmitpriv->free_xmitbuf_queue.queue));
|
||||
pxmitbuf++;
|
||||
@@ -146,6 +149,28 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
|
||||
init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
|
||||
tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh);
|
||||
return 0;
|
||||
|
||||
clean_up_alloc_buf:
|
||||
if (j) {
|
||||
/* failure happened in r8712_xmit_resource_alloc()
|
||||
* delete extra pxmitbuf->pallocated_buf
|
||||
*/
|
||||
kfree(pxmitbuf->pallocated_buf);
|
||||
}
|
||||
for (j = 0; j < i; j++) {
|
||||
int k;
|
||||
|
||||
pxmitbuf--; /* reset pointer */
|
||||
kfree(pxmitbuf->pallocated_buf);
|
||||
for (k = 0; k < 8; k++) /* delete xmit urb's */
|
||||
usb_free_urb(pxmitbuf->pxmit_urb[k]);
|
||||
}
|
||||
kfree(pxmitpriv->pallocated_xmitbuf);
|
||||
pxmitpriv->pallocated_xmitbuf = NULL;
|
||||
clean_up_frame_buf:
|
||||
kfree(pxmitpriv->pallocated_frame_buf);
|
||||
pxmitpriv->pallocated_frame_buf = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void _free_xmit_priv(struct xmit_priv *pxmitpriv)
|
||||
|
||||
@@ -118,6 +118,12 @@ int r8712_xmit_resource_alloc(struct _adapter *padapter,
|
||||
for (i = 0; i < 8; i++) {
|
||||
pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!pxmitbuf->pxmit_urb[i]) {
|
||||
int k;
|
||||
|
||||
for (k = i - 1; k >= 0; k--) {
|
||||
/* handle allocation errors part way through loop */
|
||||
usb_free_urb(pxmitbuf->pxmit_urb[k]);
|
||||
}
|
||||
netdev_err(padapter->pnetdev, "pxmitbuf->pxmit_urb[i] == NULL\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -202,8 +202,8 @@ static void n_tty_kick_worker(struct tty_struct *tty)
|
||||
struct n_tty_data *ldata = tty->disc_data;
|
||||
|
||||
/* Did the input worker stop? Restart it */
|
||||
if (unlikely(ldata->no_room)) {
|
||||
ldata->no_room = 0;
|
||||
if (unlikely(READ_ONCE(ldata->no_room))) {
|
||||
WRITE_ONCE(ldata->no_room, 0);
|
||||
|
||||
WARN_RATELIMIT(tty->port->itty == NULL,
|
||||
"scheduling with invalid itty\n");
|
||||
@@ -1661,7 +1661,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
|
||||
if (overflow && room < 0)
|
||||
ldata->read_head--;
|
||||
room = overflow;
|
||||
ldata->no_room = flow && !room;
|
||||
WRITE_ONCE(ldata->no_room, flow && !room);
|
||||
} else
|
||||
overflow = 0;
|
||||
|
||||
@@ -1692,6 +1692,17 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
|
||||
} else
|
||||
n_tty_check_throttle(tty);
|
||||
|
||||
if (unlikely(ldata->no_room)) {
|
||||
/*
|
||||
* Barrier here is to ensure to read the latest read_tail in
|
||||
* chars_in_buffer() and to make sure that read_tail is not loaded
|
||||
* before ldata->no_room is set.
|
||||
*/
|
||||
smp_mb();
|
||||
if (!chars_in_buffer(tty))
|
||||
n_tty_kick_worker(tty);
|
||||
}
|
||||
|
||||
up_read(&tty->termios_rwsem);
|
||||
|
||||
return rcvd;
|
||||
@@ -2100,7 +2111,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
|
||||
ssize_t retval = 0;
|
||||
long timeout;
|
||||
bool packet;
|
||||
size_t tail;
|
||||
size_t old_tail;
|
||||
|
||||
/*
|
||||
* Is this a continuation of a read started earler?
|
||||
@@ -2163,7 +2174,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
|
||||
}
|
||||
|
||||
packet = tty->ctrl.packet;
|
||||
tail = ldata->read_tail;
|
||||
old_tail = ldata->read_tail;
|
||||
|
||||
add_wait_queue(&tty->read_wait, &wait);
|
||||
while (nr) {
|
||||
@@ -2252,8 +2263,14 @@ more_to_be_read:
|
||||
if (time)
|
||||
timeout = time;
|
||||
}
|
||||
if (tail != ldata->read_tail)
|
||||
if (old_tail != ldata->read_tail) {
|
||||
/*
|
||||
* Make sure no_room is not read in n_tty_kick_worker()
|
||||
* before setting ldata->read_tail in copy_from_read_buf().
|
||||
*/
|
||||
smp_mb();
|
||||
n_tty_kick_worker(tty);
|
||||
}
|
||||
up_read(&tty->termios_rwsem);
|
||||
|
||||
remove_wait_queue(&tty->read_wait, &wait);
|
||||
|
||||
@@ -80,7 +80,7 @@ static void dw8250_set_divisor(struct uart_port *p, unsigned int baud,
|
||||
void dw8250_setup_port(struct uart_port *p)
|
||||
{
|
||||
struct uart_8250_port *up = up_to_u8250p(p);
|
||||
u32 reg;
|
||||
u32 reg, old_dlf;
|
||||
|
||||
/*
|
||||
* If the Component Version Register returns zero, we know that
|
||||
@@ -93,9 +93,11 @@ void dw8250_setup_port(struct uart_port *p)
|
||||
dev_dbg(p->dev, "Designware UART version %c.%c%c\n",
|
||||
(reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff);
|
||||
|
||||
/* Preserve value written by firmware or bootloader */
|
||||
old_dlf = dw8250_readl_ext(p, DW_UART_DLF);
|
||||
dw8250_writel_ext(p, DW_UART_DLF, ~0U);
|
||||
reg = dw8250_readl_ext(p, DW_UART_DLF);
|
||||
dw8250_writel_ext(p, DW_UART_DLF, 0);
|
||||
dw8250_writel_ext(p, DW_UART_DLF, old_dlf);
|
||||
|
||||
if (reg) {
|
||||
struct dw8250_port_data *d = p->private_data;
|
||||
|
||||
@@ -1479,13 +1479,6 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Set pm_runtime status as ACTIVE so that wakeup_irq gets
|
||||
* enabled/disabled from dev_pm_arm_wake_irq during system
|
||||
* suspend/resume respectively.
|
||||
*/
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
|
||||
if (port->wakeup_irq > 0) {
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
|
||||
|
||||
@@ -843,7 +843,7 @@ static void sifive_serial_console_write(struct console *co, const char *s,
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static int __init sifive_serial_console_setup(struct console *co, char *options)
|
||||
static int sifive_serial_console_setup(struct console *co, char *options)
|
||||
{
|
||||
struct sifive_serial_port *ssp;
|
||||
int baud = SIFIVE_DEFAULT_BAUD_RATE;
|
||||
|
||||
@@ -3012,12 +3012,14 @@ static int cdns3_gadget_udc_stop(struct usb_gadget *gadget)
|
||||
static int cdns3_gadget_check_config(struct usb_gadget *gadget)
|
||||
{
|
||||
struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget);
|
||||
struct cdns3_endpoint *priv_ep;
|
||||
struct usb_ep *ep;
|
||||
int n_in = 0;
|
||||
int total;
|
||||
|
||||
list_for_each_entry(ep, &gadget->ep_list, ep_list) {
|
||||
if (ep->claimed && (ep->address & USB_DIR_IN))
|
||||
priv_ep = ep_to_cdns3_ep(ep);
|
||||
if ((priv_ep->flags & EP_CLAIMED) && (ep->address & USB_DIR_IN))
|
||||
n_in++;
|
||||
}
|
||||
|
||||
|
||||
@@ -436,6 +436,10 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
/* novation SoundControl XL */
|
||||
{ USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Focusrite Scarlett Solo USB */
|
||||
{ USB_DEVICE(0x1235, 0x8211), .driver_info =
|
||||
USB_QUIRK_DISCONNECT_SUSPEND },
|
||||
|
||||
/* Huawei 4G LTE module */
|
||||
{ USB_DEVICE(0x12d1, 0x15bb), .driver_info =
|
||||
USB_QUIRK_DISCONNECT_SUSPEND },
|
||||
|
||||
@@ -275,9 +275,9 @@ int dwc3_core_soft_reset(struct dwc3 *dwc)
|
||||
/*
|
||||
* We're resetting only the device side because, if we're in host mode,
|
||||
* XHCI driver will reset the host block. If dwc3 was configured for
|
||||
* host-only mode, then we can return early.
|
||||
* host-only mode or current role is host, then we can return early.
|
||||
*/
|
||||
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
|
||||
if (dwc->dr_mode == USB_DR_MODE_HOST || dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
|
||||
return 0;
|
||||
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||
@@ -1143,22 +1143,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
|
||||
dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
|
||||
}
|
||||
|
||||
if (dwc->dr_mode == USB_DR_MODE_HOST ||
|
||||
dwc->dr_mode == USB_DR_MODE_OTG) {
|
||||
reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
|
||||
|
||||
/*
|
||||
* Enable Auto retry Feature to make the controller operating in
|
||||
* Host mode on seeing transaction errors(CRC errors or internal
|
||||
* overrun scenerios) on IN transfers to reply to the device
|
||||
* with a non-terminating retry ACK (i.e, an ACK transcation
|
||||
* packet with Retry=1 & Nump != 0)
|
||||
*/
|
||||
reg |= DWC3_GUCTL_HSTINAUTORETRY;
|
||||
|
||||
dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Must config both number of packets and max burst settings to enable
|
||||
* RX and/or TX threshold.
|
||||
|
||||
@@ -256,9 +256,6 @@
|
||||
#define DWC3_GCTL_GBLHIBERNATIONEN BIT(1)
|
||||
#define DWC3_GCTL_DSBLCLKGTNG BIT(0)
|
||||
|
||||
/* Global User Control Register */
|
||||
#define DWC3_GUCTL_HSTINAUTORETRY BIT(14)
|
||||
|
||||
/* Global User Control 1 Register */
|
||||
#define DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT BIT(31)
|
||||
#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
|
||||
|
||||
@@ -219,10 +219,12 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc,
|
||||
|
||||
/*
|
||||
* A lot of BYT devices lack ACPI resource entries for
|
||||
* the GPIOs, add a fallback mapping to the reference
|
||||
* the GPIOs. If the ACPI entry for the GPIO controller
|
||||
* is present add a fallback mapping to the reference
|
||||
* design GPIOs which all boards seem to use.
|
||||
*/
|
||||
gpiod_add_lookup_table(&platform_bytcr_gpios);
|
||||
if (acpi_dev_present("INT33FC", NULL, -1))
|
||||
gpiod_add_lookup_table(&platform_bytcr_gpios);
|
||||
|
||||
/*
|
||||
* These GPIOs will turn on the USB2 PHY. Note that we have to
|
||||
|
||||
@@ -1046,6 +1046,10 @@ int usb_add_config(struct usb_composite_dev *cdev,
|
||||
goto done;
|
||||
|
||||
status = bind(config);
|
||||
|
||||
if (status == 0)
|
||||
status = usb_gadget_check_config(cdev->gadget);
|
||||
|
||||
if (status < 0) {
|
||||
while (!list_empty(&config->functions)) {
|
||||
struct usb_function *f;
|
||||
|
||||
@@ -310,13 +310,15 @@ static int gadget_bind(struct usb_gadget *gadget,
|
||||
dev->eps_num = i;
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
|
||||
ret = raw_queue_event(dev, USB_RAW_EVENT_CONNECT, 0, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(&gadget->dev, "failed to queue event\n");
|
||||
set_gadget_data(gadget, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Matches kref_put() in gadget_unbind(). */
|
||||
kref_get(&dev->count);
|
||||
|
||||
ret = raw_queue_event(dev, USB_RAW_EVENT_CONNECT, 0, NULL);
|
||||
if (ret < 0)
|
||||
dev_err(&gadget->dev, "failed to queue event\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -3689,15 +3689,15 @@ static int tegra_xudc_powerdomain_init(struct tegra_xudc *xudc)
|
||||
int err;
|
||||
|
||||
xudc->genpd_dev_device = dev_pm_domain_attach_by_name(dev, "dev");
|
||||
if (IS_ERR_OR_NULL(xudc->genpd_dev_device)) {
|
||||
err = PTR_ERR(xudc->genpd_dev_device) ? : -ENODATA;
|
||||
if (IS_ERR(xudc->genpd_dev_device)) {
|
||||
err = PTR_ERR(xudc->genpd_dev_device);
|
||||
dev_err(dev, "failed to get device power domain: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
xudc->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "ss");
|
||||
if (IS_ERR_OR_NULL(xudc->genpd_dev_ss)) {
|
||||
err = PTR_ERR(xudc->genpd_dev_ss) ? : -ENODATA;
|
||||
if (IS_ERR(xudc->genpd_dev_ss)) {
|
||||
err = PTR_ERR(xudc->genpd_dev_ss);
|
||||
dev_err(dev, "failed to get SuperSpeed power domain: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -652,7 +652,13 @@ ohci_hcd_at91_drv_resume(struct device *dev)
|
||||
else
|
||||
at91_start_clock(ohci_at91);
|
||||
|
||||
ohci_resume(hcd, false);
|
||||
/*
|
||||
* According to the comment in ohci_hcd_at91_drv_suspend()
|
||||
* we need to do a reset if the 48Mhz clock was stopped,
|
||||
* that is, if ohci_at91->wakeup is clear. Tell ohci_resume()
|
||||
* to reset in this case by setting its "hibernated" flag.
|
||||
*/
|
||||
ohci_resume(hcd, !ohci_at91->wakeup);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user