blob: c6fc8cd8474a97ffa1159a16f04c2a018fa7cd9f [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 Jonsson116a6352020-08-20 17:25:23 +020060 struct ethosu_device *edev;
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020061 int minor;
Kristofer Jonsson116a6352020-08-20 17:25:23 +020062 int ret;
63
Kristofer Jonssond779a082023-01-04 17:09:47 +010064 /* Reserve minor number for device node */
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020065 minor = find_first_zero_bit(minors, MINOR_COUNT);
66 if (minor >= MINOR_COUNT) {
Kristofer Jonssond779a082023-01-04 17:09:47 +010067 dev_err(dev, "No more minor numbers.");
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020068
69 return -ENOMEM;
70 }
71
Kristofer Jonssond779a082023-01-04 17:09:47 +010072 edev = devm_kzalloc(dev, sizeof(*edev), GFP_KERNEL);
Kristofer Jonsson116a6352020-08-20 17:25:23 +020073 if (!edev)
74 return -ENOMEM;
75
Kristofer Jonssond779a082023-01-04 17:09:47 +010076 dev_set_drvdata(dev, edev);
Kristofer Jonsson116a6352020-08-20 17:25:23 +020077
78 /* Initialize device */
Kristofer Jonssond779a082023-01-04 17:09:47 +010079 ret = ethosu_dev_init(edev, rpdev, ethosu_class,
80 MKDEV(MAJOR(devt), minor));
Kristofer Jonsson116a6352020-08-20 17:25:23 +020081 if (ret)
Kristofer Jonssond779a082023-01-04 17:09:47 +010082 return ret;
Kristofer Jonsson116a6352020-08-20 17:25:23 +020083
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020084 set_bit(minor, minors);
85
Kristofer Jonsson116a6352020-08-20 17:25:23 +020086 return 0;
Kristofer Jonsson116a6352020-08-20 17:25:23 +020087}
88
Kristofer Jonssond779a082023-01-04 17:09:47 +010089static void ethosu_rpmsg_remove(struct rpmsg_device *rpdev)
Kristofer Jonsson116a6352020-08-20 17:25:23 +020090{
Kristofer Jonssond779a082023-01-04 17:09:47 +010091 struct ethosu_device *edev = dev_get_drvdata(&rpdev->dev);
92
93 dev_info(&rpdev->dev, "%s", __FUNCTION__);
Kristofer Jonsson116a6352020-08-20 17:25:23 +020094
Kristofer Jonsson4aec3762021-10-13 17:09:27 +020095 clear_bit(MINOR(edev->devt), minors);
Kristofer Jonsson116a6352020-08-20 17:25:23 +020096 ethosu_dev_deinit(edev);
Kristofer Jonsson116a6352020-08-20 17:25:23 +020097}
98
Kristofer Jonssond779a082023-01-04 17:09:47 +010099static int ethosu_rpmsg_cb(struct rpmsg_device *rpdev,
100 void *data,
101 int len,
102 void *priv,
103 u32 src)
104{
105 dev_err(&rpdev->dev, "%s", __FUNCTION__);
106
107 return -EINVAL;
108}
109
110static struct rpmsg_device_id ethosu_rpmsg_driver_id_table[] = {
111 { .name = "ethos-u-0.0" },
112 {},
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200113};
114
Kristofer Jonssond779a082023-01-04 17:09:47 +0100115MODULE_DEVICE_TABLE(rpmsg, ethosu_rpmsg_driver_id_table);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200116
Kristofer Jonssond779a082023-01-04 17:09:47 +0100117static struct rpmsg_driver ethosu_rpmsg_driver = {
118 .drv = {
119 .name = ETHOSU_DRIVER_NAME,
120 .owner = THIS_MODULE,
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200121 },
Kristofer Jonssond779a082023-01-04 17:09:47 +0100122 .id_table = ethosu_rpmsg_driver_id_table,
123 .probe = ethosu_rpmsg_probe,
124 .callback = ethosu_rpmsg_cb,
125 .remove = ethosu_rpmsg_remove,
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200126};
127
128/****************************************************************************
129 * Module init and exit
130 ****************************************************************************/
131
Kristofer Jonssond779a082023-01-04 17:09:47 +0100132static void __exit ethosu_exit(void)
133{
134 unregister_rpmsg_driver(&ethosu_rpmsg_driver);
135 unregister_chrdev_region(devt, MINOR_COUNT);
136 class_destroy(ethosu_class);
137}
138
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200139static int __init ethosu_init(void)
140{
141 int ret;
142
143 ethosu_class = class_create(THIS_MODULE, ETHOSU_DRIVER_NAME);
144 if (IS_ERR(ethosu_class)) {
Kristofer Jonssond779a082023-01-04 17:09:47 +0100145 pr_err("Failed to create class '%s'.\n", ETHOSU_DRIVER_NAME);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200146
147 return PTR_ERR(ethosu_class);
148 }
149
Kristofer Jonsson4aec3762021-10-13 17:09:27 +0200150 ret = alloc_chrdev_region(&devt, MINOR_BASE, MINOR_COUNT,
151 ETHOSU_DRIVER_NAME);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200152 if (ret) {
Kristofer Jonssond779a082023-01-04 17:09:47 +0100153 pr_err("Failed to allocate chrdev region.\n");
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200154 goto destroy_class;
155 }
156
Kristofer Jonssond779a082023-01-04 17:09:47 +0100157 ret = register_rpmsg_driver(&ethosu_rpmsg_driver);
Kristofer Jonsson4aec3762021-10-13 17:09:27 +0200158 if (ret) {
Kristofer Jonssond779a082023-01-04 17:09:47 +0100159 pr_err("Failed to register Arm Ethos-U rpmsg driver.\n");
Kristofer Jonsson4aec3762021-10-13 17:09:27 +0200160 goto region_unregister;
161 }
162
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200163 return 0;
164
Kristofer Jonsson4aec3762021-10-13 17:09:27 +0200165region_unregister:
166 unregister_chrdev_region(devt, MINOR_COUNT);
167
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200168destroy_class:
169 class_destroy(ethosu_class);
170
171 return ret;
172}
173
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200174module_init(ethosu_init)
175module_exit(ethosu_exit)
Kristofer Jonssond779a082023-01-04 17:09:47 +0100176
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200177MODULE_LICENSE("GPL v2");
178MODULE_AUTHOR("Arm Ltd");
179MODULE_DESCRIPTION("Arm Ethos-U NPU Driver");
180MODULE_VERSION(ETHOSU_DRIVER_VERSION);