linux/drivers/spi/spi-pxa2xx-pci.c
<<
ion 4ion 4io//spav3.io/spav class="lxr_search">ion ion 4ion 4ion 4typ Searchion 4io//spav3.n 4< io/input typ in 4< . /div id < <1//a>/spav class="comment">/*//spav3.< <2//a>/spav class="comment"> * CE4100's SPI device is more or less the sam one as found on PXA//spav3.< <3//a>/spav class="comment"> *//spav3.< <4//a>/spav class="comment"> *///spav3.< <5//a>#include <linux/pci.h//a>>.< <6//a>#include <linux/platform_device.h//a>>.< <7//a>#include <linux/of_device.h//a>>.< <8//a>#include <linux/module.h//a>>.< <9//a>#include <linux/spi/pxa2xx_spi.h//a>>.< " a3.< 11//a>structce4100_info//a> {.< 12//a> structssp_device//a> /a href="+code=ssp" class="sref">ssp//a>;.< 13//a> structplatform_device//a> */a href="+code=spi_pdev" class="sref">spi_pdev//a>;.< 14//a>};.< 15 a3.< 16//a>staticDEFINE_MUTEX//a>(/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.< 17//a>staticLIST_HEAD//a>(/a href="+code=ssp_list" class="sref">ssp_list//a>);.< 18 a3.< 19//a>structssp_device//a> */a href="+code=pxa_ssp_request" class="sref">pxa_ssp_request//a>(intport//a>, const char */a href="+code=label" class="sref">label//a>).< 2 a3{.< 21//a> structssp_device//a> */a href="+code=ssp" class="sref">ssp//a> =NULL//a>;.< 22 a3.< 23//a> /a href="+code=mutex_lock" class="sref">mutex_lock//a>(&/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.< 24 a3.< 25//a> /a href="+code=list_for_each_entry" class="sref">list_for_each_entry//a>(/a href="+code=ssp" class="sref">ssp//a>, &/a href="+code=ssp_list" class="sref">ssp_list//a>, /a href="+code=node" class="sref">node//a>) {.< 26//a> if (/a href="+code=ssp" class="sref">ssp//a>->/a href="+code=port_id" class="sref">port_id//a> ==port//a> && /a href="+code=ssp" class="sref">ssp//a>->/a href="+code=use_count" class="sref">use_count//a> ==<0) {.< 27//a> /a href="+code=ssp" class="sref">ssp//a>->/a href="+code=use_count" class="sref">use_count//a>++;.< 28//a> /a href="+code=ssp" class="sref">ssp//a>->/a href="+code=label" class="sref">label//a> =label//a>;.< 29//a> break;.< 30//a> }.< 31//a> }.< 32 a3.< 33//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.< 34 a3.< 35//a> if (&/a href="+code=ssp" class="sref">ssp//a>->/a href="+code=node" class="sref">node//a> ==<&/a href="+code=ssp_list" class="sref">ssp_list//a>).< 36//a> return /a href="+code=NULL" class="sref">NULL//a>;.< 37 a3.< 38//a> return /a href="+code=ssp" class="sref">ssp//a>;.< 39//a>}.< 40//a>/a href="+code=EXPORT_SYMBOL_GPL" class="sref">EXPORT_SYMBOL_GPL//a>(/a href="+code=pxa_ssp_request" class="sref">pxa_ssp_request//a>);.< 41 a3.< 42 a3voidpxa_ssp_free//a>(structssp_device//a> */a href="+code=ssp" class="sref">ssp//a>).< 43 a3{.< 44//a> /a href="+code=mutex_lock" class="sref">mutex_lock//a>(&/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.< 45//a> if (/a href="+code=ssp" class="sref">ssp//a>->/a href="+code=use_count" class="sref">use_count//a>) {.< 46//a> /a href="+code=ssp" class="sref">ssp//a>->/a href="+code=use_count" class="sref">use_count//a>--;.< 47//a> /a href="+code=ssp" class="sref">ssp//a>->/a href="+code=label" class="sref">label//a> =NULL//a>;.< 48//a> } else.< 49//a> /a href="+code=dev_err" class="sref">dev_err//a>(&/a href="+code=ssp" class="sref">ssp//a>->/a href="+code=pdev" class="sref">pdev//a>->/a href="+code=dev" class="sref">dev//a>, /spav class="string">"device already free\n"//spav3);.< 50//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.< 51//a>}.< 52//a>/a href="+code=EXPORT_SYMBOL_GPL" class="sref">EXPORT_SYMBOL_GPL//a>(/a href="+code=pxa_ssp_free" class="sref">pxa_ssp_free//a>);.< 53 a3.< 54//a>static__devinit//a> /a href="+code=ce4100_spi_probe" class="sref">ce4100_spi_probe//a>(structpci_dev//a> */a href="+code=dev" class="sref">dev//a>,.< 55//a> const structpci_device_id//a> */a href="+code=ent" class="sref">ent//a>).< 56 a3{.< 57//a> intret//a>;.< 58//a> /a href="+code=resource_size_t" class="sref">resource_size_t//a> /a href="+code=phys_beg" class="sref">phys_beg//a>;.< 59//a> /a href="+code=resource_size_t" class="sref">resource_size_t//a> /a href="+code=phys_len" class="sref">phys_len//a>;.< 60//a> structce4100_info//a> */a href="+code=spi_info" class="sref">spi_info//a>;.< 61//a> structplatform_device//a> */a href="+code=pdev" class="sref">pdev//a>;.< 62//a> structpxa2xx_spi_master//a> /a href="+code=spi_pdata" class="sref">spi_pdata//a>;.< 63//a> structssp_device//a> */a href="+code=ssp" class="sref">ssp//a>;.< 64 a3.< 65//a> /a href="+code=ret" class="sref">ret//a> =pci_enable_device//a>(/a href="+code=dev" class="sref">dev//a>);.< 66//a> if (/a href="+code=ret" class="sref">ret//a>).< 67//a> return /a href="+code=ret" class="sref">ret//a>;.< 68 a3.< 69//a> /a href="+code=phys_beg" class="sref">phys_beg//a> =pci_resource_start//a>(/a href="+code=dev" class="sref">dev//a>, 0);.< 70//a> /a href="+code=phys_len" class="sref">phys_len//a> =pci_resource_len//a>(/a href="+code=dev" class="sref">dev//a>, 0);.< 71 a3.< 72//a> if (!/a href="+code=request_mem_region" class="sref">request_mem_region//a>(/a href="+code=phys_beg" class="sref">phys_beg//a>, /a href="+code=phys_len" class="sref">phys_len//a>,.< 73//a> /spav class="string">"CE4100 SPI"//spav3)) {.< 74//a> /a href="+code=dev_err" class="sref">dev_err//a>(&/a href="+code=dev" class="sref">dev//a>->/a href="+code=dev" class="sref">dev//a>, /spav class="string">"Can't request register space.\n"//spav3);.< 75//a> /a href="+code=ret" class="sref">ret//a> =<-/a href="+code=EBUSY" class="sref">EBUSY//a>;.< 76//a> return /a href="+code=ret" class="sref">ret//a>;.< 77//a> }.< 78 a3.< 79//a> /a href="+code=pdev" class="sref">pdev//a> =platform_device_alloc//a>(/spav class="string">"pxa2xx-spi"//spav3, /a href="+code=dev" class="sref">dev//a>->/a href="+code=devfn" class="sref">devfn//a>);.< 80//a> /a href="+code=spi_info" class="sref">spi_info//a> =kzalloc//a>(sizeof(*/a href="+code=spi_info" class="sref">spi_info//a>), /a href="+code=GFP_KERNEL" class="sref">GFP_KERNEL//a>);.< 81//a> if (!/a href="+code=pdev" class="sref">pdev//a> || !/a href="+code=spi_info" class="sref">spi_info//a> ) {.< 82//a> /a href="+code=ret" class="sref">ret//a> =<-/a href="+code=ENOMEM" class="sref">ENOMEM//a>;.< 83//a> goto /a href="+code=err_nomem" class="sref">err_nomem//a>;.< 84//a> }.< 85//a> /a href="+code=memset" class="sref">memset//a>(&/a href="+code=spi_pdata" class="sref">spi_pdata//a>, 0, sizeof(/a href="+code=spi_pdata" class="sref">spi_pdata//a>));.< 86//a> /a href="+code=spi_pdata" class="sref">spi_pdata//a>./a href="+code=num_chipselect" class="sref">num_chipselect//a> =dev//a>->/a href="+code=devfn" class="sref">devfn//a>;.< 87 a3.< 88//a> /a href="+code=ret" class="sref">ret//a> =platform_device_add_data//a>(/a href="+code=pdev" class="sref">pdev//a>, &/a href="+code=spi_pdata" class="sref">spi_pdata//a>, sizeof(/a href="+code=spi_pdata" class="sref">spi_pdata//a>));.< 89//a> if (/a href="+code=ret" class="sref">ret//a>).< 90//a> goto /a href="+code=err_nomem" class="sref">err_nomem//a>;.< 91 a3.< 92//a> /a href="+code=pdev" class="sref">pdev//a>->/a href="+code=dev" class="sref">dev//a>./a href="+code=parent" class="sref">parent//a> =<&/a href="+code=dev" class="sref">dev//a>->/a href="+code=dev" class="sref">dev//a>;.< 93//a> /a href="+code=pdev" class="sref">pdev//a>->/a href="+code=dev" class="sref">dev//a>./a href="+code=of_node" class="sref">of_node//a> =dev//a>->/a href="+code=dev" class="sref">dev//a>./a href="+code=of_node" class="sref">of_node//a>;.< 94//a> /a href="+code=ssp" class="sref">ssp//a> =<&/a href="+code=spi_info" class="sref">spi_info//a>->/a href="+code=ssp" class="sref">ssp//a>;.< 95//a> /a href="+code=ssp" class="sref">ssp//a>->/a href="+code=phys_base" class="sref">phys_base//a> =pci_resource_start//a>(/a href="+code=dev" class="sref">dev//a>, 0);.< 96//a> /a href="+code=ssp" class="sref">ssp//a>->/a href="+code=mmio_base" class="sref">mmio_base//a> =ioremap//a>(/a href="+code=phys_beg" class="sref">phys_beg//a>, /a href="+code=phys_len" class="sref">phys_len//a>);.< 97//a> if (!/a href="+code=ssp" class="sref">ssp//a>->/a href="+code=mmio_base" class="sref">mmio_base//a>) {.< 98//a> /a href="+code=dev_err" class="sref">dev_err//a>(&/a href="+code=pdev" class="sref">pdev//a>->/a href="+code=dev" class="sref">dev//a>, /spav class="string">"failed to ioremap() registers\n"//spav3);.< 99//a> /a href="+code=ret" class="sref">ret//a> =<-/a href="+code=EIO" class="sref">EIO//a>;.<100//a> goto /a href="+code=err_nomem" class="sref">err_nomem//a>;.<101//a> }.<102//a> /a href="+code=ssp" class="sref">ssp//a>->/a href="+code=irq" class="sref">irq//a> =dev//a>->/a href="+code=irq" class="sref">irq//a>;.<103//a> /a href="+code=ssp" class="sref">ssp//a>->/a href="+code=port_id" class="sref">port_id//a> = /a href="+code=pdev" class="sref">pdev//a>->/a href="+code=id" class="sref">id//a>;.<104//a> /a href="+code=ssp" class="sref">ssp//a>->/a href="+code=typ " class="sref">typ //a> = /a href="+code=PXA25x_SSP" class="sref">PXA25x_SSP//a>;.<105 a3.<106//a> /a href="+code=mutex_lock" class="sref">mutex_lock//a>(&/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.<107//a> /a href="+code=list_add" class="sref">list_add//a>(&/a href="+code=ssp" class="sref">ssp//a>->/a href="+code=node" class="sref">node//a>, &/a href="+code=ssp_list" class="sref">ssp_list//a>);.<108//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.<109 a3.<110//a> /a href="+code=pci_set_drvdata" class="sref">pci_set_drvdata//a>(/a href="+code=dev" class="sref">dev//a>, /a href="+code=spi_info" class="sref">spi_info//a>);.<111 a3.<112//a> /a href="+code=ret" class="sref">ret//a> =platform_device_add//a>(/a href="+code=pdev" class="sref">pdev//a>);.<113//a> if (/a href="+code=ret" class="sref">ret//a>).<114//a> goto /a href="+code=err_dev_add" class="sref">err_dev_add//a>;.<115 a3.<116//a> return /a href="+code=ret" class="sref">ret//a>;.<117 a3.<118 a3/a href="+code=err_dev_add" class="sref">err_dev_add//a>:.<119//a> /a href="+code=pci_set_drvdata" class="sref">pci_set_drvdata//a>(/a href="+code=dev" class="sref">dev//a>, /a href="+code=NULL" class="sref">NULL//a>);.<120//a> /a href="+code=mutex_lock" class="sref">mutex_lock//a>(&/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.<121//a> /a href="+code=list_del" class="sref">list_del//a>(&/a href="+code=ssp" class="sref">ssp//a>->/a href="+code=node" class="sref">node//a>);.<122//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.<123//a> /a href="+code=iounmap" class="sref">iounmap//a>(/a href="+code=ssp" class="sref">ssp//a>->/a href="+code=mmio_base" class="sref">mmio_base//a>);.<124 a3.<125//a>/a href="+code=err_nomem" class="sref">err_nomem//a>:.<126//a> /a href="+code=release_mem_region" class="sref">release_mem_region//a>(/a href="+code=phys_beg" class="sref">phys_beg//a>, /a href="+code=phys_len" class="sref">phys_len//a>);.<127//a> /a href="+code=platform_device_put" class="sref">platform_device_put//a>(/a href="+code=pdev" class="sref">pdev//a>);.<128//a> /a href="+code=kfree" class="sref">kfree//a>(/a href="+code=spi_info" class="sref">spi_info//a>);.<129//a> return /a href="+code=ret" class="sref">ret//a>;.<130//a>}.<131 a3.<132 a3static__devexit//a> /a href="+code=ce4100_spi_remove" class="sref">ce4100_spi_remove//a>(structpci_dev//a> */a href="+code=dev" class="sref">dev//a>).<133 a3{.<134//a> structce4100_info//a> */a href="+code=spi_info" class="sref">spi_info//a>;.<135//a> structssp_device//a> */a href="+code=ssp" class="sref">ssp//a>;.<136//a>.<137//a> /a href="+code=spi_info" class="sref">spi_info//a> =pci_get_drvdata//a>(/a href="+code=dev" class="sref">dev//a>);.<138//a> /a href="+code=ssp" class="sref">ssp//a> =<&/a href="+code=spi_info" class="sref">spi_info//a>->/a href="+code=ssp" class="sref">ssp//a>;.<139//a> /a href="+code=platform_device_unregister" class="sref">platform_device_unregister//a>(/a href="+code=spi_info" class="sref">spi_info//a>->/a href="+code=spi_pdev" class="sref">spi_pdev//a>);.<14 a3.<141//a> /a href="+code=iounmap" class="sref">iounmap//a>(/a href="+code=ssp" class="sref">ssp//a>->/a href="+code=mmio_base" class="sref">mmio_base//a>);.<142//a> /a href="+code=release_mem_region" class="sref">release_mem_region//a>(/a href="+code=pci_resource_start" class="sref">pci_resource_start//a>(/a href="+code=dev" class="sref">dev//a>, 0),.<143//a> /a href="+code=pci_resource_len" class="sref">pci_resource_len//a>(/a href="+code=dev" class="sref">dev//a>, 0));.<144 a3.<145//a> /a href="+code=mutex_lock" class="sref">mutex_lock//a>(&/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.<146//a> /a href="+code=list_del" class="sref">list_del//a>(&/a href="+code=ssp" class="sref">ssp//a>->/a href="+code=node" class="sref">node//a>);.<147//a> /a href="+code=mutex_unlock" class="sref">mutex_unlock//a>(&/a href="+code=ssp_lock" class="sref">ssp_lock//a>);.<148 a3.<149//a> /a href="+code=pci_set_drvdata" class="sref">pci_set_drvdata//a>(/a href="+code=dev" class="sref">dev//a>, /a href="+code=NULL" class="sref">NULL//a>);.<150//a> /a href="+code=pci_disable_device" class="sref">pci_disable_device//a>(/a href="+code=dev" class="sref">dev//a>);.<151//a> /a href="+code=kfree" class="sref">kfree//a>(/a href="+code=spi_info" class="sref">spi_info//a>);.<152//a>}.<153 a3.<154//a>staticDEFINE_PCI_DEVICE_TABLE//a>(/a href="+code=ce4100_spi_devices" class="sref">ce4100_spi_devices//a>) =<{.<155//a> { /a href="+code=PCI_DEVICE" class="sref">PCI_DEVICE//a>(/a href="+code=PCI_VENDOR_ID_INTEL" class="sref">PCI_VENDOR_ID_INTEL//a>, 0x2e6a) },.<156//a> { },.<157//a>};.<158 a3/a href="+code=MODULE_DEVICE_TABLE" class="sref">MODULE_DEVICE_TABLE//a>(/a href="+code=pci" class="sref">pci//a>, /a href="+code=ce4100_spi_devices" class="sref">ce4100_spi_devices//a>);.<159 a3.<160//a>staticpci_driver//a> /a href="+code=ce4100_spi_driver" class="sref">ce4100_spi_driver//a> =<{.<161//a> ./a href="+code=nam " class="sref">nam //a> = /spav class="string">"ce4100_spi"//spav3,.<162//a> ./a href="+code=id_table" class="sref">id_table//a> =ce4100_spi_devices//a>,.<163//a> ./a href="+code=probe" class="sref">probe//a> = /a href="+code=ce4100_spi_probe" class="sref">ce4100_spi_probe//a>,.<164//a> ./a href="+code=remove" class="sref">remove//a> = /a href="+code=__devexit_p" class="sref">__devexit_p//a>(/a href="+code=ce4100_spi_remove" class="sref">ce4100_spi_remove//a>),.<165//a>};.<166//a>.<167//a>/a href="+code=module_pci_driver" class="sref">module_pci_driver//a>(/a href="+code=ce4100_spi_driver" class="sref">ce4100_spi_driver//a>);.<168 a3.<169//a>/a href="+code=MODULE_DESCRIPTION" class="sref">MODULE_DESCRIPTION//a>(/spav class="string">"CE4100 PCI-SPI glue code for PXA's driver"//spav3);.<170//a>/a href="+code=MODULE_LICENSE" class="sref">MODULE_LICENSE//a>(/spav class="string">"GPL v2"//spav3);.<171 a3/a href="+code=MODULE_AUTHOR" class="sref">MODULE_AUTHOR//a>(/spav class="string">"Sebastiav Andrzej Siewior <bigeasy@linutronix.de>"//spav3);.<172//a> The original LXR software by the LXR community//a>, this experimental version by lxr@linux.no//a>. //div3./div class="subfooter"> lxr.linux.no kindly hosted by Redpill Linpro AS//a>, provider of Linux consulting and opera vs services since 1995. //div3. //body3.//html3.