OpenWrt – Blame information for rev 2
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 8783aa0977780bc848678c6d4c506128e1ff0b6f Mon Sep 17 00:00:00 2001 |
2 | From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> |
||
3 | Date: Fri, 26 Jun 2015 14:27:06 +0200 |
||
4 | Subject: [PATCH 051/454] char: broadcom: Add vcio module |
||
5 | MIME-Version: 1.0 |
||
6 | Content-Type: text/plain; charset=UTF-8 |
||
7 | Content-Transfer-Encoding: 8bit |
||
8 | |||
9 | Add module for accessing the mailbox property channel through |
||
10 | /dev/vcio. Was previously in bcm2708-vcio. |
||
11 | |||
12 | Signed-off-by: Noralf Trønnes <noralf@tronnes.org> |
||
13 | --- |
||
14 | drivers/char/broadcom/Kconfig | 6 ++ |
||
15 | drivers/char/broadcom/Makefile | 1 + |
||
16 | drivers/char/broadcom/vcio.c | 175 +++++++++++++++++++++++++++++++++ |
||
17 | 3 files changed, 182 insertions(+) |
||
18 | create mode 100644 drivers/char/broadcom/vcio.c |
||
19 | |||
20 | --- a/drivers/char/broadcom/Kconfig |
||
21 | +++ b/drivers/char/broadcom/Kconfig |
||
22 | @@ -15,6 +15,12 @@ config BCM2708_VCMEM |
||
23 | help |
||
24 | Helper for videocore memory access and total size allocation. |
||
25 | |||
26 | +config BCM_VCIO |
||
27 | + tristate "Mailbox userspace access" |
||
28 | + depends on BCM2835_MBOX |
||
29 | + help |
||
30 | + Gives access to the mailbox property channel from userspace. |
||
31 | + |
||
32 | endif |
||
33 | |||
34 | config BCM_VC_SM |
||
35 | --- a/drivers/char/broadcom/Makefile |
||
36 | +++ b/drivers/char/broadcom/Makefile |
||
37 | @@ -1,4 +1,5 @@ |
||
38 | obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o |
||
39 | +obj-$(CONFIG_BCM_VCIO) += vcio.o |
||
40 | obj-$(CONFIG_BCM_VC_SM) += vc_sm/ |
||
41 | |||
42 | obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o |
||
43 | --- /dev/null |
||
44 | +++ b/drivers/char/broadcom/vcio.c |
||
45 | @@ -0,0 +1,175 @@ |
||
46 | +/* |
||
47 | + * Copyright (C) 2010 Broadcom |
||
48 | + * Copyright (C) 2015 Noralf Trønnes |
||
49 | + * |
||
50 | + * This program is free software; you can redistribute it and/or modify |
||
51 | + * it under the terms of the GNU General Public License version 2 as |
||
52 | + * published by the Free Software Foundation. |
||
53 | + * |
||
54 | + */ |
||
55 | + |
||
56 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
||
57 | + |
||
58 | +#include <linux/cdev.h> |
||
59 | +#include <linux/device.h> |
||
60 | +#include <linux/fs.h> |
||
61 | +#include <linux/init.h> |
||
62 | +#include <linux/ioctl.h> |
||
63 | +#include <linux/module.h> |
||
64 | +#include <linux/slab.h> |
||
65 | +#include <linux/uaccess.h> |
||
66 | +#include <soc/bcm2835/raspberrypi-firmware.h> |
||
67 | + |
||
68 | +#define MBOX_CHAN_PROPERTY 8 |
||
69 | + |
||
70 | +#define VCIO_IOC_MAGIC 100 |
||
71 | +#define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) |
||
72 | + |
||
73 | +static struct { |
||
74 | + dev_t devt; |
||
75 | + struct cdev cdev; |
||
76 | + struct class *class; |
||
77 | + struct rpi_firmware *fw; |
||
78 | +} vcio; |
||
79 | + |
||
80 | +static int vcio_user_property_list(void *user) |
||
81 | +{ |
||
82 | + u32 *buf, size; |
||
83 | + int ret; |
||
84 | + |
||
85 | + /* The first 32-bit is the size of the buffer */ |
||
86 | + if (copy_from_user(&size, user, sizeof(size))) |
||
87 | + return -EFAULT; |
||
88 | + |
||
89 | + buf = kmalloc(size, GFP_KERNEL); |
||
90 | + if (!buf) |
||
91 | + return -ENOMEM; |
||
92 | + |
||
93 | + if (copy_from_user(buf, user, size)) { |
||
94 | + kfree(buf); |
||
95 | + return -EFAULT; |
||
96 | + } |
||
97 | + |
||
98 | + /* Strip off protocol encapsulation */ |
||
99 | + ret = rpi_firmware_property_list(vcio.fw, &buf[2], size - 12); |
||
100 | + if (ret) { |
||
101 | + kfree(buf); |
||
102 | + return ret; |
||
103 | + } |
||
104 | + |
||
105 | + buf[1] = RPI_FIRMWARE_STATUS_SUCCESS; |
||
106 | + if (copy_to_user(user, buf, size)) |
||
107 | + ret = -EFAULT; |
||
108 | + |
||
109 | + kfree(buf); |
||
110 | + |
||
111 | + return ret; |
||
112 | +} |
||
113 | + |
||
114 | +static int vcio_device_open(struct inode *inode, struct file *file) |
||
115 | +{ |
||
116 | + try_module_get(THIS_MODULE); |
||
117 | + |
||
118 | + return 0; |
||
119 | +} |
||
120 | + |
||
121 | +static int vcio_device_release(struct inode *inode, struct file *file) |
||
122 | +{ |
||
123 | + module_put(THIS_MODULE); |
||
124 | + |
||
125 | + return 0; |
||
126 | +} |
||
127 | + |
||
128 | +static long vcio_device_ioctl(struct file *file, unsigned int ioctl_num, |
||
129 | + unsigned long ioctl_param) |
||
130 | +{ |
||
131 | + switch (ioctl_num) { |
||
132 | + case IOCTL_MBOX_PROPERTY: |
||
133 | + return vcio_user_property_list((void *)ioctl_param); |
||
134 | + default: |
||
135 | + pr_err("unknown ioctl: %d\n", ioctl_num); |
||
136 | + return -EINVAL; |
||
137 | + } |
||
138 | +} |
||
139 | + |
||
140 | +const struct file_operations vcio_fops = { |
||
141 | + .unlocked_ioctl = vcio_device_ioctl, |
||
142 | + .open = vcio_device_open, |
||
143 | + .release = vcio_device_release, |
||
144 | +}; |
||
145 | + |
||
146 | +static int __init vcio_init(void) |
||
147 | +{ |
||
148 | + struct device_node *np; |
||
149 | + static struct device *dev; |
||
150 | + int ret; |
||
151 | + |
||
152 | + np = of_find_compatible_node(NULL, NULL, |
||
153 | + "raspberrypi,bcm2835-firmware"); |
||
154 | +/* Uncomment this when we only boot with Device Tree |
||
155 | + if (!of_device_is_available(np)) |
||
156 | + return -ENODEV; |
||
157 | +*/ |
||
158 | + vcio.fw = rpi_firmware_get(np); |
||
159 | + if (!vcio.fw) |
||
160 | + return -ENODEV; |
||
161 | + |
||
162 | + ret = alloc_chrdev_region(&vcio.devt, 0, 1, "vcio"); |
||
163 | + if (ret) { |
||
164 | + pr_err("failed to allocate device number\n"); |
||
165 | + return ret; |
||
166 | + } |
||
167 | + |
||
168 | + cdev_init(&vcio.cdev, &vcio_fops); |
||
169 | + vcio.cdev.owner = THIS_MODULE; |
||
170 | + ret = cdev_add(&vcio.cdev, vcio.devt, 1); |
||
171 | + if (ret) { |
||
172 | + pr_err("failed to register device\n"); |
||
173 | + goto err_unregister_chardev; |
||
174 | + } |
||
175 | + |
||
176 | + /* |
||
177 | + * Create sysfs entries |
||
178 | + * 'bcm2708_vcio' is used for backwards compatibility so we don't break |
||
179 | + * userspace. Raspian has a udev rule that changes the permissions. |
||
180 | + */ |
||
181 | + vcio.class = class_create(THIS_MODULE, "bcm2708_vcio"); |
||
182 | + if (IS_ERR(vcio.class)) { |
||
183 | + ret = PTR_ERR(vcio.class); |
||
184 | + pr_err("failed to create class\n"); |
||
185 | + goto err_cdev_del; |
||
186 | + } |
||
187 | + |
||
188 | + dev = device_create(vcio.class, NULL, vcio.devt, NULL, "vcio"); |
||
189 | + if (IS_ERR(dev)) { |
||
190 | + ret = PTR_ERR(dev); |
||
191 | + pr_err("failed to create device\n"); |
||
192 | + goto err_class_destroy; |
||
193 | + } |
||
194 | + |
||
195 | + return 0; |
||
196 | + |
||
197 | +err_class_destroy: |
||
198 | + class_destroy(vcio.class); |
||
199 | +err_cdev_del: |
||
200 | + cdev_del(&vcio.cdev); |
||
201 | +err_unregister_chardev: |
||
202 | + unregister_chrdev_region(vcio.devt, 1); |
||
203 | + |
||
204 | + return ret; |
||
205 | +} |
||
206 | +module_init(vcio_init); |
||
207 | + |
||
208 | +static void __exit vcio_exit(void) |
||
209 | +{ |
||
210 | + device_destroy(vcio.class, vcio.devt); |
||
211 | + class_destroy(vcio.class); |
||
212 | + cdev_del(&vcio.cdev); |
||
213 | + unregister_chrdev_region(vcio.devt, 1); |
||
214 | +} |
||
215 | +module_exit(vcio_exit); |
||
216 | + |
||
217 | +MODULE_AUTHOR("Gray Girling"); |
||
218 | +MODULE_AUTHOR("Noralf Trønnes"); |
||
219 | +MODULE_DESCRIPTION("Mailbox userspace access"); |
||
220 | +MODULE_LICENSE("GPL"); |