mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
Compare commits
89 Commits
6da43bbeb6
...
1cc41c88ef
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1cc41c88ef | ||
|
|
d5c1b4b432 | ||
|
|
ccc0011804 | ||
|
|
241e99dbdc | ||
|
|
6014e75e87 | ||
|
|
de90cc610e | ||
|
|
809bd27452 | ||
|
|
27f518609e | ||
|
|
d4f8cccc62 | ||
|
|
ac9f4f306d | ||
|
|
b86caedd0b | ||
|
|
95baf63fe8 | ||
|
|
21a9ab5b90 | ||
|
|
fa3c727e05 | ||
|
|
362a7d4fd5 | ||
|
|
538e0110fe | ||
|
|
15ebea1bdf | ||
|
|
63444b4ca4 | ||
|
|
0a4a18e888 | ||
|
|
360b3730f8 | ||
|
|
214291cbaa | ||
|
|
2d0e88f3fd | ||
|
|
f2687d3cc9 | ||
|
|
f6fdd77b3e | ||
|
|
eac32ff423 | ||
|
|
d15deafab5 | ||
|
|
bbe3c11503 | ||
|
|
7132f7e025 | ||
|
|
33c9957091 | ||
|
|
6623c5f9fd | ||
|
|
9f8fd538e2 | ||
|
|
22a36e660d | ||
|
|
d93a89684d | ||
|
|
632108ec07 | ||
|
|
739f04f4a4 | ||
|
|
9e80562521 | ||
|
|
ed6612165b | ||
|
|
6a77267d97 | ||
|
|
d3c9c213c0 | ||
|
|
b623390045 | ||
|
|
1f214e9c3a | ||
|
|
7a7a345652 | ||
|
|
85d2c2392a | ||
|
|
6a218b9c31 | ||
|
|
240372edaf | ||
|
|
fa3376319b | ||
|
|
0b2f7be548 | ||
|
|
eb2d6774cc | ||
|
|
d32ddfeb55 | ||
|
|
d0497dd274 | ||
|
|
f2060bdc21 | ||
|
|
51a491f270 | ||
|
|
fb2cba0854 | ||
|
|
8ab523ce78 | ||
|
|
28e19737e1 | ||
|
|
7aca00d950 | ||
|
|
994dec1099 | ||
|
|
576c930e5e | ||
|
|
66e9feb03e | ||
|
|
05a1fc5efd | ||
|
|
e8c73eb7db | ||
|
|
79280191c2 | ||
|
|
7a39c723b7 | ||
|
|
b6cfddd26e | ||
|
|
939edfaa10 | ||
|
|
29528c8e64 | ||
|
|
eef295a850 | ||
|
|
c1962742ff | ||
|
|
32b415a9dc | ||
|
|
3dc8c73365 | ||
|
|
86d57d9c07 | ||
|
|
84f5526e4d | ||
|
|
1a58d865f4 | ||
|
|
6b6eddc63c | ||
|
|
82420bd4e1 | ||
|
|
59b0afd01b | ||
|
|
3cd2018e15 | ||
|
|
636f4618b1 | ||
|
|
bbde14682e | ||
|
|
fccac54b0d | ||
|
|
249d96b492 | ||
|
|
b98b69c385 | ||
|
|
8f05967b02 | ||
|
|
8da0efc3da | ||
|
|
7458f72cc2 | ||
|
|
a28352cf2d | ||
|
|
7c3643f204 | ||
|
|
90c82941ad | ||
|
|
a7b17ece40 |
@@ -105,10 +105,10 @@ In this example the SSID is 10280c63.
|
||||
|
||||
The format of the firmware file names is:
|
||||
|
||||
SoundWire (except CS35L56 Rev B0):
|
||||
SoundWire:
|
||||
cs35lxx-b0-dsp1-misc-SSID[-spkidX]-l?u?
|
||||
|
||||
SoundWire CS35L56 Rev B0:
|
||||
SoundWire CS35L56 Rev B0 firmware released before kernel version 6.16:
|
||||
cs35lxx-b0-dsp1-misc-SSID[-spkidX]-ampN
|
||||
|
||||
Non-SoundWire (HDA and I2S):
|
||||
@@ -127,9 +127,8 @@ Where:
|
||||
* spkidX is an optional part, used for laptops that have firmware
|
||||
configurations for different makes and models of internal speakers.
|
||||
|
||||
The CS35L56 Rev B0 continues to use the old filename scheme because a
|
||||
large number of firmware files have already been published with these
|
||||
names.
|
||||
Early firmware for CS35L56 Rev B0 used the ALSA prefix (ampN) as the
|
||||
filename qualifier. Support for the l?u? qualifier was added in kernel 6.16.
|
||||
|
||||
Sound Open Firmware and ALSA topology files
|
||||
-------------------------------------------
|
||||
|
||||
@@ -4399,7 +4399,7 @@ BLOCK LAYER
|
||||
M: Jens Axboe <axboe@kernel.dk>
|
||||
L: linux-block@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux.git
|
||||
F: Documentation/ABI/stable/sysfs-block
|
||||
F: Documentation/block/
|
||||
F: block/
|
||||
|
||||
@@ -874,10 +874,32 @@ static void hmat_register_target_devices(struct memory_target *target)
|
||||
}
|
||||
}
|
||||
|
||||
static void hmat_register_target(struct memory_target *target)
|
||||
static void hmat_hotplug_target(struct memory_target *target)
|
||||
{
|
||||
int nid = pxm_to_node(target->memory_pxm);
|
||||
|
||||
/*
|
||||
* Skip offline nodes. This can happen when memory marked EFI_MEMORY_SP,
|
||||
* "specific purpose", is applied to all the memory in a proximity
|
||||
* domain leading to * the node being marked offline / unplugged, or if
|
||||
* memory-only "hotplug" node is offline.
|
||||
*/
|
||||
if (nid == NUMA_NO_NODE || !node_online(nid))
|
||||
return;
|
||||
|
||||
guard(mutex)(&target_lock);
|
||||
if (target->registered)
|
||||
return;
|
||||
|
||||
hmat_register_target_initiators(target);
|
||||
hmat_register_target_cache(target);
|
||||
hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL);
|
||||
hmat_register_target_perf(target, ACCESS_COORDINATE_CPU);
|
||||
target->registered = true;
|
||||
}
|
||||
|
||||
static void hmat_register_target(struct memory_target *target)
|
||||
{
|
||||
/*
|
||||
* Devices may belong to either an offline or online
|
||||
* node, so unconditionally add them.
|
||||
@@ -895,25 +917,7 @@ static void hmat_register_target(struct memory_target *target)
|
||||
}
|
||||
mutex_unlock(&target_lock);
|
||||
|
||||
/*
|
||||
* Skip offline nodes. This can happen when memory
|
||||
* marked EFI_MEMORY_SP, "specific purpose", is applied
|
||||
* to all the memory in a proximity domain leading to
|
||||
* the node being marked offline / unplugged, or if
|
||||
* memory-only "hotplug" node is offline.
|
||||
*/
|
||||
if (nid == NUMA_NO_NODE || !node_online(nid))
|
||||
return;
|
||||
|
||||
mutex_lock(&target_lock);
|
||||
if (!target->registered) {
|
||||
hmat_register_target_initiators(target);
|
||||
hmat_register_target_cache(target);
|
||||
hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL);
|
||||
hmat_register_target_perf(target, ACCESS_COORDINATE_CPU);
|
||||
target->registered = true;
|
||||
}
|
||||
mutex_unlock(&target_lock);
|
||||
hmat_hotplug_target(target);
|
||||
}
|
||||
|
||||
static void hmat_register_targets(void)
|
||||
@@ -939,7 +943,7 @@ static int hmat_callback(struct notifier_block *self,
|
||||
if (!target)
|
||||
return NOTIFY_OK;
|
||||
|
||||
hmat_register_target(target);
|
||||
hmat_hotplug_target(target);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -237,7 +237,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
|
||||
struct acpi_srat_generic_affinity *p =
|
||||
(struct acpi_srat_generic_affinity *)header;
|
||||
|
||||
if (p->device_handle_type == 0) {
|
||||
if (p->device_handle_type == 1) {
|
||||
/*
|
||||
* For pci devices this may be the only place they
|
||||
* are assigned a proximity domain
|
||||
|
||||
@@ -3871,10 +3871,12 @@ static ssize_t qm_get_qos_value(struct hisi_qm *qm, const char *buf,
|
||||
pdev = container_of(dev, struct pci_dev, dev);
|
||||
if (pci_physfn(pdev) != qm->pdev) {
|
||||
pci_err(qm->pdev, "the pdev input does not match the pf!\n");
|
||||
put_device(dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*fun_index = pdev->devfn;
|
||||
put_device(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3702,6 +3702,7 @@ static int cxl_region_debugfs_poison_inject(void *data, u64 offset)
|
||||
if (validate_region_offset(cxlr, offset))
|
||||
return -EINVAL;
|
||||
|
||||
offset -= cxlr->params.cache_size;
|
||||
rc = region_offset_to_dpa_result(cxlr, offset, &result);
|
||||
if (rc || !result.cxlmd || result.dpa == ULLONG_MAX) {
|
||||
dev_dbg(&cxlr->dev,
|
||||
@@ -3734,6 +3735,7 @@ static int cxl_region_debugfs_poison_clear(void *data, u64 offset)
|
||||
if (validate_region_offset(cxlr, offset))
|
||||
return -EINVAL;
|
||||
|
||||
offset -= cxlr->params.cache_size;
|
||||
rc = region_offset_to_dpa_result(cxlr, offset, &result);
|
||||
if (rc || !result.cxlmd || result.dpa == ULLONG_MAX) {
|
||||
dev_dbg(&cxlr->dev,
|
||||
|
||||
@@ -236,7 +236,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
|
||||
r = amdgpu_xcp_select_scheds(adev, hw_ip, hw_prio, fpriv,
|
||||
&num_scheds, &scheds);
|
||||
if (r)
|
||||
goto cleanup_entity;
|
||||
goto error_free_entity;
|
||||
}
|
||||
|
||||
/* disable load balance if the hw engine retains context among dependent jobs */
|
||||
|
||||
@@ -82,6 +82,18 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
|
||||
/*
|
||||
* Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+.
|
||||
* Such buffers cannot be safely accessed over P2P due to device-local
|
||||
* compression metadata. Fallback to system-memory path instead.
|
||||
* Device supports GFX12 (GC 12.x or newer)
|
||||
* BO was created with the AMDGPU_GEM_CREATE_GFX12_DCC flag
|
||||
*
|
||||
*/
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0) &&
|
||||
bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC)
|
||||
attach->peer2peer = false;
|
||||
|
||||
if (!amdgpu_dmabuf_is_xgmi_accessible(attach_adev, bo) &&
|
||||
pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
|
||||
attach->peer2peer = false;
|
||||
|
||||
@@ -280,6 +280,8 @@ int isp_kernel_buffer_alloc(struct device *dev, u64 size,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Ensure *bo is NULL so a new BO will be created */
|
||||
*bo = NULL;
|
||||
ret = amdgpu_bo_create_kernel(adev,
|
||||
size,
|
||||
ISP_MC_ADDR_ALIGN,
|
||||
|
||||
@@ -151,15 +151,16 @@ void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_d
|
||||
{
|
||||
struct amdgpu_userq_fence *userq_fence, *tmp;
|
||||
struct dma_fence *fence;
|
||||
unsigned long flags;
|
||||
u64 rptr;
|
||||
int i;
|
||||
|
||||
if (!fence_drv)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&fence_drv->fence_list_lock, flags);
|
||||
rptr = amdgpu_userq_fence_read(fence_drv);
|
||||
|
||||
spin_lock(&fence_drv->fence_list_lock);
|
||||
list_for_each_entry_safe(userq_fence, tmp, &fence_drv->fences, link) {
|
||||
fence = &userq_fence->base;
|
||||
|
||||
@@ -174,7 +175,7 @@ void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_d
|
||||
list_del(&userq_fence->link);
|
||||
dma_fence_put(fence);
|
||||
}
|
||||
spin_unlock(&fence_drv->fence_list_lock);
|
||||
spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags);
|
||||
}
|
||||
|
||||
void amdgpu_userq_fence_driver_destroy(struct kref *ref)
|
||||
|
||||
@@ -878,6 +878,7 @@ static const struct amdgpu_ring_funcs jpeg_v5_0_1_dec_ring_vm_funcs = {
|
||||
.get_rptr = jpeg_v5_0_1_dec_ring_get_rptr,
|
||||
.get_wptr = jpeg_v5_0_1_dec_ring_get_wptr,
|
||||
.set_wptr = jpeg_v5_0_1_dec_ring_set_wptr,
|
||||
.parse_cs = amdgpu_jpeg_dec_parse_cs,
|
||||
.emit_frame_size =
|
||||
SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
|
||||
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
|
||||
|
||||
@@ -297,16 +297,16 @@ int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_prope
|
||||
goto out_err_unreserve;
|
||||
}
|
||||
|
||||
if (properties->ctx_save_restore_area_size != topo_dev->node_props.cwsr_size) {
|
||||
pr_debug("queue cwsr size 0x%x not equal to node cwsr size 0x%x\n",
|
||||
if (properties->ctx_save_restore_area_size < topo_dev->node_props.cwsr_size) {
|
||||
pr_debug("queue cwsr size 0x%x not sufficient for node cwsr size 0x%x\n",
|
||||
properties->ctx_save_restore_area_size,
|
||||
topo_dev->node_props.cwsr_size);
|
||||
err = -EINVAL;
|
||||
goto out_err_unreserve;
|
||||
}
|
||||
|
||||
total_cwsr_size = (topo_dev->node_props.cwsr_size + topo_dev->node_props.debug_memory_size)
|
||||
* NUM_XCC(pdd->dev->xcc_mask);
|
||||
total_cwsr_size = (properties->ctx_save_restore_area_size +
|
||||
topo_dev->node_props.debug_memory_size) * NUM_XCC(pdd->dev->xcc_mask);
|
||||
total_cwsr_size = ALIGN(total_cwsr_size, PAGE_SIZE);
|
||||
|
||||
err = kfd_queue_buffer_get(vm, (void *)properties->ctx_save_restore_area_address,
|
||||
@@ -352,8 +352,8 @@ int kfd_queue_release_buffers(struct kfd_process_device *pdd, struct queue_prope
|
||||
topo_dev = kfd_topology_device_by_id(pdd->dev->id);
|
||||
if (!topo_dev)
|
||||
return -EINVAL;
|
||||
total_cwsr_size = (topo_dev->node_props.cwsr_size + topo_dev->node_props.debug_memory_size)
|
||||
* NUM_XCC(pdd->dev->xcc_mask);
|
||||
total_cwsr_size = (properties->ctx_save_restore_area_size +
|
||||
topo_dev->node_props.debug_memory_size) * NUM_XCC(pdd->dev->xcc_mask);
|
||||
total_cwsr_size = ALIGN(total_cwsr_size, PAGE_SIZE);
|
||||
|
||||
kfd_queue_buffer_svm_put(pdd, properties->ctx_save_restore_area_address, total_cwsr_size);
|
||||
|
||||
@@ -3687,6 +3687,8 @@ svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm,
|
||||
svm_range_apply_attrs(p, prange, nattr, attrs, &update_mapping);
|
||||
/* TODO: unmap ranges from GPU that lost access */
|
||||
}
|
||||
update_mapping |= !p->xnack_enabled && !list_empty(&remap_list);
|
||||
|
||||
list_for_each_entry_safe(prange, next, &remove_list, update_list) {
|
||||
pr_debug("unlink old 0x%p prange 0x%p [0x%lx 0x%lx]\n",
|
||||
prange->svms, prange, prange->start,
|
||||
|
||||
@@ -1260,6 +1260,17 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
|
||||
update_v_total_for_static_ramp(
|
||||
core_freesync, stream, in_out_vrr);
|
||||
}
|
||||
|
||||
/*
|
||||
* If VRR is inactive, set vtotal min and max to nominal vtotal
|
||||
*/
|
||||
if (in_out_vrr->state == VRR_STATE_INACTIVE) {
|
||||
in_out_vrr->adjust.v_total_min =
|
||||
mod_freesync_calc_v_total_from_refresh(stream,
|
||||
in_out_vrr->max_refresh_in_uhz);
|
||||
in_out_vrr->adjust.v_total_max = in_out_vrr->adjust.v_total_min;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long long mod_freesync_calc_nominal_field_rate(
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
static char drm_client_default[16] = CONFIG_DRM_CLIENT_DEFAULT;
|
||||
module_param_string(active, drm_client_default, sizeof(drm_client_default), 0444);
|
||||
MODULE_PARM_DESC(active,
|
||||
"Choose which drm client to start, default is"
|
||||
CONFIG_DRM_CLIENT_DEFAULT "]");
|
||||
"Choose which drm client to start, default is "
|
||||
CONFIG_DRM_CLIENT_DEFAULT);
|
||||
|
||||
/**
|
||||
* drm_client_setup() - Setup in-kernel DRM clients
|
||||
|
||||
@@ -585,6 +585,10 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int ret;
|
||||
|
||||
/* TODO: Enable Panel Replay on MST once it's properly implemented. */
|
||||
if (intel_dp->mst_detect == DRM_DP_MST)
|
||||
return;
|
||||
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_PANEL_REPLAY_CAP_SUPPORT,
|
||||
&intel_dp->pr_dpcd, sizeof(intel_dp->pr_dpcd));
|
||||
if (ret < 0)
|
||||
@@ -888,7 +892,8 @@ static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
u32 current_dc_state = intel_display_power_get_current_dc_state(display);
|
||||
struct drm_vblank_crtc *vblank = &display->drm->vblank[intel_dp->psr.pipe];
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display, intel_dp->psr.pipe);
|
||||
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
|
||||
|
||||
return (current_dc_state != DC_STATE_EN_UPTO_DC5 &&
|
||||
current_dc_state != DC_STATE_EN_UPTO_DC6) ||
|
||||
|
||||
@@ -288,6 +288,23 @@ panthor_gem_create_with_handle(struct drm_file *file,
|
||||
|
||||
panthor_gem_debugfs_set_usage_flags(bo, 0);
|
||||
|
||||
/* If this is a write-combine mapping, we query the sgt to force a CPU
|
||||
* cache flush (dma_map_sgtable() is called when the sgt is created).
|
||||
* This ensures the zero-ing is visible to any uncached mapping created
|
||||
* by vmap/mmap.
|
||||
* FIXME: Ideally this should be done when pages are allocated, not at
|
||||
* BO creation time.
|
||||
*/
|
||||
if (shmem->map_wc) {
|
||||
struct sg_table *sgt;
|
||||
|
||||
sgt = drm_gem_shmem_get_pages_sgt(shmem);
|
||||
if (IS_ERR(sgt)) {
|
||||
ret = PTR_ERR(sgt);
|
||||
goto out_put_gem;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate an id of idr table where the obj is registered
|
||||
* and handle has the id what user can see.
|
||||
@@ -296,6 +313,7 @@ panthor_gem_create_with_handle(struct drm_file *file,
|
||||
if (!ret)
|
||||
*size = bo->base.base.size;
|
||||
|
||||
out_put_gem:
|
||||
/* drop reference from allocate - handle holds it now. */
|
||||
drm_gem_object_put(&shmem->base);
|
||||
|
||||
|
||||
@@ -100,8 +100,10 @@ vmw_cursor_update_type(struct vmw_private *vmw, struct vmw_plane_state *vps)
|
||||
if (vmw->has_mob) {
|
||||
if ((vmw->capabilities2 & SVGA_CAP2_CURSOR_MOB) != 0)
|
||||
return VMW_CURSOR_UPDATE_MOB;
|
||||
else
|
||||
return VMW_CURSOR_UPDATE_GB_ONLY;
|
||||
}
|
||||
|
||||
drm_warn_once(&vmw->drm, "Unknown Cursor Type!\n");
|
||||
return VMW_CURSOR_UPDATE_NONE;
|
||||
}
|
||||
|
||||
@@ -139,6 +141,7 @@ static u32 vmw_cursor_mob_size(enum vmw_cursor_update_type update_type,
|
||||
{
|
||||
switch (update_type) {
|
||||
case VMW_CURSOR_UPDATE_LEGACY:
|
||||
case VMW_CURSOR_UPDATE_GB_ONLY:
|
||||
case VMW_CURSOR_UPDATE_NONE:
|
||||
return 0;
|
||||
case VMW_CURSOR_UPDATE_MOB:
|
||||
@@ -623,6 +626,7 @@ int vmw_cursor_plane_prepare_fb(struct drm_plane *plane,
|
||||
if (!surface || vps->cursor.legacy.id == surface->snooper.id)
|
||||
vps->cursor.update_type = VMW_CURSOR_UPDATE_NONE;
|
||||
break;
|
||||
case VMW_CURSOR_UPDATE_GB_ONLY:
|
||||
case VMW_CURSOR_UPDATE_MOB: {
|
||||
bo = vmw_user_object_buffer(&vps->uo);
|
||||
if (bo) {
|
||||
@@ -737,6 +741,7 @@ void
|
||||
vmw_cursor_plane_atomic_update(struct drm_plane *plane,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct vmw_bo *bo;
|
||||
struct drm_plane_state *new_state =
|
||||
drm_atomic_get_new_plane_state(state, plane);
|
||||
struct drm_plane_state *old_state =
|
||||
@@ -762,6 +767,15 @@ vmw_cursor_plane_atomic_update(struct drm_plane *plane,
|
||||
case VMW_CURSOR_UPDATE_MOB:
|
||||
vmw_cursor_update_mob(dev_priv, vps);
|
||||
break;
|
||||
case VMW_CURSOR_UPDATE_GB_ONLY:
|
||||
bo = vmw_user_object_buffer(&vps->uo);
|
||||
if (bo)
|
||||
vmw_send_define_cursor_cmd(dev_priv, bo->map.virtual,
|
||||
vps->base.crtc_w,
|
||||
vps->base.crtc_h,
|
||||
vps->base.hotspot_x,
|
||||
vps->base.hotspot_y);
|
||||
break;
|
||||
case VMW_CURSOR_UPDATE_NONE:
|
||||
/* do nothing */
|
||||
break;
|
||||
|
||||
@@ -33,6 +33,7 @@ static const u32 __maybe_unused vmw_cursor_plane_formats[] = {
|
||||
enum vmw_cursor_update_type {
|
||||
VMW_CURSOR_UPDATE_NONE = 0,
|
||||
VMW_CURSOR_UPDATE_LEGACY,
|
||||
VMW_CURSOR_UPDATE_GB_ONLY,
|
||||
VMW_CURSOR_UPDATE_MOB,
|
||||
};
|
||||
|
||||
|
||||
@@ -3668,6 +3668,11 @@ static int vmw_cmd_check(struct vmw_private *dev_priv,
|
||||
|
||||
|
||||
cmd_id = header->id;
|
||||
if (header->size > SVGA_CMD_MAX_DATASIZE) {
|
||||
VMW_DEBUG_USER("SVGA3D command: %d is too big.\n",
|
||||
cmd_id + SVGA_3D_CMD_BASE);
|
||||
return -E2BIG;
|
||||
}
|
||||
*size = header->size + sizeof(SVGA3dCmdHeader);
|
||||
|
||||
cmd_id -= SVGA_3D_CMD_BASE;
|
||||
|
||||
@@ -32,22 +32,22 @@ enum vmw_bo_dirty_method {
|
||||
|
||||
/**
|
||||
* struct vmw_bo_dirty - Dirty information for buffer objects
|
||||
* @ref_count: Reference count for this structure. Must be first member!
|
||||
* @start: First currently dirty bit
|
||||
* @end: Last currently dirty bit + 1
|
||||
* @method: The currently used dirty method
|
||||
* @change_count: Number of consecutive method change triggers
|
||||
* @ref_count: Reference count for this structure
|
||||
* @bitmap_size: The size of the bitmap in bits. Typically equal to the
|
||||
* nuber of pages in the bo.
|
||||
* @bitmap: A bitmap where each bit represents a page. A set bit means a
|
||||
* dirty page.
|
||||
*/
|
||||
struct vmw_bo_dirty {
|
||||
struct kref ref_count;
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
enum vmw_bo_dirty_method method;
|
||||
unsigned int change_count;
|
||||
unsigned int ref_count;
|
||||
unsigned long bitmap_size;
|
||||
unsigned long bitmap[];
|
||||
};
|
||||
@@ -221,7 +221,7 @@ int vmw_bo_dirty_add(struct vmw_bo *vbo)
|
||||
int ret;
|
||||
|
||||
if (dirty) {
|
||||
dirty->ref_count++;
|
||||
kref_get(&dirty->ref_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ int vmw_bo_dirty_add(struct vmw_bo *vbo)
|
||||
dirty->bitmap_size = num_pages;
|
||||
dirty->start = dirty->bitmap_size;
|
||||
dirty->end = 0;
|
||||
dirty->ref_count = 1;
|
||||
kref_init(&dirty->ref_count);
|
||||
if (num_pages < PAGE_SIZE / sizeof(pte_t)) {
|
||||
dirty->method = VMW_BO_DIRTY_PAGETABLE;
|
||||
} else {
|
||||
@@ -274,10 +274,8 @@ void vmw_bo_dirty_release(struct vmw_bo *vbo)
|
||||
{
|
||||
struct vmw_bo_dirty *dirty = vbo->dirty;
|
||||
|
||||
if (dirty && --dirty->ref_count == 0) {
|
||||
kvfree(dirty);
|
||||
if (dirty && kref_put(&dirty->ref_count, (void *)kvfree))
|
||||
vbo->dirty = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -168,6 +168,7 @@
|
||||
|
||||
#define XEHP_SLICE_COMMON_ECO_CHICKEN1 XE_REG_MCR(0x731c, XE_REG_OPTION_MASKED)
|
||||
#define MSC_MSAA_REODER_BUF_BYPASS_DISABLE REG_BIT(14)
|
||||
#define FAST_CLEAR_VALIGN_FIX REG_BIT(13)
|
||||
|
||||
#define XE2LPM_CCCHKNREG1 XE_REG(0x82a8)
|
||||
|
||||
|
||||
@@ -679,6 +679,8 @@ static const struct xe_rtp_entry_sr engine_was[] = {
|
||||
},
|
||||
{ XE_RTP_NAME("14023061436"),
|
||||
XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3001),
|
||||
FUNC(xe_rtp_match_first_render_or_compute), OR,
|
||||
GRAPHICS_VERSION_RANGE(3003, 3005),
|
||||
FUNC(xe_rtp_match_first_render_or_compute)),
|
||||
XE_RTP_ACTIONS(SET(TDL_CHICKEN, QID_WAIT_FOR_THREAD_NOT_RUN_DISABLE))
|
||||
},
|
||||
@@ -916,6 +918,15 @@ static const struct xe_rtp_entry_sr lrc_was[] = {
|
||||
XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3003), ENGINE_CLASS(RENDER)),
|
||||
XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN4, SBE_PUSH_CONSTANT_BEHIND_FIX_ENABLE))
|
||||
},
|
||||
{ XE_RTP_NAME("14024681466"),
|
||||
XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3005), ENGINE_CLASS(RENDER)),
|
||||
XE_RTP_ACTIONS(SET(XEHP_SLICE_COMMON_ECO_CHICKEN1, FAST_CLEAR_VALIGN_FIX))
|
||||
},
|
||||
{ XE_RTP_NAME("15016589081"),
|
||||
XE_RTP_RULES(GRAPHICS_VERSION(3000), GRAPHICS_STEP(A0, B0),
|
||||
ENGINE_CLASS(RENDER)),
|
||||
XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX))
|
||||
},
|
||||
};
|
||||
|
||||
static __maybe_unused const struct xe_rtp_entry oob_was[] = {
|
||||
|
||||
@@ -950,7 +950,7 @@ config MMC_USHC
|
||||
config MMC_WMT
|
||||
tristate "Wondermedia SD/MMC Host Controller support"
|
||||
depends on ARCH_VT8500 || COMPILE_TEST
|
||||
default y
|
||||
default ARCH_VT8500
|
||||
help
|
||||
This selects support for the SD/MMC Host Controller on
|
||||
Wondermedia WM8505/WM8650 based SoCs.
|
||||
|
||||
@@ -42,7 +42,7 @@ struct dw_mci_rockchip_priv_data {
|
||||
*/
|
||||
static int rockchip_mmc_get_internal_phase(struct dw_mci *host, bool sample)
|
||||
{
|
||||
unsigned long rate = clk_get_rate(host->ciu_clk);
|
||||
unsigned long rate = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
|
||||
u32 raw_value;
|
||||
u16 degrees;
|
||||
u32 delay_num = 0;
|
||||
@@ -85,7 +85,7 @@ static int rockchip_mmc_get_phase(struct dw_mci *host, bool sample)
|
||||
|
||||
static int rockchip_mmc_set_internal_phase(struct dw_mci *host, bool sample, int degrees)
|
||||
{
|
||||
unsigned long rate = clk_get_rate(host->ciu_clk);
|
||||
unsigned long rate = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
|
||||
u8 nineties, remainder;
|
||||
u8 delay_num;
|
||||
u32 raw_value;
|
||||
|
||||
@@ -652,10 +652,9 @@ static int pxamci_probe(struct platform_device *pdev)
|
||||
host->clkrt = CLKRT_OFF;
|
||||
|
||||
host->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(host->clk)) {
|
||||
host->clk = NULL;
|
||||
return PTR_ERR(host->clk);
|
||||
}
|
||||
if (IS_ERR(host->clk))
|
||||
return dev_err_probe(dev, PTR_ERR(host->clk),
|
||||
"Failed to acquire clock\n");
|
||||
|
||||
host->clkrate = clk_get_rate(host->clk);
|
||||
|
||||
@@ -703,46 +702,37 @@ static int pxamci_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, mmc);
|
||||
|
||||
host->dma_chan_rx = dma_request_chan(dev, "rx");
|
||||
if (IS_ERR(host->dma_chan_rx)) {
|
||||
host->dma_chan_rx = NULL;
|
||||
host->dma_chan_rx = devm_dma_request_chan(dev, "rx");
|
||||
if (IS_ERR(host->dma_chan_rx))
|
||||
return dev_err_probe(dev, PTR_ERR(host->dma_chan_rx),
|
||||
"unable to request rx dma channel\n");
|
||||
}
|
||||
|
||||
host->dma_chan_tx = dma_request_chan(dev, "tx");
|
||||
if (IS_ERR(host->dma_chan_tx)) {
|
||||
dev_err(dev, "unable to request tx dma channel\n");
|
||||
ret = PTR_ERR(host->dma_chan_tx);
|
||||
host->dma_chan_tx = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
host->dma_chan_tx = devm_dma_request_chan(dev, "tx");
|
||||
if (IS_ERR(host->dma_chan_tx))
|
||||
return dev_err_probe(dev, PTR_ERR(host->dma_chan_tx),
|
||||
"unable to request tx dma channel\n");
|
||||
|
||||
if (host->pdata) {
|
||||
host->detect_delay_ms = host->pdata->detect_delay_ms;
|
||||
|
||||
host->power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(host->power)) {
|
||||
ret = PTR_ERR(host->power);
|
||||
dev_err(dev, "Failed requesting gpio_power\n");
|
||||
goto out;
|
||||
}
|
||||
if (IS_ERR(host->power))
|
||||
return dev_err_probe(dev, PTR_ERR(host->power),
|
||||
"Failed requesting gpio_power\n");
|
||||
|
||||
/* FIXME: should we pass detection delay to debounce? */
|
||||
ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0);
|
||||
if (ret && ret != -ENOENT) {
|
||||
dev_err(dev, "Failed requesting gpio_cd\n");
|
||||
goto out;
|
||||
}
|
||||
if (ret && ret != -ENOENT)
|
||||
return dev_err_probe(dev, ret, "Failed requesting gpio_cd\n");
|
||||
|
||||
if (!host->pdata->gpio_card_ro_invert)
|
||||
mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
|
||||
|
||||
ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0);
|
||||
if (ret && ret != -ENOENT) {
|
||||
dev_err(dev, "Failed requesting gpio_ro\n");
|
||||
goto out;
|
||||
}
|
||||
if (ret && ret != -ENOENT)
|
||||
return dev_err_probe(dev, ret, "Failed requesting gpio_ro\n");
|
||||
|
||||
if (!ret)
|
||||
host->use_ro_gpio = true;
|
||||
|
||||
@@ -759,16 +749,8 @@ static int pxamci_probe(struct platform_device *pdev)
|
||||
if (ret) {
|
||||
if (host->pdata && host->pdata->exit)
|
||||
host->pdata->exit(dev, mmc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if (host->dma_chan_rx)
|
||||
dma_release_channel(host->dma_chan_rx);
|
||||
if (host->dma_chan_tx)
|
||||
dma_release_channel(host->dma_chan_tx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -791,8 +773,6 @@ static void pxamci_remove(struct platform_device *pdev)
|
||||
|
||||
dmaengine_terminate_all(host->dma_chan_rx);
|
||||
dmaengine_terminate_all(host->dma_chan_tx);
|
||||
dma_release_channel(host->dma_chan_rx);
|
||||
dma_release_channel(host->dma_chan_tx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
#define DLL_TXCLK_TAPNUM_DEFAULT 0x10
|
||||
#define DLL_TXCLK_TAPNUM_90_DEGREES 0xA
|
||||
#define DLL_TXCLK_TAPNUM_FROM_SW BIT(24)
|
||||
#define DLL_STRBIN_TAPNUM_DEFAULT 0x8
|
||||
#define DLL_STRBIN_TAPNUM_DEFAULT 0x4
|
||||
#define DLL_STRBIN_TAPNUM_FROM_SW BIT(24)
|
||||
#define DLL_STRBIN_DELAY_NUM_SEL BIT(26)
|
||||
#define DLL_STRBIN_DELAY_NUM_OFFSET 16
|
||||
|
||||
@@ -41,7 +41,7 @@ static int scmi_pd_power_off(struct generic_pm_domain *domain)
|
||||
|
||||
static int scmi_pm_domain_probe(struct scmi_device *sdev)
|
||||
{
|
||||
int num_domains, i;
|
||||
int num_domains, i, ret;
|
||||
struct device *dev = &sdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct scmi_pm_domain *scmi_pd;
|
||||
@@ -108,9 +108,18 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
|
||||
scmi_pd_data->domains = domains;
|
||||
scmi_pd_data->num_domains = num_domains;
|
||||
|
||||
ret = of_genpd_add_provider_onecell(np, scmi_pd_data);
|
||||
if (ret)
|
||||
goto err_rm_genpds;
|
||||
|
||||
dev_set_drvdata(dev, scmi_pd_data);
|
||||
|
||||
return of_genpd_add_provider_onecell(np, scmi_pd_data);
|
||||
return 0;
|
||||
err_rm_genpds:
|
||||
for (i = num_domains - 1; i >= 0; i--)
|
||||
pm_genpd_remove(domains[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void scmi_pm_domain_remove(struct scmi_device *sdev)
|
||||
|
||||
@@ -536,6 +536,8 @@ static void imx_gpc_remove(struct platform_device *pdev)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
of_node_put(pgc_node);
|
||||
}
|
||||
|
||||
static struct platform_driver imx_gpc_driver = {
|
||||
|
||||
@@ -92,13 +92,14 @@ static const struct of_device_id exynos_pm_domain_of_match[] = {
|
||||
{ },
|
||||
};
|
||||
|
||||
static const char *exynos_get_domain_name(struct device_node *node)
|
||||
static const char *exynos_get_domain_name(struct device *dev,
|
||||
struct device_node *node)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (of_property_read_string(node, "label", &name) < 0)
|
||||
name = kbasename(node->full_name);
|
||||
return kstrdup_const(name, GFP_KERNEL);
|
||||
return devm_kstrdup_const(dev, name, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static int exynos_pd_probe(struct platform_device *pdev)
|
||||
@@ -115,20 +116,27 @@ static int exynos_pd_probe(struct platform_device *pdev)
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
|
||||
pd->pd.name = exynos_get_domain_name(np);
|
||||
pd->pd.name = exynos_get_domain_name(dev, np);
|
||||
if (!pd->pd.name)
|
||||
return -ENOMEM;
|
||||
|
||||
pd->base = of_iomap(np, 0);
|
||||
if (!pd->base) {
|
||||
kfree_const(pd->pd.name);
|
||||
if (!pd->base)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pd->pd.power_off = exynos_pd_power_off;
|
||||
pd->pd.power_on = exynos_pd_power_on;
|
||||
pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg;
|
||||
|
||||
/*
|
||||
* Some Samsung platforms with bootloaders turning on the splash-screen
|
||||
* and handing it over to the kernel, requires the power-domains to be
|
||||
* reset during boot.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_ARM) &&
|
||||
of_device_is_compatible(np, "samsung,exynos4210-pd"))
|
||||
exynos_pd_power_off(&pd->pd);
|
||||
|
||||
on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg;
|
||||
|
||||
pm_genpd_init(&pd->pd, NULL, !on);
|
||||
@@ -147,15 +155,6 @@ static int exynos_pd_probe(struct platform_device *pdev)
|
||||
parent.np, child.np);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some Samsung platforms with bootloaders turning on the splash-screen
|
||||
* and handing it over to the kernel, requires the power-domains to be
|
||||
* reset during boot. As a temporary hack to manage this, let's enforce
|
||||
* a sync_state.
|
||||
*/
|
||||
if (!ret)
|
||||
of_genpd_sync_state(np);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -334,6 +334,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
|
||||
ret = dev_err_probe(&pdev->dev, PTR_ERR(drvdata->dev),
|
||||
"Failed to register regulator: %ld\n",
|
||||
PTR_ERR(drvdata->dev));
|
||||
gpiod_put(cfg.ena_gpiod);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -519,9 +519,15 @@ static void mx51_ecspi_trigger(struct spi_imx_data *spi_imx)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = readl(spi_imx->base + MX51_ECSPI_CTRL);
|
||||
reg |= MX51_ECSPI_CTRL_XCH;
|
||||
writel(reg, spi_imx->base + MX51_ECSPI_CTRL);
|
||||
if (spi_imx->usedma) {
|
||||
reg = readl(spi_imx->base + MX51_ECSPI_DMA);
|
||||
reg |= MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN;
|
||||
writel(reg, spi_imx->base + MX51_ECSPI_DMA);
|
||||
} else {
|
||||
reg = readl(spi_imx->base + MX51_ECSPI_CTRL);
|
||||
reg |= MX51_ECSPI_CTRL_XCH;
|
||||
writel(reg, spi_imx->base + MX51_ECSPI_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
static void mx51_ecspi_disable(struct spi_imx_data *spi_imx)
|
||||
@@ -759,7 +765,6 @@ static void mx51_setup_wml(struct spi_imx_data *spi_imx)
|
||||
writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) |
|
||||
MX51_ECSPI_DMA_TX_WML(tx_wml) |
|
||||
MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
|
||||
MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN |
|
||||
MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA);
|
||||
}
|
||||
|
||||
@@ -1520,6 +1525,8 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
|
||||
reinit_completion(&spi_imx->dma_tx_completion);
|
||||
dma_async_issue_pending(controller->dma_tx);
|
||||
|
||||
spi_imx->devtype_data->trigger(spi_imx);
|
||||
|
||||
transfer_timeout = spi_imx_calculate_timeout(spi_imx, transfer->len);
|
||||
|
||||
/* Wait SDMA to finish the data transfer.*/
|
||||
|
||||
@@ -300,7 +300,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
|
||||
|
||||
/* Read out all the data from the Rx FIFO */
|
||||
rx_words = n_words;
|
||||
stalled = 10;
|
||||
stalled = 32;
|
||||
while (rx_words) {
|
||||
if (rx_words == n_words && !(stalled--) &&
|
||||
!(sr & XSPI_SR_TX_EMPTY_MASK) &&
|
||||
|
||||
@@ -2851,6 +2851,18 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr,
|
||||
acpi_set_modalias(adev, acpi_device_hid(adev), spi->modalias,
|
||||
sizeof(spi->modalias));
|
||||
|
||||
/*
|
||||
* This gets re-tried in spi_probe() for -EPROBE_DEFER handling in case
|
||||
* the GPIO controller does not have a driver yet. This needs to be done
|
||||
* here too, because this call sets the GPIO direction and/or bias.
|
||||
* Setting these needs to be done even if there is no driver, in which
|
||||
* case spi_probe() will never get called.
|
||||
* TODO: ideally the setup of the GPIO should be handled in a generic
|
||||
* manner in the ACPI/gpiolib core code.
|
||||
*/
|
||||
if (spi->irq < 0)
|
||||
spi->irq = acpi_dev_gpio_irq_get(adev, 0);
|
||||
|
||||
acpi_device_set_enumerated(adev);
|
||||
|
||||
adev->power.flags.ignore_parent = true;
|
||||
|
||||
@@ -338,6 +338,14 @@ again:
|
||||
/* Match the xprt security policy */
|
||||
if (clp->cl_xprtsec.policy != data->xprtsec.policy)
|
||||
continue;
|
||||
if (clp->cl_xprtsec.policy == RPC_XPRTSEC_TLS_X509) {
|
||||
if (clp->cl_xprtsec.cert_serial !=
|
||||
data->xprtsec.cert_serial)
|
||||
continue;
|
||||
if (clp->cl_xprtsec.privkey_serial !=
|
||||
data->xprtsec.privkey_serial)
|
||||
continue;
|
||||
}
|
||||
|
||||
refcount_inc(&clp->cl_count);
|
||||
return clp;
|
||||
|
||||
@@ -2268,11 +2268,12 @@ int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry,
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
if (open_flags & O_CREAT) {
|
||||
file->f_mode |= FMODE_CREATED;
|
||||
error = nfs_do_create(dir, dentry, mode, open_flags);
|
||||
if (error)
|
||||
if (!error) {
|
||||
file->f_mode |= FMODE_CREATED;
|
||||
return finish_open(file, dentry, NULL);
|
||||
} else if (error != -EEXIST || open_flags & O_EXCL)
|
||||
return error;
|
||||
return finish_open(file, dentry, NULL);
|
||||
}
|
||||
if (d_in_lookup(dentry)) {
|
||||
/* The only flags nfs_lookup considers are
|
||||
|
||||
@@ -718,6 +718,8 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct nfs_fattr *fattr;
|
||||
loff_t oldsize = i_size_read(inode);
|
||||
int error = 0;
|
||||
kuid_t task_uid = current_fsuid();
|
||||
kuid_t owner_uid = inode->i_uid;
|
||||
|
||||
nfs_inc_stats(inode, NFSIOS_VFSSETATTR);
|
||||
|
||||
@@ -739,9 +741,11 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
if (nfs_have_delegated_mtime(inode) && attr->ia_valid & ATTR_MTIME) {
|
||||
spin_lock(&inode->i_lock);
|
||||
if (attr->ia_valid & ATTR_MTIME_SET) {
|
||||
nfs_set_timestamps_to_ts(inode, attr);
|
||||
attr->ia_valid &= ~(ATTR_MTIME|ATTR_MTIME_SET|
|
||||
if (uid_eq(task_uid, owner_uid)) {
|
||||
nfs_set_timestamps_to_ts(inode, attr);
|
||||
attr->ia_valid &= ~(ATTR_MTIME|ATTR_MTIME_SET|
|
||||
ATTR_ATIME|ATTR_ATIME_SET);
|
||||
}
|
||||
} else {
|
||||
nfs_update_timestamps(inode, attr->ia_valid);
|
||||
attr->ia_valid &= ~(ATTR_MTIME|ATTR_ATIME);
|
||||
@@ -751,10 +755,12 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
attr->ia_valid & ATTR_ATIME &&
|
||||
!(attr->ia_valid & ATTR_MTIME)) {
|
||||
if (attr->ia_valid & ATTR_ATIME_SET) {
|
||||
spin_lock(&inode->i_lock);
|
||||
nfs_set_timestamps_to_ts(inode, attr);
|
||||
spin_unlock(&inode->i_lock);
|
||||
attr->ia_valid &= ~(ATTR_ATIME|ATTR_ATIME_SET);
|
||||
if (uid_eq(task_uid, owner_uid)) {
|
||||
spin_lock(&inode->i_lock);
|
||||
nfs_set_timestamps_to_ts(inode, attr);
|
||||
spin_unlock(&inode->i_lock);
|
||||
attr->ia_valid &= ~(ATTR_ATIME|ATTR_ATIME_SET);
|
||||
}
|
||||
} else {
|
||||
nfs_update_delegated_atime(inode);
|
||||
attr->ia_valid &= ~ATTR_ATIME;
|
||||
|
||||
229
fs/nfs/localio.c
229
fs/nfs/localio.c
@@ -42,10 +42,9 @@ struct nfs_local_kiocb {
|
||||
/* Begin mostly DIO-specific members */
|
||||
size_t end_len;
|
||||
short int end_iter_index;
|
||||
short int n_iters;
|
||||
atomic_t n_iters;
|
||||
bool iter_is_dio_aligned[NFSLOCAL_MAX_IOS];
|
||||
loff_t offset[NFSLOCAL_MAX_IOS] ____cacheline_aligned;
|
||||
struct iov_iter iters[NFSLOCAL_MAX_IOS];
|
||||
struct iov_iter iters[NFSLOCAL_MAX_IOS] ____cacheline_aligned;
|
||||
/* End mostly DIO-specific members */
|
||||
};
|
||||
|
||||
@@ -314,7 +313,9 @@ nfs_local_iocb_alloc(struct nfs_pgio_header *hdr,
|
||||
init_sync_kiocb(&iocb->kiocb, file);
|
||||
|
||||
iocb->hdr = hdr;
|
||||
iocb->kiocb.ki_pos = hdr->args.offset;
|
||||
iocb->kiocb.ki_flags &= ~IOCB_APPEND;
|
||||
iocb->kiocb.ki_complete = NULL;
|
||||
iocb->aio_complete_work = NULL;
|
||||
|
||||
iocb->end_iter_index = -1;
|
||||
@@ -388,13 +389,24 @@ static bool nfs_iov_iter_aligned_bvec(const struct iov_iter *i,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs_local_iter_setup(struct iov_iter *iter, int rw, struct bio_vec *bvec,
|
||||
unsigned int nvecs, unsigned long total,
|
||||
size_t start, size_t len)
|
||||
{
|
||||
iov_iter_bvec(iter, rw, bvec, nvecs, total);
|
||||
if (start)
|
||||
iov_iter_advance(iter, start);
|
||||
iov_iter_truncate(iter, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup as many as 3 iov_iter based on extents described by @local_dio.
|
||||
* Returns the number of iov_iter that were setup.
|
||||
*/
|
||||
static int
|
||||
nfs_local_iters_setup_dio(struct nfs_local_kiocb *iocb, int rw,
|
||||
unsigned int nvecs, size_t len,
|
||||
unsigned int nvecs, unsigned long total,
|
||||
struct nfs_local_dio *local_dio)
|
||||
{
|
||||
int n_iters = 0;
|
||||
@@ -402,39 +414,17 @@ nfs_local_iters_setup_dio(struct nfs_local_kiocb *iocb, int rw,
|
||||
|
||||
/* Setup misaligned start? */
|
||||
if (local_dio->start_len) {
|
||||
iov_iter_bvec(&iters[n_iters], rw, iocb->bvec, nvecs, len);
|
||||
iters[n_iters].count = local_dio->start_len;
|
||||
iocb->offset[n_iters] = iocb->hdr->args.offset;
|
||||
iocb->iter_is_dio_aligned[n_iters] = false;
|
||||
nfs_local_iter_setup(&iters[n_iters], rw, iocb->bvec,
|
||||
nvecs, total, 0, local_dio->start_len);
|
||||
++n_iters;
|
||||
}
|
||||
|
||||
/* Setup misaligned end?
|
||||
* If so, the end is purposely setup to be issued using buffered IO
|
||||
* before the middle (which will use DIO, if DIO-aligned, with AIO).
|
||||
* This creates problems if/when the end results in a partial write.
|
||||
* So must save index and length of end to handle this corner case.
|
||||
/*
|
||||
* Setup DIO-aligned middle, if there is no misaligned end (below)
|
||||
* then AIO completion is used, see nfs_local_call_{read,write}
|
||||
*/
|
||||
if (local_dio->end_len) {
|
||||
iov_iter_bvec(&iters[n_iters], rw, iocb->bvec, nvecs, len);
|
||||
iocb->offset[n_iters] = local_dio->end_offset;
|
||||
iov_iter_advance(&iters[n_iters],
|
||||
local_dio->start_len + local_dio->middle_len);
|
||||
iocb->iter_is_dio_aligned[n_iters] = false;
|
||||
/* Save index and length of end */
|
||||
iocb->end_iter_index = n_iters;
|
||||
iocb->end_len = local_dio->end_len;
|
||||
++n_iters;
|
||||
}
|
||||
|
||||
/* Setup DIO-aligned middle to be issued last, to allow for
|
||||
* DIO with AIO completion (see nfs_local_call_{read,write}).
|
||||
*/
|
||||
iov_iter_bvec(&iters[n_iters], rw, iocb->bvec, nvecs, len);
|
||||
if (local_dio->start_len)
|
||||
iov_iter_advance(&iters[n_iters], local_dio->start_len);
|
||||
iters[n_iters].count -= local_dio->end_len;
|
||||
iocb->offset[n_iters] = local_dio->middle_offset;
|
||||
nfs_local_iter_setup(&iters[n_iters], rw, iocb->bvec, nvecs,
|
||||
total, local_dio->start_len, local_dio->middle_len);
|
||||
|
||||
iocb->iter_is_dio_aligned[n_iters] =
|
||||
nfs_iov_iter_aligned_bvec(&iters[n_iters],
|
||||
@@ -442,12 +432,22 @@ nfs_local_iters_setup_dio(struct nfs_local_kiocb *iocb, int rw,
|
||||
|
||||
if (unlikely(!iocb->iter_is_dio_aligned[n_iters])) {
|
||||
trace_nfs_local_dio_misaligned(iocb->hdr->inode,
|
||||
iocb->hdr->args.offset, len, local_dio);
|
||||
local_dio->start_len, local_dio->middle_len, local_dio);
|
||||
return 0; /* no DIO-aligned IO possible */
|
||||
}
|
||||
iocb->end_iter_index = n_iters;
|
||||
++n_iters;
|
||||
|
||||
iocb->n_iters = n_iters;
|
||||
/* Setup misaligned end? */
|
||||
if (local_dio->end_len) {
|
||||
nfs_local_iter_setup(&iters[n_iters], rw, iocb->bvec,
|
||||
nvecs, total, local_dio->start_len +
|
||||
local_dio->middle_len, local_dio->end_len);
|
||||
iocb->end_iter_index = n_iters;
|
||||
++n_iters;
|
||||
}
|
||||
|
||||
atomic_set(&iocb->n_iters, n_iters);
|
||||
return n_iters;
|
||||
}
|
||||
|
||||
@@ -473,18 +473,26 @@ nfs_local_iters_init(struct nfs_local_kiocb *iocb, int rw)
|
||||
}
|
||||
len = hdr->args.count - total;
|
||||
|
||||
/*
|
||||
* For each iocb, iocb->n_iters is always at least 1 and we always
|
||||
* end io after first nfs_local_pgio_done call unless misaligned DIO.
|
||||
*/
|
||||
atomic_set(&iocb->n_iters, 1);
|
||||
|
||||
if (test_bit(NFS_IOHDR_ODIRECT, &hdr->flags)) {
|
||||
struct nfs_local_dio local_dio;
|
||||
|
||||
if (nfs_is_local_dio_possible(iocb, rw, len, &local_dio) &&
|
||||
nfs_local_iters_setup_dio(iocb, rw, v, len, &local_dio) != 0)
|
||||
nfs_local_iters_setup_dio(iocb, rw, v, len, &local_dio) != 0) {
|
||||
/* Ensure DIO WRITE's IO on stable storage upon completion */
|
||||
if (rw == ITER_SOURCE)
|
||||
iocb->kiocb.ki_flags |= IOCB_DSYNC|IOCB_SYNC;
|
||||
return; /* is DIO-aligned */
|
||||
}
|
||||
}
|
||||
|
||||
/* Use buffered IO */
|
||||
iocb->offset[0] = hdr->args.offset;
|
||||
iov_iter_bvec(&iocb->iters[0], rw, iocb->bvec, v, len);
|
||||
iocb->n_iters = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -504,9 +512,11 @@ nfs_local_pgio_init(struct nfs_pgio_header *hdr,
|
||||
hdr->task.tk_start = ktime_get();
|
||||
}
|
||||
|
||||
static void
|
||||
nfs_local_pgio_done(struct nfs_pgio_header *hdr, long status)
|
||||
static bool
|
||||
nfs_local_pgio_done(struct nfs_local_kiocb *iocb, long status, bool force)
|
||||
{
|
||||
struct nfs_pgio_header *hdr = iocb->hdr;
|
||||
|
||||
/* Must handle partial completions */
|
||||
if (status >= 0) {
|
||||
hdr->res.count += status;
|
||||
@@ -517,6 +527,12 @@ nfs_local_pgio_done(struct nfs_pgio_header *hdr, long status)
|
||||
hdr->res.op_status = nfs_localio_errno_to_nfs4_stat(status);
|
||||
hdr->task.tk_status = status;
|
||||
}
|
||||
|
||||
if (force)
|
||||
return true;
|
||||
|
||||
BUG_ON(atomic_read(&iocb->n_iters) <= 0);
|
||||
return atomic_dec_and_test(&iocb->n_iters);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -547,11 +563,11 @@ static inline void nfs_local_pgio_aio_complete(struct nfs_local_kiocb *iocb)
|
||||
queue_work(nfsiod_workqueue, &iocb->work);
|
||||
}
|
||||
|
||||
static void
|
||||
nfs_local_read_done(struct nfs_local_kiocb *iocb, long status)
|
||||
static void nfs_local_read_done(struct nfs_local_kiocb *iocb)
|
||||
{
|
||||
struct nfs_pgio_header *hdr = iocb->hdr;
|
||||
struct file *filp = iocb->kiocb.ki_filp;
|
||||
long status = hdr->task.tk_status;
|
||||
|
||||
if ((iocb->kiocb.ki_flags & IOCB_DIRECT) && status == -EINVAL) {
|
||||
/* Underlying FS will return -EINVAL if misaligned DIO is attempted. */
|
||||
@@ -564,20 +580,27 @@ nfs_local_read_done(struct nfs_local_kiocb *iocb, long status)
|
||||
*/
|
||||
hdr->res.replen = 0;
|
||||
|
||||
if (hdr->res.count != hdr->args.count ||
|
||||
hdr->args.offset + hdr->res.count >= i_size_read(file_inode(filp)))
|
||||
/* nfs_readpage_result() handles short read */
|
||||
|
||||
if (hdr->args.offset + hdr->res.count >= i_size_read(file_inode(filp)))
|
||||
hdr->res.eof = true;
|
||||
|
||||
dprintk("%s: read %ld bytes eof %d.\n", __func__,
|
||||
status > 0 ? status : 0, hdr->res.eof);
|
||||
}
|
||||
|
||||
static inline void nfs_local_read_iocb_done(struct nfs_local_kiocb *iocb)
|
||||
{
|
||||
nfs_local_read_done(iocb);
|
||||
nfs_local_pgio_release(iocb);
|
||||
}
|
||||
|
||||
static void nfs_local_read_aio_complete_work(struct work_struct *work)
|
||||
{
|
||||
struct nfs_local_kiocb *iocb =
|
||||
container_of(work, struct nfs_local_kiocb, work);
|
||||
|
||||
nfs_local_pgio_release(iocb);
|
||||
nfs_local_read_iocb_done(iocb);
|
||||
}
|
||||
|
||||
static void nfs_local_read_aio_complete(struct kiocb *kiocb, long ret)
|
||||
@@ -585,8 +608,10 @@ static void nfs_local_read_aio_complete(struct kiocb *kiocb, long ret)
|
||||
struct nfs_local_kiocb *iocb =
|
||||
container_of(kiocb, struct nfs_local_kiocb, kiocb);
|
||||
|
||||
nfs_local_pgio_done(iocb->hdr, ret);
|
||||
nfs_local_read_done(iocb, ret);
|
||||
/* AIO completion of DIO read should always be last to complete */
|
||||
if (unlikely(!nfs_local_pgio_done(iocb, ret, false)))
|
||||
return;
|
||||
|
||||
nfs_local_pgio_aio_complete(iocb); /* Calls nfs_local_read_aio_complete_work */
|
||||
}
|
||||
|
||||
@@ -596,32 +621,36 @@ static void nfs_local_call_read(struct work_struct *work)
|
||||
container_of(work, struct nfs_local_kiocb, work);
|
||||
struct file *filp = iocb->kiocb.ki_filp;
|
||||
const struct cred *save_cred;
|
||||
bool force_done = false;
|
||||
ssize_t status;
|
||||
int n_iters;
|
||||
|
||||
save_cred = override_creds(filp->f_cred);
|
||||
|
||||
for (int i = 0; i < iocb->n_iters ; i++) {
|
||||
n_iters = atomic_read(&iocb->n_iters);
|
||||
for (int i = 0; i < n_iters ; i++) {
|
||||
if (iocb->iter_is_dio_aligned[i]) {
|
||||
iocb->kiocb.ki_flags |= IOCB_DIRECT;
|
||||
iocb->kiocb.ki_complete = nfs_local_read_aio_complete;
|
||||
iocb->aio_complete_work = nfs_local_read_aio_complete_work;
|
||||
}
|
||||
/* Only use AIO completion if DIO-aligned segment is last */
|
||||
if (i == iocb->end_iter_index) {
|
||||
iocb->kiocb.ki_complete = nfs_local_read_aio_complete;
|
||||
iocb->aio_complete_work = nfs_local_read_aio_complete_work;
|
||||
}
|
||||
} else
|
||||
iocb->kiocb.ki_flags &= ~IOCB_DIRECT;
|
||||
|
||||
iocb->kiocb.ki_pos = iocb->offset[i];
|
||||
status = filp->f_op->read_iter(&iocb->kiocb, &iocb->iters[i]);
|
||||
if (status != -EIOCBQUEUED) {
|
||||
nfs_local_pgio_done(iocb->hdr, status);
|
||||
if (iocb->hdr->task.tk_status)
|
||||
if (unlikely(status >= 0 && status < iocb->iters[i].count))
|
||||
force_done = true; /* Partial read */
|
||||
if (nfs_local_pgio_done(iocb, status, force_done)) {
|
||||
nfs_local_read_iocb_done(iocb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
revert_creds(save_cred);
|
||||
|
||||
if (status != -EIOCBQUEUED) {
|
||||
nfs_local_read_done(iocb, status);
|
||||
nfs_local_pgio_release(iocb);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -736,11 +765,10 @@ static void nfs_local_vfs_getattr(struct nfs_local_kiocb *iocb)
|
||||
fattr->du.nfs3.used = stat.blocks << 9;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs_local_write_done(struct nfs_local_kiocb *iocb, long status)
|
||||
static void nfs_local_write_done(struct nfs_local_kiocb *iocb)
|
||||
{
|
||||
struct nfs_pgio_header *hdr = iocb->hdr;
|
||||
struct inode *inode = hdr->inode;
|
||||
long status = hdr->task.tk_status;
|
||||
|
||||
dprintk("%s: wrote %ld bytes.\n", __func__, status > 0 ? status : 0);
|
||||
|
||||
@@ -759,10 +787,17 @@ nfs_local_write_done(struct nfs_local_kiocb *iocb, long status)
|
||||
nfs_set_pgio_error(hdr, -ENOSPC, hdr->args.offset);
|
||||
status = -ENOSPC;
|
||||
/* record -ENOSPC in terms of nfs_local_pgio_done */
|
||||
nfs_local_pgio_done(hdr, status);
|
||||
(void) nfs_local_pgio_done(iocb, status, true);
|
||||
}
|
||||
if (hdr->task.tk_status < 0)
|
||||
nfs_reset_boot_verifier(inode);
|
||||
nfs_reset_boot_verifier(hdr->inode);
|
||||
}
|
||||
|
||||
static inline void nfs_local_write_iocb_done(struct nfs_local_kiocb *iocb)
|
||||
{
|
||||
nfs_local_write_done(iocb);
|
||||
nfs_local_vfs_getattr(iocb);
|
||||
nfs_local_pgio_release(iocb);
|
||||
}
|
||||
|
||||
static void nfs_local_write_aio_complete_work(struct work_struct *work)
|
||||
@@ -770,8 +805,7 @@ static void nfs_local_write_aio_complete_work(struct work_struct *work)
|
||||
struct nfs_local_kiocb *iocb =
|
||||
container_of(work, struct nfs_local_kiocb, work);
|
||||
|
||||
nfs_local_vfs_getattr(iocb);
|
||||
nfs_local_pgio_release(iocb);
|
||||
nfs_local_write_iocb_done(iocb);
|
||||
}
|
||||
|
||||
static void nfs_local_write_aio_complete(struct kiocb *kiocb, long ret)
|
||||
@@ -779,8 +813,10 @@ static void nfs_local_write_aio_complete(struct kiocb *kiocb, long ret)
|
||||
struct nfs_local_kiocb *iocb =
|
||||
container_of(kiocb, struct nfs_local_kiocb, kiocb);
|
||||
|
||||
nfs_local_pgio_done(iocb->hdr, ret);
|
||||
nfs_local_write_done(iocb, ret);
|
||||
/* AIO completion of DIO write should always be last to complete */
|
||||
if (unlikely(!nfs_local_pgio_done(iocb, ret, false)))
|
||||
return;
|
||||
|
||||
nfs_local_pgio_aio_complete(iocb); /* Calls nfs_local_write_aio_complete_work */
|
||||
}
|
||||
|
||||
@@ -791,63 +827,40 @@ static void nfs_local_call_write(struct work_struct *work)
|
||||
struct file *filp = iocb->kiocb.ki_filp;
|
||||
unsigned long old_flags = current->flags;
|
||||
const struct cred *save_cred;
|
||||
bool force_done = false;
|
||||
ssize_t status;
|
||||
int n_iters;
|
||||
|
||||
current->flags |= PF_LOCAL_THROTTLE | PF_MEMALLOC_NOIO;
|
||||
save_cred = override_creds(filp->f_cred);
|
||||
|
||||
file_start_write(filp);
|
||||
for (int i = 0; i < iocb->n_iters ; i++) {
|
||||
n_iters = atomic_read(&iocb->n_iters);
|
||||
for (int i = 0; i < n_iters ; i++) {
|
||||
if (iocb->iter_is_dio_aligned[i]) {
|
||||
iocb->kiocb.ki_flags |= IOCB_DIRECT;
|
||||
iocb->kiocb.ki_complete = nfs_local_write_aio_complete;
|
||||
iocb->aio_complete_work = nfs_local_write_aio_complete_work;
|
||||
}
|
||||
retry:
|
||||
iocb->kiocb.ki_pos = iocb->offset[i];
|
||||
/* Only use AIO completion if DIO-aligned segment is last */
|
||||
if (i == iocb->end_iter_index) {
|
||||
iocb->kiocb.ki_complete = nfs_local_write_aio_complete;
|
||||
iocb->aio_complete_work = nfs_local_write_aio_complete_work;
|
||||
}
|
||||
} else
|
||||
iocb->kiocb.ki_flags &= ~IOCB_DIRECT;
|
||||
|
||||
status = filp->f_op->write_iter(&iocb->kiocb, &iocb->iters[i]);
|
||||
if (status != -EIOCBQUEUED) {
|
||||
if (unlikely(status >= 0 && status < iocb->iters[i].count)) {
|
||||
/* partial write */
|
||||
if (i == iocb->end_iter_index) {
|
||||
/* Must not account partial end, otherwise, due
|
||||
* to end being issued before middle: the partial
|
||||
* write accounting in nfs_local_write_done()
|
||||
* would incorrectly advance hdr->args.offset
|
||||
*/
|
||||
status = 0;
|
||||
} else {
|
||||
/* Partial write at start or buffered middle,
|
||||
* exit early.
|
||||
*/
|
||||
nfs_local_pgio_done(iocb->hdr, status);
|
||||
break;
|
||||
}
|
||||
} else if (unlikely(status == -ENOTBLK &&
|
||||
(iocb->kiocb.ki_flags & IOCB_DIRECT))) {
|
||||
/* VFS will return -ENOTBLK if DIO WRITE fails to
|
||||
* invalidate the page cache. Retry using buffered IO.
|
||||
*/
|
||||
iocb->kiocb.ki_flags &= ~IOCB_DIRECT;
|
||||
iocb->kiocb.ki_complete = NULL;
|
||||
iocb->aio_complete_work = NULL;
|
||||
goto retry;
|
||||
}
|
||||
nfs_local_pgio_done(iocb->hdr, status);
|
||||
if (iocb->hdr->task.tk_status)
|
||||
if (unlikely(status >= 0 && status < iocb->iters[i].count))
|
||||
force_done = true; /* Partial write */
|
||||
if (nfs_local_pgio_done(iocb, status, force_done)) {
|
||||
nfs_local_write_iocb_done(iocb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
file_end_write(filp);
|
||||
|
||||
revert_creds(save_cred);
|
||||
current->flags = old_flags;
|
||||
|
||||
if (status != -EIOCBQUEUED) {
|
||||
nfs_local_write_done(iocb, status);
|
||||
nfs_local_vfs_getattr(iocb);
|
||||
nfs_local_pgio_release(iocb);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <linux/nfs_fs.h>
|
||||
#include <linux/nfs_mount.h>
|
||||
#include <linux/sunrpc/addr.h>
|
||||
#include <net/handshake.h>
|
||||
#include "internal.h"
|
||||
#include "nfs3_fs.h"
|
||||
#include "netns.h"
|
||||
@@ -98,7 +99,11 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
|
||||
.net = mds_clp->cl_net,
|
||||
.timeparms = &ds_timeout,
|
||||
.cred = mds_srv->cred,
|
||||
.xprtsec = mds_clp->cl_xprtsec,
|
||||
.xprtsec = {
|
||||
.policy = RPC_XPRTSEC_NONE,
|
||||
.cert_serial = TLS_NO_CERT,
|
||||
.privkey_serial = TLS_NO_PRIVKEY,
|
||||
},
|
||||
.connect_timeout = connect_timeout,
|
||||
.reconnect_timeout = connect_timeout,
|
||||
};
|
||||
@@ -111,9 +116,14 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
|
||||
cl_init.hostname = buf;
|
||||
|
||||
switch (ds_proto) {
|
||||
case XPRT_TRANSPORT_TCP_TLS:
|
||||
if (mds_clp->cl_xprtsec.policy != RPC_XPRTSEC_NONE)
|
||||
cl_init.xprtsec = mds_clp->cl_xprtsec;
|
||||
else
|
||||
ds_proto = XPRT_TRANSPORT_TCP;
|
||||
fallthrough;
|
||||
case XPRT_TRANSPORT_RDMA:
|
||||
case XPRT_TRANSPORT_TCP:
|
||||
case XPRT_TRANSPORT_TCP_TLS:
|
||||
if (mds_clp->cl_nconnect > 1)
|
||||
cl_init.nconnect = mds_clp->cl_nconnect;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/sunrpc/xprt.h>
|
||||
#include <linux/sunrpc/bc_xprt.h>
|
||||
#include <linux/sunrpc/rpc_pipe_fs.h>
|
||||
#include <net/handshake.h>
|
||||
#include "internal.h"
|
||||
#include "callback.h"
|
||||
#include "delegation.h"
|
||||
@@ -983,7 +984,11 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
|
||||
.net = mds_clp->cl_net,
|
||||
.timeparms = &ds_timeout,
|
||||
.cred = mds_srv->cred,
|
||||
.xprtsec = mds_srv->nfs_client->cl_xprtsec,
|
||||
.xprtsec = {
|
||||
.policy = RPC_XPRTSEC_NONE,
|
||||
.cert_serial = TLS_NO_CERT,
|
||||
.privkey_serial = TLS_NO_PRIVKEY,
|
||||
},
|
||||
};
|
||||
char buf[INET6_ADDRSTRLEN + 1];
|
||||
|
||||
@@ -992,9 +997,14 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
|
||||
cl_init.hostname = buf;
|
||||
|
||||
switch (ds_proto) {
|
||||
case XPRT_TRANSPORT_TCP_TLS:
|
||||
if (mds_srv->nfs_client->cl_xprtsec.policy != RPC_XPRTSEC_NONE)
|
||||
cl_init.xprtsec = mds_srv->nfs_client->cl_xprtsec;
|
||||
else
|
||||
ds_proto = XPRT_TRANSPORT_TCP;
|
||||
fallthrough;
|
||||
case XPRT_TRANSPORT_RDMA:
|
||||
case XPRT_TRANSPORT_TCP:
|
||||
case XPRT_TRANSPORT_TCP_TLS:
|
||||
if (mds_clp->cl_nconnect > 1) {
|
||||
cl_init.nconnect = mds_clp->cl_nconnect;
|
||||
cl_init.max_connect = NFS_MAX_TRANSPORTS;
|
||||
|
||||
@@ -4715,16 +4715,19 @@ static int _nfs4_proc_lookupp(struct inode *inode,
|
||||
};
|
||||
unsigned short task_flags = 0;
|
||||
|
||||
if (NFS_SERVER(inode)->flags & NFS_MOUNT_SOFTREVAL)
|
||||
if (server->flags & NFS_MOUNT_SOFTREVAL)
|
||||
task_flags |= RPC_TASK_TIMEOUT;
|
||||
if (server->caps & NFS_CAP_MOVEABLE)
|
||||
task_flags |= RPC_TASK_MOVEABLE;
|
||||
|
||||
args.bitmask = nfs4_bitmask(server, fattr->label);
|
||||
|
||||
nfs_fattr_init(fattr);
|
||||
nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
|
||||
|
||||
dprintk("NFS call lookupp ino=0x%lx\n", inode->i_ino);
|
||||
status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
|
||||
&res.seq_res, task_flags);
|
||||
status = nfs4_do_call_sync(clnt, server, &msg, &args.seq_args,
|
||||
&res.seq_res, task_flags);
|
||||
dprintk("NFS reply lookupp: %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -809,8 +809,11 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
|
||||
unsigned int retrans)
|
||||
{
|
||||
struct nfs_client *clp = ERR_PTR(-EIO);
|
||||
struct nfs_client *mds_clp = mds_srv->nfs_client;
|
||||
enum xprtsec_policies xprtsec_policy = mds_clp->cl_xprtsec.policy;
|
||||
struct nfs4_pnfs_ds_addr *da;
|
||||
unsigned long connect_timeout = timeo * (retrans + 1) * HZ / 10;
|
||||
int ds_proto;
|
||||
int status = 0;
|
||||
|
||||
dprintk("--> %s DS %s\n", __func__, ds->ds_remotestr);
|
||||
@@ -834,27 +837,28 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
|
||||
.xprtsec = clp->cl_xprtsec,
|
||||
};
|
||||
|
||||
if (da->da_transport != clp->cl_proto &&
|
||||
clp->cl_proto != XPRT_TRANSPORT_TCP_TLS)
|
||||
continue;
|
||||
if (da->da_transport == XPRT_TRANSPORT_TCP &&
|
||||
mds_srv->nfs_client->cl_proto == XPRT_TRANSPORT_TCP_TLS)
|
||||
if (xprt_args.ident == XPRT_TRANSPORT_TCP &&
|
||||
clp->cl_proto == XPRT_TRANSPORT_TCP_TLS)
|
||||
xprt_args.ident = XPRT_TRANSPORT_TCP_TLS;
|
||||
|
||||
if (da->da_addr.ss_family != clp->cl_addr.ss_family)
|
||||
if (xprt_args.ident != clp->cl_proto)
|
||||
continue;
|
||||
if (xprt_args.dstaddr->sa_family !=
|
||||
clp->cl_addr.ss_family)
|
||||
continue;
|
||||
/* Add this address as an alias */
|
||||
rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
|
||||
rpc_clnt_test_and_add_xprt, NULL);
|
||||
rpc_clnt_test_and_add_xprt, NULL);
|
||||
continue;
|
||||
}
|
||||
if (da->da_transport == XPRT_TRANSPORT_TCP &&
|
||||
mds_srv->nfs_client->cl_proto == XPRT_TRANSPORT_TCP_TLS)
|
||||
da->da_transport = XPRT_TRANSPORT_TCP_TLS;
|
||||
clp = get_v3_ds_connect(mds_srv,
|
||||
&da->da_addr,
|
||||
da->da_addrlen, da->da_transport,
|
||||
timeo, retrans);
|
||||
|
||||
ds_proto = da->da_transport;
|
||||
if (ds_proto == XPRT_TRANSPORT_TCP &&
|
||||
xprtsec_policy != RPC_XPRTSEC_NONE)
|
||||
ds_proto = XPRT_TRANSPORT_TCP_TLS;
|
||||
|
||||
clp = get_v3_ds_connect(mds_srv, &da->da_addr, da->da_addrlen,
|
||||
ds_proto, timeo, retrans);
|
||||
if (IS_ERR(clp))
|
||||
continue;
|
||||
clp->cl_rpcclient->cl_softerr = 0;
|
||||
@@ -880,7 +884,10 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
|
||||
u32 minor_version)
|
||||
{
|
||||
struct nfs_client *clp = ERR_PTR(-EIO);
|
||||
struct nfs_client *mds_clp = mds_srv->nfs_client;
|
||||
enum xprtsec_policies xprtsec_policy = mds_clp->cl_xprtsec.policy;
|
||||
struct nfs4_pnfs_ds_addr *da;
|
||||
int ds_proto;
|
||||
int status = 0;
|
||||
|
||||
dprintk("--> %s DS %s\n", __func__, ds->ds_remotestr);
|
||||
@@ -908,12 +915,8 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
|
||||
.data = &xprtdata,
|
||||
};
|
||||
|
||||
if (da->da_transport != clp->cl_proto &&
|
||||
clp->cl_proto != XPRT_TRANSPORT_TCP_TLS)
|
||||
continue;
|
||||
if (da->da_transport == XPRT_TRANSPORT_TCP &&
|
||||
mds_srv->nfs_client->cl_proto ==
|
||||
XPRT_TRANSPORT_TCP_TLS) {
|
||||
if (xprt_args.ident == XPRT_TRANSPORT_TCP &&
|
||||
clp->cl_proto == XPRT_TRANSPORT_TCP_TLS) {
|
||||
struct sockaddr *addr =
|
||||
(struct sockaddr *)&da->da_addr;
|
||||
struct sockaddr_in *sin =
|
||||
@@ -944,7 +947,10 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
|
||||
xprt_args.ident = XPRT_TRANSPORT_TCP_TLS;
|
||||
xprt_args.servername = servername;
|
||||
}
|
||||
if (da->da_addr.ss_family != clp->cl_addr.ss_family)
|
||||
if (xprt_args.ident != clp->cl_proto)
|
||||
continue;
|
||||
if (xprt_args.dstaddr->sa_family !=
|
||||
clp->cl_addr.ss_family)
|
||||
continue;
|
||||
|
||||
/**
|
||||
@@ -958,15 +964,14 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
|
||||
if (xprtdata.cred)
|
||||
put_cred(xprtdata.cred);
|
||||
} else {
|
||||
if (da->da_transport == XPRT_TRANSPORT_TCP &&
|
||||
mds_srv->nfs_client->cl_proto ==
|
||||
XPRT_TRANSPORT_TCP_TLS)
|
||||
da->da_transport = XPRT_TRANSPORT_TCP_TLS;
|
||||
clp = nfs4_set_ds_client(mds_srv,
|
||||
&da->da_addr,
|
||||
da->da_addrlen,
|
||||
da->da_transport, timeo,
|
||||
retrans, minor_version);
|
||||
ds_proto = da->da_transport;
|
||||
if (ds_proto == XPRT_TRANSPORT_TCP &&
|
||||
xprtsec_policy != RPC_XPRTSEC_NONE)
|
||||
ds_proto = XPRT_TRANSPORT_TCP_TLS;
|
||||
|
||||
clp = nfs4_set_ds_client(mds_srv, &da->da_addr,
|
||||
da->da_addrlen, ds_proto,
|
||||
timeo, retrans, minor_version);
|
||||
if (IS_ERR(clp))
|
||||
continue;
|
||||
|
||||
@@ -977,7 +982,6 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
|
||||
clp = ERR_PTR(-EIO);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -189,6 +189,7 @@ static struct nfs_netns_client *nfs_netns_client_alloc(struct kobject *parent,
|
||||
return p;
|
||||
|
||||
kobject_put(&p->kobject);
|
||||
kobject_put(&p->nfs_net_kobj);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1435,12 +1435,14 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
|
||||
cifs_errorf(fc, "Unknown error parsing devname\n");
|
||||
goto cifs_parse_mount_err;
|
||||
}
|
||||
kfree(ctx->source);
|
||||
ctx->source = smb3_fs_context_fullpath(ctx, '/');
|
||||
if (IS_ERR(ctx->source)) {
|
||||
ctx->source = NULL;
|
||||
cifs_errorf(fc, "OOM when copying UNC string\n");
|
||||
goto cifs_parse_mount_err;
|
||||
}
|
||||
kfree(fc->source);
|
||||
fc->source = kstrdup(ctx->source, GFP_KERNEL);
|
||||
if (fc->source == NULL) {
|
||||
cifs_errorf(fc, "OOM when copying UNC string\n");
|
||||
@@ -1468,7 +1470,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
|
||||
break;
|
||||
}
|
||||
|
||||
if (strnlen(param->string, CIFS_MAX_USERNAME_LEN) >
|
||||
if (strnlen(param->string, CIFS_MAX_USERNAME_LEN) ==
|
||||
CIFS_MAX_USERNAME_LEN) {
|
||||
pr_warn("username too long\n");
|
||||
goto cifs_parse_mount_err;
|
||||
|
||||
@@ -290,6 +290,9 @@ static void smbd_disconnect_rdma_connection(struct smbdirect_socket *sc)
|
||||
break;
|
||||
|
||||
case SMBDIRECT_SOCKET_CREATED:
|
||||
sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
|
||||
break;
|
||||
|
||||
case SMBDIRECT_SOCKET_CONNECTED:
|
||||
sc->status = SMBDIRECT_SOCKET_ERROR;
|
||||
break;
|
||||
|
||||
@@ -830,7 +830,7 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
|
||||
if (!server || server->terminate)
|
||||
continue;
|
||||
|
||||
if (CIFS_CHAN_NEEDS_RECONNECT(ses, i))
|
||||
if (CIFS_CHAN_NEEDS_RECONNECT(ses, cur))
|
||||
continue;
|
||||
|
||||
/*
|
||||
|
||||
@@ -36,6 +36,9 @@ struct io_uring_query_opcode {
|
||||
__u64 enter_flags;
|
||||
/* Bitmask of all supported IOSQE_* flags */
|
||||
__u64 sqe_flags;
|
||||
/* The number of available query opcodes */
|
||||
__u32 nr_query_opcodes;
|
||||
__u32 __pad;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,8 @@ static ssize_t io_query_ops(void *data)
|
||||
e->ring_setup_flags = IORING_SETUP_FLAGS;
|
||||
e->enter_flags = IORING_ENTER_FLAGS;
|
||||
e->sqe_flags = SQE_VALID_FLAGS;
|
||||
e->nr_query_opcodes = __IO_URING_QUERY_MAX;
|
||||
e->__pad = 0;
|
||||
return sizeof(*e);
|
||||
}
|
||||
|
||||
|
||||
@@ -943,8 +943,8 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
|
||||
struct req_iterator rq_iter;
|
||||
struct io_mapped_ubuf *imu;
|
||||
struct io_rsrc_node *node;
|
||||
struct bio_vec bv, *bvec;
|
||||
u16 nr_bvecs;
|
||||
struct bio_vec bv;
|
||||
unsigned int nr_bvecs = 0;
|
||||
int ret = 0;
|
||||
|
||||
io_ring_submit_lock(ctx, issue_flags);
|
||||
@@ -965,8 +965,11 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
nr_bvecs = blk_rq_nr_phys_segments(rq);
|
||||
imu = io_alloc_imu(ctx, nr_bvecs);
|
||||
/*
|
||||
* blk_rq_nr_phys_segments() may overestimate the number of bvecs
|
||||
* but avoids needing to iterate over the bvecs
|
||||
*/
|
||||
imu = io_alloc_imu(ctx, blk_rq_nr_phys_segments(rq));
|
||||
if (!imu) {
|
||||
kfree(node);
|
||||
ret = -ENOMEM;
|
||||
@@ -977,16 +980,15 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
|
||||
imu->len = blk_rq_bytes(rq);
|
||||
imu->acct_pages = 0;
|
||||
imu->folio_shift = PAGE_SHIFT;
|
||||
imu->nr_bvecs = nr_bvecs;
|
||||
refcount_set(&imu->refs, 1);
|
||||
imu->release = release;
|
||||
imu->priv = rq;
|
||||
imu->is_kbuf = true;
|
||||
imu->dir = 1 << rq_data_dir(rq);
|
||||
|
||||
bvec = imu->bvec;
|
||||
rq_for_each_bvec(bv, rq, rq_iter)
|
||||
*bvec++ = bv;
|
||||
imu->bvec[nr_bvecs++] = bv;
|
||||
imu->nr_bvecs = nr_bvecs;
|
||||
|
||||
node->buf = imu;
|
||||
data->nodes[index] = node;
|
||||
|
||||
@@ -463,7 +463,10 @@ int io_read_mshot_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
|
||||
void io_readv_writev_cleanup(struct io_kiocb *req)
|
||||
{
|
||||
struct io_async_rw *rw = req->async_data;
|
||||
|
||||
lockdep_assert_held(&req->ctx->uring_lock);
|
||||
io_vec_free(&rw->vec);
|
||||
io_rw_recycle(req, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -350,8 +350,8 @@ static int nvhdmi_mcp_probe(struct hda_codec *codec,
|
||||
static const struct hda_codec_ops nvhdmi_mcp_codec_ops = {
|
||||
.probe = nvhdmi_mcp_probe,
|
||||
.remove = snd_hda_hdmi_simple_remove,
|
||||
.build_controls = nvhdmi_mcp_build_pcms,
|
||||
.build_pcms = nvhdmi_mcp_build_controls,
|
||||
.build_pcms = nvhdmi_mcp_build_pcms,
|
||||
.build_controls = nvhdmi_mcp_build_controls,
|
||||
.init = nvhdmi_mcp_init,
|
||||
.unsol_event = snd_hda_hdmi_simple_unsol_event,
|
||||
};
|
||||
|
||||
@@ -6694,6 +6694,15 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8e60, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8e61, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8e62, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ed5, "HP Merino13X", ALC245_FIXUP_TAS2781_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ed6, "HP Merino13", ALC245_FIXUP_TAS2781_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ed7, "HP Merino14", ALC245_FIXUP_TAS2781_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ed8, "HP Merino16", ALC245_FIXUP_TAS2781_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ed9, "HP Merino14W", ALC245_FIXUP_TAS2781_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8eda, "HP Merino16W", ALC245_FIXUP_TAS2781_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8f40, "HP Lampas14", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x103c, 0x8f41, "HP Lampas16", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x103c, 0x8f42, "HP LampasW14", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x1032, "ASUS VivoBook X513EA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1034, "ASUS GU605C", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1),
|
||||
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
|
||||
|
||||
@@ -581,17 +581,17 @@ static int cs4271_component_probe(struct snd_soc_component *component)
|
||||
|
||||
ret = regcache_sync(cs4271->regmap);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err_disable_regulator;
|
||||
|
||||
ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
|
||||
CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
|
||||
CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err_disable_regulator;
|
||||
ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
|
||||
CS4271_MODE2_PDN, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err_disable_regulator;
|
||||
/* Power-up sequence requires 85 uS */
|
||||
udelay(85);
|
||||
|
||||
@@ -601,6 +601,10 @@ static int cs4271_component_probe(struct snd_soc_component *component)
|
||||
CS4271_MODE2_MUTECAEQUB);
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_regulator:
|
||||
regulator_bulk_disable(ARRAY_SIZE(cs4271->supplies), cs4271->supplies);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cs4271_component_remove(struct snd_soc_component *component)
|
||||
|
||||
@@ -2124,11 +2124,50 @@ static int da7213_probe(struct snd_soc_component *component)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int da7213_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct da7213_priv *da7213 = dev_get_drvdata(dev);
|
||||
|
||||
regcache_cache_only(da7213->regmap, true);
|
||||
regcache_mark_dirty(da7213->regmap);
|
||||
regulator_bulk_disable(DA7213_NUM_SUPPLIES, da7213->supplies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int da7213_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct da7213_priv *da7213 = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = regulator_bulk_enable(DA7213_NUM_SUPPLIES, da7213->supplies);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
regcache_cache_only(da7213->regmap, false);
|
||||
return regcache_sync(da7213->regmap);
|
||||
}
|
||||
|
||||
static int da7213_suspend(struct snd_soc_component *component)
|
||||
{
|
||||
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
return da7213_runtime_suspend(da7213->dev);
|
||||
}
|
||||
|
||||
static int da7213_resume(struct snd_soc_component *component)
|
||||
{
|
||||
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
return da7213_runtime_resume(da7213->dev);
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver soc_component_dev_da7213 = {
|
||||
.probe = da7213_probe,
|
||||
.set_bias_level = da7213_set_bias_level,
|
||||
.controls = da7213_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(da7213_snd_controls),
|
||||
.suspend = da7213_suspend,
|
||||
.resume = da7213_resume,
|
||||
.dapm_widgets = da7213_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets),
|
||||
.dapm_routes = da7213_audio_map,
|
||||
@@ -2175,6 +2214,8 @@ static int da7213_i2c_probe(struct i2c_client *i2c)
|
||||
if (!da7213->fin_min_rate)
|
||||
return -EINVAL;
|
||||
|
||||
da7213->dev = &i2c->dev;
|
||||
|
||||
i2c_set_clientdata(i2c, da7213);
|
||||
|
||||
/* Get required supplies */
|
||||
@@ -2224,31 +2265,9 @@ static void da7213_i2c_remove(struct i2c_client *i2c)
|
||||
pm_runtime_disable(&i2c->dev);
|
||||
}
|
||||
|
||||
static int da7213_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct da7213_priv *da7213 = dev_get_drvdata(dev);
|
||||
|
||||
regcache_cache_only(da7213->regmap, true);
|
||||
regcache_mark_dirty(da7213->regmap);
|
||||
regulator_bulk_disable(DA7213_NUM_SUPPLIES, da7213->supplies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int da7213_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct da7213_priv *da7213 = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = regulator_bulk_enable(DA7213_NUM_SUPPLIES, da7213->supplies);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
regcache_cache_only(da7213->regmap, false);
|
||||
return regcache_sync(da7213->regmap);
|
||||
}
|
||||
|
||||
static DEFINE_RUNTIME_DEV_PM_OPS(da7213_pm, da7213_runtime_suspend,
|
||||
da7213_runtime_resume, NULL);
|
||||
static const struct dev_pm_ops da7213_pm = {
|
||||
RUNTIME_PM_OPS(da7213_runtime_suspend, da7213_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static const struct i2c_device_id da7213_i2c_id[] = {
|
||||
{ "da7213" },
|
||||
|
||||
@@ -595,6 +595,7 @@ enum da7213_supplies {
|
||||
/* Codec private data */
|
||||
struct da7213_priv {
|
||||
struct regmap *regmap;
|
||||
struct device *dev;
|
||||
struct mutex ctrl_lock;
|
||||
struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES];
|
||||
struct clk *mclk;
|
||||
|
||||
@@ -1638,7 +1638,7 @@ static int va_macro_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_clkout;
|
||||
|
||||
va->fsgen = clk_hw_get_clk(&va->hw, "fsgen");
|
||||
va->fsgen = devm_clk_hw_get_clk(dev, &va->hw, "fsgen");
|
||||
if (IS_ERR(va->fsgen)) {
|
||||
ret = PTR_ERR(va->fsgen);
|
||||
goto err_clkout;
|
||||
|
||||
@@ -1957,7 +1957,8 @@ static void tasdevice_parse_dt(struct tasdevice_priv *tas_priv)
|
||||
{
|
||||
struct i2c_client *client = (struct i2c_client *)tas_priv->client;
|
||||
unsigned int dev_addrs[TASDEVICE_MAX_CHANNELS];
|
||||
int i, ndev = 0;
|
||||
int ndev = 0;
|
||||
int i, rc;
|
||||
|
||||
if (tas_priv->isacpi) {
|
||||
ndev = device_property_read_u32_array(&client->dev,
|
||||
@@ -1968,8 +1969,12 @@ static void tasdevice_parse_dt(struct tasdevice_priv *tas_priv)
|
||||
} else {
|
||||
ndev = (ndev < ARRAY_SIZE(dev_addrs))
|
||||
? ndev : ARRAY_SIZE(dev_addrs);
|
||||
ndev = device_property_read_u32_array(&client->dev,
|
||||
rc = device_property_read_u32_array(&client->dev,
|
||||
"ti,audio-slots", dev_addrs, ndev);
|
||||
if (rc != 0) {
|
||||
ndev = 1;
|
||||
dev_addrs[0] = client->addr;
|
||||
}
|
||||
}
|
||||
|
||||
tas_priv->irq =
|
||||
|
||||
@@ -762,10 +762,17 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context)
|
||||
goto out;
|
||||
}
|
||||
|
||||
mutex_lock(&tas_dev->pde_lock);
|
||||
img_sz = fmw->size;
|
||||
buf = fmw->data;
|
||||
offset += FW_DL_OFFSET;
|
||||
if (offset >= (img_sz - FW_FL_HDR)) {
|
||||
dev_err(tas_dev->dev,
|
||||
"firmware is too small");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mutex_lock(&tas_dev->pde_lock);
|
||||
while (offset < (img_sz - FW_FL_HDR)) {
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
offset += read_header(&buf[offset], &hdr);
|
||||
@@ -776,6 +783,14 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context)
|
||||
/* size also includes the header */
|
||||
file_blk_size = hdr.length - FW_FL_HDR;
|
||||
|
||||
/* make sure that enough data is there */
|
||||
if (offset + file_blk_size > img_sz) {
|
||||
ret = -EINVAL;
|
||||
dev_err(tas_dev->dev,
|
||||
"corrupt firmware file");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (hdr.file_id) {
|
||||
case 0:
|
||||
ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral,
|
||||
@@ -808,7 +823,8 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context)
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&tas_dev->pde_lock);
|
||||
tas2783_update_calibdata(tas_dev);
|
||||
if (!ret)
|
||||
tas2783_update_calibdata(tas_dev);
|
||||
|
||||
out:
|
||||
if (!ret)
|
||||
|
||||
@@ -509,7 +509,7 @@ void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
|
||||
int rsnd_ssiu_probe(struct rsnd_priv *priv)
|
||||
{
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
struct device_node *node;
|
||||
struct device_node *node __free(device_node) = rsnd_ssiu_of_node(priv);
|
||||
struct rsnd_ssiu *ssiu;
|
||||
struct rsnd_mod_ops *ops;
|
||||
const int *list = NULL;
|
||||
@@ -522,7 +522,6 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
|
||||
* see
|
||||
* rsnd_ssiu_bufsif_to_id()
|
||||
*/
|
||||
node = rsnd_ssiu_of_node(priv);
|
||||
if (node)
|
||||
nr = rsnd_node_count(priv, node, SSIU_NAME);
|
||||
else
|
||||
|
||||
@@ -894,7 +894,8 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
|
||||
return ret;
|
||||
}
|
||||
|
||||
control->values = devm_kzalloc(dev, hweight64(control->cn_list), GFP_KERNEL);
|
||||
control->values = devm_kcalloc(dev, hweight64(control->cn_list),
|
||||
sizeof(int), GFP_KERNEL);
|
||||
if (!control->values)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -1277,7 +1277,7 @@ static int is_sdca_endpoint_present(struct device *dev,
|
||||
struct sdw_slave *slave;
|
||||
struct device *sdw_dev;
|
||||
const char *sdw_codec_name;
|
||||
int i;
|
||||
int ret, i;
|
||||
|
||||
dlc = kzalloc(sizeof(*dlc), GFP_KERNEL);
|
||||
if (!dlc)
|
||||
@@ -1307,13 +1307,16 @@ static int is_sdca_endpoint_present(struct device *dev,
|
||||
}
|
||||
|
||||
slave = dev_to_sdw_dev(sdw_dev);
|
||||
if (!slave)
|
||||
return -EINVAL;
|
||||
if (!slave) {
|
||||
ret = -EINVAL;
|
||||
goto put_device;
|
||||
}
|
||||
|
||||
/* Make sure BIOS provides SDCA properties */
|
||||
if (!slave->sdca_data.interface_revision) {
|
||||
dev_warn(&slave->dev, "SDCA properties not found in the BIOS\n");
|
||||
return 1;
|
||||
ret = 1;
|
||||
goto put_device;
|
||||
}
|
||||
|
||||
for (i = 0; i < slave->sdca_data.num_functions; i++) {
|
||||
@@ -1322,7 +1325,8 @@ static int is_sdca_endpoint_present(struct device *dev,
|
||||
if (dai_type == dai_info->dai_type) {
|
||||
dev_dbg(&slave->dev, "DAI type %d sdca function %s found\n",
|
||||
dai_type, slave->sdca_data.function[i].name);
|
||||
return 1;
|
||||
ret = 1;
|
||||
goto put_device;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1330,7 +1334,11 @@ static int is_sdca_endpoint_present(struct device *dev,
|
||||
"SDCA device function for DAI type %d not supported, skip endpoint\n",
|
||||
dai_info->dai_type);
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
|
||||
put_device:
|
||||
put_device(sdw_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
|
||||
|
||||
@@ -1362,6 +1362,11 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
|
||||
ep->sample_rem = ep->cur_rate % ep->pps;
|
||||
ep->packsize[0] = ep->cur_rate / ep->pps;
|
||||
ep->packsize[1] = (ep->cur_rate + (ep->pps - 1)) / ep->pps;
|
||||
if (ep->packsize[1] > ep->maxpacksize) {
|
||||
usb_audio_dbg(chip, "Too small maxpacksize %u for rate %u / pps %u\n",
|
||||
ep->maxpacksize, ep->cur_rate, ep->pps);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* calculate the frequency in 16.16 format */
|
||||
ep->freqm = ep->freqn;
|
||||
|
||||
@@ -3086,6 +3086,8 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer,
|
||||
int i;
|
||||
|
||||
assoc = usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
|
||||
if (!assoc)
|
||||
return -EINVAL;
|
||||
|
||||
/* Detect BADD capture/playback channels from AS EP descriptors */
|
||||
for (i = 0; i < assoc->bInterfaceCount; i++) {
|
||||
|
||||
@@ -2022,6 +2022,8 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
|
||||
case USB_ID(0x16d0, 0x09d8): /* NuPrime IDA-8 */
|
||||
case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */
|
||||
case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */
|
||||
case USB_ID(0x16d0, 0x0ab1): /* PureAudio APA DAC */
|
||||
case USB_ID(0x16d0, 0xeca1): /* PureAudio Lotus DAC5, DAC5 SE, DAC5 Pro */
|
||||
case USB_ID(0x1db5, 0x0003): /* Bryston BDA3 */
|
||||
case USB_ID(0x20a0, 0x4143): /* WaveIO USB Audio 2.0 */
|
||||
case USB_ID(0x22e1, 0xca01): /* HDTA Serenade DSD */
|
||||
@@ -2267,6 +2269,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
|
||||
QUIRK_FLAG_FIXED_RATE),
|
||||
DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */
|
||||
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
|
||||
DEVICE_FLG(0x1038, 0x1294, /* SteelSeries Arctis Pro Wireless */
|
||||
QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
|
||||
DEVICE_FLG(0x1101, 0x0003, /* Audioengine D1 */
|
||||
QUIRK_FLAG_GET_SAMPLE_RATE),
|
||||
DEVICE_FLG(0x12d1, 0x3a07, /* Huawei Technologies Co., Ltd. */
|
||||
@@ -2297,6 +2301,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
|
||||
QUIRK_FLAG_IGNORE_CLOCK_SOURCE),
|
||||
DEVICE_FLG(0x1686, 0x00dd, /* Zoom R16/24 */
|
||||
QUIRK_FLAG_TX_LENGTH | QUIRK_FLAG_CTL_MSG_DELAY_1M),
|
||||
DEVICE_FLG(0x16d0, 0x0ab1, /* PureAudio APA DAC */
|
||||
QUIRK_FLAG_DSD_RAW),
|
||||
DEVICE_FLG(0x16d0, 0xeca1, /* PureAudio Lotus DAC5, DAC5 SE and DAC5 Pro */
|
||||
QUIRK_FLAG_DSD_RAW),
|
||||
DEVICE_FLG(0x17aa, 0x1046, /* Lenovo ThinkStation P620 Rear Line-in, Line-out and Microphone */
|
||||
QUIRK_FLAG_DISABLE_AUTOSUSPEND),
|
||||
DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */
|
||||
|
||||
Reference in New Issue
Block a user