1 /* 2 * CE4100's SPI device is more or less the same one as found on PXA 3 * 4 */ 5 #include <linux/pci.h> 6 #include <linux/platform_device.h> 7 #include <linux/of_device.h> 8 #include <linux/module.h> 9 #include <linux/spi/pxa2xx_spi.h> 10 11 struct ce4100_info { 12 struct ssp_device ssp; 13 struct platform_device *spi_pdev; 14 }; 15 16 static DEFINE_MUTEX(ssp_lock); 17 static LIST_HEAD(ssp_list); 18 19 struct ssp_device *pxa_ssp_request(int port, const char *label) 20 { 21 struct ssp_device *ssp = NULL; 22 23 mutex_lock(&ssp_lock); 24 25 list_for_each_entry(ssp, &ssp_list, node) { 26 if (ssp->port_id == port && ssp->use_count == 0) { 27 ssp->use_count++; 28 ssp->label = label; 29 break; 30 } 31 } 32 33 mutex_unlock(&ssp_lock); 34 35 if (&ssp->node == &ssp_list) 36 return NULL; 37 38 return ssp; 39 } 40 EXPORT_SYMBOL_GPL(pxa_ssp_request); 41 42 void pxa_ssp_free(struct ssp_device *ssp) 43 { 44 mutex_lock(&ssp_lock); 45 if (ssp->use_count) { 46 ssp->use_count--; 47 ssp->label = NULL; 48 } else 49 dev_err(&ssp->pdev->dev, "device already free\n"); 50 mutex_unlock(&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); 66 if (ret) 67 return ret; 68 69 phys_beg = pci_resource_start(dev, 0); 70 phys_len = pci_resource_len(dev, 0); 71 72 if (!request_mem_region(phys_beg, phys_len, 73 "CE4100 SPI")) { 74 dev_err(&dev->dev, "Can't request register space.\n"); 75 ret = -EBUSY; 76 return ret; 77 } 78 79 pdev = platform_device_alloc("pxa2xx-spi", dev->devfn); 80 spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); 81 if (!pdev || !spi_info ) { 82 ret = -ENOMEM; 83 goto err_nomem; 84 } 85 memset(&spi_pdata, 0, sizeof(spi_pdata)); 86 spi_pdata.num_chipselect = dev->devfn; 87 88 ret = platform_device_add_data(pdev, &spi_pdata, sizeof(spi_pdata)); 89 if (ret) 90 goto err_nomem; 91 92 pdev->dev.parent = &dev->dev; 93 pdev->dev.of_node = dev->dev.of_node; 94 ssp = &spi_info->ssp; 95 ssp->phys_base = pci_resource_start(dev, 0); 96 ssp->mmio_base = ioremap(phys_beg, phys_len); 97 if (!ssp->mmio_base) { 98 dev_err(&pdev->dev, "failed to ioremap() registers\n"); 99 ret = -EIO; 100 goto err_nomem; 101 } 102 ssp->irq = dev->irq; 103 ssp->port_id = pdev->id; 104 ssp->type = PXA25x_SSP; 105 106 mutex_lock(&ssp_lock); 107 list_add(&ssp->node, &ssp_list); 108 mutex_unlock(&ssp_lock); 109 110 pci_set_drvdata(dev, spi_info); 111 112 ret = platform_device_add(pdev); 113 if (ret) 114 goto err_dev_add; 115 116 return ret; 117 118 err_dev_add: 119 pci_set_drvdata(dev, NULL); 120 mutex_lock(&ssp_lock); 121 list_del(&ssp->node); 122 mutex_unlock(&ssp_lock); 123 iounmap(ssp->mmio_base); 124 125 err_nomem: 126 release_mem_region(phys_beg, phys_len); 127 platform_device_put(pdev); 128 kfree(spi_info); 129 return ret; 130 } 131 132 static void __devexit ce4100_spi_remove(struct pci_dev *dev) 133 { 134 struct ce4100_info *spi_info; 135 struct ssp_device *ssp; 136 137 spi_info = pci_get_drvdata(dev); 138 ssp = &spi_info->ssp; 139 platform_device_unregister(spi_info->spi_pdev); 140 141 iounmap(ssp->mmio_base); 142 release_mem_region(pci_resource_start(dev, 0), 143 pci_resource_len(dev, 0)); 144 145 mutex_lock(&ssp_lock); 146 list_del(&ssp->node); 147 mutex_unlock(&ssp_lock); 148 149 pci_set_drvdata(dev, NULL); 150 pci_disable_device(dev); 151 kfree(spi_info); 152 } 153 154 static DEFINE_PCI_DEVICE_TABLE(ce4100_spi_devices) = { 155 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, 156 { }, 157 }; 158 MODULE_DEVICE_TABLE(pci, ce4100_spi_devices); 159 160 static struct pci_driver ce4100_spi_driver = { 161 .name = "ce4100_spi", 162 .id_table = ce4100_spi_devices, 163 .probe = ce4100_spi_probe, 164 .remove = __devexit_p(ce4100_spi_remove), 165 }; 166 167 module_pci_driver(ce4100_spi_driver); 168 169 MODULE_DESCRIPTION("CE4100 PCI-SPI glue code for PXA's driver"); 170 MODULE_LICENSE("GPL v2"); 171 MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>"); 172