aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-04-02 12:50:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-04-02 12:50:40 -0400
commitb1a808ff436343956a6ae63178ea1810c5e5a3a1 (patch)
treebd510d5ea6b407df6ea0b8353e1788e12f95e427 /include
parent97754175042e77d02c4232d5fb24c16abd1c77f1 (diff)
parent43139a61fc68f4b0af7327a0e63f340a7c81c69a (diff)
Merge branch 'for-next' of git://gitorious.org/kernel-hsi/kernel-hsi
Pull HSI (High Speed Synchronous Serial Interface) framework from Carlos Chinea: "The High Speed Synchronous Serial Interface (HSI) is a serial interface mainly used for connecting application engines (APE) with cellular modem engines (CMT) in cellular handsets. The framework is currently being used for some people and we would like to see it integrated into the kernel for 3.3. There is no HW controller drivers in this pull, but some people have already some of them pending which they would like to push as soon as this integrated. I am also working on the acceptance for an TI OMAP one, based on a compatible legacy version of the interface called SSI." Ok, so it didn't get into 3.3, but here it is pulled into 3.4. Several people piped up to say "yeah, we want this". * 'for-next' of git://gitorious.org/kernel-hsi/kernel-hsi: HSI: hsi_char: Update ioctl-number.txt HSI: Add HSI API documentation HSI: hsi_char: Add HSI char device kernel configuration HSI: hsi_char: Add HSI char device driver HSI: hsi: Introducing HSI framework
Diffstat (limited to 'include')
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/hsi/Kbuild1
-rw-r--r--include/linux/hsi/hsi.h410
-rw-r--r--include/linux/hsi/hsi_char.h63
4 files changed, 475 insertions, 0 deletions
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index d05df281035..3c9b616c834 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -3,6 +3,7 @@ header-y += can/
3header-y += caif/ 3header-y += caif/
4header-y += dvb/ 4header-y += dvb/
5header-y += hdlc/ 5header-y += hdlc/
6header-y += hsi/
6header-y += isdn/ 7header-y += isdn/
7header-y += mmc/ 8header-y += mmc/
8header-y += nfsd/ 9header-y += nfsd/
diff --git a/include/linux/hsi/Kbuild b/include/linux/hsi/Kbuild
new file mode 100644
index 00000000000..271a770b478
--- /dev/null
+++ b/include/linux/hsi/Kbuild
@@ -0,0 +1 @@
header-y += hsi_char.h
diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h
new file mode 100644
index 00000000000..4b178067f40
--- /dev/null
+++ b/include/linux/hsi/hsi.h
@@ -0,0 +1,410 @@
1/*
2 * HSI core header file.
3 *
4 * Copyright (C) 2010 Nokia Corporation. All rights reserved.
5 *
6 * Contact: Carlos Chinea <carlos.chinea@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#ifndef __LINUX_HSI_H__
24#define __LINUX_HSI_H__
25
26#include <linux/device.h>
27#include <linux/mutex.h>
28#include <linux/scatterlist.h>
29#include <linux/spinlock.h>
30#include <linux/list.h>
31#include <linux/module.h>
32
33/* HSI message ttype */
34#define HSI_MSG_READ 0
35#define HSI_MSG_WRITE 1
36
37/* HSI configuration values */
38enum {
39 HSI_MODE_STREAM = 1,
40 HSI_MODE_FRAME,
41};
42
43enum {
44 HSI_FLOW_SYNC, /* Synchronized flow */
45 HSI_FLOW_PIPE, /* Pipelined flow */
46};
47
48enum {
49 HSI_ARB_RR, /* Round-robin arbitration */
50 HSI_ARB_PRIO, /* Channel priority arbitration */
51};
52
53#define HSI_MAX_CHANNELS 16
54
55/* HSI message status codes */
56enum {
57 HSI_STATUS_COMPLETED, /* Message transfer is completed */
58 HSI_STATUS_PENDING, /* Message pending to be read/write (POLL) */
59 HSI_STATUS_PROCEEDING, /* Message transfer is ongoing */
60 HSI_STATUS_QUEUED, /* Message waiting to be served */
61 HSI_STATUS_ERROR, /* Error when message transfer was ongoing */
62};
63
64/* HSI port event codes */
65enum {
66 HSI_EVENT_START_RX,
67 HSI_EVENT_STOP_RX,
68};
69
70/**
71 * struct hsi_config - Configuration for RX/TX HSI modules
72 * @mode: Bit transmission mode (STREAM or FRAME)
73 * @channels: Number of channels to use [1..16]
74 * @speed: Max bit transmission speed (Kbit/s)
75 * @flow: RX flow type (SYNCHRONIZED or PIPELINE)
76 * @arb_mode: Arbitration mode for TX frame (Round robin, priority)
77 */
78struct hsi_config {
79 unsigned int mode;
80 unsigned int channels;
81 unsigned int speed;
82 union {
83 unsigned int flow; /* RX only */
84 unsigned int arb_mode; /* TX only */
85 };
86};
87
88/**
89 * struct hsi_board_info - HSI client board info
90 * @name: Name for the HSI device
91 * @hsi_id: HSI controller id where the client sits
92 * @port: Port number in the controller where the client sits
93 * @tx_cfg: HSI TX configuration
94 * @rx_cfg: HSI RX configuration
95 * @platform_data: Platform related data
96 * @archdata: Architecture-dependent device data
97 */
98struct hsi_board_info {
99 const char *name;
100 unsigned int hsi_id;
101 unsigned int port;
102 struct hsi_config tx_cfg;
103 struct hsi_config rx_cfg;
104 void *platform_data;
105 struct dev_archdata *archdata;
106};
107
108#ifdef CONFIG_HSI_BOARDINFO
109extern int hsi_register_board_info(struct hsi_board_info const *info,
110 unsigned int len);
111#else
112static inline int hsi_register_board_info(struct hsi_board_info const *info,
113 unsigned int len)
114{
115 return 0;
116}
117#endif /* CONFIG_HSI_BOARDINFO */
118
119/**
120 * struct hsi_client - HSI client attached to an HSI port
121 * @device: Driver model representation of the device
122 * @tx_cfg: HSI TX configuration
123 * @rx_cfg: HSI RX configuration
124 * @hsi_start_rx: Called after incoming wake line goes high
125 * @hsi_stop_rx: Called after incoming wake line goes low
126 */
127struct hsi_client {
128 struct device device;
129 struct hsi_config tx_cfg;
130 struct hsi_config rx_cfg;
131 void (*hsi_start_rx)(struct hsi_client *cl);
132 void (*hsi_stop_rx)(struct hsi_client *cl);
133 /* private: */
134 unsigned int pclaimed:1;
135 struct list_head link;
136};
137
138#define to_hsi_client(dev) container_of(dev, struct hsi_client, device)
139
140static inline void hsi_client_set_drvdata(struct hsi_client *cl, void *data)
141{
142 dev_set_drvdata(&cl->device, data);
143}
144
145static inline void *hsi_client_drvdata(struct hsi_client *cl)
146{
147 return dev_get_drvdata(&cl->device);
148}
149
150/**
151 * struct hsi_client_driver - Driver associated to an HSI client
152 * @driver: Driver model representation of the driver
153 */
154struct hsi_client_driver {
155 struct device_driver driver;
156};
157
158#define to_hsi_client_driver(drv) container_of(drv, struct hsi_client_driver,\
159 driver)
160
161int hsi_register_client_driver(struct hsi_client_driver *drv);
162
163static inline void hsi_unregister_client_driver(struct hsi_client_driver *drv)
164{
165 driver_unregister(&drv->driver);
166}
167
168/**
169 * struct hsi_msg - HSI message descriptor
170 * @link: Free to use by the current descriptor owner
171 * @cl: HSI device client that issues the transfer
172 * @sgt: Head of the scatterlist array
173 * @context: Client context data associated to the transfer
174 * @complete: Transfer completion callback
175 * @destructor: Destructor to free resources when flushing
176 * @status: Status of the transfer when completed
177 * @actual_len: Actual length of data transfered on completion
178 * @channel: Channel were to TX/RX the message
179 * @ttype: Transfer type (TX if set, RX otherwise)
180 * @break_frame: if true HSI will send/receive a break frame. Data buffers are
181 * ignored in the request.
182 */
183struct hsi_msg {
184 struct list_head link;
185 struct hsi_client *cl;
186 struct sg_table sgt;
187 void *context;
188
189 void (*complete)(struct hsi_msg *msg);
190 void (*destructor)(struct hsi_msg *msg);
191
192 int status;
193 unsigned int actual_len;
194 unsigned int channel;
195 unsigned int ttype:1;
196 unsigned int break_frame:1;
197};
198
199struct hsi_msg *hsi_alloc_msg(unsigned int n_frag, gfp_t flags);
200void hsi_free_msg(struct hsi_msg *msg);
201
202/**
203 * struct hsi_port - HSI port device
204 * @device: Driver model representation of the device
205 * @tx_cfg: Current TX path configuration
206 * @rx_cfg: Current RX path configuration
207 * @num: Port number
208 * @shared: Set when port can be shared by different clients
209 * @claimed: Reference count of clients which claimed the port
210 * @lock: Serialize port claim
211 * @async: Asynchronous transfer callback
212 * @setup: Callback to set the HSI client configuration
213 * @flush: Callback to clean the HW state and destroy all pending transfers
214 * @start_tx: Callback to inform that a client wants to TX data
215 * @stop_tx: Callback to inform that a client no longer wishes to TX data
216 * @release: Callback to inform that a client no longer uses the port
217 * @clients: List of hsi_clients using the port.
218 * @clock: Lock to serialize access to the clients list.
219 */
220struct hsi_port {
221 struct device device;
222 struct hsi_config tx_cfg;
223 struct hsi_config rx_cfg;
224 unsigned int num;
225 unsigned int shared:1;
226 int claimed;
227 struct mutex lock;
228 int (*async)(struct hsi_msg *msg);
229 int (*setup)(struct hsi_client *cl);
230 int (*flush)(struct hsi_client *cl);
231 int (*start_tx)(struct hsi_client *cl);
232 int (*stop_tx)(struct hsi_client *cl);
233 int (*release)(struct hsi_client *cl);
234 struct list_head clients;
235 spinlock_t clock;
236};
237
238#define to_hsi_port(dev) container_of(dev, struct hsi_port, device)
239#define hsi_get_port(cl) to_hsi_port((cl)->device.parent)
240
241void hsi_event(struct hsi_port *port, unsigned int event);
242int hsi_claim_port(struct hsi_client *cl, unsigned int share);
243void hsi_release_port(struct hsi_client *cl);
244
245static inline int hsi_port_claimed(struct hsi_client *cl)
246{
247 return cl->pclaimed;
248}
249
250static inline void hsi_port_set_drvdata(struct hsi_port *port, void *data)
251{
252 dev_set_drvdata(&port->device, data);
253}
254
255static inline void *hsi_port_drvdata(struct hsi_port *port)
256{
257 return dev_get_drvdata(&port->device);
258}
259
260/**
261 * struct hsi_controller - HSI controller device
262 * @device: Driver model representation of the device
263 * @owner: Pointer to the module owning the controller
264 * @id: HSI controller ID
265 * @num_ports: Number of ports in the HSI controller
266 * @port: Array of HSI ports
267 */
268struct hsi_controller {
269 struct device device;
270 struct module *owner;
271 unsigned int id;
272 unsigned int num_ports;
273 struct hsi_port *port;
274};
275
276#define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device)
277
278struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags);
279void hsi_free_controller(struct hsi_controller *hsi);
280int hsi_register_controller(struct hsi_controller *hsi);
281void hsi_unregister_controller(struct hsi_controller *hsi);
282
283static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi,
284 void *data)
285{
286 dev_set_drvdata(&hsi->device, data);
287}
288
289static inline void *hsi_controller_drvdata(struct hsi_controller *hsi)
290{
291 return dev_get_drvdata(&hsi->device);
292}
293
294static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi,
295 unsigned int num)
296{
297 return (num < hsi->num_ports) ? &hsi->port[num] : NULL;
298}
299
300/*
301 * API for HSI clients
302 */
303int hsi_async(struct hsi_client *cl, struct hsi_msg *msg);
304
305/**
306 * hsi_id - Get HSI controller ID associated to a client
307 * @cl: Pointer to a HSI client
308 *
309 * Return the controller id where the client is attached to
310 */
311static inline unsigned int hsi_id(struct hsi_client *cl)
312{
313 return to_hsi_controller(cl->device.parent->parent)->id;
314}
315
316/**
317 * hsi_port_id - Gets the port number a client is attached to
318 * @cl: Pointer to HSI client
319 *
320 * Return the port number associated to the client
321 */
322static inline unsigned int hsi_port_id(struct hsi_client *cl)
323{
324 return to_hsi_port(cl->device.parent)->num;
325}
326
327/**
328 * hsi_setup - Configure the client's port
329 * @cl: Pointer to the HSI client
330 *
331 * When sharing ports, clients should either relay on a single
332 * client setup or have the same setup for all of them.
333 *
334 * Return -errno on failure, 0 on success
335 */
336static inline int hsi_setup(struct hsi_client *cl)
337{
338 if (!hsi_port_claimed(cl))
339 return -EACCES;
340 return hsi_get_port(cl)->setup(cl);
341}
342
343/**
344 * hsi_flush - Flush all pending transactions on the client's port
345 * @cl: Pointer to the HSI client
346 *
347 * This function will destroy all pending hsi_msg in the port and reset
348 * the HW port so it is ready to receive and transmit from a clean state.
349 *
350 * Return -errno on failure, 0 on success
351 */
352static inline int hsi_flush(struct hsi_client *cl)
353{
354 if (!hsi_port_claimed(cl))
355 return -EACCES;
356 return hsi_get_port(cl)->flush(cl);
357}
358
359/**
360 * hsi_async_read - Submit a read transfer
361 * @cl: Pointer to the HSI client
362 * @msg: HSI message descriptor of the transfer
363 *
364 * Return -errno on failure, 0 on success
365 */
366static inline int hsi_async_read(struct hsi_client *cl, struct hsi_msg *msg)
367{
368 msg->ttype = HSI_MSG_READ;
369 return hsi_async(cl, msg);
370}
371
372/**
373 * hsi_async_write - Submit a write transfer
374 * @cl: Pointer to the HSI client
375 * @msg: HSI message descriptor of the transfer
376 *
377 * Return -errno on failure, 0 on success
378 */
379static inline int hsi_async_write(struct hsi_client *cl, struct hsi_msg *msg)
380{
381 msg->ttype = HSI_MSG_WRITE;
382 return hsi_async(cl, msg);
383}
384
385/**
386 * hsi_start_tx - Signal the port that the client wants to start a TX
387 * @cl: Pointer to the HSI client
388 *
389 * Return -errno on failure, 0 on success
390 */
391static inline int hsi_start_tx(struct hsi_client *cl)
392{
393 if (!hsi_port_claimed(cl))
394 return -EACCES;
395 return hsi_get_port(cl)->start_tx(cl);
396}
397
398/**
399 * hsi_stop_tx - Signal the port that the client no longer wants to transmit
400 * @cl: Pointer to the HSI client
401 *
402 * Return -errno on failure, 0 on success
403 */
404static inline int hsi_stop_tx(struct hsi_client *cl)
405{
406 if (!hsi_port_claimed(cl))
407 return -EACCES;
408 return hsi_get_port(cl)->stop_tx(cl);
409}
410#endif /* __LINUX_HSI_H__ */
diff --git a/include/linux/hsi/hsi_char.h b/include/linux/hsi/hsi_char.h
new file mode 100644
index 00000000000..76160b4f455
--- /dev/null
+++ b/include/linux/hsi/hsi_char.h
@@ -0,0 +1,63 @@
1/*
2 * Part of the HSI character device driver.
3 *
4 * Copyright (C) 2010 Nokia Corporation. All rights reserved.
5 *
6 * Contact: Andras Domokos <andras.domokos at nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23
24#ifndef __HSI_CHAR_H
25#define __HSI_CHAR_H
26
27#define HSI_CHAR_MAGIC 'k'
28#define HSC_IOW(num, dtype) _IOW(HSI_CHAR_MAGIC, num, dtype)
29#define HSC_IOR(num, dtype) _IOR(HSI_CHAR_MAGIC, num, dtype)
30#define HSC_IOWR(num, dtype) _IOWR(HSI_CHAR_MAGIC, num, dtype)
31#define HSC_IO(num) _IO(HSI_CHAR_MAGIC, num)
32
33#define HSC_RESET HSC_IO(16)
34#define HSC_SET_PM HSC_IO(17)
35#define HSC_SEND_BREAK HSC_IO(18)
36#define HSC_SET_RX HSC_IOW(19, struct hsc_rx_config)
37#define HSC_GET_RX HSC_IOW(20, struct hsc_rx_config)
38#define HSC_SET_TX HSC_IOW(21, struct hsc_tx_config)
39#define HSC_GET_TX HSC_IOW(22, struct hsc_tx_config)
40
41#define HSC_PM_DISABLE 0
42#define HSC_PM_ENABLE 1
43
44#define HSC_MODE_STREAM 1
45#define HSC_MODE_FRAME 2
46#define HSC_FLOW_SYNC 0
47#define HSC_ARB_RR 0
48#define HSC_ARB_PRIO 1
49
50struct hsc_rx_config {
51 uint32_t mode;
52 uint32_t flow;
53 uint32_t channels;
54};
55
56struct hsc_tx_config {
57 uint32_t mode;
58 uint32_t channels;
59 uint32_t speed;
60 uint32_t arb_mode;
61};
62
63#endif /* __HSI_CHAR_H */