Skip to content

Commit

Permalink
Merge pull request #1037 from notro/fw2
Browse files Browse the repository at this point in the history
Add firmware driver
  • Loading branch information
popcornmix committed Jul 13, 2015
2 parents c66887b + d979963 commit 87f03d8
Show file tree
Hide file tree
Showing 24 changed files with 561 additions and 623 deletions.
8 changes: 7 additions & 1 deletion arch/arm/boot/dts/bcm2708_common.dtsi
Expand Up @@ -74,9 +74,10 @@
};

mailbox: mailbox@7e00b800 {
compatible = "brcm,bcm2708-vcio";
compatible = "brcm,bcm2835-mbox";
reg = <0x7e00b880 0x40>;
interrupts = <0 1>;
#mbox-cells = <0>;
};

watchdog: watchdog@7e100000 {
Expand Down Expand Up @@ -205,6 +206,11 @@
<1 9>;
};

firmware: firmware {
compatible = "raspberrypi,bcm2835-firmware";
mboxes = <&mailbox>;
};

leds: leds {
compatible = "gpio-leds";
};
Expand Down
7 changes: 7 additions & 0 deletions arch/arm/boot/dts/bcm2835-rpi.dtsi
Expand Up @@ -27,6 +27,13 @@
};
};

soc {
firmware: firmware {
compatible = "raspberrypi,bcm2835-firmware";
mboxes = <&mailbox>;
};
};

/* Onboard audio */
audio: audio {
compatible = "brcm,bcm2835-audio";
Expand Down
3 changes: 2 additions & 1 deletion arch/arm/boot/dts/bcm2835.dtsi
Expand Up @@ -62,9 +62,10 @@
};

mailbox: mailbox@7e00b800 {
compatible = "brcm,bcm2708-vcio";
compatible = "brcm,bcm2835-mbox";
reg = <0x7e00b880 0x40>;
interrupts = <0 1>;
#mbox-cells = <0>;
};

gpio: gpio@7e200000 {
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/configs/bcm2709_defconfig
Expand Up @@ -574,6 +574,7 @@ CONFIG_HW_RANDOM_BCM2708=m
CONFIG_RAW_DRIVER=y
CONFIG_BRCM_CHAR_DRIVERS=y
CONFIG_BCM_VC_CMA=y
CONFIG_BCM_VCIO=y
CONFIG_BCM_VC_SM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=m
Expand Down Expand Up @@ -1074,6 +1075,7 @@ CONFIG_FB_FLEX=m
CONFIG_FB_TFT_FBTFT_DEVICE=m
CONFIG_MAILBOX=y
CONFIG_BCM2708_MBOX=y
CONFIG_BCM2835_MBOX=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXTCON=m
CONFIG_EXTCON_ARIZONA=m
Expand All @@ -1082,6 +1084,7 @@ CONFIG_IIO_BUFFER=y
CONFIG_IIO_BUFFER_CB=y
CONFIG_IIO_KFIFO_BUF=m
CONFIG_DHT11=m
CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/configs/bcm2835_defconfig
Expand Up @@ -568,6 +568,7 @@ CONFIG_HW_RANDOM_BCM2835=m
CONFIG_RAW_DRIVER=y
CONFIG_BRCM_CHAR_DRIVERS=y
CONFIG_BCM_VC_CMA=y
CONFIG_BCM_VCIO=y
CONFIG_BCM_VC_SM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=m
Expand Down Expand Up @@ -1064,9 +1065,11 @@ CONFIG_FB_FLEX=m
CONFIG_FB_TFT_FBTFT_DEVICE=m
CONFIG_MAILBOX=y
CONFIG_BCM2708_MBOX=y
CONFIG_BCM2835_MBOX=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXTCON=m
CONFIG_EXTCON_ARIZONA=m
CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/configs/bcmrpi_defconfig
Expand Up @@ -567,6 +567,7 @@ CONFIG_HW_RANDOM_BCM2708=m
CONFIG_RAW_DRIVER=y
CONFIG_BRCM_CHAR_DRIVERS=y
CONFIG_BCM_VC_CMA=y
CONFIG_BCM_VCIO=y
CONFIG_BCM_VC_SM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=m
Expand Down Expand Up @@ -1067,6 +1068,7 @@ CONFIG_FB_FLEX=m
CONFIG_FB_TFT_FBTFT_DEVICE=m
CONFIG_MAILBOX=y
CONFIG_BCM2708_MBOX=y
CONFIG_BCM2835_MBOX=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXTCON=m
CONFIG_EXTCON_ARIZONA=m
Expand All @@ -1075,6 +1077,7 @@ CONFIG_IIO_BUFFER=y
CONFIG_IIO_BUFFER_CB=y
CONFIG_IIO_KFIFO_BUF=m
CONFIG_DHT11=m
CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
Expand Down
13 changes: 12 additions & 1 deletion arch/arm/mach-bcm2708/bcm2708.c
Expand Up @@ -405,7 +405,7 @@ static struct resource bcm2708_vcio_resources[] = {
static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);

static struct platform_device bcm2708_vcio_device = {
.name = "bcm2708_vcio",
.name = "bcm2835-mbox",
.id = -1, /* only one VideoCore I/O area */
.resource = bcm2708_vcio_resources,
.num_resources = ARRAY_SIZE(bcm2708_vcio_resources),
Expand All @@ -415,6 +415,16 @@ static struct platform_device bcm2708_vcio_device = {
},
};

static u64 rpifw_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);

static struct platform_device bcm2708_rpifw_device = {
.name = "raspberrypi-firmware",
.dev = {
.dma_mask = &rpifw_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
},
};

static struct resource bcm2708_vchiq_resources[] = {
{
.start = ARMCTRL_0_BELL_BASE,
Expand Down Expand Up @@ -871,6 +881,7 @@ void __init bcm2708_init(void)

bcm_register_device_dt(&bcm2708_dmaengine_device);
bcm_register_device_dt(&bcm2708_vcio_device);
bcm_register_device_dt(&bcm2708_rpifw_device);
bcm_register_device_dt(&bcm2708_vchiq_device);
#ifdef CONFIG_BCM2708_GPIO
bcm_register_device_dt(&bcm2708_gpio_device);
Expand Down
13 changes: 12 additions & 1 deletion arch/arm/mach-bcm2709/bcm2709.c
Expand Up @@ -426,7 +426,7 @@ static struct resource bcm2708_vcio_resources[] = {
static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);

static struct platform_device bcm2708_vcio_device = {
.name = "bcm2708_vcio",
.name = "bcm2835-mbox",
.id = -1, /* only one VideoCore I/O area */
.resource = bcm2708_vcio_resources,
.num_resources = ARRAY_SIZE(bcm2708_vcio_resources),
Expand All @@ -436,6 +436,16 @@ static struct platform_device bcm2708_vcio_device = {
},
};

static u64 rpifw_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);

static struct platform_device bcm2708_rpifw_device = {
.name = "raspberrypi-firmware",
.dev = {
.dma_mask = &rpifw_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
},
};

static struct resource bcm2708_vchiq_resources[] = {
{
.start = ARMCTRL_0_BELL_BASE,
Expand Down Expand Up @@ -892,6 +902,7 @@ void __init bcm2709_init(void)

bcm_register_device_dt(&bcm2708_dmaengine_device);
bcm_register_device_dt(&bcm2708_vcio_device);
bcm_register_device_dt(&bcm2708_rpifw_device);
bcm_register_device_dt(&bcm2708_vchiq_device);
#ifdef CONFIG_BCM2708_GPIO
bcm_register_device_dt(&bcm2708_gpio_device);
Expand Down
6 changes: 6 additions & 0 deletions drivers/char/broadcom/Kconfig
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions drivers/char/broadcom/Makefile
@@ -1,3 +1,4 @@
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/
175 changes: 175 additions & 0 deletions 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");

0 comments on commit 87f03d8

Please sign in to comment.