@ -153,7 +153,8 @@ static struct mei_cl *mei_bus_find_mei_cl_by_uuid(struct mei_device *dev,
return NULL ;
}
struct mei_cl_device * mei_cl_add_device ( struct mei_device * dev ,
uuid_le uuid , char * name )
uuid_le uuid , char * name ,
struct mei_cl_ops * ops )
{
struct mei_cl_device * device ;
struct mei_cl * cl ;
@ -168,6 +169,7 @@ struct mei_cl_device *mei_cl_add_device(struct mei_device *dev,
return NULL ;
device - > cl = cl ;
device - > ops = ops ;
device - > dev . parent = & dev - > pdev - > dev ;
device - > dev . bus = & mei_cl_bus_type ;
@ -408,6 +410,101 @@ void mei_cl_set_drvdata(struct mei_cl_device *device, void *data)
}
EXPORT_SYMBOL_GPL ( mei_cl_set_drvdata ) ;
int mei_cl_enable_device ( struct mei_cl_device * device )
{
int err ;
struct mei_device * dev ;
struct mei_cl * cl = device - > cl ;
if ( cl = = NULL )
return - ENODEV ;
dev = cl - > dev ;
mutex_lock ( & dev - > device_lock ) ;
cl - > state = MEI_FILE_CONNECTING ;
err = mei_cl_connect ( cl , NULL ) ;
if ( err < 0 ) {
mutex_unlock ( & dev - > device_lock ) ;
dev_err ( & dev - > pdev - > dev , " Could not connect to the ME client " ) ;
return err ;
}
mutex_unlock ( & dev - > device_lock ) ;
if ( device - > event_cb & & ! cl - > read_cb )
mei_cl_read_start ( device - > cl ) ;
if ( ! device - > ops | | ! device - > ops - > enable )
return 0 ;
return device - > ops - > enable ( device ) ;
}
EXPORT_SYMBOL_GPL ( mei_cl_enable_device ) ;
int mei_cl_disable_device ( struct mei_cl_device * device )
{
int err ;
struct mei_device * dev ;
struct mei_cl * cl = device - > cl ;
if ( cl = = NULL )
return - ENODEV ;
dev = cl - > dev ;
mutex_lock ( & dev - > device_lock ) ;
if ( cl - > state ! = MEI_FILE_CONNECTED ) {
mutex_unlock ( & dev - > device_lock ) ;
dev_err ( & dev - > pdev - > dev , " Already disconnected " ) ;
return 0 ;
}
cl - > state = MEI_FILE_DISCONNECTING ;
err = mei_cl_disconnect ( cl ) ;
if ( err < 0 ) {
mutex_unlock ( & dev - > device_lock ) ;
dev_err ( & dev - > pdev - > dev ,
" Could not disconnect from the ME client " ) ;
return err ;
}
/* Flush queues and remove any pending read */
mei_cl_flush_queues ( cl ) ;
if ( cl - > read_cb ) {
struct mei_cl_cb * cb = NULL ;
cb = mei_cl_find_read_cb ( cl ) ;
/* Remove entry from read list */
if ( cb )
list_del ( & cb - > list ) ;
cb = cl - > read_cb ;
cl - > read_cb = NULL ;
if ( cb ) {
mei_io_cb_free ( cb ) ;
cb = NULL ;
}
}
mutex_unlock ( & dev - > device_lock ) ;
if ( ! device - > ops | | ! device - > ops - > disable )
return 0 ;
return device - > ops - > disable ( device ) ;
}
EXPORT_SYMBOL_GPL ( mei_cl_disable_device ) ;
void mei_cl_bus_rx_event ( struct mei_cl * cl )
{
struct mei_cl_device * device = cl - > device ;