89 #define pr_fmt(fmt) "virtio-mmio: " fmt
94 #include <linux/list.h>
95 #include <linux/module.h>
97 #include <linux/slab.h>
99 #include <linux/virtio.h>
100 #include <linux/virtio_config.h>
102 #include <linux/virtio_ring.h>
108 #define VIRTIO_MMIO_VRING_ALIGN PAGE_SIZE
112 #define to_virtio_mmio_device(_plat_dev) \
113 container_of(_plat_dev, struct virtio_mmio_device, vdev)
171 void *
buf,
unsigned len)
177 for (i = 0; i < len; i++)
181 static void vm_set(
struct virtio_device *vdev,
unsigned offset,
182 const void *buf,
unsigned len)
188 for (i = 0; i < len; i++)
222 static void vm_notify(
struct virtqueue *vq)
232 static irqreturn_t vm_interrupt(
int irq,
void *opaque)
256 spin_unlock_irqrestore(&vm_dev->lock, flags);
273 spin_unlock_irqrestore(&vm_dev->
lock, flags);
318 goto error_available;
339 if (info->
num == 0) {
341 goto error_alloc_pages;
350 goto error_alloc_pages;
372 goto error_new_virtqueue;
380 spin_unlock_irqrestore(&vm_dev->
lock, flags);
394 static int vm_find_vqs(
struct virtio_device *vdev,
unsigned nvqs,
404 dev_name(&vdev->
dev), vm_dev);
408 for (i = 0; i < nvqs; ++
i) {
409 vqs[
i] = vm_setup_vq(vdev, i, callbacks[i], names[i]);
410 if (IS_ERR(vqs[i])) {
412 return PTR_ERR(vqs[i]);
423 return vm_dev->
pdev->name;
429 .get_status = vm_get_status,
430 .set_status = vm_set_status,
432 .find_vqs = vm_find_vqs,
433 .del_vqs = vm_del_vqs,
434 .get_features = vm_get_features,
435 .finalize_features = vm_finalize_features,
436 .bus_name = vm_bus_name,
454 resource_size(mem), pdev->
name))
461 vm_dev->
vdev.dev.parent = &pdev->
dev;
462 vm_dev->
vdev.config = &virtio_mmio_config_ops;
473 if (
memcmp(&magic,
"virt", 4) != 0) {
474 dev_warn(&pdev->
dev,
"Wrong magic value 0x%08lx!\n", magic);
481 dev_err(&pdev->
dev,
"Version %ld not supported!\n",
491 platform_set_drvdata(pdev, vm_dev);
509 #if defined(CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES)
511 static struct device vm_cmdline_parent = {
515 static int vm_cmdline_parent_registered;
516 static int vm_cmdline_id;
518 static int vm_cmdline_set(
const char *
device,
525 int processed, consumed = 0;
533 processed =
sscanf(str,
"@%lli:%u%n:%d%n",
534 &base, &resources[1].
start, &consumed,
535 &vm_cmdline_id, &consumed);
537 if (processed < 2 || processed > 3 || str[consumed])
540 resources[0].
start = base;
541 resources[0].
end += base;
542 resources[1].
end = resources[1].
start;
544 if (!vm_cmdline_parent_registered) {
547 pr_err(
"Failed to register parent device!\n");
550 vm_cmdline_parent_registered = 1;
553 pr_info(
"Registering device virtio-mmio.%d at 0x%llx-0x%llx, IRQ %d.\n",
555 (
unsigned long long)resources[0].
start,
556 (
unsigned long long)resources[0].
end,
557 (
int)resources[1].start);
559 pdev = platform_device_register_resndata(&vm_cmdline_parent,
560 "virtio-mmio", vm_cmdline_id++,
563 return PTR_ERR(pdev);
568 static int vm_cmdline_get_device(
struct device *
dev,
void *
data)
571 unsigned int len =
strlen(buffer);
576 (
unsigned long long)pdev->
resource[0].start,
577 (
unsigned long long)pdev->
resource[1].start,
586 vm_cmdline_get_device);
587 return strlen(buffer) + 1;
591 .
set = vm_cmdline_set,
592 .get = vm_cmdline_get,
597 static int vm_unregister_cmdline_device(
struct device *
dev,
605 static void vm_unregister_cmdline_devices(
void)
607 if (vm_cmdline_parent_registered) {
609 vm_unregister_cmdline_device);
611 vm_cmdline_parent_registered = 0;
617 static void vm_unregister_cmdline_devices(
void)
626 { .compatible =
"virtio,mmio", },
632 .probe = virtio_mmio_probe,
635 .name =
"virtio-mmio",
637 .of_match_table = virtio_mmio_match,
641 static int __init virtio_mmio_init(
void)
646 static void __exit virtio_mmio_exit(
void)
649 vm_unregister_cmdline_devices();