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>
2005-04-16 15:20:36 -07:00
# include "linux/firmware.h"
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 */
const struct firmware * fw_entry ;
2005-09-08 08:55:53 +02:00
printk ( KERN_INFO " firmware_sample_driver: a ghost device got inserted :) \n " ) ;
2005-04-16 15:20:36 -07:00
if ( request_firmware ( & fw_entry , " sample_driver_fw " , & ghost_device ) ! = 0 )
{
printk ( KERN_ERR
" firmware_sample_driver: Firmware not available \n " ) ;
return ;
}
sample_firmware_load ( fw_entry - > data , fw_entry - > size ) ;
release_firmware ( fw_entry ) ;
/* finish setting up the device */
}
static void sample_probe_specific ( void )
{
/* 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 */
2005-09-08 08:55:53 +02:00
printk ( KERN_INFO " firmware_sample_driver: a ghost device got inserted :) \n " ) ;
2005-04-16 15:20:36 -07:00
if ( request_firmware ( NULL , " sample_driver_fw " , & ghost_device ) ! = 0 )
{
printk ( KERN_ERR
" firmware_sample_driver: Firmware load failed \n " ) ;
return ;
}
/* request_firmware blocks until userspace finished, so at
* this point the firmware should be already in the device */
/* finish setting up the device */
}
static void sample_probe_async_cont ( const struct firmware * fw , void * context )
{
if ( ! fw ) {
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 ) ;
}
static void sample_probe_async ( void )
{
/* Let's say that I can't sleep */
int error ;
2006-03-25 03:08:21 -08:00
error = request_firmware_nowait ( THIS_MODULE , FW_ACTION_NOHOTPLUG ,
2005-04-16 15:20:36 -07:00
" sample_driver_fw " , & ghost_device ,
" my device pointer " ,
sample_probe_async_cont ) ;
if ( error ) {
printk ( KERN_ERR
" firmware_sample_driver: "
" request_firmware_nowait failed \n " ) ;
}
}
static int sample_init ( void )
{
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 ;
}
static void __exit sample_exit ( void )
{
}
module_init ( sample_init ) ;
module_exit ( sample_exit ) ;
MODULE_LICENSE ( " GPL " ) ;