Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61ff5cf1 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: Introduce QMI helpers" into msm-next

parents 5c1e24e2 26293589
Loading
Loading
Loading
Loading
+533 −224

File changed.

Preview size limit exceeded, changes collapsed.

+81 −61
Original line number Diff line number Diff line
@@ -14,12 +14,8 @@
#ifndef __QMI_HELPERS_H__
#define __QMI_HELPERS_H__

#include <linux/idr.h>
#include <linux/qrtr.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/completion.h>

/**
 * qmi_header - wireformat header of QMI messages
@@ -103,74 +99,68 @@ struct qmi_elem_info {
 * @error:	error value, when @result is QMI_RESULT_FAILURE_V01
 */
struct qmi_response_type_v01 {
	u32 result;
	u32 error;
	u16 result;
	u16 error;
};

extern struct qmi_elem_info qmi_response_type_v01_ei[];

/**
 * struct qrtr_service - context to track lookup-results
 * struct qmi_service - context to track lookup-results
 * @service:	service type
 * @version:	version of the @service
 * @instance:	instance id of the @service
 * @node:	node of the service
 * @port:	port of the service
 * @cookie:	handle for client's use
 * @priv:	handle for client's use
 * @list_node:	list_head for house keeping
 */
struct qrtr_service {
struct qmi_service {
	unsigned int service;
	unsigned int version;
	unsigned int instance;

	unsigned int node;
	unsigned int port;

	void *cookie;
	void *priv;
	struct list_head list_node;
};

struct qrtr_handle;
struct qmi_handle;

/**
 * struct qrtr_handle_ops - callbacks from qrtr_handle
 * @new_server:		invoked as a new_server message arrives
 * @del_server:		invoked as a del_server message arrives
 * @net_reset:		invoked as the name server is restarted
 * @msg_handler:	invoked as a non-control message arrives
 * struct qmi_ops - callbacks for qmi_handle
 * @new_server:		inform client of a new_server lookup-result, returning
 *                      successfully from this call causes the library to call
 *                      @del_server as the service is removed from the
 *                      lookup-result. @priv of the qmi_service can be used by
 *                      the client
 * @del_server:		inform client of a del_server lookup-result
 * @net_reset:		inform client that the name service was restarted and
 *                      that and any state needs to be released
 * @msg_handler:	invoked for incoming messages, allows a client to
 *                      override the usual QMI message handler
 * @bye:                inform a client that all clients from a node are gone
 * @del_client:         inform a client that a particular client is gone
 */
struct qrtr_handle_ops {
	int (*new_server)(struct qrtr_handle *, struct qrtr_service *);
	void (*del_server)(struct qrtr_handle *, struct qrtr_service *);
	void (*net_reset)(struct qrtr_handle *);
	void (*msg_handler)(struct qrtr_handle *, struct sockaddr_qrtr *,
			    const void *, size_t);
struct qmi_ops {
	int (*new_server)(struct qmi_handle *qmi, struct qmi_service *svc);
	void (*del_server)(struct qmi_handle *qmi, struct qmi_service *svc);
	void (*net_reset)(struct qmi_handle *qmi);
	void (*msg_handler)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
			    const void *data, size_t count);
	void (*bye)(struct qmi_handle *qmi, unsigned int node);
	void (*del_client)(struct qmi_handle *qmi,
			   unsigned int node, unsigned int port);
};

/**
 * struct qrtr_handle - qrtr client context
 * @sock:	socket handle
 * @sq:		sockaddr of @sock
 * @work:	work for handling incoming messages
 * @wq:		workqueue to post @work on
 * @recv_buf:	scratch buffer for handling incoming messages
 * @recv_buf_size:	size of @recv_buf
 * @services:	list of services advertised to the client
 * @ops:	reference to callbacks
 */
struct qrtr_handle {
	struct socket *sock;
	struct sockaddr_qrtr sq;

	struct work_struct work;
	struct workqueue_struct *wq;

	void *recv_buf;
	size_t recv_buf_size;

	struct list_head services;

	struct qrtr_handle_ops ops;
};

/**
 * struct qmi_txn - transaction context
 * @qmi:	QMI handle this transaction is associated with
 * @id:		transaction id
 * @lock:	for synchronization between handler and waiter of messages
 * @completion:	completion object as the transaction receives a response
 * @result:	result code for the completed transaction
 * @ei:		description of the QMI encoded response (optional)
@@ -181,6 +171,7 @@ struct qmi_txn {

	int id;

	struct mutex lock;
	struct completion completion;
	int result;

@@ -208,14 +199,39 @@ struct qmi_msg_handler {
};

/**
 * struct qmi_handle - QMI client handle
 * @qrtr:	qrtr handle backing the QMI client
 * struct qmi_handle - QMI context
 * @sock:	socket handle
 * @sock_lock:	synchronization of @sock modifications
 * @sq:		sockaddr of @sock
 * @work:	work for handling incoming messages
 * @wq:		workqueue to post @work on
 * @recv_buf:	scratch buffer for handling incoming messages
 * @recv_buf_size:	size of @recv_buf
 * @lookups:		list of registered lookup requests
 * @lookup_results:	list of lookup-results advertised to the client
 * @services:		list of registered services (by this client)
 * @ops:	reference to callbacks
 * @txns:	outstanding transactions
 * @txn_lock:	lock for modifications of @txns
 * @handlers:	list of handlers for incoming messages
 */
struct qmi_handle {
	struct qrtr_handle qrtr;
	struct socket *sock;
	struct mutex sock_lock;

	struct sockaddr_qrtr sq;

	struct work_struct work;
	struct workqueue_struct *wq;

	void *recv_buf;
	size_t recv_buf_size;

	struct list_head lookups;
	struct list_head lookup_results;
	struct list_head services;

	struct qmi_ops ops;

	struct idr txns;
	struct mutex txn_lock;
@@ -223,20 +239,24 @@ struct qmi_handle {
	struct qmi_msg_handler *handlers;
};

int qrtr_client_init(struct qrtr_handle *qrtr, size_t recv_buf_size,
		     struct qrtr_handle_ops *ops);
void qrtr_client_release(struct qrtr_handle *qrtr);
int qrtr_client_new_lookup(struct qrtr_handle *qrtr,
			   unsigned int service, unsigned int instance);
int qmi_add_lookup(struct qmi_handle *qmi, unsigned int service,
		   unsigned int version, unsigned int instance);
int qmi_add_server(struct qmi_handle *qmi, unsigned int service,
		   unsigned int version, unsigned int instance);

int qmi_client_init(struct qmi_handle *qmi, size_t max_msg_len,
		    struct qmi_msg_handler *handlers);
void qmi_client_release(struct qmi_handle *qmi);
int qmi_handle_init(struct qmi_handle *qmi, size_t max_msg_len,
		    struct qmi_ops *ops, struct qmi_msg_handler *handlers);
void qmi_handle_release(struct qmi_handle *qmi);

ssize_t qmi_send_message(struct qmi_handle *qmi,
			 struct sockaddr_qrtr *sq, struct qmi_txn *txn,
			 int type, int msg_id, size_t len,
ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
			 struct qmi_txn *txn, int msg_id, size_t len,
			 struct qmi_elem_info *ei, const void *c_struct);
ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
			  struct qmi_txn *txn, int msg_id, size_t len,
			  struct qmi_elem_info *ei, const void *c_struct);
ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
			    int msg_id, size_t len, struct qmi_elem_info *ei,
			    const void *c_struct);

void *qmi_encode_message(int type, unsigned int msg_id, size_t *len,
			 unsigned int txn_id, struct qmi_elem_info *ei,