summaryrefslogtreecommitdiff
path: root/include/linux/soc/qcom/smd.h
blob: f148e0ffbec75f443af5bdb23e8ca318b5743786 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef __QCOM_SMD_H__
#define __QCOM_SMD_H__

#include <linux/device.h>
#include <linux/mod_devicetable.h>

struct qcom_smd;
struct qcom_smd_channel;
struct qcom_smd_lookup;

/**
 * struct qcom_smd_id - struct used for matching a smd device
 * @name:	name of the channel
 */
struct qcom_smd_id {
	char name[20];
};

/**
 * struct qcom_smd_device - smd device struct
 * @dev:	the device struct
 * @channel:	handle to the smd channel for this device
 */
struct qcom_smd_device {
	struct device dev;
	struct qcom_smd_channel *channel;
};

typedef int (*qcom_smd_cb_t)(struct qcom_smd_channel *, const void *, size_t);

/**
 * struct qcom_smd_driver - smd driver struct
 * @driver:	underlying device driver
 * @smd_match_table: static channel match table
 * @probe:	invoked when the smd channel is found
 * @remove:	invoked when the smd channel is closed
 * @callback:	invoked when an inbound message is received on the channel,
 *		should return 0 on success or -EBUSY if the data cannot be
 *		consumed at this time
 */
struct qcom_smd_driver {
	struct device_driver driver;
	const struct qcom_smd_id *smd_match_table;

	int (*probe)(struct qcom_smd_device *dev);
	void (*remove)(struct qcom_smd_device *dev);
	qcom_smd_cb_t callback;
};

#if IS_ENABLED(CONFIG_QCOM_SMD)

int qcom_smd_driver_register(struct qcom_smd_driver *drv);
void qcom_smd_driver_unregister(struct qcom_smd_driver *drv);

struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *channel,
					       const char *name,
					       qcom_smd_cb_t cb);
void qcom_smd_close_channel(struct qcom_smd_channel *channel);
void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel);
void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data);
int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len);


struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent,
					     struct device_node *node);
int qcom_smd_unregister_edge(struct qcom_smd_edge *edge);

#else

static inline int qcom_smd_driver_register(struct qcom_smd_driver *drv)
{
	return -ENXIO;
}

static inline void qcom_smd_driver_unregister(struct qcom_smd_driver *drv)
{
	/* This shouldn't be possible */
	WARN_ON(1);
}

static inline struct qcom_smd_channel *
qcom_smd_open_channel(struct qcom_smd_channel *channel,
		      const char *name,
		      qcom_smd_cb_t cb)
{
	/* This shouldn't be possible */
	WARN_ON(1);
	return NULL;
}

static inline void qcom_smd_close_channel(struct qcom_smd_channel *channel)
{
	/* This shouldn't be possible */
	WARN_ON(1);
}

static inline void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel)
{
	/* This shouldn't be possible */
	WARN_ON(1);
	return NULL;
}

static inline void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data)
{
	/* This shouldn't be possible */
	WARN_ON(1);
}

static inline int qcom_smd_send(struct qcom_smd_channel *channel,
				const void *data, int len)
{
	/* This shouldn't be possible */
	WARN_ON(1);
	return -ENXIO;
}

static inline struct qcom_smd_edge *
qcom_smd_register_edge(struct device *parent,
		       struct device_node *node)
{
	return ERR_PTR(-ENXIO);
}

static inline int qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
{
	/* This shouldn't be possible */
	WARN_ON(1);
	return -ENXIO;
}

#endif

#define module_qcom_smd_driver(__smd_driver) \
	module_driver(__smd_driver, qcom_smd_driver_register, \
		      qcom_smd_driver_unregister)


#endif