Merge 4fa048ed72 ("Merge tag 'drm-fixes-2026-06-13' of https://gitlab.freedesktop.org/drm/kernel") into android-mainline

Steps on the way to v7.1-rc8

Change-Id: I1d12c519bdbd58540dac9afc3dd8a5cd2b3ae0f5
Signed-off-by: Carlos Llamas <cmllamas@google.com>
This commit is contained in:
Carlos Llamas committed 2026-06-14 13:28:57 +00:00
commit f3f901a4d4
55 files changed
+618 -306

No files matched your search

+1
View File
@@ -20557,6 +20557,7 @@ PCI ENDPOINT SUBSYSTEM
M: Manivannan Sadhasivam <mani@kernel.org>
M: Krzysztof Wilczyński <kwilczynski@kernel.org>
R: Kishon Vijay Abraham I <kishon@kernel.org>
R: Frank Li <Frank.Li@kernel.org>
L: linux-pci@vger.kernel.org
S: Supported
Q: https://patchwork.kernel.org/project/linux-pci/list/
+10 -6
View File
@@ -34,6 +34,7 @@ static int ncores;
static struct regmap *pmu;
static int has_pmu = true;
static struct reset_control *cpu_rstc[4];
static int pmu_power_domain_is_on(int pd)
{
@@ -64,9 +65,11 @@ static struct reset_control *rockchip_get_core_reset(int cpu)
static int pmu_set_power_domain(int pd, bool on)
{
u32 val = (on) ? 0 : BIT(pd);
struct reset_control *rstc = rockchip_get_core_reset(pd);
struct reset_control *rstc;
int ret;
rstc = pd < ARRAY_SIZE(cpu_rstc) ? cpu_rstc[pd] : ERR_PTR(-EINVAL);
if (IS_ERR(rstc) && read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
pr_err("%s: could not get reset control for core %d\n",
__func__, pd);
@@ -100,11 +103,8 @@ static int pmu_set_power_domain(int pd, bool on)
}
}
if (!IS_ERR(rstc)) {
if (on)
reset_control_deassert(rstc);
reset_control_put(rstc);
}
if (!IS_ERR(rstc) && on)
reset_control_deassert(rstc);
return 0;
}
@@ -312,6 +312,10 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
ncores = ((l2ctlr >> 24) & 0x3) + 1;
}
/* Collect cpu core reset control for each core */
for (i = 0; i < ncores; i++)
cpu_rstc[i] = rockchip_get_core_reset(i);
/* Make sure that all cores except the first are really off */
for (i = 1; i < ncores; i++)
pmu_set_power_domain(0 + i, false);
+3
View File
@@ -999,6 +999,7 @@ again:
if (ret == -EBUSY) {
amdxdna_umap_put(mapp);
mmput(mm);
goto again;
}
@@ -1009,11 +1010,13 @@ again:
if (mmu_interval_read_retry(&mapp->notifier, mapp->range.notifier_seq)) {
up_write(&xdna->notifier_lock);
amdxdna_umap_put(mapp);
mmput(mm);
goto again;
}
mapp->invalid = false;
up_write(&xdna->notifier_lock);
amdxdna_umap_put(mapp);
mmput(mm);
goto again;
put_mm:
+1 -1
View File
@@ -276,7 +276,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
if (ipc_buf)
memcpy(ipc_buf, rx_msg->ipc_hdr, sizeof(*ipc_buf));
if (rx_msg->jsm_msg) {
u32 size = min_t(int, rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg));
u32 size = min(rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg));
if (rx_msg->jsm_msg->result != VPU_JSM_STATUS_SUCCESS) {
ivpu_err(vdev, "IPC resp result error: %d\n", rx_msg->jsm_msg->result);
+20 -25
View File
@@ -723,15 +723,9 @@ static int stratix10_rsu_probe(struct platform_device *pdev)
return -ENOMEM;
priv->client.dev = dev;
priv->client.receive_cb = NULL;
priv->client.priv = priv;
priv->status.current_image = 0;
priv->status.fail_image = 0;
priv->status.error_location = 0;
priv->status.error_details = 0;
priv->status.version = 0;
priv->status.state = 0;
priv->retry_counter = INVALID_RETRY_COUNTER;
priv->max_retry = INVALID_RETRY_COUNTER;
priv->dcmf_version.dcmf0 = INVALID_DCMF_VERSION;
priv->dcmf_version.dcmf1 = INVALID_DCMF_VERSION;
priv->dcmf_version.dcmf2 = INVALID_DCMF_VERSION;
@@ -740,11 +734,11 @@ static int stratix10_rsu_probe(struct platform_device *pdev)
priv->dcmf_status.dcmf1 = INVALID_DCMF_STATUS;
priv->dcmf_status.dcmf2 = INVALID_DCMF_STATUS;
priv->dcmf_status.dcmf3 = INVALID_DCMF_STATUS;
priv->max_retry = INVALID_RETRY_COUNTER;
priv->spt0_address = INVALID_SPT_ADDRESS;
priv->spt1_address = INVALID_SPT_ADDRESS;
/* spt0/1_address and status fields default to 0 from kzalloc */
mutex_init(&priv->lock);
init_completion(&priv->completion);
priv->chan = stratix10_svc_request_channel_byname(&priv->client,
SVC_CLIENT_RSU);
if (IS_ERR(priv->chan)) {
@@ -756,11 +750,9 @@ static int stratix10_rsu_probe(struct platform_device *pdev)
ret = stratix10_svc_add_async_client(priv->chan, false);
if (ret) {
dev_err(dev, "failed to add async client\n");
stratix10_svc_free_channel(priv->chan);
return ret;
goto free_channel;
}
init_completion(&priv->completion);
platform_set_drvdata(pdev, priv);
/* get the initial state from firmware */
@@ -768,41 +760,44 @@ static int stratix10_rsu_probe(struct platform_device *pdev)
rsu_async_status_callback);
if (ret) {
dev_err(dev, "Error, getting RSU status %i\n", ret);
stratix10_svc_remove_async_client(priv->chan);
stratix10_svc_free_channel(priv->chan);
return ret;
goto remove_async_client;
}
/* get DCMF version from firmware */
ret = rsu_send_msg(priv, COMMAND_RSU_DCMF_VERSION,
0, rsu_dcmf_version_callback);
ret = rsu_send_msg(priv, COMMAND_RSU_DCMF_VERSION, 0,
rsu_dcmf_version_callback);
if (ret) {
dev_err(dev, "Error, getting DCMF version %i\n", ret);
stratix10_svc_free_channel(priv->chan);
goto remove_async_client;
}
ret = rsu_send_msg(priv, COMMAND_RSU_DCMF_STATUS,
0, rsu_dcmf_status_callback);
ret = rsu_send_msg(priv, COMMAND_RSU_DCMF_STATUS, 0,
rsu_dcmf_status_callback);
if (ret) {
dev_err(dev, "Error, getting DCMF status %i\n", ret);
stratix10_svc_free_channel(priv->chan);
goto remove_async_client;
}
ret = rsu_send_msg(priv, COMMAND_RSU_MAX_RETRY, 0,
rsu_max_retry_callback);
if (ret) {
dev_err(dev, "Error, getting RSU max retry %i\n", ret);
stratix10_svc_free_channel(priv->chan);
goto remove_async_client;
}
ret = rsu_send_async_msg(dev, priv, COMMAND_RSU_GET_SPT_TABLE, 0,
rsu_async_get_spt_table_callback);
if (ret) {
dev_err(dev, "Error, getting SPT table %i\n", ret);
stratix10_svc_free_channel(priv->chan);
goto remove_async_client;
}
return 0;
remove_async_client:
stratix10_svc_remove_async_client(priv->chan);
free_channel:
stratix10_svc_free_channel(priv->chan);
return ret;
}
+17 -4
View File
@@ -212,6 +212,7 @@ struct stratix10_async_chan {
/**
* struct stratix10_async_ctrl - Control structure for Stratix10
* asynchronous operations
* @supported: Flag indicating whether the system supports async operations
* @initialized: Flag indicating whether the control structure has
* been initialized
* @invoke_fn: Function pointer for invoking Stratix10 service calls
@@ -228,6 +229,7 @@ struct stratix10_async_chan {
*/
struct stratix10_async_ctrl {
bool supported;
bool initialized;
void (*invoke_fn)(struct stratix10_async_ctrl *actrl,
const struct arm_smccc_1_2_regs *args,
@@ -1103,6 +1105,7 @@ EXPORT_SYMBOL_GPL(stratix10_svc_request_channel_byname);
* Return: 0 on success, or a negative error code on failure:
* -EINVAL if the channel is NULL or the async controller is
* not initialized.
* -EOPNOTSUPP if async operations are not supported.
* -EALREADY if the async channel is already allocated.
* -ENOMEM if memory allocation fails.
* Other negative values if ID allocation fails.
@@ -1121,6 +1124,9 @@ int stratix10_svc_add_async_client(struct stratix10_svc_chan *chan,
ctrl = chan->ctrl;
actrl = &ctrl->actrl;
if (!actrl->supported)
return -EOPNOTSUPP;
if (!actrl->initialized) {
dev_err(ctrl->dev, "Async controller not initialized\n");
return -EINVAL;
@@ -1562,6 +1568,7 @@ static inline void stratix10_smc_1_2(struct stratix10_async_ctrl *actrl,
* initialized, -ENOMEM if memory allocation fails,
* -EADDRINUSE if the client ID is already reserved, or other
* negative error codes on failure.
* -EOPNOTSUPP if system doesn't support async operations.
*/
static int stratix10_svc_async_init(struct stratix10_svc_controller *controller)
{
@@ -1585,10 +1592,12 @@ static int stratix10_svc_async_init(struct stratix10_svc_controller *controller)
!(res.a1 > ASYNC_ATF_MINIMUM_MAJOR_VERSION ||
(res.a1 == ASYNC_ATF_MINIMUM_MAJOR_VERSION &&
res.a2 >= ASYNC_ATF_MINIMUM_MINOR_VERSION))) {
dev_err(dev,
"Intel Service Layer Driver: ATF version is not compatible for async operation\n");
return -EINVAL;
dev_info(dev,
"Intel Service Layer Driver: ATF version is not compatible for async operation\n");
actrl->supported = false;
return -EOPNOTSUPP;
}
actrl->supported = true;
actrl->invoke_fn = stratix10_smc_1_2;
@@ -1952,10 +1961,14 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
init_completion(&controller->complete_status);
ret = stratix10_svc_async_init(controller);
if (ret) {
if (ret == -EOPNOTSUPP) {
dev_info(dev, "Intel Service Layer Driver Initialized (sync-only mode)\n");
} else if (ret) {
dev_dbg(dev, "Intel Service Layer Driver: Error on stratix10_svc_async_init %d\n",
ret);
goto err_destroy_pool;
} else {
dev_info(dev, "Intel Service Layer Driver Initialized\n");
}
fifo_size = sizeof(struct stratix10_svc_data) * SVC_NUM_DATA_IN_FIFO;
+3 -1
View File
@@ -1277,6 +1277,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
{
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
struct amdgpu_job *leader = p->gang_leader;
struct amdgpu_vm *vm = &fpriv->vm;
struct amdgpu_bo_list_entry *e;
struct drm_gem_object *gobj;
unsigned long index;
@@ -1322,7 +1323,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
amdgpu_hmm_range_free(e->range);
e->range = NULL;
}
if (r) {
if (r || !list_empty(&vm->invalidated)) {
r = -EAGAIN;
mutex_unlock(&p->adev->notifier_lock);
return r;
@@ -593,7 +593,7 @@ free_syncobj_handles:
static int
amdgpu_userq_wait_count_fences(struct drm_file *filp,
struct drm_amdgpu_userq_wait *wait_info,
u32 *syncobj_handles, u32 *timeline_points,
u32 *syncobj_handles, u64 *timeline_points,
u32 *timeline_handles,
struct drm_gem_object **gobj_write,
struct drm_gem_object **gobj_read)
@@ -703,7 +703,7 @@ amdgpu_userq_wait_add_fence(struct drm_amdgpu_userq_wait *wait_info,
static int
amdgpu_userq_wait_return_fence_info(struct drm_file *filp,
struct drm_amdgpu_userq_wait *wait_info,
u32 *syncobj_handles, u32 *timeline_points,
u32 *syncobj_handles, u64 *timeline_points,
u32 *timeline_handles,
struct drm_gem_object **gobj_write,
struct drm_gem_object **gobj_read)
@@ -906,7 +906,8 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
int num_points, num_syncobj, num_read_bo_handles, num_write_bo_handles;
u32 *syncobj_handles, *timeline_points, *timeline_handles;
u32 *syncobj_handles, *timeline_handles;
u64 *timeline_points;
struct drm_amdgpu_userq_wait *wait_info = data;
struct drm_gem_object **gobj_write;
struct drm_gem_object **gobj_read;
@@ -935,7 +936,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
}
ptr = u64_to_user_ptr(wait_info->syncobj_timeline_points);
timeline_points = memdup_array_user(ptr, num_points, sizeof(u32));
timeline_points = memdup_array_user(ptr, num_points, sizeof(u64));
if (IS_ERR(timeline_points)) {
r = PTR_ERR(timeline_points);
goto free_timeline_handles;
+6
View File
@@ -832,6 +832,12 @@ int kfd_dbg_trap_enable(struct kfd_process *target, uint32_t fd,
if (copy_to_user(runtime_info, (void *)&target->runtime_info, copy_size)) {
kfd_dbg_trap_deactivate(target, false, 0);
fput(target->dbg_ev_file);
target->dbg_ev_file = NULL;
if (target->debugger_process)
atomic_dec(&target->debugger_process->debugged_process_count);
target->debug_trap_enabled = false;
kfd_unref_process(target);
r = -EFAULT;
}
+2
View File
@@ -795,6 +795,8 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events)
struct kfd_event_waiter *event_waiters;
uint32_t i;
if (num_events > KFD_SIGNAL_EVENT_LIMIT)
return NULL;
event_waiters = kzalloc_objs(struct kfd_event_waiter, num_events);
if (!event_waiters)
return NULL;
+5 -3
View File
@@ -254,8 +254,10 @@ void kfd_smi_event_update_vmfault(struct kfd_node *dev, uint16_t pasid)
if (task_info) {
/* Report VM faults from user applications, not retry from kernel */
if (task_info->task.pid)
kfd_smi_event_add(0, dev, KFD_SMI_EVENT_VMFAULT, KFD_EVENT_FMT_VMFAULT(
task_info->task.pid, task_info->task.comm));
kfd_smi_event_add(task_info->tgid, dev,
KFD_SMI_EVENT_VMFAULT,
KFD_EVENT_FMT_VMFAULT(task_info->task.pid,
task_info->task.comm));
amdgpu_vm_put_task_info(task_info);
}
}
@@ -356,7 +358,7 @@ void kfd_smi_event_process(struct kfd_process_device *pdd, bool start)
task_info = amdgpu_vm_get_task_info_vm(avm);
if (task_info) {
kfd_smi_event_add(0, pdd->dev,
kfd_smi_event_add(task_info->tgid, pdd->dev,
start ? KFD_SMI_EVENT_PROCESS_START :
KFD_SMI_EVENT_PROCESS_END,
KFD_EVENT_FMT_PROCESS(task_info->task.pid,
@@ -10083,7 +10083,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
continue;
bundle->surface_updates[planes_count].surface = dc_plane;
if (new_pcrtc_state->color_mgmt_changed) {
if (new_pcrtc_state->color_mgmt_changed || new_plane_state->color_mgmt_changed) {
bundle->surface_updates[planes_count].gamma = &dc_plane->gamma_correction;
bundle->surface_updates[planes_count].in_transfer_func = &dc_plane->in_transfer_func;
bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix;
@@ -11824,6 +11824,10 @@ static bool should_reset_plane(struct drm_atomic_state *state,
if (new_crtc_state->color_mgmt_changed)
return true;
/* Plane color pipeline or its colorop changes. */
if (new_plane_state->color_mgmt_changed)
return true;
/*
* On zpos change, planes need to be reordered by removing and re-adding
* them one by one to the dc state, in order of descending zpos.
@@ -13446,17 +13450,15 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
}
/* Handle MCCS */
if (do_mccs)
if (do_mccs) {
dm_helpers_read_mccs_caps(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
if ((sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A ||
as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) &&
(!sink->edid_caps.freesync_vcp_code ||
(sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)))
freesync_capable = false;
if (sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)
freesync_capable = false;
if (do_mccs && sink->mccs_caps.freesync_supported && freesync_capable)
dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
if (sink->mccs_caps.freesync_supported && freesync_capable)
dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
}
update:
if (dm_con_state)
+2 -2
View File
@@ -830,7 +830,7 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p,
case DRM_COLOROP_1D_LUT:
drm_printf(p, "\tsize=%d\n", colorop->size);
drm_printf(p, "\tinterpolation=%s\n",
drm_get_colorop_lut1d_interpolation_name(colorop->lut1d_interpolation));
drm_get_colorop_lut1d_interpolation_name(state->lut1d_interpolation));
drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0);
break;
case DRM_COLOROP_CTM_3X4:
@@ -842,7 +842,7 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p,
case DRM_COLOROP_3D_LUT:
drm_printf(p, "\tsize=%d\n", colorop->size);
drm_printf(p, "\tinterpolation=%s\n",
drm_get_colorop_lut3d_interpolation_name(colorop->lut3d_interpolation));
drm_get_colorop_lut3d_interpolation_name(state->lut3d_interpolation));
drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0);
break;
default:
+53 -15
View File
@@ -265,13 +265,19 @@ EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
*
* Helper function to select the color pipeline on a plane by setting
* it to the first drm_colorop element of the pipeline.
*
* Return: true if plane color pipeline value changed, false otherwise.
*/
void
bool
drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
struct drm_colorop *colorop)
{
struct drm_plane *plane = plane_state->plane;
/* Color pipeline didn't change */
if (plane_state->color_pipeline == colorop)
return false;
if (colorop)
drm_dbg_atomic(plane->dev,
"Set [COLOROP:%d] for [PLANE:%d:%s] state %p\n",
@@ -283,6 +289,8 @@ drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
plane->base.id, plane->name, plane_state);
plane_state->color_pipeline = colorop;
return true;
}
EXPORT_SYMBOL(drm_atomic_set_colorop_for_plane);
@@ -604,7 +612,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
if (val && !colorop)
return -EACCES;
drm_atomic_set_colorop_for_plane(state, colorop);
state->color_mgmt_changed |= drm_atomic_set_colorop_for_plane(state, colorop);
} else if (property == config->prop_fb_damage_clips) {
ret = drm_property_replace_blob_from_id(dev,
&state->fb_damage_clips,
@@ -713,11 +721,11 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
static int drm_atomic_color_set_data_property(struct drm_colorop *colorop,
struct drm_colorop_state *state,
struct drm_property *property,
uint64_t val)
uint64_t val,
bool *replaced)
{
ssize_t elem_size = -1;
ssize_t size = -1;
bool replaced = false;
switch (colorop->type) {
case DRM_COLOROP_1D_LUT:
@@ -739,28 +747,45 @@ static int drm_atomic_color_set_data_property(struct drm_colorop *colorop,
&state->data,
val,
-1, size, elem_size,
&replaced);
replaced);
}
static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
struct drm_colorop_state *state,
struct drm_file *file_priv,
struct drm_property *property,
uint64_t val)
uint64_t val,
bool *replaced)
{
if (property == colorop->bypass_property) {
state->bypass = val;
if (state->bypass != val) {
state->bypass = val;
*replaced = true;
}
} else if (property == colorop->lut1d_interpolation_property) {
colorop->lut1d_interpolation = val;
if (state->lut1d_interpolation != val) {
state->lut1d_interpolation = val;
*replaced = true;
}
} else if (property == colorop->curve_1d_type_property) {
state->curve_1d_type = val;
if (state->curve_1d_type != val) {
state->curve_1d_type = val;
*replaced = true;
}
} else if (property == colorop->multiplier_property) {
state->multiplier = val;
if (state->multiplier != val) {
state->multiplier = val;
*replaced = true;
}
} else if (property == colorop->lut3d_interpolation_property) {
colorop->lut3d_interpolation = val;
if (state->lut3d_interpolation != val) {
state->lut3d_interpolation = val;
*replaced = true;
}
} else if (property == colorop->data_property) {
return drm_atomic_color_set_data_property(colorop, state,
property, val);
property, val,
replaced);
} else {
drm_dbg_atomic(colorop->dev,
"[COLOROP:%d:%d] unknown property [PROP:%d:%s]\n",
@@ -782,7 +807,7 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop,
else if (property == colorop->bypass_property)
*val = state->bypass;
else if (property == colorop->lut1d_interpolation_property)
*val = colorop->lut1d_interpolation;
*val = state->lut1d_interpolation;
else if (property == colorop->curve_1d_type_property)
*val = state->curve_1d_type;
else if (property == colorop->multiplier_property)
@@ -790,7 +815,7 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop,
else if (property == colorop->size_property)
*val = colorop->size;
else if (property == colorop->lut3d_interpolation_property)
*val = colorop->lut3d_interpolation;
*val = state->lut3d_interpolation;
else if (property == colorop->data_property)
*val = (state->data) ? state->data->base.id : 0;
else
@@ -1275,8 +1300,10 @@ int drm_atomic_set_property(struct drm_atomic_state *state,
break;
}
case DRM_MODE_OBJECT_COLOROP: {
struct drm_plane_state *plane_state;
struct drm_colorop *colorop = obj_to_colorop(obj);
struct drm_colorop_state *colorop_state;
bool replaced = false;
colorop_state = drm_atomic_get_colorop_state(state, colorop);
if (IS_ERR(colorop_state)) {
@@ -1285,7 +1312,18 @@ int drm_atomic_set_property(struct drm_atomic_state *state,
}
ret = drm_atomic_colorop_set_property(colorop, colorop_state,
file_priv, prop, prop_value);
file_priv, prop, prop_value,
&replaced);
if (ret || !replaced)
break;
plane_state = drm_atomic_get_plane_state(state, colorop->plane);
if (IS_ERR(plane_state)) {
ret = PTR_ERR(plane_state);
break;
}
plane_state->color_mgmt_changed |= replaced;
break;
}
default:
+14 -2
View File
@@ -342,7 +342,6 @@ int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_color
colorop->lut1d_interpolation_property = prop;
drm_object_attach_property(&colorop->base, prop, interpolation);
colorop->lut1d_interpolation = interpolation;
/* data */
ret = drm_colorop_create_data_prop(dev, colorop);
@@ -442,7 +441,6 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
colorop->lut3d_interpolation_property = prop;
drm_object_attach_property(&colorop->base, prop, interpolation);
colorop->lut3d_interpolation = interpolation;
/* data */
ret = drm_colorop_create_data_prop(dev, colorop);
@@ -521,6 +519,20 @@ static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
&val);
colorop_state->curve_1d_type = val;
}
if (colorop->lut1d_interpolation_property) {
if (!drm_object_property_get_default_value(&colorop->base,
colorop->lut1d_interpolation_property,
&val))
colorop_state->lut1d_interpolation = val;
}
if (colorop->lut3d_interpolation_property) {
if (!drm_object_property_get_default_value(&colorop->base,
colorop->lut3d_interpolation_property,
&val))
colorop_state->lut3d_interpolation = val;
}
}
/**
+9 -2
View File
@@ -4678,10 +4678,17 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
__le16 sink_rates[DP_MAX_SUPPORTED_RATES];
int ret;
int i;
drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
sink_rates, sizeof(sink_rates));
ret = drm_dp_dpcd_read_data(&intel_dp->aux,
DP_SUPPORTED_LINK_RATES,
sink_rates, sizeof(sink_rates));
if (ret < 0) {
drm_dbg_kms(display->drm,
"Unable to read eDP supported link rates, using default rates\n");
memset(sink_rates, 0, sizeof(sink_rates));
}
for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
int rate;
+15 -4
View File
@@ -18,6 +18,17 @@
#include "i915_gem_tiling.h"
#include "i915_scatterlist.h"
/* Abuse scatterlist to store pointer instead of struct page. */
static inline void __set_phys_vaddr(struct scatterlist *sg, void *vaddr)
{
sg_assign_page(sg, (struct page *)vaddr);
}
static inline void *__get_phys_vaddr(struct scatterlist *sg)
{
return (void *)sg_page(sg);
}
static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
{
struct address_space *mapping = obj->base.filp->f_mapping;
@@ -58,7 +69,7 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
sg->offset = 0;
sg->length = obj->base.size;
sg_assign_page(sg, (struct page *)vaddr);
__set_phys_vaddr(sg, vaddr);
sg_dma_address(sg) = dma;
sg_dma_len(sg) = obj->base.size;
@@ -99,7 +110,7 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
struct sg_table *pages)
{
dma_addr_t dma = sg_dma_address(pages->sgl);
void *vaddr = sg_page(pages->sgl);
void *vaddr = __get_phys_vaddr(pages->sgl);
__i915_gem_object_release_shmem(obj, pages, false);
@@ -139,7 +150,7 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
int i915_gem_object_pwrite_phys(struct drm_i915_gem_object *obj,
const struct drm_i915_gem_pwrite *args)
{
void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
void *vaddr = __get_phys_vaddr(obj->mm.pages->sgl) + args->offset;
char __user *user_data = u64_to_user_ptr(args->data_ptr);
struct drm_i915_private *i915 = to_i915(obj->base.dev);
int err;
@@ -170,7 +181,7 @@ int i915_gem_object_pwrite_phys(struct drm_i915_gem_object *obj,
int i915_gem_object_pread_phys(struct drm_i915_gem_object *obj,
const struct drm_i915_gem_pread *args)
{
void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
void *vaddr = __get_phys_vaddr(obj->mm.pages->sgl) + args->offset;
char __user *user_data = u64_to_user_ptr(args->data_ptr);
int err;
+7 -6
View File
@@ -290,15 +290,16 @@ static bool require_uniform_address_uniform(struct vc4_validated_shader_info *va
{
uint32_t o = validated_shader->num_uniform_addr_offsets;
uint32_t num_uniforms = validated_shader->uniforms_size / 4;
u32 *offsets;
validated_shader->uniform_addr_offsets =
krealloc(validated_shader->uniform_addr_offsets,
(o + 1) *
sizeof(*validated_shader->uniform_addr_offsets),
GFP_KERNEL);
if (!validated_shader->uniform_addr_offsets)
offsets = krealloc_array(validated_shader->uniform_addr_offsets,
o + 1,
sizeof(*validated_shader->uniform_addr_offsets),
GFP_KERNEL);
if (!offsets)
return false;
validated_shader->uniform_addr_offsets = offsets;
validated_shader->uniform_addr_offsets[o] = num_uniforms;
validated_shader->num_uniform_addr_offsets++;
+4 -1
View File
@@ -124,7 +124,10 @@ static void virtio_gpu_remove(struct virtio_device *vdev)
struct drm_device *dev = vdev->priv;
drm_dev_unplug(dev);
drm_atomic_helper_shutdown(dev);
if (drm_core_check_feature(dev, DRIVER_ATOMIC))
drm_atomic_helper_shutdown(dev);
virtio_gpu_deinit(dev);
drm_dev_put(dev);
}
+3 -1
View File
@@ -65,8 +65,10 @@ static int virtio_gpu_dma_fence_wait(struct virtio_gpu_submit *submit,
dma_fence_unwrap_for_each(f, &itr, fence) {
err = virtio_gpu_do_fence_wait(submit, f);
if (err)
if (err) {
dma_fence_put(itr.chain);
return err;
}
}
return 0;
+9 -2
View File
@@ -124,6 +124,15 @@ int xe_display_init_early(struct xe_device *xe)
intel_display_driver_early_probe(display);
intel_display_device_info_runtime_init(display);
/* Display may have been disabled at runtime init */
if (!intel_display_device_present(display)) {
xe->info.probe_display = false;
unset_display_features(xe);
return 0;
}
/* Early display init.. */
intel_opregion_setup(display);
@@ -137,8 +146,6 @@ int xe_display_init_early(struct xe_device *xe)
intel_bw_init_hw(display);
intel_display_device_info_runtime_init(display);
err = intel_display_driver_probe_noirq(display);
if (err)
goto err_opregion;
+24 -37
View File
@@ -52,7 +52,7 @@ static struct xe_drm_ras_counter *allocate_and_copy_counters(struct xe_device *x
struct xe_drm_ras_counter *counter;
int i;
counter = kcalloc(DRM_XE_RAS_ERR_COMP_MAX, sizeof(*counter), GFP_KERNEL);
counter = drmm_kcalloc(&xe->drm, DRM_XE_RAS_ERR_COMP_MAX, sizeof(*counter), GFP_KERNEL);
if (!counter)
return ERR_PTR(-ENOMEM);
@@ -100,54 +100,47 @@ static int assign_node_params(struct xe_device *xe, struct drm_ras_node *node,
return 0;
}
static void cleanup_node_param(struct xe_drm_ras *ras, const enum drm_xe_ras_error_severity severity)
static void cleanup_node_param(struct drm_ras_node *node)
{
struct drm_ras_node *node = &ras->node[severity];
kfree(ras->info[severity]);
ras->info[severity] = NULL;
kfree(node->device_name);
node->device_name = NULL;
}
static void cleanup_node(struct drm_device *drm, void *node)
{
drm_ras_node_unregister(node);
cleanup_node_param(node);
}
static int register_nodes(struct xe_device *xe)
{
struct xe_drm_ras *ras = &xe->ras;
int i;
struct drm_ras_node *node;
int i, ret;
for_each_error_severity(i) {
struct drm_ras_node *node = &ras->node[i];
int ret;
node = &ras->node[i];
ret = assign_node_params(xe, node, i);
if (ret) {
cleanup_node_param(ras, i);
return ret;
}
if (ret)
goto free_param;
ret = drm_ras_node_register(node);
if (ret) {
cleanup_node_param(ras, i);
return ret;
}
if (ret)
goto free_param;
ret = drmm_add_action_or_reset(&xe->drm, cleanup_node, node);
if (ret)
goto null_info;
}
return 0;
}
static void xe_drm_ras_unregister_nodes(struct drm_device *device, void *arg)
{
struct xe_device *xe = arg;
struct xe_drm_ras *ras = &xe->ras;
int i;
for_each_error_severity(i) {
struct drm_ras_node *node = &ras->node[i];
drm_ras_node_unregister(node);
cleanup_node_param(ras, i);
}
free_param:
cleanup_node_param(node);
null_info:
ras->info[i] = NULL;
return ret;
}
/**
@@ -176,11 +169,5 @@ int xe_drm_ras_init(struct xe_device *xe)
return err;
}
err = drmm_add_action_or_reset(&xe->drm, xe_drm_ras_unregister_nodes, xe);
if (err) {
drm_err(&xe->drm, "Failed to add action for Xe DRM RAS (%pe)\n", ERR_PTR(err));
return err;
}
return 0;
}
+35 -14
View File
@@ -157,6 +157,11 @@ static void set_exec_queue_banned(struct xe_exec_queue *q)
atomic_or(EXEC_QUEUE_STATE_BANNED, &q->guc->state);
}
static void clear_exec_queue_banned(struct xe_exec_queue *q)
{
atomic_andnot(EXEC_QUEUE_STATE_BANNED, &q->guc->state);
}
static bool exec_queue_suspended(struct xe_exec_queue *q)
{
return atomic_read(&q->guc->state) & EXEC_QUEUE_STATE_SUSPENDED;
@@ -1361,7 +1366,8 @@ static bool check_timeout(struct xe_exec_queue *q, struct xe_sched_job *job)
xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job),
q->guc->id);
return xe_sched_invalidate_job(job, 2);
/* GuC never scheduled this job - let the caller trigger a GT reset. */
return true;
}
ctx_timestamp = lower_32_bits(xe_lrc_timestamp(q->lrc[0]));
@@ -1458,6 +1464,21 @@ static void disable_scheduling(struct xe_exec_queue *q, bool immediate)
G2H_LEN_DW_SCHED_CONTEXT_MODE_SET, 1);
}
/*
* Recover via GT reset for a kernel queue, or for a GuC scheduling failure (job
* never started) on a queue that was not already killed or banned. An already
* banned queue must stay banned, so its unstarted jobs do not clear the ban or
* trigger a reset.
*/
static bool timeout_needs_gt_reset(struct xe_exec_queue *q, struct xe_sched_job *job,
bool skip_timeout_check)
{
if (q->flags & EXEC_QUEUE_FLAG_KERNEL)
return true;
return !skip_timeout_check && !xe_sched_job_started(job);
}
static enum drm_gpu_sched_stat
guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
{
@@ -1606,19 +1627,19 @@ trigger_reset:
xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job),
q->guc->id, q->flags);
/*
* Kernel jobs should never fail, nor should VM jobs if they do
* somethings has gone wrong and the GT needs a reset
*/
xe_gt_WARN(q->gt, q->flags & EXEC_QUEUE_FLAG_KERNEL,
"Kernel-submitted job timed out\n");
xe_gt_WARN(q->gt, q->flags & EXEC_QUEUE_FLAG_VM && !exec_queue_killed(q),
"VM job timed out on non-killed execqueue\n");
if (!wedged && (q->flags & EXEC_QUEUE_FLAG_KERNEL ||
(q->flags & EXEC_QUEUE_FLAG_VM && !exec_queue_killed(q)))) {
if (!xe_sched_invalidate_job(job, 2)) {
xe_gt_reset_async(q->gt);
goto rearm;
if (!wedged) {
if (timeout_needs_gt_reset(q, job, skip_timeout_check)) {
if (!xe_sched_invalidate_job(job, 2)) {
clear_exec_queue_banned(q);
xe_gt_reset_async(q->gt);
goto rearm;
}
if (q->flags & EXEC_QUEUE_FLAG_KERNEL) {
xe_gt_WARN(q->gt, true, "Kernel-submitted job timed out\n");
xe_device_declare_wedged(gt_to_xe(q->gt));
}
} else if (q->flags & EXEC_QUEUE_FLAG_VM && !exec_queue_killed(q)) {
xe_gt_WARN(q->gt, true, "VM job timed out on non-killed execqueue\n");
}
}
+3 -4
View File
@@ -255,9 +255,8 @@ static int send_tlb_inval_ctx_ppgtt(struct xe_tlb_inval *tlb_inval, u32 seqno,
#undef EXEC_QUEUE_COUNT_FULL_THRESHOLD
/*
* Move exec queues to a temporary list to issue invalidations. The exec
* queue must active and a reference must be taken to prevent concurrent
* deregistrations.
* Move exec queues to a temporary list to issue invalidations. A
* reference must be taken to prevent concurrent deregistrations.
*
* List modification is safe because we hold 'vm->exec_queues.lock' for
* reading, which prevents external modifications. Using a per-GT list
@@ -266,7 +265,7 @@ static int send_tlb_inval_ctx_ppgtt(struct xe_tlb_inval *tlb_inval, u32 seqno,
*/
list_for_each_entry_safe(q, next, &vm->exec_queues.list[id],
vm_exec_queue_link) {
if (q->ops->active(q) && xe_exec_queue_get_unless_zero(q)) {
if (xe_exec_queue_get_unless_zero(q)) {
last_q = q;
list_move_tail(&q->vm_exec_queue_link, &tlb_inval_list);
}
+6 -6
View File
@@ -219,9 +219,9 @@ static void log_hw_error(struct xe_tile *tile, const char *name,
struct xe_device *xe = tile_to_xe(tile);
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
drm_warn(&xe->drm, "%s %s detected\n", name, severity_str);
drm_warn(&xe->drm, HW_ERR "%s %s detected\n", name, severity_str);
else
drm_err_ratelimited(&xe->drm, "%s %s detected\n", name, severity_str);
drm_err_ratelimited(&xe->drm, HW_ERR "%s %s detected\n", name, severity_str);
}
static void log_gt_err(struct xe_tile *tile, const char *name, int i, u32 err,
@@ -231,10 +231,10 @@ static void log_gt_err(struct xe_tile *tile, const char *name, int i, u32 err,
struct xe_device *xe = tile_to_xe(tile);
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
drm_warn(&xe->drm, "%s %s detected, ERROR_STAT_GT_VECTOR%d:0x%08x\n",
drm_warn(&xe->drm, HW_ERR "%s %s detected, ERROR_STAT_GT_VECTOR%d:0x%08x\n",
name, severity_str, i, err);
else
drm_err_ratelimited(&xe->drm, "%s %s detected, ERROR_STAT_GT_VECTOR%d:0x%08x\n",
drm_err_ratelimited(&xe->drm, HW_ERR "%s %s detected, ERROR_STAT_GT_VECTOR%d:0x%08x\n",
name, severity_str, i, err);
}
@@ -251,9 +251,9 @@ static void log_soc_error(struct xe_tile *tile, const char * const *reg_info,
if (strcmp(name, "Undefined")) {
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
drm_warn(&xe->drm, "%s SOC %s detected", name, severity_str);
drm_warn(&xe->drm, HW_ERR "%s SOC %s detected", name, severity_str);
else
drm_err_ratelimited(&xe->drm, "%s SOC %s detected", name, severity_str);
drm_err_ratelimited(&xe->drm, HW_ERR "%s SOC %s detected", name, severity_str);
atomic_inc(&info[index].counter);
}
}
+2
View File
@@ -77,6 +77,8 @@ int xe_range_fence_insert(struct xe_range_fence_tree *tree,
} else if (err == 0) {
xe_range_fence_tree_insert(rfence, &tree->root);
return 0;
} else {
dma_fence_put(fence);
}
free:
+13 -6
View File
@@ -1922,12 +1922,18 @@ static int iommu_dma_iova_link_swiotlb(struct device *dev,
return 0;
}
/*
* After removing the partial head and tail, there may be no aligned
* middle left to map. The tail still gets bounced below.
*/
size -= iova_end_pad;
error = __dma_iova_link(dev, addr + mapped, phys + mapped, size, dir,
attrs);
if (error)
goto out_unmap;
mapped += size;
if (size) {
error = __dma_iova_link(dev, addr + mapped, phys + mapped,
size, dir, attrs);
if (error)
goto out_unmap;
mapped += size;
}
if (iova_end_pad) {
error = iommu_dma_iova_bounce_and_link(dev, addr + mapped,
@@ -1940,7 +1946,8 @@ static int iommu_dma_iova_link_swiotlb(struct device *dev,
return 0;
out_unmap:
dma_iova_unlink(dev, state, 0, mapped, dir, attrs);
if (mapped)
dma_iova_unlink(dev, state, offset, mapped, dir, attrs);
return error;
}
+68 -39
View File
@@ -310,6 +310,8 @@ struct fastrpc_user {
spinlock_t lock;
/* lock for allocations */
struct mutex mutex;
/* Reference count */
struct kref refcount;
};
/* Extract SMMU PA from consolidated IOVA */
@@ -386,7 +388,7 @@ static int fastrpc_map_get(struct fastrpc_map *map)
static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
struct fastrpc_map **ppmap)
struct fastrpc_map **ppmap, bool take_ref)
{
struct fastrpc_map *map = NULL;
struct dma_buf *buf;
@@ -401,6 +403,12 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
if (map->fd != fd || map->buf != buf)
continue;
if (take_ref) {
ret = fastrpc_map_get(map);
if (ret)
break;
}
*ppmap = map;
ret = 0;
break;
@@ -497,15 +505,57 @@ static void fastrpc_channel_ctx_put(struct fastrpc_channel_ctx *cctx)
kref_put(&cctx->refcount, fastrpc_channel_ctx_free);
}
static void fastrpc_context_put(struct fastrpc_invoke_ctx *ctx);
static void fastrpc_user_free(struct kref *ref)
{
struct fastrpc_user *fl = container_of(ref, struct fastrpc_user, refcount);
struct fastrpc_invoke_ctx *ctx, *n;
struct fastrpc_map *map, *m;
struct fastrpc_buf *buf, *b;
if (fl->init_mem)
fastrpc_buf_free(fl->init_mem);
list_for_each_entry_safe(ctx, n, &fl->pending, node) {
list_del(&ctx->node);
fastrpc_context_put(ctx);
}
list_for_each_entry_safe(map, m, &fl->maps, node)
fastrpc_map_put(map);
list_for_each_entry_safe(buf, b, &fl->mmaps, node) {
list_del(&buf->node);
fastrpc_buf_free(buf);
}
fastrpc_channel_ctx_put(fl->cctx);
mutex_destroy(&fl->mutex);
kfree(fl);
}
static void fastrpc_user_get(struct fastrpc_user *fl)
{
kref_get(&fl->refcount);
}
static void fastrpc_user_put(struct fastrpc_user *fl)
{
kref_put(&fl->refcount, fastrpc_user_free);
}
static void fastrpc_context_free(struct kref *ref)
{
struct fastrpc_invoke_ctx *ctx;
struct fastrpc_channel_ctx *cctx;
struct fastrpc_user *fl;
unsigned long flags;
int i;
ctx = container_of(ref, struct fastrpc_invoke_ctx, refcount);
cctx = ctx->cctx;
fl = ctx->fl;
for (i = 0; i < ctx->nbufs; i++)
fastrpc_map_put(ctx->maps[i]);
@@ -521,6 +571,8 @@ static void fastrpc_context_free(struct kref *ref)
kfree(ctx->olaps);
kfree(ctx);
/* Release the reference taken in fastrpc_context_alloc() */
fastrpc_user_put(fl);
fastrpc_channel_ctx_put(cctx);
}
@@ -628,6 +680,8 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
/* Released in fastrpc_context_put() */
fastrpc_channel_ctx_get(cctx);
/* Take a reference to user, released in fastrpc_context_free() */
fastrpc_user_get(user);
ctx->sc = sc;
ctx->retval = -1;
@@ -658,6 +712,7 @@ err_idr:
spin_lock(&user->lock);
list_del(&ctx->node);
spin_unlock(&user->lock);
fastrpc_user_put(user);
fastrpc_channel_ctx_put(cctx);
kfree(ctx->maps);
kfree(ctx->olaps);
@@ -871,19 +926,10 @@ get_err:
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
u64 len, u32 attr, struct fastrpc_map **ppmap)
{
struct fastrpc_session_ctx *sess = fl->sctx;
int err = 0;
if (!fastrpc_map_lookup(fl, fd, ppmap, true))
return 0;
if (!fastrpc_map_lookup(fl, fd, ppmap)) {
if (!fastrpc_map_get(*ppmap))
return 0;
dev_dbg(sess->dev, "%s: Failed to get map fd=%d\n",
__func__, fd);
}
err = fastrpc_map_attach(fl, fd, len, attr, ppmap);
return err;
return fastrpc_map_attach(fl, fd, len, attr, ppmap);
}
/*
@@ -1041,7 +1087,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx)
pages[i].addr = ctx->maps[i]->dma_addr;
mmap_read_lock(current->mm);
vma = find_vma(current->mm, ctx->args[i].ptr);
vma = vma_lookup(current->mm, ctx->args[i].ptr);
if (vma)
pages[i].addr += (ctx->args[i].ptr & PAGE_MASK) -
vma->vm_start;
@@ -1153,7 +1199,7 @@ cleanup_fdlist:
for (i = 0; i < FASTRPC_MAX_FDLIST; i++) {
if (!fdlist[i])
break;
if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap))
if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false))
fastrpc_map_put(mmap);
}
@@ -1579,9 +1625,6 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
{
struct fastrpc_user *fl = (struct fastrpc_user *)file->private_data;
struct fastrpc_channel_ctx *cctx = fl->cctx;
struct fastrpc_invoke_ctx *ctx, *n;
struct fastrpc_map *map, *m;
struct fastrpc_buf *buf, *b;
unsigned long flags;
fastrpc_release_current_dsp_process(fl);
@@ -1590,28 +1633,10 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
list_del(&fl->user);
spin_unlock_irqrestore(&cctx->lock, flags);
if (fl->init_mem)
fastrpc_buf_free(fl->init_mem);
list_for_each_entry_safe(ctx, n, &fl->pending, node) {
list_del(&ctx->node);
fastrpc_context_put(ctx);
}
list_for_each_entry_safe(map, m, &fl->maps, node)
fastrpc_map_put(map);
list_for_each_entry_safe(buf, b, &fl->mmaps, node) {
list_del(&buf->node);
fastrpc_buf_free(buf);
}
fastrpc_session_free(cctx, fl->sctx);
fastrpc_channel_ctx_put(cctx);
mutex_destroy(&fl->mutex);
kfree(fl);
file->private_data = NULL;
/* Release the reference taken in fastrpc_device_open */
fastrpc_user_put(fl);
return 0;
}
@@ -1655,6 +1680,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
spin_lock_irqsave(&cctx->lock, flags);
list_add_tail(&fl->user, &cctx->users);
spin_unlock_irqrestore(&cctx->lock, flags);
kref_init(&fl->refcount);
return 0;
}
@@ -2431,7 +2457,6 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
kref_init(&data->refcount);
dev_set_drvdata(&rpdev->dev, data);
rdev->dma_mask = &data->dma_mask;
dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32));
INIT_LIST_HEAD(&data->users);
@@ -2440,6 +2465,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
idr_init(&data->ctx_idr);
data->domain_id = domain_id;
data->rpdev = rpdev;
dev_set_drvdata(&rpdev->dev, data);
err = of_platform_populate(rdev->of_node, NULL, NULL, rdev);
if (err)
@@ -2513,6 +2539,9 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
if (len < sizeof(*rsp))
return -EINVAL;
if (!cctx)
return -ENODEV;
ctxid = ((rsp->ctx & FASTRPC_CTXID_MASK) >> 4);
spin_lock_irqsave(&cctx->lock, flags);
+5 -7
View File
@@ -1468,18 +1468,16 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np);
of_node_put(cell_np);
if (!cell_entry) {
__nvmem_device_put(nvmem);
nvmem_layout_module_put(nvmem);
if (nvmem->layout)
return ERR_PTR(-EPROBE_DEFER);
else
return ERR_PTR(-ENOENT);
ret = nvmem->layout ? -EPROBE_DEFER : -ENOENT;
__nvmem_device_put(nvmem);
return ERR_PTR(ret);
}
cell = nvmem_create_cell(cell_entry, id, cell_index);
if (IS_ERR(cell)) {
__nvmem_device_put(nvmem);
nvmem_layout_module_put(nvmem);
__nvmem_device_put(nvmem);
}
return cell;
@@ -1593,8 +1591,8 @@ void nvmem_cell_put(struct nvmem_cell *cell)
kfree_const(cell->id);
kfree(cell);
__nvmem_device_put(nvmem);
nvmem_layout_module_put(nvmem);
__nvmem_device_put(nvmem);
}
EXPORT_SYMBOL_GPL(nvmem_cell_put);
+2 -1
View File
@@ -119,7 +119,7 @@ static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem,
cell.name = onie_tlv_cell_name(tlv.type);
if (!cell.name)
continue;
goto next;
cell.offset = hdr_len + offset + sizeof(tlv.type) + sizeof(tlv.len);
cell.bytes = tlv.len;
@@ -132,6 +132,7 @@ static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem,
return ret;
}
next:
offset += sizeof(tlv) + tlv.len;
}
+77 -45
View File
@@ -1471,15 +1471,12 @@ static int qcom_slim_ngd_ssr_pdr_notify(struct qcom_slim_ngd_ctrl *ctrl,
switch (action) {
case QCOM_SSR_BEFORE_SHUTDOWN:
case SERVREG_SERVICE_STATE_DOWN:
/* Make sure the last dma xfer is finished */
mutex_lock(&ctrl->tx_lock);
if (ctrl->state != QCOM_SLIM_NGD_CTRL_DOWN) {
pm_runtime_get_noresume(ctrl->ctrl.dev);
ctrl->state = QCOM_SLIM_NGD_CTRL_DOWN;
qcom_slim_ngd_down(ctrl);
qcom_slim_ngd_exit_dma(ctrl);
}
mutex_unlock(&ctrl->tx_lock);
break;
case QCOM_SSR_AFTER_POWERUP:
case SERVREG_SERVICE_STATE_UP:
@@ -1542,7 +1539,7 @@ static int of_qcom_slim_ngd_register(struct device *parent,
kfree(ngd);
return ret;
}
ngd->pdev->dev.of_node = node;
ngd->pdev->dev.of_node = of_node_get(node);
ctrl->ngd = ngd;
ret = platform_device_add(ngd->pdev);
@@ -1560,6 +1557,13 @@ static int of_qcom_slim_ngd_register(struct device *parent,
return -ENODEV;
}
static void qcom_slim_ngd_unregister(struct qcom_slim_ngd_ctrl *ctrl)
{
struct qcom_slim_ngd *ngd = ctrl->ngd;
platform_device_del(ngd->pdev);
}
static int qcom_slim_ngd_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1577,24 +1581,10 @@ static int qcom_slim_ngd_probe(struct platform_device *pdev)
ret = qcom_slim_ngd_qmi_svc_event_init(ctrl);
if (ret) {
dev_err(&pdev->dev, "QMI service registration failed:%d", ret);
return ret;
pm_runtime_dont_use_autosuspend(dev);
pm_runtime_disable(dev);
}
INIT_WORK(&ctrl->m_work, qcom_slim_ngd_master_worker);
INIT_WORK(&ctrl->ngd_up_work, qcom_slim_ngd_up_worker);
ctrl->mwq = create_singlethread_workqueue("ngd_master");
if (!ctrl->mwq) {
dev_err(&pdev->dev, "Failed to start master worker\n");
ret = -ENOMEM;
goto wq_err;
}
return 0;
wq_err:
qcom_slim_ngd_qmi_svc_event_deinit(&ctrl->qmi);
if (ctrl->mwq)
destroy_workqueue(ctrl->mwq);
return ret;
}
@@ -1602,6 +1592,7 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct qcom_slim_ngd_ctrl *ctrl;
int irq;
int ret;
struct pdr_service *pds;
@@ -1615,20 +1606,16 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)
if (IS_ERR(ctrl->base))
return PTR_ERR(ctrl->base);
ret = platform_get_irq(pdev, 0);
if (ret < 0)
return ret;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
ret = devm_request_irq(dev, ret, qcom_slim_ngd_interrupt,
IRQF_TRIGGER_HIGH, "slim-ngd", ctrl);
ret = devm_request_irq(dev, irq, qcom_slim_ngd_interrupt,
IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN,
"slim-ngd", ctrl);
if (ret)
return dev_err_probe(&pdev->dev, ret, "request IRQ failed\n");
ctrl->nb.notifier_call = qcom_slim_ngd_ssr_notify;
ctrl->notifier = qcom_register_ssr_notifier("lpass", &ctrl->nb);
if (IS_ERR(ctrl->notifier))
return PTR_ERR(ctrl->notifier);
ctrl->dev = dev;
ctrl->framer.rootfreq = SLIM_ROOT_FREQ >> 3;
ctrl->framer.superfreq =
@@ -1649,48 +1636,71 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)
init_completion(&ctrl->qmi.qmi_comp);
init_completion(&ctrl->qmi_up);
INIT_WORK(&ctrl->m_work, qcom_slim_ngd_master_worker);
INIT_WORK(&ctrl->ngd_up_work, qcom_slim_ngd_up_worker);
ctrl->mwq = create_singlethread_workqueue("ngd_master");
if (!ctrl->mwq)
return dev_err_probe(dev, -ENOMEM, "Failed to start master worker\n");
ctrl->pdr = pdr_handle_alloc(slim_pd_status, ctrl);
if (IS_ERR(ctrl->pdr)) {
ret = dev_err_probe(dev, PTR_ERR(ctrl->pdr),
"Failed to init PDR handle\n");
goto err_pdr_alloc;
ret = dev_err_probe(dev, PTR_ERR(ctrl->pdr), "Failed to init PDR handle\n");
goto err_destroy_mwq;
}
ret = of_qcom_slim_ngd_register(dev, ctrl);
if (ret)
goto err_pdr_release;
pds = pdr_add_lookup(ctrl->pdr, "avs/audio", "msm/adsp/audio_pd");
if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) {
ret = dev_err_probe(dev, PTR_ERR(pds), "pdr add lookup failed\n");
goto err_pdr_lookup;
goto err_unregister_ngd;
}
platform_driver_register(&qcom_slim_ngd_driver);
return of_qcom_slim_ngd_register(dev, ctrl);
ctrl->nb.notifier_call = qcom_slim_ngd_ssr_notify;
ctrl->notifier = qcom_register_ssr_notifier("lpass", &ctrl->nb);
if (IS_ERR(ctrl->notifier)) {
ret = PTR_ERR(ctrl->notifier);
goto err_unregister_ngd;
}
err_pdr_alloc:
qcom_unregister_ssr_notifier(ctrl->notifier, &ctrl->nb);
enable_irq(irq);
err_pdr_lookup:
return 0;
err_unregister_ngd:
qcom_slim_ngd_unregister(ctrl);
err_pdr_release:
pdr_handle_release(ctrl->pdr);
err_destroy_mwq:
destroy_workqueue(ctrl->mwq);
return ret;
}
static void qcom_slim_ngd_ctrl_remove(struct platform_device *pdev)
{
platform_driver_unregister(&qcom_slim_ngd_driver);
struct qcom_slim_ngd_ctrl *ctrl = platform_get_drvdata(pdev);
pdr_handle_release(ctrl->pdr);
qcom_unregister_ssr_notifier(ctrl->notifier, &ctrl->nb);
qcom_slim_ngd_unregister(ctrl);
destroy_workqueue(ctrl->mwq);
}
static void qcom_slim_ngd_remove(struct platform_device *pdev)
{
struct qcom_slim_ngd_ctrl *ctrl = platform_get_drvdata(pdev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pdr_handle_release(ctrl->pdr);
qcom_unregister_ssr_notifier(ctrl->notifier, &ctrl->nb);
qcom_slim_ngd_enable(ctrl, false);
qcom_slim_ngd_exit_dma(ctrl);
qcom_slim_ngd_qmi_svc_event_deinit(&ctrl->qmi);
if (ctrl->mwq)
destroy_workqueue(ctrl->mwq);
kfree(ctrl->ngd);
ctrl->ngd = NULL;
@@ -1752,6 +1762,28 @@ static struct platform_driver qcom_slim_ngd_driver = {
},
};
module_platform_driver(qcom_slim_ngd_ctrl_driver);
static int qcom_slim_ngd_init(void)
{
int ret;
ret = platform_driver_register(&qcom_slim_ngd_driver);
if (ret)
return ret;
ret = platform_driver_register(&qcom_slim_ngd_ctrl_driver);
if (ret)
platform_driver_unregister(&qcom_slim_ngd_driver);
return ret;
}
static void qcom_slim_ngd_exit(void)
{
platform_driver_unregister(&qcom_slim_ngd_ctrl_driver);
platform_driver_unregister(&qcom_slim_ngd_driver);
}
module_init(qcom_slim_ngd_init);
module_exit(qcom_slim_ngd_exit);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Qualcomm SLIMBus NGD controller");
+4 -2
View File
@@ -158,8 +158,8 @@ no_flash:
of_data = (struct mpfs_syscon_config *) device_get_match_data(dev);
if (!of_data) {
dev_err(dev, "Error getting match data\n");
return -EINVAL;
ret = dev_err_probe(dev, -EINVAL, "Error getting match data\n");
goto out_free_channel;
}
for (i = 0; i < of_data->nb_subdevs; i++) {
@@ -173,6 +173,8 @@ no_flash:
return 0;
out_free_channel:
mbox_free_channel(sys_controller->chan);
out_free:
kfree(sys_controller);
return ret;
+2
View File
@@ -472,7 +472,9 @@ static inline void dw_spi_abort(struct spi_controller *ctlr)
if (dws->dma_mapped)
dws->dma_ops->dma_stop(dws);
disable_irq(dws->irq);
dw_spi_reset_chip(dws);
enable_irq(dws->irq);
}
static void dw_spi_handle_err(struct spi_controller *ctlr,
+19 -8
View File
@@ -440,10 +440,15 @@ static int setup_gsi_xfer(struct spi_transfer *xfer, struct spi_geni_master *mas
return ret;
}
if (!xfer->cs_change) {
if (!list_is_last(&xfer->transfer_list, &spi->cur_msg->transfers))
peripheral.fragmentation = FRAGMENTATION;
}
/*
* Set fragmentation to keep CS asserted after this transfer when:
* - non-last transfer with cs_change=0: keep CS asserted between chained transfers
* - last transfer with cs_change=1: keep CS asserted after the message
* (e.g. TPM TIS SPI uses cs_change=1 on single-transfer messages to
* keep CS asserted across header, wait-state and data phases)
*/
peripheral.fragmentation = list_is_last(&xfer->transfer_list, &spi->cur_msg->transfers) ?
xfer->cs_change : !xfer->cs_change;
if (peripheral.cmd & SPI_RX) {
dmaengine_slave_config(mas->rx, &config);
@@ -849,10 +854,16 @@ static int setup_se_xfer(struct spi_transfer *xfer,
mas->cur_xfer_mode = GENI_SE_DMA;
geni_se_select_mode(se, mas->cur_xfer_mode);
if (!xfer->cs_change) {
if (!list_is_last(&xfer->transfer_list, &spi->cur_msg->transfers))
m_params = FRAGMENTATION;
}
/*
* Set FRAGMENTATION to keep CS asserted after this transfer when:
* - non-last transfer with cs_change=0: keep CS asserted between chained transfers
* - last transfer with cs_change=1: keep CS asserted after the message
* (e.g. TPM TIS SPI uses cs_change=1 on single-transfer messages to
* keep CS asserted across header, wait-state and data phases)
*/
if (list_is_last(&xfer->transfer_list, &spi->cur_msg->transfers) ?
xfer->cs_change : !xfer->cs_change)
m_params = FRAGMENTATION;
/*
* Lock around right before we start the transfer since our
+2 -1
View File
@@ -135,8 +135,9 @@ static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi, \
RZV2H_RSPI_TX(writel, u32)
RZV2H_RSPI_TX(writew, u16)
RZV2H_RSPI_TX(writeb, u8)
/* The read access size for RSPI_SPDR is fixed at 32 bits */
RZV2H_RSPI_RX(readl, u32)
RZV2H_RSPI_RX(readw, u16)
RZV2H_RSPI_RX(readl, u16)
RZV2H_RSPI_RX(readl, u8)
static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,
+18 -6
View File
@@ -464,8 +464,11 @@ static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex
if (check_fwstate(pmlmepriv, _FW_LINKED) && (is_same_network(&pmlmepriv->cur_network.network, pnetwork, 0))) {
update_network(&pmlmepriv->cur_network.network, pnetwork, adapter, true);
if (pmlmepriv->cur_network.network.ie_length < sizeof(struct ndis_802_11_fix_ie))
return;
rtw_update_protection(adapter, (pmlmepriv->cur_network.network.ies) + sizeof(struct ndis_802_11_fix_ie),
pmlmepriv->cur_network.network.ie_length);
pmlmepriv->cur_network.network.ie_length - sizeof(struct ndis_802_11_fix_ie));
}
}
@@ -601,6 +604,8 @@ static bool rtw_is_desired_network(struct adapter *adapter, struct wlan_network
privacy = pnetwork->network.privacy;
if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
if (pnetwork->network.ie_length < _FIXED_IE_LENGTH_)
return false;
if (rtw_get_wps_ie(pnetwork->network.ies + _FIXED_IE_LENGTH_, pnetwork->network.ie_length - _FIXED_IE_LENGTH_, NULL, &wps_ielen))
return true;
else
@@ -614,11 +619,15 @@ static bool rtw_is_desired_network(struct adapter *adapter, struct wlan_network
bselected = false;
if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
p = rtw_get_ie(pnetwork->network.ies + _BEACON_IE_OFFSET_, WLAN_EID_RSN, &ie_len, (pnetwork->network.ie_length - _BEACON_IE_OFFSET_));
if (p && ie_len > 0)
bselected = true;
else
if (pnetwork->network.ie_length < _BEACON_IE_OFFSET_) {
bselected = false;
} else {
p = rtw_get_ie(pnetwork->network.ies + _BEACON_IE_OFFSET_, WLAN_EID_RSN, &ie_len, (pnetwork->network.ie_length - _BEACON_IE_OFFSET_));
if (p && ie_len > 0)
bselected = true;
else
bselected = false;
}
}
}
@@ -1072,8 +1081,11 @@ static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_net
break;
}
if (cur_network->network.ie_length < sizeof(struct ndis_802_11_fix_ie))
return;
rtw_update_protection(padapter, (cur_network->network.ies) + sizeof(struct ndis_802_11_fix_ie),
(cur_network->network.ie_length));
(cur_network->network.ie_length - sizeof(struct ndis_802_11_fix_ie)));
rtw_update_ht_cap(padapter, cur_network->network.ies, cur_network->network.ie_length, (u8) cur_network->network.configuration.ds_config);
}
+6
View File
@@ -60,6 +60,8 @@ static bool tb_property_entry_valid(const struct tb_property_entry *entry,
case TB_PROPERTY_TYPE_DIRECTORY:
case TB_PROPERTY_TYPE_DATA:
case TB_PROPERTY_TYPE_TEXT:
if (!entry->length)
return false;
if (entry->length > block_len)
return false;
if (check_add_overflow(entry->value, entry->length, &end) ||
@@ -185,6 +187,10 @@ static struct tb_property_dir *__tb_property_parse_dir(const u32 *block,
if (is_root) {
content_offset = dir_offset + 2;
content_len = dir_len;
if (content_offset + content_len > block_len) {
tb_property_free_dir(dir);
return NULL;
}
} else {
if (dir_len < 4) {
tb_property_free_dir(dir);
+11 -3
View File
@@ -55,6 +55,7 @@ static const char * const state_names[] = {
struct xdomain_request_work {
struct work_struct work;
struct tb_xdp_header *pkg;
size_t pkg_len;
struct tb *tb;
};
@@ -122,7 +123,9 @@ static bool tb_xdomain_match(const struct tb_cfg_request *req,
static bool tb_xdomain_copy(struct tb_cfg_request *req,
const struct ctl_pkg *pkg)
{
memcpy(req->response, pkg->buffer, req->response_size);
size_t len = min_t(size_t, pkg->frame.size, req->response_size);
memcpy(req->response, pkg->buffer, len);
req->result.err = 0;
return true;
}
@@ -393,6 +396,8 @@ static int tb_xdp_properties_request(struct tb_ctl *ctl, u64 route,
}
}
if (req.offset + len > data_len)
len = data_len - req.offset;
memcpy(data + req.offset, res->data, len * 4);
req.offset += len;
} while (!data_len || req.offset < data_len);
@@ -731,6 +736,7 @@ static void tb_xdp_handle_request(struct work_struct *work)
struct xdomain_request_work *xw = container_of(work, typeof(*xw), work);
const struct tb_xdp_header *pkg = xw->pkg;
const struct tb_xdomain_header *xhdr = &pkg->xd_hdr;
size_t pkg_len = xw->pkg_len;
struct tb *tb = xw->tb;
struct tb_ctl *ctl = tb->ctl;
struct tb_xdomain *xd;
@@ -762,7 +768,7 @@ static void tb_xdp_handle_request(struct work_struct *work)
switch (pkg->type) {
case PROPERTIES_REQUEST:
tb_dbg(tb, "%llx: received XDomain properties request\n", route);
if (xd) {
if (xd && pkg_len >= sizeof(struct tb_xdp_properties)) {
ret = tb_xdp_properties_response(tb, ctl, xd, sequence,
(const struct tb_xdp_properties *)pkg);
}
@@ -816,7 +822,8 @@ static void tb_xdp_handle_request(struct work_struct *work)
tb_dbg(tb, "%llx: received XDomain link state change request\n",
route);
if (xd && xd->state == XDOMAIN_STATE_BONDING_UUID_HIGH) {
if (xd && xd->state == XDOMAIN_STATE_BONDING_UUID_HIGH &&
pkg_len >= sizeof(struct tb_xdp_link_state_change)) {
const struct tb_xdp_link_state_change *lsc =
(const struct tb_xdp_link_state_change *)pkg;
@@ -868,6 +875,7 @@ tb_xdp_schedule_request(struct tb *tb, const struct tb_xdp_header *hdr,
kfree(xw);
return false;
}
xw->pkg_len = size;
xw->tb = tb_domain_get(tb);
schedule_work(&xw->work);
+11
View File
@@ -773,6 +773,12 @@ static int get_manuf_info(struct edgeport_serial *serial, u8 *buffer)
}
/* Read the descriptor data */
if (le16_to_cpu(rom_desc->Size) != sizeof(struct edge_ti_manuf_descriptor)) {
dev_err(dev, "unexpected Edge descriptor length: %u\n",
le16_to_cpu(rom_desc->Size));
status = -EINVAL;
goto exit;
}
status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc),
le16_to_cpu(rom_desc->Size), buffer);
if (status)
@@ -838,6 +844,11 @@ static int build_i2c_fw_hdr(u8 *header, const struct firmware *fw)
/* Pointer to fw_down memory image */
img_header = (struct ti_i2c_image_header *)&fw->data[4];
if (le16_to_cpu(img_header->Length) >
buffer_size - sizeof(struct ti_i2c_firmware_rec)) {
kfree(buffer);
return -EINVAL;
}
memcpy(buffer + sizeof(struct ti_i2c_firmware_rec),
&fw->data[4 + sizeof(struct ti_i2c_image_header)],
le16_to_cpu(img_header->Length));
+2 -2
View File
@@ -330,8 +330,8 @@ static int klsi_105_prepare_write_buffer(struct usb_serial_port *port,
unsigned char *buf = dest;
int count;
count = kfifo_out_locked(&port->write_fifo, buf + KLSI_HDR_LEN, size,
&port->lock);
count = kfifo_out_locked(&port->write_fifo, buf + KLSI_HDR_LEN,
size - KLSI_HDR_LEN, &port->lock);
put_unaligned_le16(count, buf);
return count + KLSI_HDR_LEN;
+3
View File
@@ -202,6 +202,7 @@ static void option_instat_callback(struct urb *urb);
#define DELL_PRODUCT_5821E_ESIM 0x81e0
#define DELL_PRODUCT_5829E_ESIM 0x81e4
#define DELL_PRODUCT_5829E 0x81e6
#define DELL_PRODUCT_5826E_ESIM 0x81ea
#define DELL_PRODUCT_FM101R_ESIM 0x8213
#define DELL_PRODUCT_FM101R 0x8215
@@ -1123,6 +1124,8 @@ static const struct usb_device_id option_ids[] = {
.driver_info = RSVD(0) | RSVD(6) },
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM),
.driver_info = RSVD(0) | RSVD(6) },
{ USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_5826E_ESIM, 0xff),
.driver_info = RSVD(1) | RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R, 0xff) },
{ USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R_ESIM, 0xff) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */
+3 -1
View File
@@ -29,6 +29,8 @@
#ifndef DRM_ATOMIC_UAPI_H_
#define DRM_ATOMIC_UAPI_H_
#include <linux/types.h>
struct drm_crtc_state;
struct drm_display_mode;
struct drm_property_blob;
@@ -50,7 +52,7 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
struct drm_crtc *crtc);
void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
struct drm_framebuffer *fb);
void drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
bool drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
struct drm_colorop *colorop);
int __must_check
drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
+16 -18
View File
@@ -183,6 +183,20 @@ struct drm_colorop_state {
*/
struct drm_property_blob *data;
/**
* @lut1d_interpolation:
*
* Interpolation for DRM_COLOROP_1D_LUT
*/
enum drm_colorop_lut1d_interpolation_type lut1d_interpolation;
/**
* @lut3d_interpolation:
*
* Interpolation for DRM_COLOROP_3D_LUT
*/
enum drm_colorop_lut3d_interpolation_type lut3d_interpolation;
/** @state: backpointer to global drm_atomic_state */
struct drm_atomic_state *state;
};
@@ -306,26 +320,10 @@ struct drm_colorop {
*/
uint32_t size;
/**
* @lut1d_interpolation:
*
* Read-only
* Interpolation for DRM_COLOROP_1D_LUT
*/
enum drm_colorop_lut1d_interpolation_type lut1d_interpolation;
/**
* @lut3d_interpolation:
*
* Read-only
* Interpolation for DRM_COLOROP_3D_LUT
*/
enum drm_colorop_lut3d_interpolation_type lut3d_interpolation;
/**
* @lut1d_interpolation_property:
*
* Read-only property for DRM_COLOROP_1D_LUT interpolation
* Property for DRM_COLOROP_1D_LUT interpolation
*/
struct drm_property *lut1d_interpolation_property;
@@ -353,7 +351,7 @@ struct drm_colorop {
/**
* @lut3d_interpolation_property:
*
* Read-only property for DRM_COLOROP_3D_LUT interpolation
* Property for DRM_COLOROP_3D_LUT interpolation
*/
struct drm_property *lut3d_interpolation_property;
-1
View File
@@ -305,7 +305,6 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg,
arg->partial_map = 1;
if (iov != arg->iovs)
break;
WRITE_ONCE(buf->len, len);
}
}
+1 -1
View File
@@ -103,7 +103,7 @@ static enum hrtimer_restart io_cqring_min_timer_wakeup(struct hrtimer *timer)
}
/* any generated CQE posted past this time should wake us up */
iowq->cq_tail = iowq->cq_min_tail;
iowq->cq_tail = iowq->cq_min_tail + 1;
hrtimer_update_function(&iowq->t, io_cqring_timer_wakeup);
hrtimer_set_expires(timer, iowq->timeout);
+1 -1
View File
@@ -1557,7 +1557,7 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
struct dma_debug_entry ref = {
.type = dma_debug_sg,
.dev = dev,
.paddr = sg_phys(sg),
.paddr = sg_phys(s),
.dev_addr = sg_dma_address(s),
.size = sg_dma_len(s),
.direction = direction,
+1 -1
View File
@@ -478,7 +478,7 @@ int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
* must be mapped with CPU physical address and not PCI
* bus addresses.
*/
break;
fallthrough;
case PCI_P2PDMA_MAP_NONE:
need_sync = true;
sg->dma_address = dma_direct_map_phys(dev, sg_phys(sg),
+10 -7
View File
@@ -430,6 +430,8 @@ static void snd_timer_close_locked(struct snd_timer_instance *timeri,
if (timer) {
guard(spinlock_irq)(&timer->lock);
if (timeri->flags & SNDRV_TIMER_IFLG_DEAD)
return; /* already closed */
timeri->flags |= SNDRV_TIMER_IFLG_DEAD;
}
@@ -975,18 +977,18 @@ EXPORT_SYMBOL(snd_timer_new);
static int snd_timer_free(struct snd_timer *timer)
{
struct snd_timer_instance *ti, *n;
if (!timer)
return 0;
guard(mutex)(&register_mutex);
if (! list_empty(&timer->open_list_head)) {
struct list_head *p, *n;
struct snd_timer_instance *ti;
pr_warn("ALSA: timer %p is busy?\n", timer);
list_for_each_safe(p, n, &timer->open_list_head) {
list_del_init(p);
ti = list_entry(p, struct snd_timer_instance, open_list);
ti->timer = NULL;
list_for_each_entry_safe(ti, n, &timer->open_list_head, open_list) {
struct device *card_dev_to_put = NULL;
snd_timer_close_locked(ti, &card_dev_to_put);
put_device(card_dev_to_put);
}
}
list_del(&timer->device_list);
@@ -1809,6 +1811,7 @@ static int snd_timer_user_params(struct file *file,
struct snd_timer *t;
int err;
guard(mutex)(&register_mutex);
tu = file->private_data;
if (!tu->timeri)
return -EBADFD;
+7
View File
@@ -808,6 +808,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "MS-17LN"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "PM1403CDA"),
}
},
{}
};
+3
View File
@@ -679,6 +679,9 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl)
{
struct wm_coeff_ctl *ctl = cs_ctl->priv;
if (!ctl)
return;
cancel_work_sync(&ctl->work);
kfree(ctl->name);
+10 -2
View File
@@ -199,6 +199,7 @@ loongson_pcm_pointer(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct device *dev = substream->pcm->card->dev;
struct loongson_runtime_data *prtd = runtime->private_data;
struct loongson_dma_desc *desc;
snd_pcm_uframes_t x;
@@ -207,9 +208,16 @@ loongson_pcm_pointer(struct snd_soc_component *component,
desc = dma_desc_save(prtd);
addr = ((u64)desc->saddr_hi << 32) | desc->saddr;
x = bytes_to_frames(runtime, addr - runtime->dma_addr);
if (x == runtime->buffer_size)
if (addr < runtime->dma_addr ||
addr > runtime->dma_addr + runtime->dma_bytes) {
dev_warn(dev, "WARNING! dma_addr:0x%llx\n", addr);
x = 0;
} else {
x = bytes_to_frames(runtime, addr - runtime->dma_addr);
if (x == runtime->buffer_size)
x = 0;
}
return x;
}
+21 -3
View File
@@ -82,6 +82,9 @@ static struct sdca_dev *sdca_dev_register(struct device *parent,
static void sdca_dev_unregister(struct sdca_dev *sdev)
{
if (!sdev)
return;
auxiliary_device_delete(&sdev->auxdev);
auxiliary_device_uninit(&sdev->auxdev);
}
@@ -90,14 +93,24 @@ int sdca_dev_register_functions(struct sdw_slave *slave)
{
struct sdca_device_data *sdca_data = &slave->sdca_data;
int i;
int ret;
for (i = 0; i < sdca_data->num_functions; i++) {
struct sdca_dev *func_dev;
func_dev = sdca_dev_register(&slave->dev,
&sdca_data->function[i]);
if (IS_ERR(func_dev))
return PTR_ERR(func_dev);
if (IS_ERR(func_dev)) {
ret = PTR_ERR(func_dev);
/*
* Unregister functions that were successfully
* registered before this failure. This also
* sets func_dev to NULL so the caller will not
* try to unregister them again.
*/
sdca_dev_unregister_functions(slave);
return ret;
}
sdca_data->function[i].func_dev = func_dev;
}
@@ -111,7 +124,12 @@ void sdca_dev_unregister_functions(struct sdw_slave *slave)
struct sdca_device_data *sdca_data = &slave->sdca_data;
int i;
for (i = 0; i < sdca_data->num_functions; i++)
for (i = 0; i < sdca_data->num_functions; i++) {
if (!sdca_data->function[i].func_dev)
continue;
sdca_dev_unregister(sdca_data->function[i].func_dev);
sdca_data->function[i].func_dev = NULL;
}
}
EXPORT_SYMBOL_NS(sdca_dev_unregister_functions, "SND_SOC_SDCA");
+2 -2
View File
@@ -181,14 +181,14 @@ irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context)
}
dsp_msg = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_msg_write);
if (dsp_msg) {
if (dsp_msg == ACP_DSP_MSG_SET) {
snd_sof_ipc_msgs_rx(sdev);
acp_dsp_ipc_host_done(sdev);
ipc_irq = true;
}
dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write);
if (dsp_ack) {
if (dsp_ack == ACP_DSP_ACK_SET) {
if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
guard(spinlock_irq)(&sdev->ipc_lock);
+28
View File
@@ -377,6 +377,33 @@ void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src,
snd_sof_dsp_write(sdev, ACP_DSP_BAR, reg_offset + i, src[j]);
}
static int acp_init_scratch_mem_ipc_flags(struct snd_sof_dev *sdev)
{
u32 dsp_msg_write, dsp_ack_write, host_msg_write, host_ack_write;
dsp_msg_write = sdev->debug_box.offset +
offsetof(struct scratch_ipc_conf, sof_dsp_msg_write);
dsp_ack_write = sdev->debug_box.offset +
offsetof(struct scratch_ipc_conf, sof_dsp_ack_write);
host_msg_write = sdev->debug_box.offset +
offsetof(struct scratch_ipc_conf, sof_host_msg_write);
host_ack_write = sdev->debug_box.offset +
offsetof(struct scratch_ipc_conf, sof_host_ack_write);
/* Initialize host message write flag */
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + host_msg_write, 0);
/* Initialize host ack write flag */
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + host_ack_write, 0);
/* Initialize DSP message write flag */
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_msg_write, 0);
/* Initialize DSP ack write flag */
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write, 0);
return 0;
}
static int acp_memory_init(struct snd_sof_dev *sdev)
{
struct acp_dev_data *adata = sdev->pdata->hw_pdata;
@@ -384,6 +411,7 @@ static int acp_memory_init(struct snd_sof_dev *sdev)
snd_sof_dsp_update_bits(sdev, ACP_DSP_BAR, desc->dsp_intr_base + DSP_SW_INTR_CNTL_OFFSET,
ACP_DSP_INTR_EN_MASK, ACP_DSP_INTR_EN_MASK);
acp_init_scratch_mem_ipc_flags(sdev);
init_dma_descriptor(adata);
return 0;
+2
View File
@@ -116,6 +116,8 @@
#define ACP_SRAM_PAGE_COUNT 128
#define ACP6X_SDW_MAX_MANAGER_COUNT 2
#define ACP70_SDW_MAX_MANAGER_COUNT ACP6X_SDW_MAX_MANAGER_COUNT
#define ACP_DSP_MSG_SET 1
#define ACP_DSP_ACK_SET 1
enum clock_source {
ACP_CLOCK_96M = 0,