Commit 926e9785 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'scmi-fixes-5.10' of...

Merge tag 'scmi-fixes-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes

ARM SCMI fixes for v5.10

Handful of fixes, some of them fixing issues since SCMI was merged.
It indicates that it is getting used now and people are finding bugs.
Fixes include unblocking multiple thread access with SMC/HVC transport,
ARCH_COLD_RESET value, locking in notifications, avoiding workqueue
name duplication with multiple instances of SCMI and adding missing
Rx size initialisation when using buffers for repeat transmits.

* tag 'scmi-fixes-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
  firmware: arm_scmi: Fix duplicate workqueue name
  firmware: arm_scmi: Fix locking in notifications
  firmware: arm_scmi: Add missing Rx size re-initialisation
  firmware: arm_scmi: Expand SMC/HVC message pool to more than one
  firmware: arm_scmi: Fix ARCH_COLD_RESET

Link: https://lore.kernel.org/r/20201015123518.GA3839@bogusSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 9774dd68 b9ceca6b
......@@ -197,6 +197,8 @@ static int scmi_base_implementation_list_get(const struct scmi_handle *handle,
protocols_imp[tot_num_ret + loop] = *(list + loop);
tot_num_ret += loop_num_ret;
scmi_reset_rx_to_maxsz(handle, t);
} while (loop_num_ret);
scmi_xfer_put(handle, t);
......
......@@ -192,6 +192,8 @@ scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id,
}
tot_rate_cnt += num_returned;
scmi_reset_rx_to_maxsz(handle, t);
/*
* check for both returned and remaining to avoid infinite
* loop due to buggy firmware
......
......@@ -147,6 +147,8 @@ int scmi_do_xfer_with_response(const struct scmi_handle *h,
struct scmi_xfer *xfer);
int scmi_xfer_get_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id,
size_t tx_size, size_t rx_size, struct scmi_xfer **p);
void scmi_reset_rx_to_maxsz(const struct scmi_handle *handle,
struct scmi_xfer *xfer);
int scmi_handle_put(const struct scmi_handle *handle);
struct scmi_handle *scmi_handle_get(struct device *dev);
void scmi_set_handle(struct scmi_device *scmi_dev);
......
......@@ -402,6 +402,14 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer)
return ret;
}
void scmi_reset_rx_to_maxsz(const struct scmi_handle *handle,
struct scmi_xfer *xfer)
{
struct scmi_info *info = handle_to_scmi_info(handle);
xfer->rx.len = info->desc->max_msg_size;
}
#define SCMI_MAX_RESPONSE_TIMEOUT (2 * MSEC_PER_SEC)
/**
......
......@@ -1403,15 +1403,21 @@ static void scmi_protocols_late_init(struct work_struct *work)
"finalized PENDING handler - key:%X\n",
hndl->key);
ret = scmi_event_handler_enable_events(hndl);
if (ret) {
dev_dbg(ni->handle->dev,
"purging INVALID handler - key:%X\n",
hndl->key);
scmi_put_active_handler(ni, hndl);
}
} else {
ret = scmi_valid_pending_handler(ni, hndl);
}
if (ret) {
dev_dbg(ni->handle->dev,
"purging PENDING handler - key:%X\n",
hndl->key);
/* this hndl can be only a pending one */
scmi_put_handler_unlocked(ni, hndl);
if (ret) {
dev_dbg(ni->handle->dev,
"purging PENDING handler - key:%X\n",
hndl->key);
/* this hndl can be only a pending one */
scmi_put_handler_unlocked(ni, hndl);
}
}
}
mutex_unlock(&ni->pending_mtx);
......@@ -1468,7 +1474,7 @@ int scmi_notification_init(struct scmi_handle *handle)
ni->gid = gid;
ni->handle = handle;
ni->notify_wq = alloc_workqueue("scmi_notify",
ni->notify_wq = alloc_workqueue(dev_name(handle->dev),
WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
0);
if (!ni->notify_wq)
......
......@@ -304,6 +304,8 @@ scmi_perf_describe_levels_get(const struct scmi_handle *handle, u32 domain,
}
tot_opp_cnt += num_returned;
scmi_reset_rx_to_maxsz(handle, t);
/*
* check for both returned and remaining to avoid infinite
* loop due to buggy firmware
......
......@@ -36,9 +36,7 @@ struct scmi_msg_reset_domain_reset {
#define EXPLICIT_RESET_ASSERT BIT(1)
#define ASYNCHRONOUS_RESET BIT(2)
__le32 reset_state;
#define ARCH_RESET_TYPE BIT(31)
#define COLD_RESET_STATE BIT(0)
#define ARCH_COLD_RESET (ARCH_RESET_TYPE | COLD_RESET_STATE)
#define ARCH_COLD_RESET 0
};
struct scmi_msg_reset_notify {
......
......@@ -166,6 +166,8 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
}
desc_index += num_returned;
scmi_reset_rx_to_maxsz(handle, t);
/*
* check for both returned and remaining to avoid infinite
* loop due to buggy firmware
......
......@@ -149,6 +149,6 @@ static const struct scmi_transport_ops scmi_smc_ops = {
const struct scmi_desc scmi_smc_desc = {
.ops = &scmi_smc_ops,
.max_rx_timeout_ms = 30,
.max_msg = 1,
.max_msg = 20,
.max_msg_size = 128,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment