root/drivers/staging/most/configfs.c

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

DEFINITIONS

This source file includes following definitions.
  1. set_cfg_buffer_size
  2. set_cfg_subbuffer_size
  3. set_cfg_dbr_size
  4. set_cfg_num_buffers
  5. set_cfg_packets_xact
  6. set_cfg_direction
  7. set_cfg_datatype
  8. to_mdev_link
  9. set_config_and_add_link
  10. mdev_link_create_link_store
  11. mdev_link_destroy_link_store
  12. mdev_link_direction_show
  13. mdev_link_direction_store
  14. mdev_link_datatype_show
  15. mdev_link_datatype_store
  16. mdev_link_device_show
  17. mdev_link_device_store
  18. mdev_link_channel_show
  19. mdev_link_channel_store
  20. mdev_link_comp_show
  21. mdev_link_comp_store
  22. mdev_link_comp_params_show
  23. mdev_link_comp_params_store
  24. mdev_link_num_buffers_show
  25. mdev_link_num_buffers_store
  26. mdev_link_buffer_size_show
  27. mdev_link_buffer_size_store
  28. mdev_link_subbuffer_size_show
  29. mdev_link_subbuffer_size_store
  30. mdev_link_packets_per_xact_show
  31. mdev_link_packets_per_xact_store
  32. mdev_link_dbr_size_show
  33. mdev_link_dbr_size_store
  34. mdev_link_release
  35. to_most_common
  36. most_common_make_item
  37. most_common_release
  38. to_most_snd_grp
  39. most_snd_grp_make_item
  40. most_snd_grp_create_card_store
  41. most_snd_grp_release
  42. most_sound_make_group
  43. most_register_configfs_subsys
  44. most_interface_register_notify
  45. most_deregister_configfs_subsys
  46. configfs_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * configfs.c - Implementation of configfs interface to the driver stack
   4  *
   5  * Copyright (C) 2013-2015 Microchip Technology Germany II GmbH & Co. KG
   6  */
   7 
   8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9 #include <linux/module.h>
  10 #include <linux/slab.h>
  11 #include <linux/init.h>
  12 #include <linux/configfs.h>
  13 #include <most/core.h>
  14 
  15 struct mdev_link {
  16         struct config_item item;
  17         struct list_head list;
  18         bool create_link;
  19         bool destroy_link;
  20         u16 num_buffers;
  21         u16 buffer_size;
  22         u16 subbuffer_size;
  23         u16 packets_per_xact;
  24         u16 dbr_size;
  25         char datatype[PAGE_SIZE];
  26         char direction[PAGE_SIZE];
  27         char name[PAGE_SIZE];
  28         char device[PAGE_SIZE];
  29         char channel[PAGE_SIZE];
  30         char comp[PAGE_SIZE];
  31         char comp_params[PAGE_SIZE];
  32 };
  33 
  34 static struct list_head mdev_link_list;
  35 
  36 static int set_cfg_buffer_size(struct mdev_link *link)
  37 {
  38         return most_set_cfg_buffer_size(link->device, link->channel,
  39                                         link->buffer_size);
  40 }
  41 
  42 static int set_cfg_subbuffer_size(struct mdev_link *link)
  43 {
  44         return most_set_cfg_subbuffer_size(link->device, link->channel,
  45                                            link->subbuffer_size);
  46 }
  47 
  48 static int set_cfg_dbr_size(struct mdev_link *link)
  49 {
  50         return most_set_cfg_dbr_size(link->device, link->channel,
  51                                      link->dbr_size);
  52 }
  53 
  54 static int set_cfg_num_buffers(struct mdev_link *link)
  55 {
  56         return most_set_cfg_num_buffers(link->device, link->channel,
  57                                         link->num_buffers);
  58 }
  59 
  60 static int set_cfg_packets_xact(struct mdev_link *link)
  61 {
  62         return most_set_cfg_packets_xact(link->device, link->channel,
  63                                          link->packets_per_xact);
  64 }
  65 
  66 static int set_cfg_direction(struct mdev_link *link)
  67 {
  68         return most_set_cfg_direction(link->device, link->channel,
  69                                       link->direction);
  70 }
  71 
  72 static int set_cfg_datatype(struct mdev_link *link)
  73 {
  74         return most_set_cfg_datatype(link->device, link->channel,
  75                                      link->datatype);
  76 }
  77 
  78 static int (*set_config_val[])(struct mdev_link *link) = {
  79         set_cfg_buffer_size,
  80         set_cfg_subbuffer_size,
  81         set_cfg_dbr_size,
  82         set_cfg_num_buffers,
  83         set_cfg_packets_xact,
  84         set_cfg_direction,
  85         set_cfg_datatype,
  86 };
  87 
  88 static struct mdev_link *to_mdev_link(struct config_item *item)
  89 {
  90         return container_of(item, struct mdev_link, item);
  91 }
  92 
  93 static int set_config_and_add_link(struct mdev_link *mdev_link)
  94 {
  95         int i;
  96         int ret;
  97 
  98         for (i = 0; i < ARRAY_SIZE(set_config_val); i++) {
  99                 ret = set_config_val[i](mdev_link);
 100                 if (ret < 0 && ret != -ENODEV) {
 101                         pr_err("Config failed\n");
 102                         return ret;
 103                 }
 104         }
 105 
 106         return most_add_link(mdev_link->device, mdev_link->channel,
 107                              mdev_link->comp, mdev_link->name,
 108                              mdev_link->comp_params);
 109 }
 110 
 111 static ssize_t mdev_link_create_link_store(struct config_item *item,
 112                                            const char *page, size_t count)
 113 {
 114         struct mdev_link *mdev_link = to_mdev_link(item);
 115         bool tmp;
 116         int ret;
 117 
 118         ret = kstrtobool(page, &tmp);
 119         if (ret)
 120                 return ret;
 121         if (!tmp)
 122                 return count;
 123         ret = set_config_and_add_link(mdev_link);
 124         if (ret && ret != -ENODEV)
 125                 return ret;
 126         list_add_tail(&mdev_link->list, &mdev_link_list);
 127         mdev_link->create_link = tmp;
 128         return count;
 129 }
 130 
 131 static ssize_t mdev_link_destroy_link_store(struct config_item *item,
 132                                             const char *page, size_t count)
 133 {
 134         struct mdev_link *mdev_link = to_mdev_link(item);
 135         bool tmp;
 136         int ret;
 137 
 138         ret = kstrtobool(page, &tmp);
 139         if (ret)
 140                 return ret;
 141         if (!tmp)
 142                 return count;
 143         mdev_link->destroy_link = tmp;
 144         ret = most_remove_link(mdev_link->device, mdev_link->channel,
 145                                mdev_link->comp);
 146         if (ret)
 147                 return ret;
 148         if (!list_empty(&mdev_link_list))
 149                 list_del(&mdev_link->list);
 150         return count;
 151 }
 152 
 153 static ssize_t mdev_link_direction_show(struct config_item *item, char *page)
 154 {
 155         return snprintf(page, PAGE_SIZE, "%s\n", to_mdev_link(item)->direction);
 156 }
 157 
 158 static ssize_t mdev_link_direction_store(struct config_item *item,
 159                                          const char *page, size_t count)
 160 {
 161         struct mdev_link *mdev_link = to_mdev_link(item);
 162 
 163         if (!sysfs_streq(page, "dir_rx") && !sysfs_streq(page, "rx") &&
 164             !sysfs_streq(page, "dir_tx") && !sysfs_streq(page, "tx"))
 165                 return -EINVAL;
 166         strcpy(mdev_link->direction, page);
 167         return count;
 168 }
 169 
 170 static ssize_t mdev_link_datatype_show(struct config_item *item, char *page)
 171 {
 172         return snprintf(page, PAGE_SIZE, "%s\n", to_mdev_link(item)->datatype);
 173 }
 174 
 175 static ssize_t mdev_link_datatype_store(struct config_item *item,
 176                                         const char *page, size_t count)
 177 {
 178         struct mdev_link *mdev_link = to_mdev_link(item);
 179 
 180         if (!sysfs_streq(page, "control") && !sysfs_streq(page, "async") &&
 181             !sysfs_streq(page, "sync") && !sysfs_streq(page, "isoc") &&
 182             !sysfs_streq(page, "isoc_avp"))
 183                 return -EINVAL;
 184         strcpy(mdev_link->datatype, page);
 185         return count;
 186 }
 187 
 188 static ssize_t mdev_link_device_show(struct config_item *item, char *page)
 189 {
 190         return snprintf(page, PAGE_SIZE, "%s\n", to_mdev_link(item)->device);
 191 }
 192 
 193 static ssize_t mdev_link_device_store(struct config_item *item,
 194                                       const char *page, size_t count)
 195 {
 196         struct mdev_link *mdev_link = to_mdev_link(item);
 197 
 198         strcpy(mdev_link->device, page);
 199         return count;
 200 }
 201 
 202 static ssize_t mdev_link_channel_show(struct config_item *item, char *page)
 203 {
 204         return snprintf(page, PAGE_SIZE, "%s\n", to_mdev_link(item)->channel);
 205 }
 206 
 207 static ssize_t mdev_link_channel_store(struct config_item *item,
 208                                        const char *page, size_t count)
 209 {
 210         struct mdev_link *mdev_link = to_mdev_link(item);
 211 
 212         strcpy(mdev_link->channel, page);
 213         return count;
 214 }
 215 
 216 static ssize_t mdev_link_comp_show(struct config_item *item, char *page)
 217 {
 218         return snprintf(page, PAGE_SIZE, "%s\n", to_mdev_link(item)->comp);
 219 }
 220 
 221 static ssize_t mdev_link_comp_store(struct config_item *item,
 222                                     const char *page, size_t count)
 223 {
 224         struct mdev_link *mdev_link = to_mdev_link(item);
 225 
 226         strcpy(mdev_link->comp, page);
 227         return count;
 228 }
 229 
 230 static ssize_t mdev_link_comp_params_show(struct config_item *item, char *page)
 231 {
 232         return snprintf(page, PAGE_SIZE, "%s\n",
 233                         to_mdev_link(item)->comp_params);
 234 }
 235 
 236 static ssize_t mdev_link_comp_params_store(struct config_item *item,
 237                                            const char *page, size_t count)
 238 {
 239         struct mdev_link *mdev_link = to_mdev_link(item);
 240 
 241         strcpy(mdev_link->comp_params, page);
 242         return count;
 243 }
 244 
 245 static ssize_t mdev_link_num_buffers_show(struct config_item *item, char *page)
 246 {
 247         return snprintf(page, PAGE_SIZE, "%d\n",
 248                         to_mdev_link(item)->num_buffers);
 249 }
 250 
 251 static ssize_t mdev_link_num_buffers_store(struct config_item *item,
 252                                            const char *page, size_t count)
 253 {
 254         struct mdev_link *mdev_link = to_mdev_link(item);
 255         int ret;
 256 
 257         ret = kstrtou16(page, 0, &mdev_link->num_buffers);
 258         if (ret)
 259                 return ret;
 260         return count;
 261 }
 262 
 263 static ssize_t mdev_link_buffer_size_show(struct config_item *item, char *page)
 264 {
 265         return snprintf(page, PAGE_SIZE, "%d\n",
 266                         to_mdev_link(item)->buffer_size);
 267 }
 268 
 269 static ssize_t mdev_link_buffer_size_store(struct config_item *item,
 270                                            const char *page, size_t count)
 271 {
 272         struct mdev_link *mdev_link = to_mdev_link(item);
 273         int ret;
 274 
 275         ret = kstrtou16(page, 0, &mdev_link->buffer_size);
 276         if (ret)
 277                 return ret;
 278         return count;
 279 }
 280 
 281 static ssize_t mdev_link_subbuffer_size_show(struct config_item *item,
 282                                              char *page)
 283 {
 284         return snprintf(page, PAGE_SIZE, "%d\n",
 285                         to_mdev_link(item)->subbuffer_size);
 286 }
 287 
 288 static ssize_t mdev_link_subbuffer_size_store(struct config_item *item,
 289                                               const char *page, size_t count)
 290 {
 291         struct mdev_link *mdev_link = to_mdev_link(item);
 292         int ret;
 293 
 294         ret = kstrtou16(page, 0, &mdev_link->subbuffer_size);
 295         if (ret)
 296                 return ret;
 297         return count;
 298 }
 299 
 300 static ssize_t mdev_link_packets_per_xact_show(struct config_item *item,
 301                                                char *page)
 302 {
 303         return snprintf(page, PAGE_SIZE, "%d\n",
 304                         to_mdev_link(item)->packets_per_xact);
 305 }
 306 
 307 static ssize_t mdev_link_packets_per_xact_store(struct config_item *item,
 308                                                 const char *page, size_t count)
 309 {
 310         struct mdev_link *mdev_link = to_mdev_link(item);
 311         int ret;
 312 
 313         ret = kstrtou16(page, 0, &mdev_link->packets_per_xact);
 314         if (ret)
 315                 return ret;
 316         return count;
 317 }
 318 
 319 static ssize_t mdev_link_dbr_size_show(struct config_item *item, char *page)
 320 {
 321         return snprintf(page, PAGE_SIZE, "%d\n", to_mdev_link(item)->dbr_size);
 322 }
 323 
 324 static ssize_t mdev_link_dbr_size_store(struct config_item *item,
 325                                         const char *page, size_t count)
 326 {
 327         struct mdev_link *mdev_link = to_mdev_link(item);
 328         int ret;
 329 
 330         ret = kstrtou16(page, 0, &mdev_link->dbr_size);
 331         if (ret)
 332                 return ret;
 333         return count;
 334 }
 335 
 336 CONFIGFS_ATTR_WO(mdev_link_, create_link);
 337 CONFIGFS_ATTR_WO(mdev_link_, destroy_link);
 338 CONFIGFS_ATTR(mdev_link_, device);
 339 CONFIGFS_ATTR(mdev_link_, channel);
 340 CONFIGFS_ATTR(mdev_link_, comp);
 341 CONFIGFS_ATTR(mdev_link_, comp_params);
 342 CONFIGFS_ATTR(mdev_link_, num_buffers);
 343 CONFIGFS_ATTR(mdev_link_, buffer_size);
 344 CONFIGFS_ATTR(mdev_link_, subbuffer_size);
 345 CONFIGFS_ATTR(mdev_link_, packets_per_xact);
 346 CONFIGFS_ATTR(mdev_link_, datatype);
 347 CONFIGFS_ATTR(mdev_link_, direction);
 348 CONFIGFS_ATTR(mdev_link_, dbr_size);
 349 
 350 static struct configfs_attribute *mdev_link_attrs[] = {
 351         &mdev_link_attr_create_link,
 352         &mdev_link_attr_destroy_link,
 353         &mdev_link_attr_device,
 354         &mdev_link_attr_channel,
 355         &mdev_link_attr_comp,
 356         &mdev_link_attr_comp_params,
 357         &mdev_link_attr_num_buffers,
 358         &mdev_link_attr_buffer_size,
 359         &mdev_link_attr_subbuffer_size,
 360         &mdev_link_attr_packets_per_xact,
 361         &mdev_link_attr_datatype,
 362         &mdev_link_attr_direction,
 363         &mdev_link_attr_dbr_size,
 364         NULL,
 365 };
 366 
 367 static void mdev_link_release(struct config_item *item)
 368 {
 369         struct mdev_link *mdev_link = to_mdev_link(item);
 370         int ret;
 371 
 372         if (!list_empty(&mdev_link_list)) {
 373                 ret = most_remove_link(mdev_link->device, mdev_link->channel,
 374                                        mdev_link->comp);
 375                 if (ret && (ret != -ENODEV))
 376                         pr_err("Removing link failed.\n");
 377                 list_del(&mdev_link->list);
 378         }
 379         kfree(to_mdev_link(item));
 380 }
 381 
 382 static struct configfs_item_operations mdev_link_item_ops = {
 383         .release                = mdev_link_release,
 384 };
 385 
 386 static const struct config_item_type mdev_link_type = {
 387         .ct_item_ops    = &mdev_link_item_ops,
 388         .ct_attrs       = mdev_link_attrs,
 389         .ct_owner       = THIS_MODULE,
 390 };
 391 
 392 struct most_common {
 393         struct config_group group;
 394 };
 395 
 396 static struct most_common *to_most_common(struct config_item *item)
 397 {
 398         return container_of(to_config_group(item), struct most_common, group);
 399 }
 400 
 401 static struct config_item *most_common_make_item(struct config_group *group,
 402                                                  const char *name)
 403 {
 404         struct mdev_link *mdev_link;
 405 
 406         mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL);
 407         if (!mdev_link)
 408                 return ERR_PTR(-ENOMEM);
 409 
 410         config_item_init_type_name(&mdev_link->item, name,
 411                                    &mdev_link_type);
 412 
 413         if (!strcmp(group->cg_item.ci_namebuf, "most_cdev"))
 414                 strcpy(mdev_link->comp, "cdev");
 415         else if (!strcmp(group->cg_item.ci_namebuf, "most_net"))
 416                 strcpy(mdev_link->comp, "net");
 417         else if (!strcmp(group->cg_item.ci_namebuf, "most_video"))
 418                 strcpy(mdev_link->comp, "video");
 419         strcpy(mdev_link->name, name);
 420         return &mdev_link->item;
 421 }
 422 
 423 static void most_common_release(struct config_item *item)
 424 {
 425         kfree(to_most_common(item));
 426 }
 427 
 428 static struct configfs_item_operations most_common_item_ops = {
 429         .release        = most_common_release,
 430 };
 431 
 432 static struct configfs_group_operations most_common_group_ops = {
 433         .make_item      = most_common_make_item,
 434 };
 435 
 436 static const struct config_item_type most_common_type = {
 437         .ct_item_ops    = &most_common_item_ops,
 438         .ct_group_ops   = &most_common_group_ops,
 439         .ct_owner       = THIS_MODULE,
 440 };
 441 
 442 static struct configfs_subsystem most_cdev_subsys = {
 443         .su_group = {
 444                 .cg_item = {
 445                         .ci_namebuf = "most_cdev",
 446                         .ci_type = &most_common_type,
 447                 },
 448         },
 449 };
 450 
 451 static struct configfs_subsystem most_net_subsys = {
 452         .su_group = {
 453                 .cg_item = {
 454                         .ci_namebuf = "most_net",
 455                         .ci_type = &most_common_type,
 456                 },
 457         },
 458 };
 459 
 460 static struct configfs_subsystem most_video_subsys = {
 461         .su_group = {
 462                 .cg_item = {
 463                         .ci_namebuf = "most_video",
 464                         .ci_type = &most_common_type,
 465                 },
 466         },
 467 };
 468 
 469 struct most_snd_grp {
 470         struct config_group group;
 471         bool create_card;
 472         struct list_head list;
 473 };
 474 
 475 static struct most_snd_grp *to_most_snd_grp(struct config_item *item)
 476 {
 477         return container_of(to_config_group(item), struct most_snd_grp, group);
 478 }
 479 
 480 static struct config_item *most_snd_grp_make_item(struct config_group *group,
 481                                                   const char *name)
 482 {
 483         struct mdev_link *mdev_link;
 484 
 485         mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL);
 486         if (!mdev_link)
 487                 return ERR_PTR(-ENOMEM);
 488 
 489         config_item_init_type_name(&mdev_link->item, name, &mdev_link_type);
 490         mdev_link->create_link = 0;
 491         strcpy(mdev_link->name, name);
 492         strcpy(mdev_link->comp, "sound");
 493         return &mdev_link->item;
 494 }
 495 
 496 static ssize_t most_snd_grp_create_card_store(struct config_item *item,
 497                                               const char *page, size_t count)
 498 {
 499         struct most_snd_grp *snd_grp = to_most_snd_grp(item);
 500         int ret;
 501         bool tmp;
 502 
 503         ret = kstrtobool(page, &tmp);
 504         if (ret)
 505                 return ret;
 506         if (tmp) {
 507                 ret = most_cfg_complete("sound");
 508                 if (ret)
 509                         return ret;
 510         }
 511         snd_grp->create_card = tmp;
 512         return count;
 513 }
 514 
 515 CONFIGFS_ATTR_WO(most_snd_grp_, create_card);
 516 
 517 static struct configfs_attribute *most_snd_grp_attrs[] = {
 518         &most_snd_grp_attr_create_card,
 519         NULL,
 520 };
 521 
 522 static void most_snd_grp_release(struct config_item *item)
 523 {
 524         struct most_snd_grp *group = to_most_snd_grp(item);
 525 
 526         list_del(&group->list);
 527         kfree(group);
 528 }
 529 
 530 static struct configfs_item_operations most_snd_grp_item_ops = {
 531         .release        = most_snd_grp_release,
 532 };
 533 
 534 static struct configfs_group_operations most_snd_grp_group_ops = {
 535         .make_item      = most_snd_grp_make_item,
 536 };
 537 
 538 static const struct config_item_type most_snd_grp_type = {
 539         .ct_item_ops    = &most_snd_grp_item_ops,
 540         .ct_group_ops   = &most_snd_grp_group_ops,
 541         .ct_attrs       = most_snd_grp_attrs,
 542         .ct_owner       = THIS_MODULE,
 543 };
 544 
 545 struct most_sound {
 546         struct configfs_subsystem subsys;
 547         struct list_head soundcard_list;
 548 };
 549 
 550 static struct config_group *most_sound_make_group(struct config_group *group,
 551                                                   const char *name)
 552 {
 553         struct most_snd_grp *most;
 554         struct most_sound *ms = container_of(to_configfs_subsystem(group),
 555                                              struct most_sound, subsys);
 556 
 557         list_for_each_entry(most, &ms->soundcard_list, list) {
 558                 if (!most->create_card) {
 559                         pr_info("adapter configuration still in progress.\n");
 560                         return ERR_PTR(-EPROTO);
 561                 }
 562         }
 563         most = kzalloc(sizeof(*most), GFP_KERNEL);
 564         if (!most)
 565                 return ERR_PTR(-ENOMEM);
 566 
 567         config_group_init_type_name(&most->group, name, &most_snd_grp_type);
 568         list_add_tail(&most->list, &ms->soundcard_list);
 569         return &most->group;
 570 }
 571 
 572 static struct configfs_group_operations most_sound_group_ops = {
 573         .make_group     = most_sound_make_group,
 574 };
 575 
 576 static const struct config_item_type most_sound_type = {
 577         .ct_group_ops   = &most_sound_group_ops,
 578         .ct_owner       = THIS_MODULE,
 579 };
 580 
 581 static struct most_sound most_sound_subsys = {
 582         .subsys = {
 583                 .su_group = {
 584                         .cg_item = {
 585                                 .ci_namebuf = "most_sound",
 586                                 .ci_type = &most_sound_type,
 587                         },
 588                 },
 589         },
 590 };
 591 
 592 int most_register_configfs_subsys(struct core_component *c)
 593 {
 594         int ret;
 595 
 596         if (!strcmp(c->name, "cdev"))
 597                 ret = configfs_register_subsystem(&most_cdev_subsys);
 598         else if (!strcmp(c->name, "net"))
 599                 ret = configfs_register_subsystem(&most_net_subsys);
 600         else if (!strcmp(c->name, "video"))
 601                 ret = configfs_register_subsystem(&most_video_subsys);
 602         else if (!strcmp(c->name, "sound"))
 603                 ret = configfs_register_subsystem(&most_sound_subsys.subsys);
 604         else
 605                 return -ENODEV;
 606 
 607         if (ret) {
 608                 pr_err("Error %d while registering subsystem %s\n",
 609                        ret, c->name);
 610         }
 611         return ret;
 612 }
 613 EXPORT_SYMBOL_GPL(most_register_configfs_subsys);
 614 
 615 void most_interface_register_notify(const char *mdev)
 616 {
 617         bool register_snd_card = false;
 618         struct mdev_link *mdev_link;
 619 
 620         list_for_each_entry(mdev_link, &mdev_link_list, list) {
 621                 if (!strcmp(mdev_link->device, mdev)) {
 622                         set_config_and_add_link(mdev_link);
 623                         if (!strcmp(mdev_link->comp, "sound"))
 624                                 register_snd_card = true;
 625                 }
 626         }
 627         if (register_snd_card)
 628                 most_cfg_complete("sound");
 629 }
 630 
 631 void most_deregister_configfs_subsys(struct core_component *c)
 632 {
 633         if (!strcmp(c->name, "cdev"))
 634                 configfs_unregister_subsystem(&most_cdev_subsys);
 635         else if (!strcmp(c->name, "net"))
 636                 configfs_unregister_subsystem(&most_net_subsys);
 637         else if (!strcmp(c->name, "video"))
 638                 configfs_unregister_subsystem(&most_video_subsys);
 639         else if (!strcmp(c->name, "sound"))
 640                 configfs_unregister_subsystem(&most_sound_subsys.subsys);
 641 }
 642 EXPORT_SYMBOL_GPL(most_deregister_configfs_subsys);
 643 
 644 int __init configfs_init(void)
 645 {
 646         config_group_init(&most_cdev_subsys.su_group);
 647         mutex_init(&most_cdev_subsys.su_mutex);
 648 
 649         config_group_init(&most_net_subsys.su_group);
 650         mutex_init(&most_net_subsys.su_mutex);
 651 
 652         config_group_init(&most_video_subsys.su_group);
 653         mutex_init(&most_video_subsys.su_mutex);
 654 
 655         config_group_init(&most_sound_subsys.subsys.su_group);
 656         mutex_init(&most_sound_subsys.subsys.su_mutex);
 657 
 658         INIT_LIST_HEAD(&most_sound_subsys.soundcard_list);
 659         INIT_LIST_HEAD(&mdev_link_list);
 660 
 661         return 0;
 662 }

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