Commit f95adbc1 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'mailbox-for-next' of git://git.linaro.org/landing-teams/working/fujitsu/integration

Pull mailbox updates from Jassi Brar:

 - new features (poll and SRAM usage) added to the mailbox-test driver

 - major update of Broadcom's PDC controller driver

 - minor fix for auto-loading test and STI driver modules

* 'mailbox-for-next' of git://git.linaro.org/landing-teams/working/fujitsu/integration:
  mailbox: mailbox-test: allow reserved areas in SRAM
  mailbox: mailbox-test: add support for fasync/poll
  mailbox: bcm-pdc: Remove unnecessary void* casts
  mailbox: bcm-pdc: Simplify interrupt handler logic
  mailbox: bcm-pdc: Performance improvements
  mailbox: bcm-pdc: Don't use iowrite32 to write DMA descriptors
  mailbox: bcm-pdc: Convert from threaded IRQ to tasklet
  mailbox: bcm-pdc: Try to improve branch prediction
  mailbox: bcm-pdc: streamline rx code
  mailbox: bcm-pdc: Convert from interrupts to poll for tx done
  mailbox: bcm-pdc: PDC driver leaves debugfs files after removal
  mailbox: bcm-pdc: Changes so mbox client can be removed / re-inserted
  mailbox: bcm-pdc: Use octal permissions rather than symbolic
  mailbox: sti: Fix module autoload for OF registration
  mailbox: mailbox-test: Fix module autoload
parents 74f65bbf db4d22c0
This diff is collapsed.
...@@ -403,6 +403,7 @@ static const struct of_device_id sti_mailbox_match[] = { ...@@ -403,6 +403,7 @@ static const struct of_device_id sti_mailbox_match[] = {
}, },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, sti_mailbox_match);
static int sti_mbox_probe(struct platform_device *pdev) static int sti_mbox_probe(struct platform_device *pdev)
{ {
......
...@@ -11,12 +11,14 @@ ...@@ -11,12 +11,14 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/fs.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mailbox_client.h> #include <linux/mailbox_client.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
...@@ -39,6 +41,8 @@ struct mbox_test_device { ...@@ -39,6 +41,8 @@ struct mbox_test_device {
char *signal; char *signal;
char *message; char *message;
spinlock_t lock; spinlock_t lock;
wait_queue_head_t waitq;
struct fasync_struct *async_queue;
}; };
static ssize_t mbox_test_signal_write(struct file *filp, static ssize_t mbox_test_signal_write(struct file *filp,
...@@ -81,6 +85,13 @@ static const struct file_operations mbox_test_signal_ops = { ...@@ -81,6 +85,13 @@ static const struct file_operations mbox_test_signal_ops = {
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
}; };
static int mbox_test_message_fasync(int fd, struct file *filp, int on)
{
struct mbox_test_device *tdev = filp->private_data;
return fasync_helper(fd, filp, on, &tdev->async_queue);
}
static ssize_t mbox_test_message_write(struct file *filp, static ssize_t mbox_test_message_write(struct file *filp,
const char __user *userbuf, const char __user *userbuf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -138,6 +149,20 @@ static ssize_t mbox_test_message_write(struct file *filp, ...@@ -138,6 +149,20 @@ static ssize_t mbox_test_message_write(struct file *filp,
return ret < 0 ? ret : count; return ret < 0 ? ret : count;
} }
static bool mbox_test_message_data_ready(struct mbox_test_device *tdev)
{
unsigned char data;
unsigned long flags;
spin_lock_irqsave(&tdev->lock, flags);
data = tdev->rx_buffer[0];
spin_unlock_irqrestore(&tdev->lock, flags);
if (data != '\0')
return true;
return false;
}
static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf, static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
...@@ -147,6 +172,8 @@ static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf, ...@@ -147,6 +172,8 @@ static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
int l = 0; int l = 0;
int ret; int ret;
DECLARE_WAITQUEUE(wait, current);
touser = kzalloc(MBOX_HEXDUMP_MAX_LEN + 1, GFP_KERNEL); touser = kzalloc(MBOX_HEXDUMP_MAX_LEN + 1, GFP_KERNEL);
if (!touser) if (!touser)
return -ENOMEM; return -ENOMEM;
...@@ -155,15 +182,29 @@ static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf, ...@@ -155,15 +182,29 @@ static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
ret = snprintf(touser, 20, "<NO RX CAPABILITY>\n"); ret = snprintf(touser, 20, "<NO RX CAPABILITY>\n");
ret = simple_read_from_buffer(userbuf, count, ppos, ret = simple_read_from_buffer(userbuf, count, ppos,
touser, ret); touser, ret);
goto out; goto kfree_err;
} }
if (tdev->rx_buffer[0] == '\0') { add_wait_queue(&tdev->waitq, &wait);
ret = snprintf(touser, 9, "<EMPTY>\n");
ret = simple_read_from_buffer(userbuf, count, ppos, do {
touser, ret); __set_current_state(TASK_INTERRUPTIBLE);
goto out;
} if (mbox_test_message_data_ready(tdev))
break;
if (filp->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
goto waitq_err;
}
if (signal_pending(current)) {
ret = -ERESTARTSYS;
goto waitq_err;
}
schedule();
} while (1);
spin_lock_irqsave(&tdev->lock, flags); spin_lock_irqsave(&tdev->lock, flags);
...@@ -185,14 +226,31 @@ static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf, ...@@ -185,14 +226,31 @@ static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
spin_unlock_irqrestore(&tdev->lock, flags); spin_unlock_irqrestore(&tdev->lock, flags);
ret = simple_read_from_buffer(userbuf, count, ppos, touser, MBOX_HEXDUMP_MAX_LEN); ret = simple_read_from_buffer(userbuf, count, ppos, touser, MBOX_HEXDUMP_MAX_LEN);
out: waitq_err:
__set_current_state(TASK_RUNNING);
remove_wait_queue(&tdev->waitq, &wait);
kfree_err:
kfree(touser); kfree(touser);
return ret; return ret;
} }
static unsigned int
mbox_test_message_poll(struct file *filp, struct poll_table_struct *wait)
{
struct mbox_test_device *tdev = filp->private_data;
poll_wait(filp, &tdev->waitq, wait);
if (mbox_test_message_data_ready(tdev))
return POLLIN | POLLRDNORM;
return 0;
}
static const struct file_operations mbox_test_message_ops = { static const struct file_operations mbox_test_message_ops = {
.write = mbox_test_message_write, .write = mbox_test_message_write,
.read = mbox_test_message_read, .read = mbox_test_message_read,
.fasync = mbox_test_message_fasync,
.poll = mbox_test_message_poll,
.open = simple_open, .open = simple_open,
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
}; };
...@@ -234,6 +292,10 @@ static void mbox_test_receive_message(struct mbox_client *client, void *message) ...@@ -234,6 +292,10 @@ static void mbox_test_receive_message(struct mbox_client *client, void *message)
memcpy(tdev->rx_buffer, message, MBOX_MAX_MSG_LEN); memcpy(tdev->rx_buffer, message, MBOX_MAX_MSG_LEN);
} }
spin_unlock_irqrestore(&tdev->lock, flags); spin_unlock_irqrestore(&tdev->lock, flags);
wake_up_interruptible(&tdev->waitq);
kill_fasync(&tdev->async_queue, SIGIO, POLL_IN);
} }
static void mbox_test_prepare_message(struct mbox_client *client, void *message) static void mbox_test_prepare_message(struct mbox_client *client, void *message)
...@@ -290,6 +352,7 @@ static int mbox_test_probe(struct platform_device *pdev) ...@@ -290,6 +352,7 @@ static int mbox_test_probe(struct platform_device *pdev)
{ {
struct mbox_test_device *tdev; struct mbox_test_device *tdev;
struct resource *res; struct resource *res;
resource_size_t size;
int ret; int ret;
tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL); tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
...@@ -298,14 +361,21 @@ static int mbox_test_probe(struct platform_device *pdev) ...@@ -298,14 +361,21 @@ static int mbox_test_probe(struct platform_device *pdev)
/* It's okay for MMIO to be NULL */ /* It's okay for MMIO to be NULL */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
size = resource_size(res);
tdev->tx_mmio = devm_ioremap_resource(&pdev->dev, res); tdev->tx_mmio = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(tdev->tx_mmio)) if (PTR_ERR(tdev->tx_mmio) == -EBUSY)
/* if reserved area in SRAM, try just ioremap */
tdev->tx_mmio = devm_ioremap(&pdev->dev, res->start, size);
else if (IS_ERR(tdev->tx_mmio))
tdev->tx_mmio = NULL; tdev->tx_mmio = NULL;
/* If specified, second reg entry is Rx MMIO */ /* If specified, second reg entry is Rx MMIO */
res = platform_get_resource(pdev, IORESOURCE_MEM, 1); res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
size = resource_size(res);
tdev->rx_mmio = devm_ioremap_resource(&pdev->dev, res); tdev->rx_mmio = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(tdev->rx_mmio)) if (PTR_ERR(tdev->rx_mmio) == -EBUSY)
tdev->rx_mmio = devm_ioremap(&pdev->dev, res->start, size);
else if (IS_ERR(tdev->rx_mmio))
tdev->rx_mmio = tdev->tx_mmio; tdev->rx_mmio = tdev->tx_mmio;
tdev->tx_channel = mbox_test_request_channel(pdev, "tx"); tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
...@@ -334,6 +404,7 @@ static int mbox_test_probe(struct platform_device *pdev) ...@@ -334,6 +404,7 @@ static int mbox_test_probe(struct platform_device *pdev)
if (ret) if (ret)
return ret; return ret;
init_waitqueue_head(&tdev->waitq);
dev_info(&pdev->dev, "Successfully registered\n"); dev_info(&pdev->dev, "Successfully registered\n");
return 0; return 0;
...@@ -357,6 +428,7 @@ static const struct of_device_id mbox_test_match[] = { ...@@ -357,6 +428,7 @@ static const struct of_device_id mbox_test_match[] = {
{ .compatible = "mailbox-test" }, { .compatible = "mailbox-test" },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, mbox_test_match);
static struct platform_driver mbox_test_driver = { static struct platform_driver mbox_test_driver = {
.driver = { .driver = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment