Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109301142
D47426.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D47426.diff
View Options
diff --git a/sys/dev/firmware/arm/scmi.h b/sys/dev/firmware/arm/scmi.h
--- a/sys/dev/firmware/arm/scmi.h
+++ b/sys/dev/firmware/arm/scmi.h
@@ -84,6 +84,7 @@
void scmi_msg_put(device_t dev, struct scmi_msg *msg);
int scmi_request(device_t dev, void *in, void **);
int scmi_request_tx(device_t dev, void *in);
+int scmi_msg_async_enqueue(struct scmi_msg *msg);
void scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr, uint32_t rx_len);
DECLARE_CLASS(scmi_driver);
diff --git a/sys/dev/firmware/arm/scmi.c b/sys/dev/firmware/arm/scmi.c
--- a/sys/dev/firmware/arm/scmi.c
+++ b/sys/dev/firmware/arm/scmi.c
@@ -43,6 +43,7 @@
#include <sys/mutex.h>
#include <sys/queue.h>
#include <sys/refcount.h>
+#include <sys/taskqueue.h>
#include <dev/clk/clk.h>
#include <dev/fdt/simplebus.h>
@@ -94,6 +95,8 @@
bool use_polling;
bool done;
bool is_raw;
+ device_t dev;
+ struct task tsk;
struct mtx mtx;
LIST_ENTRY(scmi_req) next;
int protocol_id;
@@ -103,6 +106,7 @@
struct scmi_msg msg;
};
+#define tsk_to_req(t) __containerof((t), struct scmi_req, tsk)
#define buf_to_msg(b) __containerof((b), struct scmi_msg, payld)
#define msg_to_req(m) __containerof((m), struct scmi_req, msg)
#define buf_to_req(b) msg_to_req(buf_to_msg(b))
@@ -131,7 +135,9 @@
static void scmi_transport_configure(struct scmi_transport_desc *, phandle_t);
static int scmi_transport_init(struct scmi_softc *, phandle_t);
static void scmi_transport_cleanup(struct scmi_softc *);
-static struct scmi_reqs_pool *scmi_reqs_pool_allocate(const int, const int);
+static void scmi_req_async_waiter(void *, int);
+static struct scmi_reqs_pool *scmi_reqs_pool_allocate(device_t, const int,
+ const int);
static void scmi_reqs_pool_free(struct scmi_reqs_pool *);
static struct scmi_req *scmi_req_alloc(struct scmi_softc *, enum scmi_chan);
static struct scmi_req *scmi_req_initialized_alloc(device_t, int, int);
@@ -217,7 +223,7 @@
MODULE_VERSION(scmi, 1);
static struct scmi_reqs_pool *
-scmi_reqs_pool_allocate(const int max_msg, const int max_payld_sz)
+scmi_reqs_pool_allocate(device_t dev, const int max_msg, const int max_payld_sz)
{
struct scmi_reqs_pool *rp;
struct scmi_req *req;
@@ -229,6 +235,10 @@
req = malloc(sizeof(*req) + max_payld_sz,
M_DEVBUF, M_ZERO | M_WAITOK);
+ req->dev = dev;
+ req->tsk.ta_context = &req->tsk;
+ req->tsk.ta_func = scmi_req_async_waiter;
+
mtx_init(&req->mtx, "req", "SCMI", MTX_SPIN);
LIST_INSERT_HEAD(&rp->head, req, next);
}
@@ -280,14 +290,14 @@
trs->inflight_ht = hashinit(td->max_msg, M_DEVBUF, &trs->inflight_mask);
trs->chans[SCMI_CHAN_A2P] =
- scmi_reqs_pool_allocate(td->max_msg, td->max_payld_sz);
+ scmi_reqs_pool_allocate(sc->dev, td->max_msg, td->max_payld_sz);
if (trs->chans[SCMI_CHAN_A2P] == NULL) {
free(trs, M_DEVBUF);
return (ENOMEM);
}
trs->chans[SCMI_CHAN_P2A] =
- scmi_reqs_pool_allocate(td->max_msg, td->max_payld_sz);
+ scmi_reqs_pool_allocate(sc->dev, td->max_msg, td->max_payld_sz);
if (trs->chans[SCMI_CHAN_P2A] == NULL) {
scmi_reqs_pool_free(trs->chans[SCMI_CHAN_A2P]);
free(trs, M_DEVBUF);
@@ -648,7 +658,8 @@
SCMI_COLLECT_REPLY(sc->dev, &req->msg);
if (req->msg.payld[0] != 0)
ret = req->msg.payld[0];
- *out = &req->msg.payld[SCMI_MSG_HDR_SIZE];
+ if (out != NULL)
+ *out = &req->msg.payld[SCMI_MSG_HDR_SIZE];
} else {
device_printf(sc->dev,
"Request for token 0x%X timed-out.\n", req->token);
@@ -703,6 +714,20 @@
return (&req->msg);
}
+static void
+scmi_req_async_waiter(void *context, int pending)
+{
+ struct task *ta = context;
+ struct scmi_softc *sc;
+ struct scmi_req *req;
+
+ req = tsk_to_req(ta);
+ sc = device_get_softc(req->dev);
+ scmi_wait_for_response(sc, req, NULL);
+
+ scmi_msg_put(req->dev, &req->msg);
+}
+
void
scmi_msg_put(device_t dev, struct scmi_msg *msg)
{
@@ -763,3 +788,14 @@
return (scmi_wait_for_response(sc, req, out));
}
+
+int
+scmi_msg_async_enqueue(struct scmi_msg *msg)
+{
+ struct scmi_req *req;
+
+ req = msg_to_req(msg);
+
+ return taskqueue_enqueue_flags(taskqueue_thread, &req->tsk,
+ TASKQUEUE_FAIL_IF_PENDING | TASKQUEUE_FAIL_IF_CANCELING);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Feb 4, 6:54 AM (20 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14462616
Default Alt Text
D47426.diff (4 KB)
Attached To
Mode
D47426: scmi: Add optional asynchronous handling of replies
Attached
Detach File
Event Timeline
Log In to Comment