mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/uio-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/uio-2.6: UIO: Hilscher CIF card driver UIO: Documentation UIO: Add the User IO core code
This commit is contained in:
@@ -408,6 +408,10 @@ X!Edrivers/pnp/system.c
|
||||
!Edrivers/pnp/manager.c
|
||||
!Edrivers/pnp/support.c
|
||||
</sect1>
|
||||
<sect1><title>Userspace IO devices</title>
|
||||
!Edrivers/uio/uio.c
|
||||
!Iinclude/linux/uio_driver.h
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="blkdev">
|
||||
|
||||
611
Documentation/DocBook/uio-howto.tmpl
Normal file
611
Documentation/DocBook/uio-howto.tmpl
Normal file
File diff suppressed because it is too large
Load Diff
@@ -84,4 +84,5 @@ source "drivers/auxdisplay/Kconfig"
|
||||
|
||||
source "drivers/kvm/Kconfig"
|
||||
|
||||
source "drivers/uio/Kconfig"
|
||||
endmenu
|
||||
|
||||
@@ -40,6 +40,7 @@ obj-$(CONFIG_ATA) += ata/
|
||||
obj-$(CONFIG_FUSION) += message/
|
||||
obj-$(CONFIG_FIREWIRE) += firewire/
|
||||
obj-$(CONFIG_IEEE1394) += ieee1394/
|
||||
obj-$(CONFIG_UIO) += uio/
|
||||
obj-y += cdrom/
|
||||
obj-y += auxdisplay/
|
||||
obj-$(CONFIG_MTD) += mtd/
|
||||
|
||||
29
drivers/uio/Kconfig
Normal file
29
drivers/uio/Kconfig
Normal file
@@ -0,0 +1,29 @@
|
||||
menu "Userspace I/O"
|
||||
depends on !S390
|
||||
|
||||
config UIO
|
||||
tristate "Userspace I/O drivers"
|
||||
default n
|
||||
help
|
||||
Enable this to allow the userspace driver core code to be
|
||||
built. This code allows userspace programs easy access to
|
||||
kernel interrupts and memory locations, allowing some drivers
|
||||
to be written in userspace. Note that a small kernel driver
|
||||
is also required for interrupt handling to work properly.
|
||||
|
||||
If you don't know what to do here, say N.
|
||||
|
||||
config UIO_CIF
|
||||
tristate "generic Hilscher CIF Card driver"
|
||||
depends on UIO && PCI
|
||||
default n
|
||||
help
|
||||
Driver for Hilscher CIF DeviceNet and Profibus cards. This
|
||||
driver requires a userspace component that handles all of the
|
||||
heavy lifting and can be found at:
|
||||
http://www.osadl.org/projects/downloads/UIO/user/cif-*
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called uio_cif.
|
||||
|
||||
endmenu
|
||||
2
drivers/uio/Makefile
Normal file
2
drivers/uio/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
obj-$(CONFIG_UIO) += uio.o
|
||||
obj-$(CONFIG_UIO_CIF) += uio_cif.o
|
||||
701
drivers/uio/uio.c
Normal file
701
drivers/uio/uio.c
Normal file
File diff suppressed because it is too large
Load Diff
156
drivers/uio/uio_cif.c
Normal file
156
drivers/uio/uio_cif.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* UIO Hilscher CIF card driver
|
||||
*
|
||||
* (C) 2007 Hans J. Koch <hjk@linutronix.de>
|
||||
* Original code (C) 2005 Benedikt Spranger <b.spranger@linutronix.de>
|
||||
*
|
||||
* Licensed under GPL version 2 only.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/uio_driver.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#ifndef PCI_DEVICE_ID_PLX_9030
|
||||
#define PCI_DEVICE_ID_PLX_9030 0x9030
|
||||
#endif
|
||||
|
||||
#define PLX9030_INTCSR 0x4C
|
||||
#define INTSCR_INT1_ENABLE 0x01
|
||||
#define INTSCR_INT1_STATUS 0x04
|
||||
#define INT1_ENABLED_AND_ACTIVE (INTSCR_INT1_ENABLE | INTSCR_INT1_STATUS)
|
||||
|
||||
#define PCI_SUBVENDOR_ID_PEP 0x1518
|
||||
#define CIF_SUBDEVICE_PROFIBUS 0x430
|
||||
#define CIF_SUBDEVICE_DEVICENET 0x432
|
||||
|
||||
|
||||
static irqreturn_t hilscher_handler(int irq, struct uio_info *dev_info)
|
||||
{
|
||||
void __iomem *plx_intscr = dev_info->mem[0].internal_addr
|
||||
+ PLX9030_INTCSR;
|
||||
|
||||
if ((ioread8(plx_intscr) & INT1_ENABLED_AND_ACTIVE)
|
||||
!= INT1_ENABLED_AND_ACTIVE)
|
||||
return IRQ_NONE;
|
||||
|
||||
/* Disable interrupt */
|
||||
iowrite8(ioread8(plx_intscr) & ~INTSCR_INT1_ENABLE, plx_intscr);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __devinit hilscher_pci_probe(struct pci_dev *dev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct uio_info *info;
|
||||
|
||||
info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
if (pci_enable_device(dev))
|
||||
goto out_free;
|
||||
|
||||
if (pci_request_regions(dev, "hilscher"))
|
||||
goto out_disable;
|
||||
|
||||
info->mem[0].addr = pci_resource_start(dev, 0);
|
||||
if (!info->mem[0].addr)
|
||||
goto out_release;
|
||||
info->mem[0].internal_addr = ioremap(pci_resource_start(dev, 0),
|
||||
pci_resource_len(dev, 0));
|
||||
if (!info->mem[0].internal_addr)
|
||||
goto out_release;
|
||||
|
||||
info->mem[0].size = pci_resource_len(dev, 0);
|
||||
info->mem[0].memtype = UIO_MEM_PHYS;
|
||||
info->mem[1].addr = pci_resource_start(dev, 2);
|
||||
info->mem[1].size = pci_resource_len(dev, 2);
|
||||
info->mem[1].memtype = UIO_MEM_PHYS;
|
||||
switch (id->subdevice) {
|
||||
case CIF_SUBDEVICE_PROFIBUS:
|
||||
info->name = "CIF_Profibus";
|
||||
break;
|
||||
case CIF_SUBDEVICE_DEVICENET:
|
||||
info->name = "CIF_Devicenet";
|
||||
break;
|
||||
default:
|
||||
info->name = "CIF_???";
|
||||
}
|
||||
info->version = "0.0.1";
|
||||
info->irq = dev->irq;
|
||||
info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
|
||||
info->handler = hilscher_handler;
|
||||
|
||||
if (uio_register_device(&dev->dev, info))
|
||||
goto out_unmap;
|
||||
|
||||
pci_set_drvdata(dev, info);
|
||||
|
||||
return 0;
|
||||
out_unmap:
|
||||
iounmap(info->mem[0].internal_addr);
|
||||
out_release:
|
||||
pci_release_regions(dev);
|
||||
out_disable:
|
||||
pci_disable_device(dev);
|
||||
out_free:
|
||||
kfree (info);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void hilscher_pci_remove(struct pci_dev *dev)
|
||||
{
|
||||
struct uio_info *info = pci_get_drvdata(dev);
|
||||
|
||||
uio_unregister_device(info);
|
||||
pci_release_regions(dev);
|
||||
pci_disable_device(dev);
|
||||
pci_set_drvdata(dev, NULL);
|
||||
iounmap(info->mem[0].internal_addr);
|
||||
|
||||
kfree (info);
|
||||
}
|
||||
|
||||
static struct pci_device_id hilscher_pci_ids[] = {
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_PLX,
|
||||
.device = PCI_DEVICE_ID_PLX_9030,
|
||||
.subvendor = PCI_SUBVENDOR_ID_PEP,
|
||||
.subdevice = CIF_SUBDEVICE_PROFIBUS,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_PLX,
|
||||
.device = PCI_DEVICE_ID_PLX_9030,
|
||||
.subvendor = PCI_SUBVENDOR_ID_PEP,
|
||||
.subdevice = CIF_SUBDEVICE_DEVICENET,
|
||||
},
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
static struct pci_driver hilscher_pci_driver = {
|
||||
.name = "hilscher",
|
||||
.id_table = hilscher_pci_ids,
|
||||
.probe = hilscher_pci_probe,
|
||||
.remove = hilscher_pci_remove,
|
||||
};
|
||||
|
||||
static int __init hilscher_init_module(void)
|
||||
{
|
||||
return pci_register_driver(&hilscher_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit hilscher_exit_module(void)
|
||||
{
|
||||
pci_unregister_driver(&hilscher_pci_driver);
|
||||
}
|
||||
|
||||
module_init(hilscher_init_module);
|
||||
module_exit(hilscher_exit_module);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger");
|
||||
91
include/linux/uio_driver.h
Normal file
91
include/linux/uio_driver.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* include/linux/uio_driver.h
|
||||
*
|
||||
* Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
|
||||
* Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
|
||||
* Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
|
||||
* Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
|
||||
*
|
||||
* Userspace IO driver.
|
||||
*
|
||||
* Licensed under the GPLv2 only.
|
||||
*/
|
||||
|
||||
#ifndef _UIO_DRIVER_H_
|
||||
#define _UIO_DRIVER_H_
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
/**
|
||||
* struct uio_mem - description of a UIO memory region
|
||||
* @kobj: kobject for this mapping
|
||||
* @addr: address of the device's memory
|
||||
* @size: size of IO
|
||||
* @memtype: type of memory addr points to
|
||||
* @internal_addr: ioremap-ped version of addr, for driver internal use
|
||||
*/
|
||||
struct uio_mem {
|
||||
struct kobject kobj;
|
||||
unsigned long addr;
|
||||
unsigned long size;
|
||||
int memtype;
|
||||
void __iomem *internal_addr;
|
||||
};
|
||||
|
||||
#define MAX_UIO_MAPS 5
|
||||
|
||||
struct uio_device;
|
||||
|
||||
/**
|
||||
* struct uio_info - UIO device capabilities
|
||||
* @uio_dev: the UIO device this info belongs to
|
||||
* @name: device name
|
||||
* @version: device driver version
|
||||
* @mem: list of mappable memory regions, size==0 for end of list
|
||||
* @irq: interrupt number or UIO_IRQ_CUSTOM
|
||||
* @irq_flags: flags for request_irq()
|
||||
* @priv: optional private data
|
||||
* @handler: the device's irq handler
|
||||
* @mmap: mmap operation for this uio device
|
||||
* @open: open operation for this uio device
|
||||
* @release: release operation for this uio device
|
||||
*/
|
||||
struct uio_info {
|
||||
struct uio_device *uio_dev;
|
||||
char *name;
|
||||
char *version;
|
||||
struct uio_mem mem[MAX_UIO_MAPS];
|
||||
long irq;
|
||||
unsigned long irq_flags;
|
||||
void *priv;
|
||||
irqreturn_t (*handler)(int irq, struct uio_info *dev_info);
|
||||
int (*mmap)(struct uio_info *info, struct vm_area_struct *vma);
|
||||
int (*open)(struct uio_info *info, struct inode *inode);
|
||||
int (*release)(struct uio_info *info, struct inode *inode);
|
||||
};
|
||||
|
||||
extern int __must_check
|
||||
__uio_register_device(struct module *owner,
|
||||
struct device *parent,
|
||||
struct uio_info *info);
|
||||
static inline int __must_check
|
||||
uio_register_device(struct device *parent, struct uio_info *info)
|
||||
{
|
||||
return __uio_register_device(THIS_MODULE, parent, info);
|
||||
}
|
||||
extern void uio_unregister_device(struct uio_info *info);
|
||||
extern void uio_event_notify(struct uio_info *info);
|
||||
|
||||
/* defines for uio_device->irq */
|
||||
#define UIO_IRQ_CUSTOM -1
|
||||
#define UIO_IRQ_NONE -2
|
||||
|
||||
/* defines for uio_device->memtype */
|
||||
#define UIO_MEM_NONE 0
|
||||
#define UIO_MEM_PHYS 1
|
||||
#define UIO_MEM_LOGICAL 2
|
||||
#define UIO_MEM_VIRTUAL 3
|
||||
|
||||
#endif /* _LINUX_UIO_DRIVER_H_ */
|
||||
Reference in New Issue
Block a user