2008-05-31 13:37:27 +04:00
/*
* drivers / uio / uio_pdrv . c
*
* Copyright ( C ) 2008 by Digi International Inc .
* All rights reserved .
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation .
*/
# include <linux/platform_device.h>
# include <linux/uio_driver.h>
# include <linux/stringify.h>
2008-09-19 01:03:07 +04:00
# define DRIVER_NAME "uio_pdrv"
2008-05-31 13:37:27 +04:00
struct uio_platdata {
struct uio_info * uioinfo ;
} ;
static int uio_pdrv_probe ( struct platform_device * pdev )
{
struct uio_info * uioinfo = pdev - > dev . platform_data ;
struct uio_platdata * pdata ;
struct uio_mem * uiomem ;
int ret = - ENODEV ;
int i ;
if ( ! uioinfo | | ! uioinfo - > name | | ! uioinfo - > version ) {
dev_dbg ( & pdev - > dev , " %s: err_uioinfo \n " , __func__ ) ;
goto err_uioinfo ;
}
pdata = kzalloc ( sizeof ( * pdata ) , GFP_KERNEL ) ;
if ( ! pdata ) {
ret = - ENOMEM ;
dev_dbg ( & pdev - > dev , " %s: err_alloc_pdata \n " , __func__ ) ;
goto err_alloc_pdata ;
}
pdata - > uioinfo = uioinfo ;
uiomem = & uioinfo - > mem [ 0 ] ;
for ( i = 0 ; i < pdev - > num_resources ; + + i ) {
struct resource * r = & pdev - > resource [ i ] ;
if ( r - > flags ! = IORESOURCE_MEM )
continue ;
if ( uiomem > = & uioinfo - > mem [ MAX_UIO_MAPS ] ) {
dev_warn ( & pdev - > dev , " device has more than "
__stringify ( MAX_UIO_MAPS )
" I/O memory resources. \n " ) ;
break ;
}
uiomem - > memtype = UIO_MEM_PHYS ;
uiomem - > addr = r - > start ;
uiomem - > size = r - > end - r - > start + 1 ;
+ + uiomem ;
}
while ( uiomem < & uioinfo - > mem [ MAX_UIO_MAPS ] ) {
uiomem - > size = 0 ;
+ + uiomem ;
}
pdata - > uioinfo - > priv = pdata ;
ret = uio_register_device ( & pdev - > dev , pdata - > uioinfo ) ;
if ( ret ) {
kfree ( pdata ) ;
err_alloc_pdata :
err_uioinfo :
return ret ;
}
platform_set_drvdata ( pdev , pdata ) ;
return 0 ;
}
static int uio_pdrv_remove ( struct platform_device * pdev )
{
struct uio_platdata * pdata = platform_get_drvdata ( pdev ) ;
uio_unregister_device ( pdata - > uioinfo ) ;
2008-07-11 13:10:36 +04:00
kfree ( pdata ) ;
2008-05-31 13:37:27 +04:00
return 0 ;
}
static struct platform_driver uio_pdrv = {
. probe = uio_pdrv_probe ,
. remove = uio_pdrv_remove ,
. driver = {
. name = DRIVER_NAME ,
. owner = THIS_MODULE ,
} ,
} ;
static int __init uio_pdrv_init ( void )
{
return platform_driver_register ( & uio_pdrv ) ;
}
static void __exit uio_pdrv_exit ( void )
{
platform_driver_unregister ( & uio_pdrv ) ;
}
module_init ( uio_pdrv_init ) ;
module_exit ( uio_pdrv_exit ) ;
MODULE_AUTHOR ( " Uwe Kleine-Koenig " ) ;
MODULE_DESCRIPTION ( " Userspace I/O platform driver " ) ;
2008-07-11 13:10:37 +04:00
MODULE_LICENSE ( " GPL v2 " ) ;
2008-05-31 13:37:27 +04:00
MODULE_ALIAS ( " platform: " DRIVER_NAME ) ;