Lines Matching +full:host +full:- +full:wake
1 // SPDX-License-Identifier: GPL-2.0
6 * Copyright (C) 2011-2016 Google, Inc.
44 * guest user addresses into host ones.
62 #include <linux/dma-mapping.h>
69 * Update this when something changes in the driver's behavior so the host
85 /* A per-pipe command structure, shared with the host */
87 s32 cmd; /* PipeCmdCode, guest -> host */
88 s32 id; /* pipe id, guest -> host */
89 s32 status; /* command execution status, host -> guest */
90 s32 reserved; /* to pad to 64-bit boundary */
94 /* number of buffers, guest -> host */
96 /* number of consumed bytes, host -> guest */
98 /* buffer pointers, guest -> host */
100 /* buffer sizes, guest -> host */
118 /* Device-level set of buffers shared with the host */
127 /* pipe ID - index into goldfish_pipe_dev::pipes array */
130 /* The wake flags pipe is waiting for
132 * and barriers to make it thread-safe.
136 /* wake flags host have signalled,
137 * - protected by goldfish_pipe_dev::lock
152 * - *command_buffer - makes sure a command can safely write its
153 * parameters to the host and read the results back.
157 /* A wake queue for sleeping until host signals an event */
168 * communicate with the emulator, and a wake queue for blocked tasks
177 * - pipes, pipes_capacity
178 * - [*pipes, *pipes + pipes_capacity) - array data
179 * - first_signalled_pipe,
182 * goldfish_pipe::signalled_flags - all singnalled-related fields,
184 * - open_command_params - PIPE_CMD_OPEN-related buffers
201 /* Pointers to the buffers host uses for interaction with this driver */
210 /* Some device-specific data */
221 pipe->command_buffer->cmd = cmd; in goldfish_pipe_cmd_locked()
223 pipe->command_buffer->status = PIPE_ERROR_INVAL; in goldfish_pipe_cmd_locked()
224 writel(pipe->id, pipe->dev->base + PIPE_REG_CMD); in goldfish_pipe_cmd_locked()
225 return pipe->command_buffer->status; in goldfish_pipe_cmd_locked()
232 if (mutex_lock_interruptible(&pipe->lock)) in goldfish_pipe_cmd()
235 mutex_unlock(&pipe->lock); in goldfish_pipe_cmd()
247 return -EAGAIN; in goldfish_pipe_error_convert()
249 return -ENOMEM; in goldfish_pipe_error_convert()
251 return -EIO; in goldfish_pipe_error_convert()
253 return -EINVAL; in goldfish_pipe_error_convert()
265 int requested_pages = ((last_page - first_page) >> PAGE_SHIFT) + 1; in goldfish_pin_pages()
278 return -EFAULT; in goldfish_pin_pages()
297 * Process the first page separately - it's the only page that in populate_rw_params()
305 ? (int)(address_end - address) in populate_rw_params()
306 : (PAGE_SIZE - (address & ~PAGE_MASK)); in populate_rw_params()
307 command->rw_params.ptrs[0] = (u64)(xaddr | (address & ~PAGE_MASK)); in populate_rw_params()
308 command->rw_params.sizes[0] = size_on_page; in populate_rw_params()
311 size_on_page = (i == pages_count - 1) ? in populate_rw_params()
314 command->rw_params.sizes[buffer_idx] += size_on_page; in populate_rw_params()
317 command->rw_params.ptrs[buffer_idx] = (u64)xaddr; in populate_rw_params()
318 command->rw_params.sizes[buffer_idx] = size_on_page; in populate_rw_params()
322 command->rw_params.buffers_count = buffer_idx + 1; in populate_rw_params()
339 if (mutex_lock_interruptible(&pipe->lock)) in transfer_max_buffers()
340 return -ERESTARTSYS; in transfer_max_buffers()
344 pipe->pages, &iter_last_page_size); in transfer_max_buffers()
346 mutex_unlock(&pipe->lock); in transfer_max_buffers()
350 populate_rw_params(pipe->pages, pages_count, address, address_end, in transfer_max_buffers()
352 pipe->command_buffer); in transfer_max_buffers()
358 *consumed_size = pipe->command_buffer->rw_params.consumed_size; in transfer_max_buffers()
360 unpin_user_pages_dirty_lock(pipe->pages, pages_count, in transfer_max_buffers()
363 mutex_unlock(&pipe->lock); in transfer_max_buffers()
371 set_bit(wake_bit, &pipe->flags); in wait_for_host_signal()
373 /* Tell the emulator we're going to wait for a wake event */ in wait_for_host_signal()
377 while (test_bit(wake_bit, &pipe->flags)) { in wait_for_host_signal()
378 if (wait_event_interruptible(pipe->wake_queue, in wait_for_host_signal()
379 !test_bit(wake_bit, &pipe->flags))) in wait_for_host_signal()
380 return -ERESTARTSYS; in wait_for_host_signal()
382 if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) in wait_for_host_signal()
383 return -EIO; in wait_for_host_signal()
394 struct goldfish_pipe *pipe = filp->private_data; in goldfish_pipe_read_write()
395 int count = 0, ret = -EINVAL; in goldfish_pipe_read_write()
400 if (unlikely(test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))) in goldfish_pipe_read_write()
401 return -EIO; in goldfish_pipe_read_write()
407 return -EFAULT; in goldfish_pipe_read_write()
411 last_page = (address_end - 1) & PAGE_MASK; in goldfish_pipe_read_write()
412 last_page_size = ((address_end - 1) & ~PAGE_MASK) + 1; in goldfish_pipe_read_write()
446 dev_err_ratelimited(pipe->dev->pdev_dev, in goldfish_pipe_read_write()
454 * non-blocking mode, just return the error code. in goldfish_pipe_read_write()
457 (filp->f_flags & O_NONBLOCK) != 0) { in goldfish_pipe_read_write()
492 struct goldfish_pipe *pipe = filp->private_data; in goldfish_pipe_poll()
496 poll_wait(filp, &pipe->wake_queue, wait); in goldfish_pipe_poll()
500 return -ERESTARTSYS; in goldfish_pipe_poll()
508 if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) in goldfish_pipe_poll()
519 if (WARN_ON(id >= dev->pipes_capacity)) in signalled_pipes_add_locked()
522 pipe = dev->pipes[id]; in signalled_pipes_add_locked()
525 pipe->signalled_flags |= flags; in signalled_pipes_add_locked()
527 if (pipe->prev_signalled || pipe->next_signalled || in signalled_pipes_add_locked()
528 dev->first_signalled_pipe == pipe) in signalled_pipes_add_locked()
530 pipe->next_signalled = dev->first_signalled_pipe; in signalled_pipes_add_locked()
531 if (dev->first_signalled_pipe) in signalled_pipes_add_locked()
532 dev->first_signalled_pipe->prev_signalled = pipe; in signalled_pipes_add_locked()
533 dev->first_signalled_pipe = pipe; in signalled_pipes_add_locked()
539 if (pipe->prev_signalled) in signalled_pipes_remove_locked()
540 pipe->prev_signalled->next_signalled = pipe->next_signalled; in signalled_pipes_remove_locked()
541 if (pipe->next_signalled) in signalled_pipes_remove_locked()
542 pipe->next_signalled->prev_signalled = pipe->prev_signalled; in signalled_pipes_remove_locked()
543 if (pipe == dev->first_signalled_pipe) in signalled_pipes_remove_locked()
544 dev->first_signalled_pipe = pipe->next_signalled; in signalled_pipes_remove_locked()
545 pipe->prev_signalled = NULL; in signalled_pipes_remove_locked()
546 pipe->next_signalled = NULL; in signalled_pipes_remove_locked()
555 spin_lock_irqsave(&dev->lock, flags); in signalled_pipes_pop_front()
557 pipe = dev->first_signalled_pipe; in signalled_pipes_pop_front()
559 *wakes = pipe->signalled_flags; in signalled_pipes_pop_front()
560 pipe->signalled_flags = 0; in signalled_pipes_pop_front()
564 * - We want to make it as fast as possible to in signalled_pipes_pop_front()
565 * wake the sleeping pipe operations faster. in signalled_pipes_pop_front()
567 dev->first_signalled_pipe = pipe->next_signalled; in signalled_pipes_pop_front()
568 if (dev->first_signalled_pipe) in signalled_pipes_pop_front()
569 dev->first_signalled_pipe->prev_signalled = NULL; in signalled_pipes_pop_front()
570 pipe->next_signalled = NULL; in signalled_pipes_pop_front()
573 spin_unlock_irqrestore(&dev->lock, flags); in signalled_pipes_pop_front()
579 /* Iterate over the signalled pipes and wake them one by one */ in goldfish_interrupt_task()
586 pipe->flags = 1 << BIT_CLOSED_ON_HOST; in goldfish_interrupt_task()
589 clear_bit(BIT_WAKE_ON_READ, &pipe->flags); in goldfish_interrupt_task()
591 clear_bit(BIT_WAKE_ON_WRITE, &pipe->flags); in goldfish_interrupt_task()
597 wake_up_interruptible(&pipe->wake_queue); in goldfish_interrupt_task()
625 if (dev->magic != &goldfish_pipe_device_deinit) in goldfish_pipe_interrupt()
629 spin_lock_irqsave(&dev->lock, flags); in goldfish_pipe_interrupt()
631 count = readl(dev->base + PIPE_REG_GET_SIGNALLED); in goldfish_pipe_interrupt()
633 spin_unlock_irqrestore(&dev->lock, flags); in goldfish_pipe_interrupt()
641 dev->buffers->signalled_pipe_buffers[i].id, in goldfish_pipe_interrupt()
642 dev->buffers->signalled_pipe_buffers[i].flags); in goldfish_pipe_interrupt()
644 spin_unlock_irqrestore(&dev->lock, flags); in goldfish_pipe_interrupt()
653 for (id = 0; id < dev->pipes_capacity; ++id) in get_free_pipe_id_locked()
654 if (!dev->pipes[id]) in get_free_pipe_id_locked()
662 u32 new_capacity = 2 * dev->pipes_capacity; in get_free_pipe_id_locked()
666 return -ENOMEM; in get_free_pipe_id_locked()
667 memcpy(pipes, dev->pipes, sizeof(*pipes) * dev->pipes_capacity); in get_free_pipe_id_locked()
668 kfree(dev->pipes); in get_free_pipe_id_locked()
669 dev->pipes = pipes; in get_free_pipe_id_locked()
670 id = dev->pipes_capacity; in get_free_pipe_id_locked()
671 dev->pipes_capacity = new_capacity; in get_free_pipe_id_locked()
679 struct miscdevice *miscdev = file->private_data; in to_goldfish_pipe_dev()
685 * goldfish_pipe_open - open a channel to the AVD
706 return -ENOMEM; in goldfish_pipe_open()
708 pipe->dev = dev; in goldfish_pipe_open()
709 mutex_init(&pipe->lock); in goldfish_pipe_open()
710 init_waitqueue_head(&pipe->wake_queue); in goldfish_pipe_open()
714 * it is physically contiguous in host's address space. in goldfish_pipe_open()
717 pipe->command_buffer = in goldfish_pipe_open()
719 if (!pipe->command_buffer) { in goldfish_pipe_open()
720 status = -ENOMEM; in goldfish_pipe_open()
724 spin_lock_irqsave(&dev->lock, flags); in goldfish_pipe_open()
732 dev->pipes[id] = pipe; in goldfish_pipe_open()
733 pipe->id = id; in goldfish_pipe_open()
734 pipe->command_buffer->id = id; in goldfish_pipe_open()
737 dev->buffers->open_command_params.rw_params_max_count = in goldfish_pipe_open()
739 dev->buffers->open_command_params.command_buffer_ptr = in goldfish_pipe_open()
740 (u64)(unsigned long)__pa(pipe->command_buffer); in goldfish_pipe_open()
742 spin_unlock_irqrestore(&dev->lock, flags); in goldfish_pipe_open()
746 file->private_data = pipe; in goldfish_pipe_open()
750 spin_lock_irqsave(&dev->lock, flags); in goldfish_pipe_open()
751 dev->pipes[id] = NULL; in goldfish_pipe_open()
753 spin_unlock_irqrestore(&dev->lock, flags); in goldfish_pipe_open()
754 free_page((unsigned long)pipe->command_buffer); in goldfish_pipe_open()
763 struct goldfish_pipe *pipe = filp->private_data; in goldfish_pipe_release()
764 struct goldfish_pipe_dev *dev = pipe->dev; in goldfish_pipe_release()
769 spin_lock_irqsave(&dev->lock, flags); in goldfish_pipe_release()
770 dev->pipes[pipe->id] = NULL; in goldfish_pipe_release()
772 spin_unlock_irqrestore(&dev->lock, flags); in goldfish_pipe_release()
774 filp->private_data = NULL; in goldfish_pipe_release()
775 free_page((unsigned long)pipe->command_buffer); in goldfish_pipe_release()
793 miscdev->minor = MISC_DYNAMIC_MINOR; in init_miscdevice()
794 miscdev->name = "goldfish_pipe"; in init_miscdevice()
795 miscdev->fops = &goldfish_pipe_fops; in init_miscdevice()
811 err = devm_request_threaded_irq(&pdev->dev, dev->irq, in goldfish_pipe_device_init()
816 dev_err(&pdev->dev, "unable to allocate IRQ for v2\n"); in goldfish_pipe_device_init()
820 init_miscdevice(&dev->miscdev); in goldfish_pipe_device_init()
821 err = misc_register(&dev->miscdev); in goldfish_pipe_device_init()
823 dev_err(&pdev->dev, "unable to register v2 device\n"); in goldfish_pipe_device_init()
827 dev->pdev_dev = &pdev->dev; in goldfish_pipe_device_init()
828 dev->first_signalled_pipe = NULL; in goldfish_pipe_device_init()
829 dev->pipes_capacity = INITIAL_PIPES_CAPACITY; in goldfish_pipe_device_init()
830 dev->pipes = kcalloc(dev->pipes_capacity, sizeof(*dev->pipes), in goldfish_pipe_device_init()
832 if (!dev->pipes) { in goldfish_pipe_device_init()
833 misc_deregister(&dev->miscdev); in goldfish_pipe_device_init()
834 return -ENOMEM; in goldfish_pipe_device_init()
839 * signalled_pipe_buffers, to the host. This means each of those buffers in goldfish_pipe_device_init()
844 dev->buffers = (struct goldfish_pipe_dev_buffers *) in goldfish_pipe_device_init()
846 if (!dev->buffers) { in goldfish_pipe_device_init()
847 kfree(dev->pipes); in goldfish_pipe_device_init()
848 misc_deregister(&dev->miscdev); in goldfish_pipe_device_init()
849 return -ENOMEM; in goldfish_pipe_device_init()
852 /* Send the buffer addresses to the host */ in goldfish_pipe_device_init()
853 write_pa_addr(&dev->buffers->signalled_pipe_buffers, in goldfish_pipe_device_init()
854 dev->base + PIPE_REG_SIGNAL_BUFFER, in goldfish_pipe_device_init()
855 dev->base + PIPE_REG_SIGNAL_BUFFER_HIGH); in goldfish_pipe_device_init()
858 dev->base + PIPE_REG_SIGNAL_BUFFER_COUNT); in goldfish_pipe_device_init()
860 write_pa_addr(&dev->buffers->open_command_params, in goldfish_pipe_device_init()
861 dev->base + PIPE_REG_OPEN_BUFFER, in goldfish_pipe_device_init()
862 dev->base + PIPE_REG_OPEN_BUFFER_HIGH); in goldfish_pipe_device_init()
871 misc_deregister(&dev->miscdev); in goldfish_pipe_device_deinit()
872 kfree(dev->pipes); in goldfish_pipe_device_deinit()
873 free_page((unsigned long)dev->buffers); in goldfish_pipe_device_deinit()
881 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in goldfish_pipe_probe()
883 return -ENOMEM; in goldfish_pipe_probe()
885 dev->magic = &goldfish_pipe_device_deinit; in goldfish_pipe_probe()
886 spin_lock_init(&dev->lock); in goldfish_pipe_probe()
890 dev_err(&pdev->dev, "can't allocate i/o page\n"); in goldfish_pipe_probe()
891 return -EINVAL; in goldfish_pipe_probe()
893 dev->base = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE); in goldfish_pipe_probe()
894 if (!dev->base) { in goldfish_pipe_probe()
895 dev_err(&pdev->dev, "ioremap failed\n"); in goldfish_pipe_probe()
896 return -EINVAL; in goldfish_pipe_probe()
899 dev->irq = platform_get_irq(pdev, 0); in goldfish_pipe_probe()
900 if (dev->irq < 0) in goldfish_pipe_probe()
901 return dev->irq; in goldfish_pipe_probe()
904 * Exchange the versions with the host device in goldfish_pipe_probe()
907 * reading device version back: this allows the host implementation to in goldfish_pipe_probe()
910 writel(PIPE_DRIVER_VERSION, dev->base + PIPE_REG_VERSION); in goldfish_pipe_probe()
911 dev->version = readl(dev->base + PIPE_REG_VERSION); in goldfish_pipe_probe()
912 if (WARN_ON(dev->version < PIPE_CURRENT_DEVICE_VERSION)) in goldfish_pipe_probe()
913 return -EINVAL; in goldfish_pipe_probe()
932 { .compatible = "google,android-pipe", },