Skip to content

Instantly share code, notes, and snippets.

@notro
Created April 29, 2015 22:19
Show Gist options
  • Save notro/bc1a204f5d3fe11454a6 to your computer and use it in GitHub Desktop.
Save notro/bc1a204f5d3fe11454a6 to your computer and use it in GitHub Desktop.
diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi
index 065a424..ec43d76 100644
--- a/arch/arm/boot/dts/bcm2708_common.dtsi
+++ b/arch/arm/boot/dts/bcm2708_common.dtsi
@@ -36,6 +36,12 @@
#interrupt-cells = <2>;
};
+ mbox: mailbox@7e00b800 {
+ compatible = "brcm,bcm2708-vcio";
+ reg = <0x7e00b880 0x40>;
+ interrupts = <0 1>;
+ };
+
gpio: gpio {
compatible = "brcm,bcm2835-gpio";
reg = <0x7e200000 0xb4>;
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 486e090..7cc47c1 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -55,7 +55,6 @@
#include <asm/mach/map.h>
#include <mach/timex.h>
-#include <mach/vcio.h>
#include <mach/system.h>
#include <linux/delay.h>
@@ -414,17 +413,21 @@ static struct platform_device bcm2708_usb_device = {
};
static struct resource bcm2708_vcio_resources[] = {
- [0] = { /* mailbox/semaphore/doorbell access */
- .start = MCORE_BASE,
- .end = MCORE_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
+ {
+ .start = ARMCTRL_0_MAIL0_BASE,
+ .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_ARM_MAILBOX,
+ .end = IRQ_ARM_MAILBOX,
+ .flags = IORESOURCE_IRQ,
+ },
};
static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
static struct platform_device bcm2708_vcio_device = {
- .name = BCM_VCIO_DRIVER_NAME,
+ .name = "bcm2708_vcio",
.id = -1, /* only one VideoCore I/O area */
.resource = bcm2708_vcio_resources,
.num_resources = ARRAY_SIZE(bcm2708_vcio_resources),
@@ -905,7 +908,7 @@ void __init bcm2708_init(void)
bcm2708_dt_init();
bcm_register_device_dt(&bcm2708_dmaengine_device);
- bcm_register_device(&bcm2708_vcio_device);
+ bcm_register_device_dt(&bcm2708_vcio_device);
#ifdef CONFIG_BCM2708_GPIO
bcm_register_device_dt(&bcm2708_gpio_device);
#endif
diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h
index 2e7e1bb..bef3e5a 100644
--- a/arch/arm/mach-bcm2708/include/mach/platform.h
+++ b/arch/arm/mach-bcm2708/include/mach/platform.h
@@ -81,6 +81,7 @@
#define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */
#define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */
#define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */
+#define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */
/*
diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c
index 700bff4..6c43a64 100644
--- a/arch/arm/mach-bcm2708/vcio.c
+++ b/arch/arm/mach-bcm2708/vcio.c
@@ -40,19 +40,19 @@
#include <asm/uaccess.h>
-#define DRIVER_NAME BCM_VCIO_DRIVER_NAME
+#define DRIVER_NAME "bcm2708_vcio"
/* ----------------------------------------------------------------------
* Mailbox
* -------------------------------------------------------------------- */
/* offsets from a mail box base address */
-#define MAIL_WRT 0x00 /* write - and next 4 words */
-#define MAIL_RD 0x00 /* read - and next 4 words */
-#define MAIL_POL 0x10 /* read without popping the fifo */
-#define MAIL_SND 0x14 /* sender ID (bottom two bits) */
-#define MAIL_STA 0x18 /* status */
-#define MAIL_CNF 0x1C /* configuration */
+#define MAIL0_RD 0x00 /* read - and next 4 words */
+#define MAIL0_POL 0x10 /* read without popping the fifo */
+#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */
+#define MAIL0_STA 0x18 /* status */
+#define MAIL0_CNF 0x1C /* configuration */
+#define MAIL1_WRT 0x20 /* write - and next 4 words */
#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf))
#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf))
@@ -74,18 +74,17 @@ struct vc_mailbox {
};
static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev,
- uint32_t addr_mbox)
+ void __iomem *regs)
{
int i;
mbox_out->dev = dev;
- mbox_out->status = __io_address(addr_mbox + MAIL_STA);
- mbox_out->config = __io_address(addr_mbox + MAIL_CNF);
- mbox_out->read = __io_address(addr_mbox + MAIL_RD);
- /* Write to the other mailbox */
- mbox_out->write =
- __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) +
- MAIL_WRT);
+ mbox_out->status = regs + MAIL0_STA;
+ mbox_out->config = regs + MAIL0_CNF;
+ mbox_out->read = regs + MAIL0_RD;
+ mbox_out->write = regs + MAIL1_WRT;
+
+pr_info("%s: status=%p, config=%p, read=%p, write=%p\n", __func__, mbox_out->status, mbox_out->config, mbox_out->read, mbox_out->write);
for (i = 0; i < MBOX_CHAN_COUNT; i++) {
mbox_out->msg[i] = 0;
@@ -130,7 +129,7 @@ static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28)
return rc;
}
-static irqreturn_t mbox_irq(int irq, void *dev_id)
+static irqreturn_t mbox_irq_handler(int irq, void *dev_id)
{
/* wait for the mailbox FIFO to have some data in it */
struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id;
@@ -160,12 +159,6 @@ static irqreturn_t mbox_irq(int irq, void *dev_id)
return ret;
}
-static struct irqaction mbox_irqaction = {
- .name = "ARM Mailbox IRQ",
- .flags = IRQF_DISABLED | IRQF_IRQPOLL,
- .handler = mbox_irq,
-};
-
/* ----------------------------------------------------------------------
* Mailbox Methods
* -------------------------------------------------------------------- */
@@ -214,11 +207,6 @@ extern int bcm_mailbox_read(unsigned chan, uint32_t *data28)
}
EXPORT_SYMBOL_GPL(bcm_mailbox_read);
-static void dev_mbox_register(const char *dev_name, struct device *dev)
-{
- mbox_dev = dev;
-}
-
static int mbox_copy_from_user(void *dst, const void *src, int size)
{
if ( (uint32_t)src < TASK_SIZE)
@@ -376,72 +364,70 @@ struct file_operations fops = {
static int bcm_vcio_probe(struct platform_device *pdev)
{
- int ret = 0;
+ struct device *dev = &pdev->dev;
struct vc_mailbox *mailbox;
+ struct resource *res;
+ void __iomem *regs;
+ int irq, ret;
+
+ mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL);
+ if (!mailbox)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+
+ irq = platform_get_irq(pdev, 0);
+ ret = devm_request_irq(dev, irq, mbox_irq_handler,
+ IRQF_DISABLED | IRQF_IRQPOLL,
+ dev_name(dev), mailbox);
+ if (ret) {
+ dev_err(dev, "Interrupt request failed %d\n", ret);
+ return ret;
+ }
- mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL);
- if (NULL == mailbox) {
- printk(KERN_ERR DRIVER_NAME ": failed to allocate "
- "mailbox memory\n");
- ret = -ENOMEM;
- } else {
- struct resource *res;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- printk(KERN_ERR DRIVER_NAME ": failed to obtain memory "
- "resource\n");
- ret = -ENODEV;
- kfree(mailbox);
- } else {
- /* should be based on the registers from res really */
- mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD);
-
- platform_set_drvdata(pdev, mailbox);
- dev_mbox_register(DRIVER_NAME, &pdev->dev);
+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops);
+ if (ret < 0) {
+ dev_err(dev, "Character device registration failed %d\n", ret);
+ return ret;
+ }
- mbox_irqaction.dev_id = mailbox;
- setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction);
- printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n",
- __io_address(ARM_0_MAIL0_RD));
- }
+ vcio_class = class_create(THIS_MODULE, DRIVER_NAME);
+ if (IS_ERR(vcio_class)) {
+ ret = PTR_ERR(vcio_class);
+ dev_err(dev, "Class creation failed %d\n", ret);
+ return ret;
}
- if (ret == 0) {
- /*
- * Register the character device
- */
- ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops);
+ device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, "vcio");
+
+ mbox_init(mailbox, &pdev->dev, regs);
+ platform_set_drvdata(pdev, mailbox);
+ mbox_dev = dev;
+
+ dev_info(dev, "mailbox at %p\n", regs);
- /*
- * Negative values signify an error
- */
- if (ret < 0) {
- printk(KERN_ERR DRIVER_NAME
- "Failed registering the character device %d\n", ret);
- return ret;
- }
- vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME);
- if (IS_ERR(vcio_class)) {
- ret = PTR_ERR(vcio_class);
- return ret ;
- }
- device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL,
- "vcio");
- }
return ret;
}
static int bcm_vcio_remove(struct platform_device *pdev)
{
- struct vc_mailbox *mailbox = platform_get_drvdata(pdev);
-
platform_set_drvdata(pdev, NULL);
- kfree(mailbox);
+ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0));
+ class_destroy(vcio_class);
+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME);
return 0;
}
+static const struct of_device_id bcm_vcio_of_match_table[] = {
+ { .compatible = "brcm,bcm2708-vcio", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table);
+
static struct platform_driver bcm_mbox_driver = {
.probe = bcm_vcio_probe,
.remove = bcm_vcio_remove,
@@ -449,29 +435,17 @@ static struct platform_driver bcm_mbox_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+ .of_match_table = bcm_vcio_of_match_table,
},
};
static int __init bcm_mbox_init(void)
{
- int ret;
-
- printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n");
-
- ret = platform_driver_register(&bcm_mbox_driver);
- if (ret != 0) {
- printk(KERN_ERR DRIVER_NAME ": failed to register "
- "on platform\n");
- }
-
- return ret;
+ return platform_driver_register(&bcm_mbox_driver);
}
static void __exit bcm_mbox_exit(void)
{
- device_destroy(vcio_class,MKDEV(MAJOR_NUM, 0));
- class_destroy(vcio_class);
- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME);
platform_driver_unregister(&bcm_mbox_driver);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment