Merge branch 'spi/merge' of git://git.secretlab.ca/git/linux-2.6

* 'spi/merge' of git://git.secretlab.ca/git/linux-2.6:
spi/pxa2xx pci: fix the release - remove race

+21 -40
+21 -40
drivers/spi/pxa2xx_spi_pci.c
··· 7 #include <linux/of_device.h> 8 #include <linux/spi/pxa2xx_spi.h> 9 10 - struct awesome_struct { 11 struct ssp_device ssp; 12 - struct platform_device spi_pdev; 13 - struct pxa2xx_spi_master spi_pdata; 14 }; 15 16 static DEFINE_MUTEX(ssp_lock); ··· 50 } 51 EXPORT_SYMBOL_GPL(pxa_ssp_free); 52 53 - static void plat_dev_release(struct device *dev) 54 - { 55 - struct awesome_struct *as = container_of(dev, 56 - struct awesome_struct, spi_pdev.dev); 57 - 58 - of_device_node_put(&as->spi_pdev.dev); 59 - } 60 - 61 static int __devinit ce4100_spi_probe(struct pci_dev *dev, 62 const struct pci_device_id *ent) 63 { 64 int ret; 65 resource_size_t phys_beg; 66 resource_size_t phys_len; 67 - struct awesome_struct *spi_info; 68 struct platform_device *pdev; 69 - struct pxa2xx_spi_master *spi_pdata; 70 struct ssp_device *ssp; 71 72 ret = pci_enable_device(dev); ··· 75 return ret; 76 } 77 78 spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); 79 - if (!spi_info) { 80 ret = -ENOMEM; 81 - goto err_kz; 82 } 83 - ssp = &spi_info->ssp; 84 - pdev = &spi_info->spi_pdev; 85 - spi_pdata = &spi_info->spi_pdata; 86 87 - pdev->name = "pxa2xx-spi"; 88 - pdev->id = dev->devfn; 89 pdev->dev.parent = &dev->dev; 90 - pdev->dev.platform_data = &spi_info->spi_pdata; 91 - 92 #ifdef CONFIG_OF 93 pdev->dev.of_node = dev->dev.of_node; 94 #endif 95 - pdev->dev.release = plat_dev_release; 96 - 97 - spi_pdata->num_chipselect = dev->devfn; 98 - 99 ssp->phys_base = pci_resource_start(dev, 0); 100 ssp->mmio_base = ioremap(phys_beg, phys_len); 101 if (!ssp->mmio_base) { 102 dev_err(&pdev->dev, "failed to ioremap() registers\n"); 103 ret = -EIO; 104 - goto err_remap; 105 } 106 ssp->irq = dev->irq; 107 ssp->port_id = pdev->id; ··· 110 111 pci_set_drvdata(dev, spi_info); 112 113 - ret = platform_device_register(pdev); 114 if (ret) 115 goto err_dev_add; 116 ··· 123 mutex_unlock(&ssp_lock); 124 iounmap(ssp->mmio_base); 125 126 - err_remap: 127 - kfree(spi_info); 128 - 129 - err_kz: 130 release_mem_region(phys_beg, phys_len); 131 - 132 return ret; 133 } 134 135 static void __devexit ce4100_spi_remove(struct pci_dev *dev) 136 { 137 - struct awesome_struct *spi_info; 138 - struct platform_device *pdev; 139 struct ssp_device *ssp; 140 141 spi_info = pci_get_drvdata(dev); 142 - 143 ssp = &spi_info->ssp; 144 - pdev = &spi_info->spi_pdev; 145 - 146 - platform_device_unregister(pdev); 147 148 iounmap(ssp->mmio_base); 149 release_mem_region(pci_resource_start(dev, 0), ··· 153 } 154 155 static struct pci_device_id ce4100_spi_devices[] __devinitdata = { 156 - 157 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, 158 { }, 159 };
··· 7 #include <linux/of_device.h> 8 #include <linux/spi/pxa2xx_spi.h> 9 10 + struct ce4100_info { 11 struct ssp_device ssp; 12 + struct platform_device *spi_pdev; 13 }; 14 15 static DEFINE_MUTEX(ssp_lock); ··· 51 } 52 EXPORT_SYMBOL_GPL(pxa_ssp_free); 53 54 static int __devinit ce4100_spi_probe(struct pci_dev *dev, 55 const struct pci_device_id *ent) 56 { 57 int ret; 58 resource_size_t phys_beg; 59 resource_size_t phys_len; 60 + struct ce4100_info *spi_info; 61 struct platform_device *pdev; 62 + struct pxa2xx_spi_master spi_pdata; 63 struct ssp_device *ssp; 64 65 ret = pci_enable_device(dev); ··· 84 return ret; 85 } 86 87 + pdev = platform_device_alloc("pxa2xx-spi", dev->devfn); 88 spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); 89 + if (!pdev || !spi_info ) { 90 ret = -ENOMEM; 91 + goto err_nomem; 92 } 93 + memset(&spi_pdata, 0, sizeof(spi_pdata)); 94 + spi_pdata.num_chipselect = dev->devfn; 95 96 + ret = platform_device_add_data(pdev, &spi_pdata, sizeof(spi_pdata)); 97 + if (ret) 98 + goto err_nomem; 99 + 100 pdev->dev.parent = &dev->dev; 101 #ifdef CONFIG_OF 102 pdev->dev.of_node = dev->dev.of_node; 103 #endif 104 + ssp = &spi_info->ssp; 105 ssp->phys_base = pci_resource_start(dev, 0); 106 ssp->mmio_base = ioremap(phys_beg, phys_len); 107 if (!ssp->mmio_base) { 108 dev_err(&pdev->dev, "failed to ioremap() registers\n"); 109 ret = -EIO; 110 + goto err_nomem; 111 } 112 ssp->irq = dev->irq; 113 ssp->port_id = pdev->id; ··· 122 123 pci_set_drvdata(dev, spi_info); 124 125 + ret = platform_device_add(pdev); 126 if (ret) 127 goto err_dev_add; 128 ··· 135 mutex_unlock(&ssp_lock); 136 iounmap(ssp->mmio_base); 137 138 + err_nomem: 139 release_mem_region(phys_beg, phys_len); 140 + platform_device_put(pdev); 141 + kfree(spi_info); 142 return ret; 143 } 144 145 static void __devexit ce4100_spi_remove(struct pci_dev *dev) 146 { 147 + struct ce4100_info *spi_info; 148 struct ssp_device *ssp; 149 150 spi_info = pci_get_drvdata(dev); 151 ssp = &spi_info->ssp; 152 + platform_device_unregister(spi_info->spi_pdev); 153 154 iounmap(ssp->mmio_base); 155 release_mem_region(pci_resource_start(dev, 0), ··· 171 } 172 173 static struct pci_device_id ce4100_spi_devices[] __devinitdata = { 174 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, 175 { }, 176 };