2005-04-16 15:20:36 -07:00
/*
* firmware_sample_driver . c -
*
2007-06-04 18:45:44 +02:00
* Copyright ( c ) 2003 Manuel Estrada Sainz
2005-04-16 15:20:36 -07:00
*
* Sample code on how to use request_firmware ( ) from drivers .
*
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/device.h>
2005-10-30 15:03:48 -08:00
# include <linux/string.h>
2008-02-20 16:07:07 -08:00
# include <linux/firmware.h>
2005-04-16 15:20:36 -07:00
static struct device ghost_device = {
. bus_id = " ghost0 " ,
} ;
static void sample_firmware_load ( char * firmware , int size )
{
u8 buf [ size + 1 ] ;
memcpy ( buf , firmware , size ) ;
buf [ size ] = ' \0 ' ;
2005-09-08 08:55:53 +02:00
printk ( KERN_INFO " firmware_sample_driver: firmware: %s \n " , buf ) ;
2005-04-16 15:20:36 -07:00
}
static void sample_probe_default ( void )
{
/* uses the default method to get the firmware */
2008-02-20 16:07:07 -08:00
const struct firmware * fw_entry ;
int retval ;
printk ( KERN_INFO " firmware_sample_driver: "
" a ghost device got inserted :) \n " ) ;
2005-04-16 15:20:36 -07:00
2008-02-20 16:07:07 -08:00
retval = request_firmware ( & fw_entry , " sample_driver_fw " , & ghost_device ) ;
if ( retval ) {
2005-04-16 15:20:36 -07:00
printk ( KERN_ERR
" firmware_sample_driver: Firmware not available \n " ) ;
return ;
}
2008-02-20 13:20:50 -08:00
2005-04-16 15:20:36 -07:00
sample_firmware_load ( fw_entry - > data , fw_entry - > size ) ;
release_firmware ( fw_entry ) ;
/* finish setting up the device */
}
2008-02-20 16:07:07 -08:00
2005-04-16 15:20:36 -07:00
static void sample_probe_specific ( void )
{
2008-02-20 16:07:07 -08:00
int retval ;
2005-04-16 15:20:36 -07:00
/* Uses some specific hotplug support to get the firmware from
* userspace directly into the hardware , or via some sysfs file */
/* NOTE: This currently doesn't work */
2008-02-20 16:07:07 -08:00
printk ( KERN_INFO " firmware_sample_driver: "
" a ghost device got inserted :) \n " ) ;
2005-04-16 15:20:36 -07:00
2008-02-20 16:07:07 -08:00
retval = request_firmware ( NULL , " sample_driver_fw " , & ghost_device ) ;
if ( retval ) {
2005-04-16 15:20:36 -07:00
printk ( KERN_ERR
" firmware_sample_driver: Firmware load failed \n " ) ;
return ;
}
2008-02-20 13:20:50 -08:00
2005-04-16 15:20:36 -07:00
/* request_firmware blocks until userspace finished, so at
* this point the firmware should be already in the device */
/* finish setting up the device */
}
2008-04-21 16:36:46 -07:00
2005-04-16 15:20:36 -07:00
static void sample_probe_async_cont ( const struct firmware * fw , void * context )
{
2008-02-20 16:07:07 -08:00
if ( ! fw ) {
2005-04-16 15:20:36 -07:00
printk ( KERN_ERR
" firmware_sample_driver: firmware load failed \n " ) ;
return ;
}
2005-09-08 08:55:53 +02:00
printk ( KERN_INFO " firmware_sample_driver: device pointer \" %s \" \n " ,
2005-04-16 15:20:36 -07:00
( char * ) context ) ;
sample_firmware_load ( fw - > data , fw - > size ) ;
}
2008-02-20 16:07:07 -08:00
2005-04-16 15:20:36 -07:00
static void sample_probe_async ( void )
{
/* Let's say that I can't sleep */
int error ;
2008-02-20 16:07:07 -08:00
error = request_firmware_nowait ( THIS_MODULE , FW_ACTION_NOHOTPLUG ,
" sample_driver_fw " , & ghost_device ,
" my device pointer " ,
sample_probe_async_cont ) ;
if ( error )
printk ( KERN_ERR " firmware_sample_driver: "
2005-04-16 15:20:36 -07:00
" request_firmware_nowait failed \n " ) ;
}
2009-01-06 14:40:52 -08:00
static int __init sample_init ( void )
2005-04-16 15:20:36 -07:00
{
device_initialize ( & ghost_device ) ;
/* since there is no real hardware insertion I just call the
* sample probe functions here */
sample_probe_specific ( ) ;
sample_probe_default ( ) ;
sample_probe_async ( ) ;
return 0 ;
}
2008-02-20 16:07:07 -08:00
2005-04-16 15:20:36 -07:00
static void __exit sample_exit ( void )
{
}
2008-02-20 16:07:07 -08:00
module_init ( sample_init ) ;
module_exit ( sample_exit ) ;
2005-04-16 15:20:36 -07:00
MODULE_LICENSE ( " GPL " ) ;