@ -288,9 +288,38 @@ EXPORT_SYMBOL_GPL(kempld_release_mutex);
*/
static int kempld_get_info ( struct kempld_device_data * pld )
{
int ret ;
struct kempld_platform_data * pdata = dev_get_platdata ( pld - > dev ) ;
char major , minor ;
ret = pdata - > get_info ( pld ) ;
if ( ret )
return ret ;
/* The Kontron PLD firmware version string has the following format:
* Pwxy . zzzz
* P : Fixed
* w : PLD number - 1 hex digit
* x : Major version - 1 alphanumerical digit ( 0 - 9 A - V )
* y : Minor version - 1 alphanumerical digit ( 0 - 9 A - V )
* zzzz : Build number - 4 zero padded hex digits */
return pdata - > get_info ( pld ) ;
if ( pld - > info . major < 10 )
major = pld - > info . major + ' 0 ' ;
else
major = ( pld - > info . major - 10 ) + ' A ' ;
if ( pld - > info . minor < 10 )
minor = pld - > info . minor + ' 0 ' ;
else
minor = ( pld - > info . minor - 10 ) + ' A ' ;
ret = scnprintf ( pld - > info . version , sizeof ( pld - > info . version ) ,
" P%X%c%c.%04X " , pld - > info . number , major , minor ,
pld - > info . buildnr ) ;
if ( ret < 0 )
return ret ;
return 0 ;
}
/*
@ -307,9 +336,71 @@ static int kempld_register_cells(struct kempld_device_data *pld)
return pdata - > register_cells ( pld ) ;
}
static const char * kempld_get_type_string ( struct kempld_device_data * pld )
{
const char * version_type ;
switch ( pld - > info . type ) {
case 0 :
version_type = " release " ;
break ;
case 1 :
version_type = " debug " ;
break ;
case 2 :
version_type = " custom " ;
break ;
default :
version_type = " unspecified " ;
break ;
}
return version_type ;
}
static ssize_t kempld_version_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct kempld_device_data * pld = dev_get_drvdata ( dev ) ;
return scnprintf ( buf , PAGE_SIZE , " %s \n " , pld - > info . version ) ;
}
static ssize_t kempld_specification_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct kempld_device_data * pld = dev_get_drvdata ( dev ) ;
return scnprintf ( buf , PAGE_SIZE , " %d.%d \n " , pld - > info . spec_major ,
pld - > info . spec_minor ) ;
}
static ssize_t kempld_type_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct kempld_device_data * pld = dev_get_drvdata ( dev ) ;
return scnprintf ( buf , PAGE_SIZE , " %s \n " , kempld_get_type_string ( pld ) ) ;
}
static DEVICE_ATTR ( pld_version , S_IRUGO , kempld_version_show , NULL ) ;
static DEVICE_ATTR ( pld_specification , S_IRUGO , kempld_specification_show ,
NULL ) ;
static DEVICE_ATTR ( pld_type , S_IRUGO , kempld_type_show , NULL ) ;
static struct attribute * pld_attributes [ ] = {
& dev_attr_pld_version . attr ,
& dev_attr_pld_specification . attr ,
& dev_attr_pld_type . attr ,
NULL
} ;
static const struct attribute_group pld_attr_group = {
. attrs = pld_attributes ,
} ;
static int kempld_detect_device ( struct kempld_device_data * pld )
{
char * version_type ;
u8 index_reg ;
int ret ;
@ -335,27 +426,19 @@ static int kempld_detect_device(struct kempld_device_data *pld)
if ( ret )
return ret ;
switch ( pld - > info . type ) {
case 0 :
version_type = " release " ;
break ;
case 1 :
version_type = " debug " ;
break ;
case 2 :
version_type = " custom " ;
break ;
default :
version_type = " unspecified " ;
}
dev_info ( pld - > dev , " Found Kontron PLD - %s (%s), spec %d.%d \n " ,
pld - > info . version , kempld_get_type_string ( pld ) ,
pld - > info . spec_major , pld - > info . spec_minor ) ;
ret = sysfs_create_group ( & pld - > dev - > kobj , & pld_attr_group ) ;
if ( ret )
return ret ;
dev_info ( pld - > dev , " Found Kontron PLD %d \n " , pld - > info . number ) ;
dev_info ( pld - > dev , " %s version %d.%d build %d, specification %d.%d \n " ,
version_type , pld - > info . major , pld - > info . minor ,
pld - > info . buildnr , pld - > info . spec_major ,
pld - > info . spec_minor ) ;
ret = kempld_register_cells ( pld ) ;
if ( ret )
sysfs_remove_group ( & pld - > dev - > kobj , & pld_attr_group ) ;
return kempld_ regis ter_cells ( pld ) ;
return ret ;
}
static int kempld_probe ( struct platform_device * pdev )
@ -399,6 +482,8 @@ static int kempld_remove(struct platform_device *pdev)
struct kempld_device_data * pld = platform_get_drvdata ( pdev ) ;
struct kempld_platform_data * pdata = dev_get_platdata ( pld - > dev ) ;
sysfs_remove_group ( & pld - > dev - > kobj , & pld_attr_group ) ;
mfd_remove_devices ( & pdev - > dev ) ;
pdata - > release_hardware_mutex ( pld ) ;