root/drivers/media/cec/cec-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cec_get_device
  2. cec_put_device
  3. cec_devnode_release
  4. cec_devnode_register
  5. cec_devnode_unregister
  6. cec_cec_notify
  7. cec_register_cec_notifier
  8. cec_error_inj_write
  9. cec_error_inj_show
  10. cec_error_inj_open
  11. cec_allocate_adapter
  12. cec_register_adapter
  13. cec_unregister_adapter
  14. cec_delete_adapter
  15. cec_devnode_init
  16. cec_devnode_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * cec-core.c - HDMI Consumer Electronics Control framework - Core
   4  *
   5  * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
   6  */
   7 
   8 #include <linux/errno.h>
   9 #include <linux/init.h>
  10 #include <linux/module.h>
  11 #include <linux/kernel.h>
  12 #include <linux/kmod.h>
  13 #include <linux/slab.h>
  14 #include <linux/mm.h>
  15 #include <linux/string.h>
  16 #include <linux/types.h>
  17 
  18 #include "cec-priv.h"
  19 
  20 #define CEC_NUM_DEVICES 256
  21 #define CEC_NAME        "cec"
  22 
  23 int cec_debug;
  24 module_param_named(debug, cec_debug, int, 0644);
  25 MODULE_PARM_DESC(debug, "debug level (0-2)");
  26 
  27 static bool debug_phys_addr;
  28 module_param(debug_phys_addr, bool, 0644);
  29 MODULE_PARM_DESC(debug_phys_addr, "add CEC_CAP_PHYS_ADDR if set");
  30 
  31 static dev_t cec_dev_t;
  32 
  33 /* Active devices */
  34 static DEFINE_MUTEX(cec_devnode_lock);
  35 static DECLARE_BITMAP(cec_devnode_nums, CEC_NUM_DEVICES);
  36 
  37 static struct dentry *top_cec_dir;
  38 
  39 /* dev to cec_devnode */
  40 #define to_cec_devnode(cd) container_of(cd, struct cec_devnode, dev)
  41 
  42 int cec_get_device(struct cec_devnode *devnode)
  43 {
  44         /*
  45          * Check if the cec device is available. This needs to be done with
  46          * the devnode->lock held to prevent an open/unregister race:
  47          * without the lock, the device could be unregistered and freed between
  48          * the devnode->registered check and get_device() calls, leading to
  49          * a crash.
  50          */
  51         mutex_lock(&devnode->lock);
  52         /*
  53          * return ENXIO if the cec device has been removed
  54          * already or if it is not registered anymore.
  55          */
  56         if (!devnode->registered) {
  57                 mutex_unlock(&devnode->lock);
  58                 return -ENXIO;
  59         }
  60         /* and increase the device refcount */
  61         get_device(&devnode->dev);
  62         mutex_unlock(&devnode->lock);
  63         return 0;
  64 }
  65 
  66 void cec_put_device(struct cec_devnode *devnode)
  67 {
  68         put_device(&devnode->dev);
  69 }
  70 
  71 /* Called when the last user of the cec device exits. */
  72 static void cec_devnode_release(struct device *cd)
  73 {
  74         struct cec_devnode *devnode = to_cec_devnode(cd);
  75 
  76         mutex_lock(&cec_devnode_lock);
  77         /* Mark device node number as free */
  78         clear_bit(devnode->minor, cec_devnode_nums);
  79         mutex_unlock(&cec_devnode_lock);
  80 
  81         cec_delete_adapter(to_cec_adapter(devnode));
  82 }
  83 
  84 static struct bus_type cec_bus_type = {
  85         .name = CEC_NAME,
  86 };
  87 
  88 /*
  89  * Register a cec device node
  90  *
  91  * The registration code assigns minor numbers and registers the new device node
  92  * with the kernel. An error is returned if no free minor number can be found,
  93  * or if the registration of the device node fails.
  94  *
  95  * Zero is returned on success.
  96  *
  97  * Note that if the cec_devnode_register call fails, the release() callback of
  98  * the cec_devnode structure is *not* called, so the caller is responsible for
  99  * freeing any data.
 100  */
 101 static int __must_check cec_devnode_register(struct cec_devnode *devnode,
 102                                              struct module *owner)
 103 {
 104         int minor;
 105         int ret;
 106 
 107         /* Part 1: Find a free minor number */
 108         mutex_lock(&cec_devnode_lock);
 109         minor = find_next_zero_bit(cec_devnode_nums, CEC_NUM_DEVICES, 0);
 110         if (minor == CEC_NUM_DEVICES) {
 111                 mutex_unlock(&cec_devnode_lock);
 112                 pr_err("could not get a free minor\n");
 113                 return -ENFILE;
 114         }
 115 
 116         set_bit(minor, cec_devnode_nums);
 117         mutex_unlock(&cec_devnode_lock);
 118 
 119         devnode->minor = minor;
 120         devnode->dev.bus = &cec_bus_type;
 121         devnode->dev.devt = MKDEV(MAJOR(cec_dev_t), minor);
 122         devnode->dev.release = cec_devnode_release;
 123         dev_set_name(&devnode->dev, "cec%d", devnode->minor);
 124         device_initialize(&devnode->dev);
 125 
 126         /* Part 2: Initialize and register the character device */
 127         cdev_init(&devnode->cdev, &cec_devnode_fops);
 128         devnode->cdev.owner = owner;
 129         kobject_set_name(&devnode->cdev.kobj, "cec%d", devnode->minor);
 130 
 131         devnode->registered = true;
 132         ret = cdev_device_add(&devnode->cdev, &devnode->dev);
 133         if (ret) {
 134                 devnode->registered = false;
 135                 pr_err("%s: cdev_device_add failed\n", __func__);
 136                 goto clr_bit;
 137         }
 138 
 139         return 0;
 140 
 141 clr_bit:
 142         mutex_lock(&cec_devnode_lock);
 143         clear_bit(devnode->minor, cec_devnode_nums);
 144         mutex_unlock(&cec_devnode_lock);
 145         return ret;
 146 }
 147 
 148 /*
 149  * Unregister a cec device node
 150  *
 151  * This unregisters the passed device. Future open calls will be met with
 152  * errors.
 153  *
 154  * This function can safely be called if the device node has never been
 155  * registered or has already been unregistered.
 156  */
 157 static void cec_devnode_unregister(struct cec_adapter *adap)
 158 {
 159         struct cec_devnode *devnode = &adap->devnode;
 160         struct cec_fh *fh;
 161 
 162         mutex_lock(&devnode->lock);
 163 
 164         /* Check if devnode was never registered or already unregistered */
 165         if (!devnode->registered || devnode->unregistered) {
 166                 mutex_unlock(&devnode->lock);
 167                 return;
 168         }
 169 
 170         list_for_each_entry(fh, &devnode->fhs, list)
 171                 wake_up_interruptible(&fh->wait);
 172 
 173         devnode->registered = false;
 174         devnode->unregistered = true;
 175         mutex_unlock(&devnode->lock);
 176 
 177         mutex_lock(&adap->lock);
 178         __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
 179         __cec_s_log_addrs(adap, NULL, false);
 180         mutex_unlock(&adap->lock);
 181 
 182         cdev_device_del(&devnode->cdev, &devnode->dev);
 183         put_device(&devnode->dev);
 184 }
 185 
 186 #ifdef CONFIG_CEC_NOTIFIER
 187 static void cec_cec_notify(struct cec_adapter *adap, u16 pa)
 188 {
 189         cec_s_phys_addr(adap, pa, false);
 190 }
 191 
 192 void cec_register_cec_notifier(struct cec_adapter *adap,
 193                                struct cec_notifier *notifier)
 194 {
 195         if (WARN_ON(!cec_is_registered(adap)))
 196                 return;
 197 
 198         adap->notifier = notifier;
 199         cec_notifier_register(adap->notifier, adap, cec_cec_notify);
 200 }
 201 EXPORT_SYMBOL_GPL(cec_register_cec_notifier);
 202 #endif
 203 
 204 #ifdef CONFIG_DEBUG_FS
 205 static ssize_t cec_error_inj_write(struct file *file,
 206         const char __user *ubuf, size_t count, loff_t *ppos)
 207 {
 208         struct seq_file *sf = file->private_data;
 209         struct cec_adapter *adap = sf->private;
 210         char *buf;
 211         char *line;
 212         char *p;
 213 
 214         buf = memdup_user_nul(ubuf, min_t(size_t, PAGE_SIZE, count));
 215         if (IS_ERR(buf))
 216                 return PTR_ERR(buf);
 217         p = buf;
 218         while (p && *p) {
 219                 p = skip_spaces(p);
 220                 line = strsep(&p, "\n");
 221                 if (!*line || *line == '#')
 222                         continue;
 223                 if (!adap->ops->error_inj_parse_line(adap, line)) {
 224                         kfree(buf);
 225                         return -EINVAL;
 226                 }
 227         }
 228         kfree(buf);
 229         return count;
 230 }
 231 
 232 static int cec_error_inj_show(struct seq_file *sf, void *unused)
 233 {
 234         struct cec_adapter *adap = sf->private;
 235 
 236         return adap->ops->error_inj_show(adap, sf);
 237 }
 238 
 239 static int cec_error_inj_open(struct inode *inode, struct file *file)
 240 {
 241         return single_open(file, cec_error_inj_show, inode->i_private);
 242 }
 243 
 244 static const struct file_operations cec_error_inj_fops = {
 245         .open = cec_error_inj_open,
 246         .write = cec_error_inj_write,
 247         .read = seq_read,
 248         .llseek = seq_lseek,
 249         .release = single_release,
 250 };
 251 #endif
 252 
 253 struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
 254                                          void *priv, const char *name, u32 caps,
 255                                          u8 available_las)
 256 {
 257         struct cec_adapter *adap;
 258         int res;
 259 
 260         /*
 261          * Disable this capability until the connector info public API
 262          * is ready.
 263          */
 264         caps &= ~CEC_CAP_CONNECTOR_INFO;
 265 #ifndef CONFIG_MEDIA_CEC_RC
 266         caps &= ~CEC_CAP_RC;
 267 #endif
 268 
 269         if (WARN_ON(!caps))
 270                 return ERR_PTR(-EINVAL);
 271         if (WARN_ON(!ops))
 272                 return ERR_PTR(-EINVAL);
 273         if (WARN_ON(!available_las || available_las > CEC_MAX_LOG_ADDRS))
 274                 return ERR_PTR(-EINVAL);
 275         adap = kzalloc(sizeof(*adap), GFP_KERNEL);
 276         if (!adap)
 277                 return ERR_PTR(-ENOMEM);
 278         strscpy(adap->name, name, sizeof(adap->name));
 279         adap->phys_addr = CEC_PHYS_ADDR_INVALID;
 280         adap->cec_pin_is_high = true;
 281         adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
 282         adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE;
 283         adap->capabilities = caps;
 284         if (debug_phys_addr)
 285                 adap->capabilities |= CEC_CAP_PHYS_ADDR;
 286         adap->needs_hpd = caps & CEC_CAP_NEEDS_HPD;
 287         adap->available_log_addrs = available_las;
 288         adap->sequence = 0;
 289         adap->ops = ops;
 290         adap->priv = priv;
 291         memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
 292         mutex_init(&adap->lock);
 293         INIT_LIST_HEAD(&adap->transmit_queue);
 294         INIT_LIST_HEAD(&adap->wait_queue);
 295         init_waitqueue_head(&adap->kthread_waitq);
 296 
 297         /* adap->devnode initialization */
 298         INIT_LIST_HEAD(&adap->devnode.fhs);
 299         mutex_init(&adap->devnode.lock);
 300 
 301         adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name);
 302         if (IS_ERR(adap->kthread)) {
 303                 pr_err("cec-%s: kernel_thread() failed\n", name);
 304                 res = PTR_ERR(adap->kthread);
 305                 kfree(adap);
 306                 return ERR_PTR(res);
 307         }
 308 
 309 #ifdef CONFIG_MEDIA_CEC_RC
 310         if (!(caps & CEC_CAP_RC))
 311                 return adap;
 312 
 313         /* Prepare the RC input device */
 314         adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE);
 315         if (!adap->rc) {
 316                 pr_err("cec-%s: failed to allocate memory for rc_dev\n",
 317                        name);
 318                 kthread_stop(adap->kthread);
 319                 kfree(adap);
 320                 return ERR_PTR(-ENOMEM);
 321         }
 322 
 323         snprintf(adap->input_phys, sizeof(adap->input_phys),
 324                  "%s/input0", adap->name);
 325 
 326         adap->rc->device_name = adap->name;
 327         adap->rc->input_phys = adap->input_phys;
 328         adap->rc->input_id.bustype = BUS_CEC;
 329         adap->rc->input_id.vendor = 0;
 330         adap->rc->input_id.product = 0;
 331         adap->rc->input_id.version = 1;
 332         adap->rc->driver_name = CEC_NAME;
 333         adap->rc->allowed_protocols = RC_PROTO_BIT_CEC;
 334         adap->rc->priv = adap;
 335         adap->rc->map_name = RC_MAP_CEC;
 336         adap->rc->timeout = MS_TO_NS(550);
 337 #endif
 338         return adap;
 339 }
 340 EXPORT_SYMBOL_GPL(cec_allocate_adapter);
 341 
 342 int cec_register_adapter(struct cec_adapter *adap,
 343                          struct device *parent)
 344 {
 345         int res;
 346 
 347         if (IS_ERR_OR_NULL(adap))
 348                 return 0;
 349 
 350         if (WARN_ON(!parent))
 351                 return -EINVAL;
 352 
 353         adap->owner = parent->driver->owner;
 354         adap->devnode.dev.parent = parent;
 355 
 356 #ifdef CONFIG_MEDIA_CEC_RC
 357         if (adap->capabilities & CEC_CAP_RC) {
 358                 adap->rc->dev.parent = parent;
 359                 res = rc_register_device(adap->rc);
 360 
 361                 if (res) {
 362                         pr_err("cec-%s: failed to prepare input device\n",
 363                                adap->name);
 364                         rc_free_device(adap->rc);
 365                         adap->rc = NULL;
 366                         return res;
 367                 }
 368         }
 369 #endif
 370 
 371         res = cec_devnode_register(&adap->devnode, adap->owner);
 372         if (res) {
 373 #ifdef CONFIG_MEDIA_CEC_RC
 374                 /* Note: rc_unregister also calls rc_free */
 375                 rc_unregister_device(adap->rc);
 376                 adap->rc = NULL;
 377 #endif
 378                 return res;
 379         }
 380 
 381         dev_set_drvdata(&adap->devnode.dev, adap);
 382 #ifdef CONFIG_DEBUG_FS
 383         if (!top_cec_dir)
 384                 return 0;
 385 
 386         adap->cec_dir = debugfs_create_dir(dev_name(&adap->devnode.dev), top_cec_dir);
 387         if (IS_ERR_OR_NULL(adap->cec_dir)) {
 388                 pr_warn("cec-%s: Failed to create debugfs dir\n", adap->name);
 389                 return 0;
 390         }
 391         adap->status_file = debugfs_create_devm_seqfile(&adap->devnode.dev,
 392                 "status", adap->cec_dir, cec_adap_status);
 393         if (IS_ERR_OR_NULL(adap->status_file)) {
 394                 pr_warn("cec-%s: Failed to create status file\n", adap->name);
 395                 debugfs_remove_recursive(adap->cec_dir);
 396                 adap->cec_dir = NULL;
 397                 return 0;
 398         }
 399         if (!adap->ops->error_inj_show || !adap->ops->error_inj_parse_line)
 400                 return 0;
 401         adap->error_inj_file = debugfs_create_file("error-inj", 0644,
 402                                                    adap->cec_dir, adap,
 403                                                    &cec_error_inj_fops);
 404         if (IS_ERR_OR_NULL(adap->error_inj_file))
 405                 pr_warn("cec-%s: Failed to create error-inj file\n",
 406                         adap->name);
 407 #endif
 408         return 0;
 409 }
 410 EXPORT_SYMBOL_GPL(cec_register_adapter);
 411 
 412 void cec_unregister_adapter(struct cec_adapter *adap)
 413 {
 414         if (IS_ERR_OR_NULL(adap))
 415                 return;
 416 
 417 #ifdef CONFIG_MEDIA_CEC_RC
 418         /* Note: rc_unregister also calls rc_free */
 419         rc_unregister_device(adap->rc);
 420         adap->rc = NULL;
 421 #endif
 422         debugfs_remove_recursive(adap->cec_dir);
 423 #ifdef CONFIG_CEC_NOTIFIER
 424         if (adap->notifier)
 425                 cec_notifier_unregister(adap->notifier);
 426 #endif
 427         cec_devnode_unregister(adap);
 428 }
 429 EXPORT_SYMBOL_GPL(cec_unregister_adapter);
 430 
 431 void cec_delete_adapter(struct cec_adapter *adap)
 432 {
 433         if (IS_ERR_OR_NULL(adap))
 434                 return;
 435         kthread_stop(adap->kthread);
 436         if (adap->kthread_config)
 437                 kthread_stop(adap->kthread_config);
 438         if (adap->ops->adap_free)
 439                 adap->ops->adap_free(adap);
 440 #ifdef CONFIG_MEDIA_CEC_RC
 441         rc_free_device(adap->rc);
 442 #endif
 443         kfree(adap);
 444 }
 445 EXPORT_SYMBOL_GPL(cec_delete_adapter);
 446 
 447 /*
 448  *      Initialise cec for linux
 449  */
 450 static int __init cec_devnode_init(void)
 451 {
 452         int ret = alloc_chrdev_region(&cec_dev_t, 0, CEC_NUM_DEVICES, CEC_NAME);
 453 
 454         if (ret < 0) {
 455                 pr_warn("cec: unable to allocate major\n");
 456                 return ret;
 457         }
 458 
 459 #ifdef CONFIG_DEBUG_FS
 460         top_cec_dir = debugfs_create_dir("cec", NULL);
 461         if (IS_ERR_OR_NULL(top_cec_dir)) {
 462                 pr_warn("cec: Failed to create debugfs cec dir\n");
 463                 top_cec_dir = NULL;
 464         }
 465 #endif
 466 
 467         ret = bus_register(&cec_bus_type);
 468         if (ret < 0) {
 469                 unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES);
 470                 pr_warn("cec: bus_register failed\n");
 471                 return -EIO;
 472         }
 473 
 474         return 0;
 475 }
 476 
 477 static void __exit cec_devnode_exit(void)
 478 {
 479         debugfs_remove_recursive(top_cec_dir);
 480         bus_unregister(&cec_bus_type);
 481         unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES);
 482 }
 483 
 484 subsys_initcall(cec_devnode_init);
 485 module_exit(cec_devnode_exit)
 486 
 487 MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
 488 MODULE_DESCRIPTION("Device node registration for cec drivers");
 489 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */