1 /* 2 * HSI core header file. 3 * 4 * Copyright (C) 2010 Nokia Corporation. All rights reserved. 5 * 6 * Contact: Carlos Chinea <[email protected]> 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/list.h> 30 #include <linux/module.h> 31 #include <linux/notifier.h> 32 33 /* HSI message ttype */ 34 #define HSI_MSG_READ 0 35 #define HSI_MSG_WRITE 1 36 37 /* HSI configuration values */ 38 enum { 39 HSI_MODE_STREAM = 1, 40 HSI_MODE_FRAME, 41 }; 42 43 enum { 44 HSI_FLOW_SYNC, /* Synchronized flow */ 45 HSI_FLOW_PIPE, /* Pipelined flow */ 46 }; 47 48 enum { 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 */ 56 enum { 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 */ 65 enum { 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 */ 78 struct 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 */ 98 struct 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 109 extern int hsi_register_board_info(struct hsi_board_info const *info, 110 unsigned int len); 111 #else 112 static 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 * @e_handler: Callback for handling port events (RX Wake High/Low) 125 * @pclaimed: Keeps tracks if the clients claimed its associated HSI port 126 * @nb: Notifier block for port events 127 */ 128 struct hsi_client { 129 struct device device; 130 struct hsi_config tx_cfg; 131 struct hsi_config rx_cfg; 132 /* private: */ 133 void (*ehandler)(struct hsi_client *, unsigned long); 134 unsigned int pclaimed:1; 135 struct notifier_block nb; 136 }; 137 138 #define to_hsi_client(dev) container_of(dev, struct hsi_client, device) 139 140 static inline void hsi_client_set_drvdata(struct hsi_client *cl, void *data) 141 { 142 dev_set_drvdata(&cl->device, data); 143 } 144 145 static inline void *hsi_client_drvdata(struct hsi_client *cl) 146 { 147 return dev_get_drvdata(&cl->device); 148 } 149 150 int hsi_register_port_event(struct hsi_client *cl, 151 void (*handler)(struct hsi_client *, unsigned long)); 152 int hsi_unregister_port_event(struct hsi_client *cl); 153 154 /** 155 * struct hsi_client_driver - Driver associated to an HSI client 156 * @driver: Driver model representation of the driver 157 */ 158 struct hsi_client_driver { 159 struct device_driver driver; 160 }; 161 162 #define to_hsi_client_driver(drv) container_of(drv, struct hsi_client_driver,\ 163 driver) 164 165 int hsi_register_client_driver(struct hsi_client_driver *drv); 166 167 static inline void hsi_unregister_client_driver(struct hsi_client_driver *drv) 168 { 169 driver_unregister(&drv->driver); 170 } 171 172 /** 173 * struct hsi_msg - HSI message descriptor 174 * @link: Free to use by the current descriptor owner 175 * @cl: HSI device client that issues the transfer 176 * @sgt: Head of the scatterlist array 177 * @context: Client context data associated to the transfer 178 * @complete: Transfer completion callback 179 * @destructor: Destructor to free resources when flushing 180 * @status: Status of the transfer when completed 181 * @actual_len: Actual length of data transfered on completion 182 * @channel: Channel were to TX/RX the message 183 * @ttype: Transfer type (TX if set, RX otherwise) 184 * @break_frame: if true HSI will send/receive a break frame. Data buffers are 185 * ignored in the request. 186 */ 187 struct hsi_msg { 188 struct list_head link; 189 struct hsi_client *cl; 190 struct sg_table sgt; 191 void *context; 192 193 void (*complete)(struct hsi_msg *msg); 194 void (*destructor)(struct hsi_msg *msg); 195 196 int status; 197 unsigned int actual_len; 198 unsigned int channel; 199 unsigned int ttype:1; 200 unsigned int break_frame:1; 201 }; 202 203 struct hsi_msg *hsi_alloc_msg(unsigned int n_frag, gfp_t flags); 204 void hsi_free_msg(struct hsi_msg *msg); 205 206 /** 207 * struct hsi_port - HSI port device 208 * @device: Driver model representation of the device 209 * @tx_cfg: Current TX path configuration 210 * @rx_cfg: Current RX path configuration 211 * @num: Port number 212 * @shared: Set when port can be shared by different clients 213 * @claimed: Reference count of clients which claimed the port 214 * @lock: Serialize port claim 215 * @async: Asynchronous transfer callback 216 * @setup: Callback to set the HSI client configuration 217 * @flush: Callback to clean the HW state and destroy all pending transfers 218 * @start_tx: Callback to inform that a client wants to TX data 219 * @stop_tx: Callback to inform that a client no longer wishes to TX data 220 * @release: Callback to inform that a client no longer uses the port 221 * @n_head: Notifier chain for signaling port events to the clients. 222 */ 223 struct hsi_port { 224 struct device device; 225 struct hsi_config tx_cfg; 226 struct hsi_config rx_cfg; 227 unsigned int num; 228 unsigned int shared:1; 229 int claimed; 230 struct mutex lock; 231 int (*async)(struct hsi_msg *msg); 232 int (*setup)(struct hsi_client *cl); 233 int (*flush)(struct hsi_client *cl); 234 int (*start_tx)(struct hsi_client *cl); 235 int (*stop_tx)(struct hsi_client *cl); 236 int (*release)(struct hsi_client *cl); 237 /* private */ 238 struct atomic_notifier_head n_head; 239 }; 240 241 #define to_hsi_port(dev) container_of(dev, struct hsi_port, device) 242 #define hsi_get_port(cl) to_hsi_port((cl)->device.parent) 243 244 int hsi_event(struct hsi_port *port, unsigned long event); 245 int hsi_claim_port(struct hsi_client *cl, unsigned int share); 246 void hsi_release_port(struct hsi_client *cl); 247 248 static inline int hsi_port_claimed(struct hsi_client *cl) 249 { 250 return cl->pclaimed; 251 } 252 253 static inline void hsi_port_set_drvdata(struct hsi_port *port, void *data) 254 { 255 dev_set_drvdata(&port->device, data); 256 } 257 258 static inline void *hsi_port_drvdata(struct hsi_port *port) 259 { 260 return dev_get_drvdata(&port->device); 261 } 262 263 /** 264 * struct hsi_controller - HSI controller device 265 * @device: Driver model representation of the device 266 * @owner: Pointer to the module owning the controller 267 * @id: HSI controller ID 268 * @num_ports: Number of ports in the HSI controller 269 * @port: Array of HSI ports 270 */ 271 struct hsi_controller { 272 struct device device; 273 struct module *owner; 274 unsigned int id; 275 unsigned int num_ports; 276 struct hsi_port **port; 277 }; 278 279 #define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device) 280 281 struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags); 282 void hsi_put_controller(struct hsi_controller *hsi); 283 int hsi_register_controller(struct hsi_controller *hsi); 284 void hsi_unregister_controller(struct hsi_controller *hsi); 285 286 static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi, 287 void *data) 288 { 289 dev_set_drvdata(&hsi->device, data); 290 } 291 292 static inline void *hsi_controller_drvdata(struct hsi_controller *hsi) 293 { 294 return dev_get_drvdata(&hsi->device); 295 } 296 297 static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi, 298 unsigned int num) 299 { 300 return (num < hsi->num_ports) ? hsi->port[num] : NULL; 301 } 302 303 /* 304 * API for HSI clients 305 */ 306 int hsi_async(struct hsi_client *cl, struct hsi_msg *msg); 307 308 /** 309 * hsi_id - Get HSI controller ID associated to a client 310 * @cl: Pointer to a HSI client 311 * 312 * Return the controller id where the client is attached to 313 */ 314 static inline unsigned int hsi_id(struct hsi_client *cl) 315 { 316 return to_hsi_controller(cl->device.parent->parent)->id; 317 } 318 319 /** 320 * hsi_port_id - Gets the port number a client is attached to 321 * @cl: Pointer to HSI client 322 * 323 * Return the port number associated to the client 324 */ 325 static inline unsigned int hsi_port_id(struct hsi_client *cl) 326 { 327 return to_hsi_port(cl->device.parent)->num; 328 } 329 330 /** 331 * hsi_setup - Configure the client's port 332 * @cl: Pointer to the HSI client 333 * 334 * When sharing ports, clients should either relay on a single 335 * client setup or have the same setup for all of them. 336 * 337 * Return -errno on failure, 0 on success 338 */ 339 static inline int hsi_setup(struct hsi_client *cl) 340 { 341 if (!hsi_port_claimed(cl)) 342 return -EACCES; 343 return hsi_get_port(cl)->setup(cl); 344 } 345 346 /** 347 * hsi_flush - Flush all pending transactions on the client's port 348 * @cl: Pointer to the HSI client 349 * 350 * This function will destroy all pending hsi_msg in the port and reset 351 * the HW port so it is ready to receive and transmit from a clean state. 352 * 353 * Return -errno on failure, 0 on success 354 */ 355 static inline int hsi_flush(struct hsi_client *cl) 356 { 357 if (!hsi_port_claimed(cl)) 358 return -EACCES; 359 return hsi_get_port(cl)->flush(cl); 360 } 361 362 /** 363 * hsi_async_read - Submit a read transfer 364 * @cl: Pointer to the HSI client 365 * @msg: HSI message descriptor of the transfer 366 * 367 * Return -errno on failure, 0 on success 368 */ 369 static inline int hsi_async_read(struct hsi_client *cl, struct hsi_msg *msg) 370 { 371 msg->ttype = HSI_MSG_READ; 372 return hsi_async(cl, msg); 373 } 374 375 /** 376 * hsi_async_write - Submit a write transfer 377 * @cl: Pointer to the HSI client 378 * @msg: HSI message descriptor of the transfer 379 * 380 * Return -errno on failure, 0 on success 381 */ 382 static inline int hsi_async_write(struct hsi_client *cl, struct hsi_msg *msg) 383 { 384 msg->ttype = HSI_MSG_WRITE; 385 return hsi_async(cl, msg); 386 } 387 388 /** 389 * hsi_start_tx - Signal the port that the client wants to start a TX 390 * @cl: Pointer to the HSI client 391 * 392 * Return -errno on failure, 0 on success 393 */ 394 static inline int hsi_start_tx(struct hsi_client *cl) 395 { 396 if (!hsi_port_claimed(cl)) 397 return -EACCES; 398 return hsi_get_port(cl)->start_tx(cl); 399 } 400 401 /** 402 * hsi_stop_tx - Signal the port that the client no longer wants to transmit 403 * @cl: Pointer to the HSI client 404 * 405 * Return -errno on failure, 0 on success 406 */ 407 static inline int hsi_stop_tx(struct hsi_client *cl) 408 { 409 if (!hsi_port_claimed(cl)) 410 return -EACCES; 411 return hsi_get_port(cl)->stop_tx(cl); 412 } 413 #endif /* __LINUX_HSI_H__ */ 414