Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2/*
  3 * Copyright(c) 2015, 2016 Intel Corporation.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  4 */
  5
  6#include <linux/cdev.h>
 
  7#include <linux/device.h>
  8#include <linux/fs.h>
  9
 10#include "hfi.h"
 11#include "device.h"
 12
 13static char *hfi1_devnode(const struct device *dev, umode_t *mode)
 14{
 15	if (mode)
 16		*mode = 0600;
 17	return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
 18}
 19
 20static const struct class class = {
 21	.name = "hfi1",
 22	.devnode = hfi1_devnode,
 23};
 24
 25static char *hfi1_user_devnode(const struct device *dev, umode_t *mode)
 26{
 27	if (mode)
 28		*mode = 0666;
 29	return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
 30}
 31
 32static const struct class user_class = {
 33	.name = "hfi1_user",
 34	.devnode = hfi1_user_devnode,
 35};
 36static dev_t hfi1_dev;
 37
 38int hfi1_cdev_init(int minor, const char *name,
 39		   const struct file_operations *fops,
 40		   struct cdev *cdev, struct device **devp,
 41		   bool user_accessible,
 42		   struct kobject *parent)
 43{
 44	const dev_t dev = MKDEV(MAJOR(hfi1_dev), minor);
 45	struct device *device = NULL;
 46	int ret;
 47
 48	cdev_init(cdev, fops);
 49	cdev->owner = THIS_MODULE;
 50	cdev_set_parent(cdev, parent);
 51	kobject_set_name(&cdev->kobj, name);
 52
 53	ret = cdev_add(cdev, dev, 1);
 54	if (ret < 0) {
 55		pr_err("Could not add cdev for minor %d, %s (err %d)\n",
 56		       minor, name, -ret);
 57		goto done;
 58	}
 59
 60	if (user_accessible)
 61		device = device_create(&user_class, NULL, dev, NULL, "%s", name);
 62	else
 63		device = device_create(&class, NULL, dev, NULL, "%s", name);
 64
 65	if (IS_ERR(device)) {
 66		ret = PTR_ERR(device);
 67		device = NULL;
 68		pr_err("Could not create device for minor %d, %s (err %d)\n",
 69			minor, name, -ret);
 70		cdev_del(cdev);
 71	}
 72done:
 73	*devp = device;
 74	return ret;
 75}
 76
 77void hfi1_cdev_cleanup(struct cdev *cdev, struct device **devp)
 78{
 79	struct device *device = *devp;
 80
 81	if (device) {
 82		device_unregister(device);
 83		*devp = NULL;
 84
 85		cdev_del(cdev);
 86	}
 87}
 88
 89static const char *hfi1_class_name = "hfi1";
 90
 91const char *class_name(void)
 92{
 93	return hfi1_class_name;
 94}
 95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 96int __init dev_init(void)
 97{
 98	int ret;
 99
100	ret = alloc_chrdev_region(&hfi1_dev, 0, HFI1_NMINORS, DRIVER_NAME);
101	if (ret < 0) {
102		pr_err("Could not allocate chrdev region (err %d)\n", -ret);
103		goto done;
104	}
105
106	ret = class_register(&class);
107	if (ret) {
 
108		pr_err("Could not create device class (err %d)\n", -ret);
109		unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
110		goto done;
111	}
 
112
113	ret = class_register(&user_class);
114	if (ret) {
 
115		pr_err("Could not create device class for user accessible files (err %d)\n",
116		       -ret);
117		class_unregister(&class);
 
 
118		unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
119		goto done;
120	}
 
121
122done:
123	return ret;
124}
125
126void dev_cleanup(void)
127{
128	class_unregister(&class);
129	class_unregister(&user_class);
 
 
 
130
131	unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
132}
v5.4
 
  1/*
  2 * Copyright(c) 2015, 2016 Intel Corporation.
  3 *
  4 * This file is provided under a dual BSD/GPLv2 license.  When using or
  5 * redistributing this file, you may do so under either license.
  6 *
  7 * GPL LICENSE SUMMARY
  8 *
  9 * This program is free software; you can redistribute it and/or modify
 10 * it under the terms of version 2 of the GNU General Public License as
 11 * published by the Free Software Foundation.
 12 *
 13 * This program is distributed in the hope that it will be useful, but
 14 * WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16 * General Public License for more details.
 17 *
 18 * BSD LICENSE
 19 *
 20 * Redistribution and use in source and binary forms, with or without
 21 * modification, are permitted provided that the following conditions
 22 * are met:
 23 *
 24 *  - Redistributions of source code must retain the above copyright
 25 *    notice, this list of conditions and the following disclaimer.
 26 *  - Redistributions in binary form must reproduce the above copyright
 27 *    notice, this list of conditions and the following disclaimer in
 28 *    the documentation and/or other materials provided with the
 29 *    distribution.
 30 *  - Neither the name of Intel Corporation nor the names of its
 31 *    contributors may be used to endorse or promote products derived
 32 *    from this software without specific prior written permission.
 33 *
 34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 35 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 36 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 37 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 38 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 45 *
 46 */
 47
 48#include <linux/cdev.h>
 49#include <linux/module.h>
 50#include <linux/device.h>
 51#include <linux/fs.h>
 52
 53#include "hfi.h"
 54#include "device.h"
 55
 56static struct class *class;
 57static struct class *user_class;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 58static dev_t hfi1_dev;
 59
 60int hfi1_cdev_init(int minor, const char *name,
 61		   const struct file_operations *fops,
 62		   struct cdev *cdev, struct device **devp,
 63		   bool user_accessible,
 64		   struct kobject *parent)
 65{
 66	const dev_t dev = MKDEV(MAJOR(hfi1_dev), minor);
 67	struct device *device = NULL;
 68	int ret;
 69
 70	cdev_init(cdev, fops);
 71	cdev->owner = THIS_MODULE;
 72	cdev_set_parent(cdev, parent);
 73	kobject_set_name(&cdev->kobj, name);
 74
 75	ret = cdev_add(cdev, dev, 1);
 76	if (ret < 0) {
 77		pr_err("Could not add cdev for minor %d, %s (err %d)\n",
 78		       minor, name, -ret);
 79		goto done;
 80	}
 81
 82	if (user_accessible)
 83		device = device_create(user_class, NULL, dev, NULL, "%s", name);
 84	else
 85		device = device_create(class, NULL, dev, NULL, "%s", name);
 86
 87	if (IS_ERR(device)) {
 88		ret = PTR_ERR(device);
 89		device = NULL;
 90		pr_err("Could not create device for minor %d, %s (err %d)\n",
 91			minor, name, -ret);
 92		cdev_del(cdev);
 93	}
 94done:
 95	*devp = device;
 96	return ret;
 97}
 98
 99void hfi1_cdev_cleanup(struct cdev *cdev, struct device **devp)
100{
101	struct device *device = *devp;
102
103	if (device) {
104		device_unregister(device);
105		*devp = NULL;
106
107		cdev_del(cdev);
108	}
109}
110
111static const char *hfi1_class_name = "hfi1";
112
113const char *class_name(void)
114{
115	return hfi1_class_name;
116}
117
118static char *hfi1_devnode(struct device *dev, umode_t *mode)
119{
120	if (mode)
121		*mode = 0600;
122	return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
123}
124
125static const char *hfi1_class_name_user = "hfi1_user";
126static const char *class_name_user(void)
127{
128	return hfi1_class_name_user;
129}
130
131static char *hfi1_user_devnode(struct device *dev, umode_t *mode)
132{
133	if (mode)
134		*mode = 0666;
135	return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
136}
137
138int __init dev_init(void)
139{
140	int ret;
141
142	ret = alloc_chrdev_region(&hfi1_dev, 0, HFI1_NMINORS, DRIVER_NAME);
143	if (ret < 0) {
144		pr_err("Could not allocate chrdev region (err %d)\n", -ret);
145		goto done;
146	}
147
148	class = class_create(THIS_MODULE, class_name());
149	if (IS_ERR(class)) {
150		ret = PTR_ERR(class);
151		pr_err("Could not create device class (err %d)\n", -ret);
152		unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
153		goto done;
154	}
155	class->devnode = hfi1_devnode;
156
157	user_class = class_create(THIS_MODULE, class_name_user());
158	if (IS_ERR(user_class)) {
159		ret = PTR_ERR(user_class);
160		pr_err("Could not create device class for user accessible files (err %d)\n",
161		       -ret);
162		class_destroy(class);
163		class = NULL;
164		user_class = NULL;
165		unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
166		goto done;
167	}
168	user_class->devnode = hfi1_user_devnode;
169
170done:
171	return ret;
172}
173
174void dev_cleanup(void)
175{
176	class_destroy(class);
177	class = NULL;
178
179	class_destroy(user_class);
180	user_class = NULL;
181
182	unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
183}