1bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch/* 2bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch * UIO Hilscher CIF card driver 3bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch * 4318af55ddd38bdaaa2b57f5c3bd394f3ce3a2610Hans J. Koch * (C) 2007 Hans J. Koch <hjk@hansjkoch.de> 5bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch * Original code (C) 2005 Benedikt Spranger <b.spranger@linutronix.de> 6bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch * 7bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch * Licensed under GPL version 2 only. 8bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch * 9bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch */ 10bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 11bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#include <linux/device.h> 12bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#include <linux/module.h> 13bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#include <linux/pci.h> 145a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 15bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#include <linux/uio_driver.h> 16bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 17bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#include <asm/io.h> 18bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 19bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#define PLX9030_INTCSR 0x4C 20bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#define INTSCR_INT1_ENABLE 0x01 21bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#define INTSCR_INT1_STATUS 0x04 22bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#define INT1_ENABLED_AND_ACTIVE (INTSCR_INT1_ENABLE | INTSCR_INT1_STATUS) 23bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 24bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#define PCI_SUBVENDOR_ID_PEP 0x1518 25bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#define CIF_SUBDEVICE_PROFIBUS 0x430 26bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch#define CIF_SUBDEVICE_DEVICENET 0x432 27bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 28bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 29bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Kochstatic irqreturn_t hilscher_handler(int irq, struct uio_info *dev_info) 30bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch{ 31bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch void __iomem *plx_intscr = dev_info->mem[0].internal_addr 32bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch + PLX9030_INTCSR; 33bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 34bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch if ((ioread8(plx_intscr) & INT1_ENABLED_AND_ACTIVE) 35bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch != INT1_ENABLED_AND_ACTIVE) 36bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch return IRQ_NONE; 37bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 38bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch /* Disable interrupt */ 39bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch iowrite8(ioread8(plx_intscr) & ~INTSCR_INT1_ENABLE, plx_intscr); 40bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch return IRQ_HANDLED; 41bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch} 42bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 43b17b75bb524c6c0dfa5ee4a33591b8a7dcc034d2Bill Pembertonstatic int hilscher_pci_probe(struct pci_dev *dev, 44bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch const struct pci_device_id *id) 45bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch{ 46bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch struct uio_info *info; 47bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 48bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info = kzalloc(sizeof(struct uio_info), GFP_KERNEL); 49bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch if (!info) 50bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch return -ENOMEM; 51bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 52bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch if (pci_enable_device(dev)) 53bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch goto out_free; 54bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 55bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch if (pci_request_regions(dev, "hilscher")) 56bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch goto out_disable; 57bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 58bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->mem[0].addr = pci_resource_start(dev, 0); 59bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch if (!info->mem[0].addr) 60bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch goto out_release; 617898aa5c39d159684dad15bab1150b8e77c7aed6Arjan van de Ven info->mem[0].internal_addr = pci_ioremap_bar(dev, 0); 62bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch if (!info->mem[0].internal_addr) 63bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch goto out_release; 64bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 65bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->mem[0].size = pci_resource_len(dev, 0); 66bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->mem[0].memtype = UIO_MEM_PHYS; 67bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->mem[1].addr = pci_resource_start(dev, 2); 68bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->mem[1].size = pci_resource_len(dev, 2); 69bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->mem[1].memtype = UIO_MEM_PHYS; 70bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch switch (id->subdevice) { 71bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch case CIF_SUBDEVICE_PROFIBUS: 72bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->name = "CIF_Profibus"; 73bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch break; 74bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch case CIF_SUBDEVICE_DEVICENET: 75bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->name = "CIF_Devicenet"; 76bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch break; 77bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch default: 78bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->name = "CIF_???"; 79bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch } 80bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->version = "0.0.1"; 81bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->irq = dev->irq; 8214ec5394827eea8df7bbf14775c52fc48fc97a40Hans J. Koch info->irq_flags = IRQF_SHARED; 83bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch info->handler = hilscher_handler; 84bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 85bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch if (uio_register_device(&dev->dev, info)) 86bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch goto out_unmap; 87bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 88bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch pci_set_drvdata(dev, info); 89bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 90bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch return 0; 91bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Kochout_unmap: 92bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch iounmap(info->mem[0].internal_addr); 93bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Kochout_release: 94bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch pci_release_regions(dev); 95bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Kochout_disable: 96bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch pci_disable_device(dev); 97bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Kochout_free: 98bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch kfree (info); 99bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch return -ENODEV; 100bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch} 101bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 102bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Kochstatic void hilscher_pci_remove(struct pci_dev *dev) 103bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch{ 104bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch struct uio_info *info = pci_get_drvdata(dev); 105bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 106bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch uio_unregister_device(info); 107bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch pci_release_regions(dev); 108bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch pci_disable_device(dev); 109bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch iounmap(info->mem[0].internal_addr); 110bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 111bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch kfree (info); 112bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch} 113bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 114d46f743822ee6e890a6e7971e089a020e6c0000aBill Pembertonstatic struct pci_device_id hilscher_pci_ids[] = { 115bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch { 116bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .vendor = PCI_VENDOR_ID_PLX, 117bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .device = PCI_DEVICE_ID_PLX_9030, 118bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .subvendor = PCI_SUBVENDOR_ID_PEP, 119bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .subdevice = CIF_SUBDEVICE_PROFIBUS, 120bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch }, 121bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch { 122bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .vendor = PCI_VENDOR_ID_PLX, 123bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .device = PCI_DEVICE_ID_PLX_9030, 124bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .subvendor = PCI_SUBVENDOR_ID_PEP, 125bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .subdevice = CIF_SUBDEVICE_DEVICENET, 126bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch }, 127bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch { 0, } 128bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch}; 129bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 130bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Kochstatic struct pci_driver hilscher_pci_driver = { 131bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .name = "hilscher", 132bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .id_table = hilscher_pci_ids, 133bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .probe = hilscher_pci_probe, 134bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch .remove = hilscher_pci_remove, 135bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch}; 136bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen Koch 137ced9017a4fc7ecf35a9c0c0bd8e46d14876b9fd1Peter Huewemodule_pci_driver(hilscher_pci_driver); 138912335c43bb10d124471bf063a85e132aa814214Hans J. KochMODULE_DEVICE_TABLE(pci, hilscher_pci_ids); 139bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen KochMODULE_LICENSE("GPL v2"); 140bc4c4f45acbe1f1528d654b0b1793f25c175bf8fHans-Jürgen KochMODULE_AUTHOR("Hans J. Koch, Benedikt Spranger"); 141