aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio/virtio_pci.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-12 11:19:20 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-12 11:19:20 -0500
commit68556ca1e03d6a35be3b315eba58df2f8176e3a0 (patch)
tree36a390d29a0d03a59a90c0f223b0d98a80f0f6c3 /drivers/virtio/virtio_pci.c
parent0604ca48f1689ad06144b81f5c08f297b6edd831 (diff)
parent8ab30691826fc05efa47c4ffba19b80496bb3a2c (diff)
Merge branch 'mfd/wm8994' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc into for-3.3
Diffstat (limited to 'drivers/virtio/virtio_pci.c')
-rw-r--r--drivers/virtio/virtio_pci.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 79a31e5b4b68..03d1984bd363 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -169,11 +169,29 @@ static void vp_set_status(struct virtio_device *vdev, u8 status)
169 iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); 169 iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
170} 170}
171 171
172/* wait for pending irq handlers */
173static void vp_synchronize_vectors(struct virtio_device *vdev)
174{
175 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
176 int i;
177
178 if (vp_dev->intx_enabled)
179 synchronize_irq(vp_dev->pci_dev->irq);
180
181 for (i = 0; i < vp_dev->msix_vectors; ++i)
182 synchronize_irq(vp_dev->msix_entries[i].vector);
183}
184
172static void vp_reset(struct virtio_device *vdev) 185static void vp_reset(struct virtio_device *vdev)
173{ 186{
174 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 187 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
175 /* 0 status means a reset. */ 188 /* 0 status means a reset. */
176 iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); 189 iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
190 /* Flush out the status write, and flush in device writes,
191 * including MSi-X interrupts, if any. */
192 ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS);
193 /* Flush pending VQ/configuration callbacks. */
194 vp_synchronize_vectors(vdev);
177} 195}
178 196
179/* the notify function used when creating a virt queue */ 197/* the notify function used when creating a virt queue */
@@ -594,11 +612,11 @@ static struct virtio_config_ops virtio_pci_config_ops = {
594 612
595static void virtio_pci_release_dev(struct device *_d) 613static void virtio_pci_release_dev(struct device *_d)
596{ 614{
597 struct virtio_device *dev = container_of(_d, struct virtio_device, 615 /*
598 dev); 616 * No need for a release method as we allocate/free
599 struct virtio_pci_device *vp_dev = to_vp_device(dev); 617 * all devices together with the pci devices.
600 618 * Provide an empty one to avoid getting a warning from core.
601 kfree(vp_dev); 619 */
602} 620}
603 621
604/* the PCI probing function */ 622/* the PCI probing function */
@@ -686,6 +704,7 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)
686 pci_iounmap(pci_dev, vp_dev->ioaddr); 704 pci_iounmap(pci_dev, vp_dev->ioaddr);
687 pci_release_regions(pci_dev); 705 pci_release_regions(pci_dev);
688 pci_disable_device(pci_dev); 706 pci_disable_device(pci_dev);
707 kfree(vp_dev);
689} 708}
690 709
691#ifdef CONFIG_PM 710#ifdef CONFIG_PM