lantiq: VGV7510KW22BRN - set the phy clock source
[openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0047-char-broadcom-Add-vcio-module.patch
1 From abcf04d54ccb3d0897b1f7a95ddf9d9ccf63dc76 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 047/170] 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 @@ -22,6 +22,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,5 +1,6 @@
38  obj-$(CONFIG_BCM_VC_CMA)       += vc_cma/
39  obj-$(CONFIG_BCM2708_VCMEM)    += vc_mem.o
40 +obj-$(CONFIG_BCM_VCIO)         += vcio.o
41  obj-$(CONFIG_BCM_VC_SM)         += vc_sm/
42  
43  obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o
44 --- /dev/null
45 +++ b/drivers/char/broadcom/vcio.c
46 @@ -0,0 +1,175 @@
47 +/*
48 + *  Copyright (C) 2010 Broadcom
49 + *  Copyright (C) 2015 Noralf Trønnes
50 + *
51 + * This program is free software; you can redistribute it and/or modify
52 + * it under the terms of the GNU General Public License version 2 as
53 + * published by the Free Software Foundation.
54 + *
55 + */
56 +
57 +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
58 +
59 +#include <linux/cdev.h>
60 +#include <linux/device.h>
61 +#include <linux/fs.h>
62 +#include <linux/init.h>
63 +#include <linux/ioctl.h>
64 +#include <linux/module.h>
65 +#include <linux/slab.h>
66 +#include <linux/uaccess.h>
67 +#include <soc/bcm2835/raspberrypi-firmware.h>
68 +
69 +#define MBOX_CHAN_PROPERTY 8
70 +
71 +#define VCIO_IOC_MAGIC 100
72 +#define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *)
73 +
74 +static struct {
75 +       dev_t devt;
76 +       struct cdev cdev;
77 +       struct class *class;
78 +       struct rpi_firmware *fw;
79 +} vcio;
80 +
81 +static int vcio_user_property_list(void *user)
82 +{
83 +       u32 *buf, size;
84 +       int ret;
85 +
86 +       /* The first 32-bit is the size of the buffer */
87 +       if (copy_from_user(&size, user, sizeof(size)))
88 +               return -EFAULT;
89 +
90 +       buf = kmalloc(size, GFP_KERNEL);
91 +       if (!buf)
92 +               return -ENOMEM;
93 +
94 +       if (copy_from_user(buf, user, size)) {
95 +               kfree(buf);
96 +               return -EFAULT;
97 +       }
98 +
99 +       /* Strip off protocol encapsulation */
100 +       ret = rpi_firmware_property_list(vcio.fw, &buf[2], size - 12);
101 +       if (ret) {
102 +               kfree(buf);
103 +               return ret;
104 +       }
105 +
106 +       buf[1] = RPI_FIRMWARE_STATUS_SUCCESS;
107 +       if (copy_to_user(user, buf, size))
108 +               ret = -EFAULT;
109 +
110 +       kfree(buf);
111 +
112 +       return ret;
113 +}
114 +
115 +static int vcio_device_open(struct inode *inode, struct file *file)
116 +{
117 +       try_module_get(THIS_MODULE);
118 +
119 +       return 0;
120 +}
121 +
122 +static int vcio_device_release(struct inode *inode, struct file *file)
123 +{
124 +       module_put(THIS_MODULE);
125 +
126 +       return 0;
127 +}
128 +
129 +static long vcio_device_ioctl(struct file *file, unsigned int ioctl_num,
130 +                             unsigned long ioctl_param)
131 +{
132 +       switch (ioctl_num) {
133 +       case IOCTL_MBOX_PROPERTY:
134 +               return vcio_user_property_list((void *)ioctl_param);
135 +       default:
136 +               pr_err("unknown ioctl: %d\n", ioctl_num);
137 +               return -EINVAL;
138 +       }
139 +}
140 +
141 +const struct file_operations vcio_fops = {
142 +       .unlocked_ioctl = vcio_device_ioctl,
143 +       .open = vcio_device_open,
144 +       .release = vcio_device_release,
145 +};
146 +
147 +static int __init vcio_init(void)
148 +{
149 +       struct device_node *np;
150 +       static struct device *dev;
151 +       int ret;
152 +
153 +       np = of_find_compatible_node(NULL, NULL,
154 +                                    "raspberrypi,bcm2835-firmware");
155 +/* Uncomment this when we only boot with Device Tree
156 +       if (!of_device_is_available(np))
157 +               return -ENODEV;
158 +*/
159 +       vcio.fw = rpi_firmware_get(np);
160 +       if (!vcio.fw)
161 +               return -ENODEV;
162 +
163 +       ret = alloc_chrdev_region(&vcio.devt, 0, 1, "vcio");
164 +       if (ret) {
165 +               pr_err("failed to allocate device number\n");
166 +               return ret;
167 +       }
168 +
169 +       cdev_init(&vcio.cdev, &vcio_fops);
170 +       vcio.cdev.owner = THIS_MODULE;
171 +       ret = cdev_add(&vcio.cdev, vcio.devt, 1);
172 +       if (ret) {
173 +               pr_err("failed to register device\n");
174 +               goto err_unregister_chardev;
175 +       }
176 +
177 +       /*
178 +        * Create sysfs entries
179 +        * 'bcm2708_vcio' is used for backwards compatibility so we don't break
180 +        * userspace. Raspian has a udev rule that changes the permissions.
181 +        */
182 +       vcio.class = class_create(THIS_MODULE, "bcm2708_vcio");
183 +       if (IS_ERR(vcio.class)) {
184 +               ret = PTR_ERR(vcio.class);
185 +               pr_err("failed to create class\n");
186 +               goto err_cdev_del;
187 +       }
188 +
189 +       dev = device_create(vcio.class, NULL, vcio.devt, NULL, "vcio");
190 +       if (IS_ERR(dev)) {
191 +               ret = PTR_ERR(dev);
192 +               pr_err("failed to create device\n");
193 +               goto err_class_destroy;
194 +       }
195 +
196 +       return 0;
197 +
198 +err_class_destroy:
199 +       class_destroy(vcio.class);
200 +err_cdev_del:
201 +       cdev_del(&vcio.cdev);
202 +err_unregister_chardev:
203 +       unregister_chrdev_region(vcio.devt, 1);
204 +
205 +       return ret;
206 +}
207 +module_init(vcio_init);
208 +
209 +static void __exit vcio_exit(void)
210 +{
211 +       device_destroy(vcio.class, vcio.devt);
212 +       class_destroy(vcio.class);
213 +       cdev_del(&vcio.cdev);
214 +       unregister_chrdev_region(vcio.devt, 1);
215 +}
216 +module_exit(vcio_exit);
217 +
218 +MODULE_AUTHOR("Gray Girling");
219 +MODULE_AUTHOR("Noralf Trønnes");
220 +MODULE_DESCRIPTION("Mailbox userspace access");
221 +MODULE_LICENSE("GPL");