blob: 6e5bfb96636fe3a3194e8a980d60f1e87c5e0edc [file] [log] [blame]
Kristofer Jonsson116a6352020-08-20 17:25:23 +02001/*
Kristofer Jonssond779a082023-01-04 17:09:47 +01002 * Copyright 2020-2023 Arm Limited and/or its affiliates
Kristofer Jonsson116a6352020-08-20 17:25:23 +02003 *
4 * This program is free software and is provided to you under the terms of the
5 * GNU General Public License version 2 as published by the Free Software
6 * Foundation, and any use by you of this program is subject to the terms
7 * of such GNU licence.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, you can access it online at
16 * http://www.gnu.org/licenses/gpl-2.0.html.
17 *
18 * SPDX-License-Identifier: GPL-2.0-only
19 */
20
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020021#include <linux/bitmap.h>
22#include <linux/fs.h>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020023#include <linux/module.h>
24#include <linux/io.h>
25#include <linux/of.h>
26#include <linux/of_address.h>
Kristofer Jonssond779a082023-01-04 17:09:47 +010027#include <linux/rpmsg.h>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020028
29#include "ethosu_device.h"
30
31/****************************************************************************
32 * Defines
33 ****************************************************************************/
34
35#define ETHOSU_DRIVER_VERSION "1.0"
36#define ETHOSU_DRIVER_NAME "ethosu"
37
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020038#define MINOR_BASE 0 /* Minor version starts at 0 */
39#define MINOR_COUNT 64 /* Allocate minor versions */
40
Kristofer Jonssond779a082023-01-04 17:09:47 +010041#define DMA_ADDR_BITS 32 /* Number of address bits */
42
Kristofer Jonsson116a6352020-08-20 17:25:23 +020043/****************************************************************************
44 * Variables
45 ****************************************************************************/
46
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020047static struct class *ethosu_class;
48
49static dev_t devt;
50
51static DECLARE_BITMAP(minors, MINOR_COUNT);
Kristofer Jonsson116a6352020-08-20 17:25:23 +020052
53/****************************************************************************
Kristofer Jonssond779a082023-01-04 17:09:47 +010054 * Rpmsg driver
Kristofer Jonsson116a6352020-08-20 17:25:23 +020055 ****************************************************************************/
56
Kristofer Jonssond779a082023-01-04 17:09:47 +010057static int ethosu_rpmsg_probe(struct rpmsg_device *rpdev)
Kristofer Jonsson116a6352020-08-20 17:25:23 +020058{
Kristofer Jonssond779a082023-01-04 17:09:47 +010059 struct device *dev = &rpdev->dev;
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020060 int minor;
Kristofer Jonsson116a6352020-08-20 17:25:23 +020061 int ret;
62
Kristofer Jonssond779a082023-01-04 17:09:47 +010063 /* Reserve minor number for device node */
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020064 minor = find_first_zero_bit(minors, MINOR_COUNT);
65 if (minor >= MINOR_COUNT) {
Kristofer Jonssond779a082023-01-04 17:09:47 +010066 dev_err(dev, "No more minor numbers.");
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020067
68 return -ENOMEM;
69 }
70
Kristofer Jonsson116a6352020-08-20 17:25:23 +020071 /* Initialize device */
Kristofer Jonssonec477042023-01-20 13:38:13 +010072 ret = ethosu_dev_init(rpdev, ethosu_class, MKDEV(MAJOR(devt), minor));
Kristofer Jonsson116a6352020-08-20 17:25:23 +020073 if (ret)
Kristofer Jonssond779a082023-01-04 17:09:47 +010074 return ret;
Kristofer Jonsson116a6352020-08-20 17:25:23 +020075
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020076 set_bit(minor, minors);
77
Kristofer Jonsson116a6352020-08-20 17:25:23 +020078 return 0;
Kristofer Jonsson116a6352020-08-20 17:25:23 +020079}
80
Kristofer Jonssond779a082023-01-04 17:09:47 +010081static void ethosu_rpmsg_remove(struct rpmsg_device *rpdev)
Kristofer Jonsson116a6352020-08-20 17:25:23 +020082{
Kristofer Jonssonec477042023-01-20 13:38:13 +010083 struct device *dev = &rpdev->dev;
84 struct ethosu_device *edev = dev_get_drvdata(dev);
Kristofer Jonssond779a082023-01-04 17:09:47 +010085
Kristofer Jonssonec477042023-01-20 13:38:13 +010086 dev_info(dev, "%s", __FUNCTION__);
Kristofer Jonsson116a6352020-08-20 17:25:23 +020087
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020088 clear_bit(MINOR(edev->devt), minors);
Kristofer Jonssonec477042023-01-20 13:38:13 +010089 ethosu_dev_deinit(rpdev);
Kristofer Jonsson116a6352020-08-20 17:25:23 +020090}
91
Kristofer Jonssond779a082023-01-04 17:09:47 +010092static int ethosu_rpmsg_cb(struct rpmsg_device *rpdev,
93 void *data,
94 int len,
95 void *priv,
96 u32 src)
97{
98 dev_err(&rpdev->dev, "%s", __FUNCTION__);
99
100 return -EINVAL;
101}
102
103static struct rpmsg_device_id ethosu_rpmsg_driver_id_table[] = {
104 { .name = "ethos-u-0.0" },
105 {},
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200106};
107
Kristofer Jonssond779a082023-01-04 17:09:47 +0100108MODULE_DEVICE_TABLE(rpmsg, ethosu_rpmsg_driver_id_table);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200109
Kristofer Jonssond779a082023-01-04 17:09:47 +0100110static struct rpmsg_driver ethosu_rpmsg_driver = {
111 .drv = {
112 .name = ETHOSU_DRIVER_NAME,
113 .owner = THIS_MODULE,
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200114 },
Kristofer Jonssond779a082023-01-04 17:09:47 +0100115 .id_table = ethosu_rpmsg_driver_id_table,
116 .probe = ethosu_rpmsg_probe,
117 .callback = ethosu_rpmsg_cb,
118 .remove = ethosu_rpmsg_remove,
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200119};
120
121/****************************************************************************
122 * Module init and exit
123 ****************************************************************************/
124
Kristofer Jonssond779a082023-01-04 17:09:47 +0100125static void __exit ethosu_exit(void)
126{
127 unregister_rpmsg_driver(&ethosu_rpmsg_driver);
128 unregister_chrdev_region(devt, MINOR_COUNT);
129 class_destroy(ethosu_class);
130}
131
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200132static int __init ethosu_init(void)
133{
134 int ret;
135
136 ethosu_class = class_create(THIS_MODULE, ETHOSU_DRIVER_NAME);
137 if (IS_ERR(ethosu_class)) {
Kristofer Jonssond779a082023-01-04 17:09:47 +0100138 pr_err("Failed to create class '%s'.\n", ETHOSU_DRIVER_NAME);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200139
140 return PTR_ERR(ethosu_class);
141 }
142
Kristofer Jonsson4aec3762021-10-13 17:09:27 +0200143 ret = alloc_chrdev_region(&devt, MINOR_BASE, MINOR_COUNT,
144 ETHOSU_DRIVER_NAME);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200145 if (ret) {
Kristofer Jonssond779a082023-01-04 17:09:47 +0100146 pr_err("Failed to allocate chrdev region.\n");
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200147 goto destroy_class;
148 }
149
Kristofer Jonssond779a082023-01-04 17:09:47 +0100150 ret = register_rpmsg_driver(&ethosu_rpmsg_driver);
Kristofer Jonsson4aec3762021-10-13 17:09:27 +0200151 if (ret) {
Kristofer Jonssond779a082023-01-04 17:09:47 +0100152 pr_err("Failed to register Arm Ethos-U rpmsg driver.\n");
Kristofer Jonsson4aec3762021-10-13 17:09:27 +0200153 goto region_unregister;
154 }
155
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200156 return 0;
157
Kristofer Jonsson4aec3762021-10-13 17:09:27 +0200158region_unregister:
159 unregister_chrdev_region(devt, MINOR_COUNT);
160
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200161destroy_class:
162 class_destroy(ethosu_class);
163
164 return ret;
165}
166
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200167module_init(ethosu_init)
168module_exit(ethosu_exit)
Kristofer Jonssond779a082023-01-04 17:09:47 +0100169
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200170MODULE_LICENSE("GPL v2");
171MODULE_AUTHOR("Arm Ltd");
172MODULE_DESCRIPTION("Arm Ethos-U NPU Driver");
173MODULE_VERSION(ETHOSU_DRIVER_VERSION);