Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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