123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- From a7543fe261e31e16e8a6c1804d562556f0c1b794 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
- Date: Fri, 26 Jun 2015 14:27:06 +0200
- Subject: [PATCH] char: broadcom: Add vcio module
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- Add module for accessing the mailbox property channel through
- /dev/vcio. Was previously in bcm2708-vcio.
- Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
- ---
- drivers/char/broadcom/Kconfig | 6 ++
- drivers/char/broadcom/Makefile | 1 +
- drivers/char/broadcom/vcio.c | 175 +++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 182 insertions(+)
- create mode 100644 drivers/char/broadcom/vcio.c
- --- a/drivers/char/broadcom/Kconfig
- +++ b/drivers/char/broadcom/Kconfig
- @@ -22,6 +22,12 @@ config BCM2708_VCMEM
- help
- Helper for videocore memory access and total size allocation.
-
- +config BCM_VCIO
- + tristate "Mailbox userspace access"
- + depends on BCM2835_MBOX
- + help
- + Gives access to the mailbox property channel from userspace.
- +
- endif
-
- config BCM_VC_SM
- --- a/drivers/char/broadcom/Makefile
- +++ b/drivers/char/broadcom/Makefile
- @@ -1,5 +1,6 @@
- obj-$(CONFIG_BCM_VC_CMA) += vc_cma/
- obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o
- +obj-$(CONFIG_BCM_VCIO) += vcio.o
- obj-$(CONFIG_BCM_VC_SM) += vc_sm/
-
- obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o
- --- /dev/null
- +++ b/drivers/char/broadcom/vcio.c
- @@ -0,0 +1,175 @@
- +/*
- + * Copyright (C) 2010 Broadcom
- + * Copyright (C) 2015 Noralf Trønnes
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + *
- + */
- +
- +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
- +
- +#include <linux/cdev.h>
- +#include <linux/device.h>
- +#include <linux/fs.h>
- +#include <linux/init.h>
- +#include <linux/ioctl.h>
- +#include <linux/module.h>
- +#include <linux/slab.h>
- +#include <linux/uaccess.h>
- +#include <soc/bcm2835/raspberrypi-firmware.h>
- +
- +#define MBOX_CHAN_PROPERTY 8
- +
- +#define VCIO_IOC_MAGIC 100
- +#define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *)
- +
- +static struct {
- + dev_t devt;
- + struct cdev cdev;
- + struct class *class;
- + struct rpi_firmware *fw;
- +} vcio;
- +
- +static int vcio_user_property_list(void *user)
- +{
- + u32 *buf, size;
- + int ret;
- +
- + /* The first 32-bit is the size of the buffer */
- + if (copy_from_user(&size, user, sizeof(size)))
- + return -EFAULT;
- +
- + buf = kmalloc(size, GFP_KERNEL);
- + if (!buf)
- + return -ENOMEM;
- +
- + if (copy_from_user(buf, user, size)) {
- + kfree(buf);
- + return -EFAULT;
- + }
- +
- + /* Strip off protocol encapsulation */
- + ret = rpi_firmware_property_list(vcio.fw, &buf[2], size - 12);
- + if (ret) {
- + kfree(buf);
- + return ret;
- + }
- +
- + buf[1] = RPI_FIRMWARE_STATUS_SUCCESS;
- + if (copy_to_user(user, buf, size))
- + ret = -EFAULT;
- +
- + kfree(buf);
- +
- + return ret;
- +}
- +
- +static int vcio_device_open(struct inode *inode, struct file *file)
- +{
- + try_module_get(THIS_MODULE);
- +
- + return 0;
- +}
- +
- +static int vcio_device_release(struct inode *inode, struct file *file)
- +{
- + module_put(THIS_MODULE);
- +
- + return 0;
- +}
- +
- +static long vcio_device_ioctl(struct file *file, unsigned int ioctl_num,
- + unsigned long ioctl_param)
- +{
- + switch (ioctl_num) {
- + case IOCTL_MBOX_PROPERTY:
- + return vcio_user_property_list((void *)ioctl_param);
- + default:
- + pr_err("unknown ioctl: %d\n", ioctl_num);
- + return -EINVAL;
- + }
- +}
- +
- +const struct file_operations vcio_fops = {
- + .unlocked_ioctl = vcio_device_ioctl,
- + .open = vcio_device_open,
- + .release = vcio_device_release,
- +};
- +
- +static int __init vcio_init(void)
- +{
- + struct device_node *np;
- + static struct device *dev;
- + int ret;
- +
- + np = of_find_compatible_node(NULL, NULL,
- + "raspberrypi,bcm2835-firmware");
- +/* Uncomment this when we only boot with Device Tree
- + if (!of_device_is_available(np))
- + return -ENODEV;
- +*/
- + vcio.fw = rpi_firmware_get(np);
- + if (!vcio.fw)
- + return -ENODEV;
- +
- + ret = alloc_chrdev_region(&vcio.devt, 0, 1, "vcio");
- + if (ret) {
- + pr_err("failed to allocate device number\n");
- + return ret;
- + }
- +
- + cdev_init(&vcio.cdev, &vcio_fops);
- + vcio.cdev.owner = THIS_MODULE;
- + ret = cdev_add(&vcio.cdev, vcio.devt, 1);
- + if (ret) {
- + pr_err("failed to register device\n");
- + goto err_unregister_chardev;
- + }
- +
- + /*
- + * Create sysfs entries
- + * 'bcm2708_vcio' is used for backwards compatibility so we don't break
- + * userspace. Raspian has a udev rule that changes the permissions.
- + */
- + vcio.class = class_create(THIS_MODULE, "bcm2708_vcio");
- + if (IS_ERR(vcio.class)) {
- + ret = PTR_ERR(vcio.class);
- + pr_err("failed to create class\n");
- + goto err_cdev_del;
- + }
- +
- + dev = device_create(vcio.class, NULL, vcio.devt, NULL, "vcio");
- + if (IS_ERR(dev)) {
- + ret = PTR_ERR(dev);
- + pr_err("failed to create device\n");
- + goto err_class_destroy;
- + }
- +
- + return 0;
- +
- +err_class_destroy:
- + class_destroy(vcio.class);
- +err_cdev_del:
- + cdev_del(&vcio.cdev);
- +err_unregister_chardev:
- + unregister_chrdev_region(vcio.devt, 1);
- +
- + return ret;
- +}
- +module_init(vcio_init);
- +
- +static void __exit vcio_exit(void)
- +{
- + device_destroy(vcio.class, vcio.devt);
- + class_destroy(vcio.class);
- + cdev_del(&vcio.cdev);
- + unregister_chrdev_region(vcio.devt, 1);
- +}
- +module_exit(vcio_exit);
- +
- +MODULE_AUTHOR("Gray Girling");
- +MODULE_AUTHOR("Noralf Trønnes");
- +MODULE_DESCRIPTION("Mailbox userspace access");
- +MODULE_LICENSE("GPL");
|