at v4.6 12 kB view raw
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/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 */ 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_channel - channel resource used by the hsi clients 72 * @id: Channel number 73 * @name: Channel name 74 */ 75struct hsi_channel { 76 unsigned int id; 77 const char *name; 78}; 79 80/** 81 * struct hsi_config - Configuration for RX/TX HSI modules 82 * @mode: Bit transmission mode (STREAM or FRAME) 83 * @channels: Channel resources used by the client 84 * @num_channels: Number of channel resources 85 * @num_hw_channels: Number of channels the transceiver is configured for [1..16] 86 * @speed: Max bit transmission speed (Kbit/s) 87 * @flow: RX flow type (SYNCHRONIZED or PIPELINE) 88 * @arb_mode: Arbitration mode for TX frame (Round robin, priority) 89 */ 90struct hsi_config { 91 unsigned int mode; 92 struct hsi_channel *channels; 93 unsigned int num_channels; 94 unsigned int num_hw_channels; 95 unsigned int speed; 96 union { 97 unsigned int flow; /* RX only */ 98 unsigned int arb_mode; /* TX only */ 99 }; 100}; 101 102/** 103 * struct hsi_board_info - HSI client board info 104 * @name: Name for the HSI device 105 * @hsi_id: HSI controller id where the client sits 106 * @port: Port number in the controller where the client sits 107 * @tx_cfg: HSI TX configuration 108 * @rx_cfg: HSI RX configuration 109 * @platform_data: Platform related data 110 * @archdata: Architecture-dependent device data 111 */ 112struct hsi_board_info { 113 const char *name; 114 unsigned int hsi_id; 115 unsigned int port; 116 struct hsi_config tx_cfg; 117 struct hsi_config rx_cfg; 118 void *platform_data; 119 struct dev_archdata *archdata; 120}; 121 122#ifdef CONFIG_HSI_BOARDINFO 123extern int hsi_register_board_info(struct hsi_board_info const *info, 124 unsigned int len); 125#else 126static inline int hsi_register_board_info(struct hsi_board_info const *info, 127 unsigned int len) 128{ 129 return 0; 130} 131#endif /* CONFIG_HSI_BOARDINFO */ 132 133/** 134 * struct hsi_client - HSI client attached to an HSI port 135 * @device: Driver model representation of the device 136 * @tx_cfg: HSI TX configuration 137 * @rx_cfg: HSI RX configuration 138 */ 139struct hsi_client { 140 struct device device; 141 struct hsi_config tx_cfg; 142 struct hsi_config rx_cfg; 143 /* private: */ 144 void (*ehandler)(struct hsi_client *, unsigned long); 145 unsigned int pclaimed:1; 146 struct notifier_block nb; 147}; 148 149#define to_hsi_client(dev) container_of(dev, struct hsi_client, device) 150 151static inline void hsi_client_set_drvdata(struct hsi_client *cl, void *data) 152{ 153 dev_set_drvdata(&cl->device, data); 154} 155 156static inline void *hsi_client_drvdata(struct hsi_client *cl) 157{ 158 return dev_get_drvdata(&cl->device); 159} 160 161int hsi_register_port_event(struct hsi_client *cl, 162 void (*handler)(struct hsi_client *, unsigned long)); 163int hsi_unregister_port_event(struct hsi_client *cl); 164 165/** 166 * struct hsi_client_driver - Driver associated to an HSI client 167 * @driver: Driver model representation of the driver 168 */ 169struct hsi_client_driver { 170 struct device_driver driver; 171}; 172 173#define to_hsi_client_driver(drv) container_of(drv, struct hsi_client_driver,\ 174 driver) 175 176int hsi_register_client_driver(struct hsi_client_driver *drv); 177 178static inline void hsi_unregister_client_driver(struct hsi_client_driver *drv) 179{ 180 driver_unregister(&drv->driver); 181} 182 183/** 184 * struct hsi_msg - HSI message descriptor 185 * @link: Free to use by the current descriptor owner 186 * @cl: HSI device client that issues the transfer 187 * @sgt: Head of the scatterlist array 188 * @context: Client context data associated to the transfer 189 * @complete: Transfer completion callback 190 * @destructor: Destructor to free resources when flushing 191 * @status: Status of the transfer when completed 192 * @actual_len: Actual length of data transferred on completion 193 * @channel: Channel were to TX/RX the message 194 * @ttype: Transfer type (TX if set, RX otherwise) 195 * @break_frame: if true HSI will send/receive a break frame. Data buffers are 196 * ignored in the request. 197 */ 198struct hsi_msg { 199 struct list_head link; 200 struct hsi_client *cl; 201 struct sg_table sgt; 202 void *context; 203 204 void (*complete)(struct hsi_msg *msg); 205 void (*destructor)(struct hsi_msg *msg); 206 207 int status; 208 unsigned int actual_len; 209 unsigned int channel; 210 unsigned int ttype:1; 211 unsigned int break_frame:1; 212}; 213 214struct hsi_msg *hsi_alloc_msg(unsigned int n_frag, gfp_t flags); 215void hsi_free_msg(struct hsi_msg *msg); 216 217/** 218 * struct hsi_port - HSI port device 219 * @device: Driver model representation of the device 220 * @tx_cfg: Current TX path configuration 221 * @rx_cfg: Current RX path configuration 222 * @num: Port number 223 * @shared: Set when port can be shared by different clients 224 * @claimed: Reference count of clients which claimed the port 225 * @lock: Serialize port claim 226 * @async: Asynchronous transfer callback 227 * @setup: Callback to set the HSI client configuration 228 * @flush: Callback to clean the HW state and destroy all pending transfers 229 * @start_tx: Callback to inform that a client wants to TX data 230 * @stop_tx: Callback to inform that a client no longer wishes to TX data 231 * @release: Callback to inform that a client no longer uses the port 232 * @n_head: Notifier chain for signaling port events to the clients. 233 */ 234struct hsi_port { 235 struct device device; 236 struct hsi_config tx_cfg; 237 struct hsi_config rx_cfg; 238 unsigned int num; 239 unsigned int shared:1; 240 int claimed; 241 struct mutex lock; 242 int (*async)(struct hsi_msg *msg); 243 int (*setup)(struct hsi_client *cl); 244 int (*flush)(struct hsi_client *cl); 245 int (*start_tx)(struct hsi_client *cl); 246 int (*stop_tx)(struct hsi_client *cl); 247 int (*release)(struct hsi_client *cl); 248 /* private */ 249 struct atomic_notifier_head n_head; 250}; 251 252#define to_hsi_port(dev) container_of(dev, struct hsi_port, device) 253#define hsi_get_port(cl) to_hsi_port((cl)->device.parent) 254 255int hsi_event(struct hsi_port *port, unsigned long event); 256int hsi_claim_port(struct hsi_client *cl, unsigned int share); 257void hsi_release_port(struct hsi_client *cl); 258 259static inline int hsi_port_claimed(struct hsi_client *cl) 260{ 261 return cl->pclaimed; 262} 263 264static inline void hsi_port_set_drvdata(struct hsi_port *port, void *data) 265{ 266 dev_set_drvdata(&port->device, data); 267} 268 269static inline void *hsi_port_drvdata(struct hsi_port *port) 270{ 271 return dev_get_drvdata(&port->device); 272} 273 274/** 275 * struct hsi_controller - HSI controller device 276 * @device: Driver model representation of the device 277 * @owner: Pointer to the module owning the controller 278 * @id: HSI controller ID 279 * @num_ports: Number of ports in the HSI controller 280 * @port: Array of HSI ports 281 */ 282struct hsi_controller { 283 struct device device; 284 struct module *owner; 285 unsigned int id; 286 unsigned int num_ports; 287 struct hsi_port **port; 288}; 289 290#define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device) 291 292struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags); 293void hsi_put_controller(struct hsi_controller *hsi); 294int hsi_register_controller(struct hsi_controller *hsi); 295void hsi_unregister_controller(struct hsi_controller *hsi); 296struct hsi_client *hsi_new_client(struct hsi_port *port, 297 struct hsi_board_info *info); 298int hsi_remove_client(struct device *dev, void *data); 299void hsi_port_unregister_clients(struct hsi_port *port); 300 301#ifdef CONFIG_OF 302void hsi_add_clients_from_dt(struct hsi_port *port, 303 struct device_node *clients); 304#else 305static inline void hsi_add_clients_from_dt(struct hsi_port *port, 306 struct device_node *clients) 307{ 308 return; 309} 310#endif 311 312static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi, 313 void *data) 314{ 315 dev_set_drvdata(&hsi->device, data); 316} 317 318static inline void *hsi_controller_drvdata(struct hsi_controller *hsi) 319{ 320 return dev_get_drvdata(&hsi->device); 321} 322 323static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi, 324 unsigned int num) 325{ 326 return (num < hsi->num_ports) ? hsi->port[num] : NULL; 327} 328 329/* 330 * API for HSI clients 331 */ 332int hsi_async(struct hsi_client *cl, struct hsi_msg *msg); 333 334int hsi_get_channel_id_by_name(struct hsi_client *cl, char *name); 335 336/** 337 * hsi_id - Get HSI controller ID associated to a client 338 * @cl: Pointer to a HSI client 339 * 340 * Return the controller id where the client is attached to 341 */ 342static inline unsigned int hsi_id(struct hsi_client *cl) 343{ 344 return to_hsi_controller(cl->device.parent->parent)->id; 345} 346 347/** 348 * hsi_port_id - Gets the port number a client is attached to 349 * @cl: Pointer to HSI client 350 * 351 * Return the port number associated to the client 352 */ 353static inline unsigned int hsi_port_id(struct hsi_client *cl) 354{ 355 return to_hsi_port(cl->device.parent)->num; 356} 357 358/** 359 * hsi_setup - Configure the client's port 360 * @cl: Pointer to the HSI client 361 * 362 * When sharing ports, clients should either relay on a single 363 * client setup or have the same setup for all of them. 364 * 365 * Return -errno on failure, 0 on success 366 */ 367static inline int hsi_setup(struct hsi_client *cl) 368{ 369 if (!hsi_port_claimed(cl)) 370 return -EACCES; 371 return hsi_get_port(cl)->setup(cl); 372} 373 374/** 375 * hsi_flush - Flush all pending transactions on the client's port 376 * @cl: Pointer to the HSI client 377 * 378 * This function will destroy all pending hsi_msg in the port and reset 379 * the HW port so it is ready to receive and transmit from a clean state. 380 * 381 * Return -errno on failure, 0 on success 382 */ 383static inline int hsi_flush(struct hsi_client *cl) 384{ 385 if (!hsi_port_claimed(cl)) 386 return -EACCES; 387 return hsi_get_port(cl)->flush(cl); 388} 389 390/** 391 * hsi_async_read - Submit a read transfer 392 * @cl: Pointer to the HSI client 393 * @msg: HSI message descriptor of the transfer 394 * 395 * Return -errno on failure, 0 on success 396 */ 397static inline int hsi_async_read(struct hsi_client *cl, struct hsi_msg *msg) 398{ 399 msg->ttype = HSI_MSG_READ; 400 return hsi_async(cl, msg); 401} 402 403/** 404 * hsi_async_write - Submit a write transfer 405 * @cl: Pointer to the HSI client 406 * @msg: HSI message descriptor of the transfer 407 * 408 * Return -errno on failure, 0 on success 409 */ 410static inline int hsi_async_write(struct hsi_client *cl, struct hsi_msg *msg) 411{ 412 msg->ttype = HSI_MSG_WRITE; 413 return hsi_async(cl, msg); 414} 415 416/** 417 * hsi_start_tx - Signal the port that the client wants to start a TX 418 * @cl: Pointer to the HSI client 419 * 420 * Return -errno on failure, 0 on success 421 */ 422static inline int hsi_start_tx(struct hsi_client *cl) 423{ 424 if (!hsi_port_claimed(cl)) 425 return -EACCES; 426 return hsi_get_port(cl)->start_tx(cl); 427} 428 429/** 430 * hsi_stop_tx - Signal the port that the client no longer wants to transmit 431 * @cl: Pointer to the HSI client 432 * 433 * Return -errno on failure, 0 on success 434 */ 435static inline int hsi_stop_tx(struct hsi_client *cl) 436{ 437 if (!hsi_port_claimed(cl)) 438 return -EACCES; 439 return hsi_get_port(cl)->stop_tx(cl); 440} 441#endif /* __LINUX_HSI_H__ */