Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.14-rc3 509 lines 13 kB view raw
1/* 2 * HSI core. 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#include <linux/hsi/hsi.h> 23#include <linux/compiler.h> 24#include <linux/list.h> 25#include <linux/kobject.h> 26#include <linux/slab.h> 27#include <linux/string.h> 28#include <linux/notifier.h> 29#include "hsi_core.h" 30 31static ssize_t modalias_show(struct device *dev, 32 struct device_attribute *a __maybe_unused, char *buf) 33{ 34 return sprintf(buf, "hsi:%s\n", dev_name(dev)); 35} 36static DEVICE_ATTR_RO(modalias); 37 38static struct attribute *hsi_bus_dev_attrs[] = { 39 &dev_attr_modalias.attr, 40 NULL, 41}; 42ATTRIBUTE_GROUPS(hsi_bus_dev); 43 44static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env) 45{ 46 add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev)); 47 48 return 0; 49} 50 51static int hsi_bus_match(struct device *dev, struct device_driver *driver) 52{ 53 return strcmp(dev_name(dev), driver->name) == 0; 54} 55 56static struct bus_type hsi_bus_type = { 57 .name = "hsi", 58 .dev_groups = hsi_bus_dev_groups, 59 .match = hsi_bus_match, 60 .uevent = hsi_bus_uevent, 61}; 62 63static void hsi_client_release(struct device *dev) 64{ 65 kfree(to_hsi_client(dev)); 66} 67 68static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info) 69{ 70 struct hsi_client *cl; 71 72 cl = kzalloc(sizeof(*cl), GFP_KERNEL); 73 if (!cl) 74 return; 75 cl->tx_cfg = info->tx_cfg; 76 cl->rx_cfg = info->rx_cfg; 77 cl->device.bus = &hsi_bus_type; 78 cl->device.parent = &port->device; 79 cl->device.release = hsi_client_release; 80 dev_set_name(&cl->device, "%s", info->name); 81 cl->device.platform_data = info->platform_data; 82 if (info->archdata) 83 cl->device.archdata = *info->archdata; 84 if (device_register(&cl->device) < 0) { 85 pr_err("hsi: failed to register client: %s\n", info->name); 86 put_device(&cl->device); 87 } 88} 89 90static void hsi_scan_board_info(struct hsi_controller *hsi) 91{ 92 struct hsi_cl_info *cl_info; 93 struct hsi_port *p; 94 95 list_for_each_entry(cl_info, &hsi_board_list, list) 96 if (cl_info->info.hsi_id == hsi->id) { 97 p = hsi_find_port_num(hsi, cl_info->info.port); 98 if (!p) 99 continue; 100 hsi_new_client(p, &cl_info->info); 101 } 102} 103 104static int hsi_remove_client(struct device *dev, void *data __maybe_unused) 105{ 106 device_unregister(dev); 107 108 return 0; 109} 110 111static int hsi_remove_port(struct device *dev, void *data __maybe_unused) 112{ 113 device_for_each_child(dev, NULL, hsi_remove_client); 114 device_unregister(dev); 115 116 return 0; 117} 118 119static void hsi_controller_release(struct device *dev) 120{ 121 struct hsi_controller *hsi = to_hsi_controller(dev); 122 123 kfree(hsi->port); 124 kfree(hsi); 125} 126 127static void hsi_port_release(struct device *dev) 128{ 129 kfree(to_hsi_port(dev)); 130} 131 132/** 133 * hsi_unregister_controller - Unregister an HSI controller 134 * @hsi: The HSI controller to register 135 */ 136void hsi_unregister_controller(struct hsi_controller *hsi) 137{ 138 device_for_each_child(&hsi->device, NULL, hsi_remove_port); 139 device_unregister(&hsi->device); 140} 141EXPORT_SYMBOL_GPL(hsi_unregister_controller); 142 143/** 144 * hsi_register_controller - Register an HSI controller and its ports 145 * @hsi: The HSI controller to register 146 * 147 * Returns -errno on failure, 0 on success. 148 */ 149int hsi_register_controller(struct hsi_controller *hsi) 150{ 151 unsigned int i; 152 int err; 153 154 err = device_add(&hsi->device); 155 if (err < 0) 156 return err; 157 for (i = 0; i < hsi->num_ports; i++) { 158 hsi->port[i]->device.parent = &hsi->device; 159 err = device_add(&hsi->port[i]->device); 160 if (err < 0) 161 goto out; 162 } 163 /* Populate HSI bus with HSI clients */ 164 hsi_scan_board_info(hsi); 165 166 return 0; 167out: 168 while (i-- > 0) 169 device_del(&hsi->port[i]->device); 170 device_del(&hsi->device); 171 172 return err; 173} 174EXPORT_SYMBOL_GPL(hsi_register_controller); 175 176/** 177 * hsi_register_client_driver - Register an HSI client to the HSI bus 178 * @drv: HSI client driver to register 179 * 180 * Returns -errno on failure, 0 on success. 181 */ 182int hsi_register_client_driver(struct hsi_client_driver *drv) 183{ 184 drv->driver.bus = &hsi_bus_type; 185 186 return driver_register(&drv->driver); 187} 188EXPORT_SYMBOL_GPL(hsi_register_client_driver); 189 190static inline int hsi_dummy_msg(struct hsi_msg *msg __maybe_unused) 191{ 192 return 0; 193} 194 195static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused) 196{ 197 return 0; 198} 199 200/** 201 * hsi_put_controller - Free an HSI controller 202 * 203 * @hsi: Pointer to the HSI controller to freed 204 * 205 * HSI controller drivers should only use this function if they need 206 * to free their allocated hsi_controller structures before a successful 207 * call to hsi_register_controller. Other use is not allowed. 208 */ 209void hsi_put_controller(struct hsi_controller *hsi) 210{ 211 unsigned int i; 212 213 if (!hsi) 214 return; 215 216 for (i = 0; i < hsi->num_ports; i++) 217 if (hsi->port && hsi->port[i]) 218 put_device(&hsi->port[i]->device); 219 put_device(&hsi->device); 220} 221EXPORT_SYMBOL_GPL(hsi_put_controller); 222 223/** 224 * hsi_alloc_controller - Allocate an HSI controller and its ports 225 * @n_ports: Number of ports on the HSI controller 226 * @flags: Kernel allocation flags 227 * 228 * Return NULL on failure or a pointer to an hsi_controller on success. 229 */ 230struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags) 231{ 232 struct hsi_controller *hsi; 233 struct hsi_port **port; 234 unsigned int i; 235 236 if (!n_ports) 237 return NULL; 238 239 hsi = kzalloc(sizeof(*hsi), flags); 240 if (!hsi) 241 return NULL; 242 port = kzalloc(sizeof(*port)*n_ports, flags); 243 if (!port) { 244 kfree(hsi); 245 return NULL; 246 } 247 hsi->num_ports = n_ports; 248 hsi->port = port; 249 hsi->device.release = hsi_controller_release; 250 device_initialize(&hsi->device); 251 252 for (i = 0; i < n_ports; i++) { 253 port[i] = kzalloc(sizeof(**port), flags); 254 if (port[i] == NULL) 255 goto out; 256 port[i]->num = i; 257 port[i]->async = hsi_dummy_msg; 258 port[i]->setup = hsi_dummy_cl; 259 port[i]->flush = hsi_dummy_cl; 260 port[i]->start_tx = hsi_dummy_cl; 261 port[i]->stop_tx = hsi_dummy_cl; 262 port[i]->release = hsi_dummy_cl; 263 mutex_init(&port[i]->lock); 264 ATOMIC_INIT_NOTIFIER_HEAD(&port[i]->n_head); 265 dev_set_name(&port[i]->device, "port%d", i); 266 hsi->port[i]->device.release = hsi_port_release; 267 device_initialize(&hsi->port[i]->device); 268 } 269 270 return hsi; 271out: 272 hsi_put_controller(hsi); 273 274 return NULL; 275} 276EXPORT_SYMBOL_GPL(hsi_alloc_controller); 277 278/** 279 * hsi_free_msg - Free an HSI message 280 * @msg: Pointer to the HSI message 281 * 282 * Client is responsible to free the buffers pointed by the scatterlists. 283 */ 284void hsi_free_msg(struct hsi_msg *msg) 285{ 286 if (!msg) 287 return; 288 sg_free_table(&msg->sgt); 289 kfree(msg); 290} 291EXPORT_SYMBOL_GPL(hsi_free_msg); 292 293/** 294 * hsi_alloc_msg - Allocate an HSI message 295 * @nents: Number of memory entries 296 * @flags: Kernel allocation flags 297 * 298 * nents can be 0. This mainly makes sense for read transfer. 299 * In that case, HSI drivers will call the complete callback when 300 * there is data to be read without consuming it. 301 * 302 * Return NULL on failure or a pointer to an hsi_msg on success. 303 */ 304struct hsi_msg *hsi_alloc_msg(unsigned int nents, gfp_t flags) 305{ 306 struct hsi_msg *msg; 307 int err; 308 309 msg = kzalloc(sizeof(*msg), flags); 310 if (!msg) 311 return NULL; 312 313 if (!nents) 314 return msg; 315 316 err = sg_alloc_table(&msg->sgt, nents, flags); 317 if (unlikely(err)) { 318 kfree(msg); 319 msg = NULL; 320 } 321 322 return msg; 323} 324EXPORT_SYMBOL_GPL(hsi_alloc_msg); 325 326/** 327 * hsi_async - Submit an HSI transfer to the controller 328 * @cl: HSI client sending the transfer 329 * @msg: The HSI transfer passed to controller 330 * 331 * The HSI message must have the channel, ttype, complete and destructor 332 * fields set beforehand. If nents > 0 then the client has to initialize 333 * also the scatterlists to point to the buffers to write to or read from. 334 * 335 * HSI controllers relay on pre-allocated buffers from their clients and they 336 * do not allocate buffers on their own. 337 * 338 * Once the HSI message transfer finishes, the HSI controller calls the 339 * complete callback with the status and actual_len fields of the HSI message 340 * updated. The complete callback can be called before returning from 341 * hsi_async. 342 * 343 * Returns -errno on failure or 0 on success 344 */ 345int hsi_async(struct hsi_client *cl, struct hsi_msg *msg) 346{ 347 struct hsi_port *port = hsi_get_port(cl); 348 349 if (!hsi_port_claimed(cl)) 350 return -EACCES; 351 352 WARN_ON_ONCE(!msg->destructor || !msg->complete); 353 msg->cl = cl; 354 355 return port->async(msg); 356} 357EXPORT_SYMBOL_GPL(hsi_async); 358 359/** 360 * hsi_claim_port - Claim the HSI client's port 361 * @cl: HSI client that wants to claim its port 362 * @share: Flag to indicate if the client wants to share the port or not. 363 * 364 * Returns -errno on failure, 0 on success. 365 */ 366int hsi_claim_port(struct hsi_client *cl, unsigned int share) 367{ 368 struct hsi_port *port = hsi_get_port(cl); 369 int err = 0; 370 371 mutex_lock(&port->lock); 372 if ((port->claimed) && (!port->shared || !share)) { 373 err = -EBUSY; 374 goto out; 375 } 376 if (!try_module_get(to_hsi_controller(port->device.parent)->owner)) { 377 err = -ENODEV; 378 goto out; 379 } 380 port->claimed++; 381 port->shared = !!share; 382 cl->pclaimed = 1; 383out: 384 mutex_unlock(&port->lock); 385 386 return err; 387} 388EXPORT_SYMBOL_GPL(hsi_claim_port); 389 390/** 391 * hsi_release_port - Release the HSI client's port 392 * @cl: HSI client which previously claimed its port 393 */ 394void hsi_release_port(struct hsi_client *cl) 395{ 396 struct hsi_port *port = hsi_get_port(cl); 397 398 mutex_lock(&port->lock); 399 /* Allow HW driver to do some cleanup */ 400 port->release(cl); 401 if (cl->pclaimed) 402 port->claimed--; 403 BUG_ON(port->claimed < 0); 404 cl->pclaimed = 0; 405 if (!port->claimed) 406 port->shared = 0; 407 module_put(to_hsi_controller(port->device.parent)->owner); 408 mutex_unlock(&port->lock); 409} 410EXPORT_SYMBOL_GPL(hsi_release_port); 411 412static int hsi_event_notifier_call(struct notifier_block *nb, 413 unsigned long event, void *data __maybe_unused) 414{ 415 struct hsi_client *cl = container_of(nb, struct hsi_client, nb); 416 417 (*cl->ehandler)(cl, event); 418 419 return 0; 420} 421 422/** 423 * hsi_register_port_event - Register a client to receive port events 424 * @cl: HSI client that wants to receive port events 425 * @handler: Event handler callback 426 * 427 * Clients should register a callback to be able to receive 428 * events from the ports. Registration should happen after 429 * claiming the port. 430 * The handler can be called in interrupt context. 431 * 432 * Returns -errno on error, or 0 on success. 433 */ 434int hsi_register_port_event(struct hsi_client *cl, 435 void (*handler)(struct hsi_client *, unsigned long)) 436{ 437 struct hsi_port *port = hsi_get_port(cl); 438 439 if (!handler || cl->ehandler) 440 return -EINVAL; 441 if (!hsi_port_claimed(cl)) 442 return -EACCES; 443 cl->ehandler = handler; 444 cl->nb.notifier_call = hsi_event_notifier_call; 445 446 return atomic_notifier_chain_register(&port->n_head, &cl->nb); 447} 448EXPORT_SYMBOL_GPL(hsi_register_port_event); 449 450/** 451 * hsi_unregister_port_event - Stop receiving port events for a client 452 * @cl: HSI client that wants to stop receiving port events 453 * 454 * Clients should call this function before releasing their associated 455 * port. 456 * 457 * Returns -errno on error, or 0 on success. 458 */ 459int hsi_unregister_port_event(struct hsi_client *cl) 460{ 461 struct hsi_port *port = hsi_get_port(cl); 462 int err; 463 464 WARN_ON(!hsi_port_claimed(cl)); 465 466 err = atomic_notifier_chain_unregister(&port->n_head, &cl->nb); 467 if (!err) 468 cl->ehandler = NULL; 469 470 return err; 471} 472EXPORT_SYMBOL_GPL(hsi_unregister_port_event); 473 474/** 475 * hsi_event -Notifies clients about port events 476 * @port: Port where the event occurred 477 * @event: The event type 478 * 479 * Clients should not be concerned about wake line behavior. However, due 480 * to a race condition in HSI HW protocol, clients need to be notified 481 * about wake line changes, so they can implement a workaround for it. 482 * 483 * Events: 484 * HSI_EVENT_START_RX - Incoming wake line high 485 * HSI_EVENT_STOP_RX - Incoming wake line down 486 * 487 * Returns -errno on error, or 0 on success. 488 */ 489int hsi_event(struct hsi_port *port, unsigned long event) 490{ 491 return atomic_notifier_call_chain(&port->n_head, event, NULL); 492} 493EXPORT_SYMBOL_GPL(hsi_event); 494 495static int __init hsi_init(void) 496{ 497 return bus_register(&hsi_bus_type); 498} 499postcore_initcall(hsi_init); 500 501static void __exit hsi_exit(void) 502{ 503 bus_unregister(&hsi_bus_type); 504} 505module_exit(hsi_exit); 506 507MODULE_AUTHOR("Carlos Chinea <carlos.chinea@nokia.com>"); 508MODULE_DESCRIPTION("High-speed Synchronous Serial Interface (HSI) framework"); 509MODULE_LICENSE("GPL v2");