@ -710,12 +710,55 @@ static inline void dsa_of_remove(struct device *dev)
}
# endif
static void dsa_setup_dst ( struct dsa_switch_tree * dst , struct net_device * dev ,
struct device * parent , struct dsa_platform_data * pd )
{
int i ;
dst - > pd = pd ;
dst - > master_netdev = dev ;
dst - > cpu_switch = - 1 ;
dst - > cpu_port = - 1 ;
for ( i = 0 ; i < pd - > nr_chips ; i + + ) {
struct dsa_switch * ds ;
ds = dsa_switch_setup ( dst , i , parent , pd - > chip [ i ] . host_dev ) ;
if ( IS_ERR ( ds ) ) {
netdev_err ( dev , " [%d]: couldn't create dsa switch instance (error %ld) \n " ,
i , PTR_ERR ( ds ) ) ;
continue ;
}
dst - > ds [ i ] = ds ;
if ( ds - > drv - > poll_link ! = NULL )
dst - > link_poll_needed = 1 ;
}
/*
* If we use a tagging format that doesn ' t have an ethertype
* field , make sure that all packets from this point on get
* sent to the tag format ' s receive function .
*/
wmb ( ) ;
dev - > dsa_ptr = ( void * ) dst ;
if ( dst - > link_poll_needed ) {
INIT_WORK ( & dst - > link_poll_work , dsa_link_poll_work ) ;
init_timer ( & dst - > link_poll_timer ) ;
dst - > link_poll_timer . data = ( unsigned long ) dst ;
dst - > link_poll_timer . function = dsa_link_poll_timer ;
dst - > link_poll_timer . expires = round_jiffies ( jiffies + HZ ) ;
add_timer ( & dst - > link_poll_timer ) ;
}
}
static int dsa_probe ( struct platform_device * pdev )
{
struct dsa_platform_data * pd = pdev - > dev . platform_data ;
struct net_device * dev ;
struct dsa_switch_tree * dst ;
int i , ret ;
int ret ;
pr_notice_once ( " Distributed Switch Architecture driver version %s \n " ,
dsa_driver_version ) ;
@ -752,42 +795,7 @@ static int dsa_probe(struct platform_device *pdev)
platform_set_drvdata ( pdev , dst ) ;
dst - > pd = pd ;
dst - > master_netdev = dev ;
dst - > cpu_switch = - 1 ;
dst - > cpu_port = - 1 ;
for ( i = 0 ; i < pd - > nr_chips ; i + + ) {
struct dsa_switch * ds ;
ds = dsa_switch_setup ( dst , i , & pdev - > dev , pd - > chip [ i ] . host_dev ) ;
if ( IS_ERR ( ds ) ) {
netdev_err ( dev , " [%d]: couldn't create dsa switch instance (error %ld) \n " ,
i , PTR_ERR ( ds ) ) ;
continue ;
}
dst - > ds [ i ] = ds ;
if ( ds - > drv - > poll_link ! = NULL )
dst - > link_poll_needed = 1 ;
}
/*
* If we use a tagging format that doesn ' t have an ethertype
* field , make sure that all packets from this point on get
* sent to the tag format ' s receive function .
*/
wmb ( ) ;
dev - > dsa_ptr = ( void * ) dst ;
if ( dst - > link_poll_needed ) {
INIT_WORK ( & dst - > link_poll_work , dsa_link_poll_work ) ;
init_timer ( & dst - > link_poll_timer ) ;
dst - > link_poll_timer . data = ( unsigned long ) dst ;
dst - > link_poll_timer . function = dsa_link_poll_timer ;
dst - > link_poll_timer . expires = round_jiffies ( jiffies + HZ ) ;
add_timer ( & dst - > link_poll_timer ) ;
}
dsa_setup_dst ( dst , dev , & pdev - > dev , pd ) ;
return 0 ;
@ -797,9 +805,8 @@ out:
return ret ;
}
static int dsa_remove ( struct platform_device * pdev )
static void dsa_remove_dst ( struct dsa_switch_tree * dst )
{
struct dsa_switch_tree * dst = platform_get_drvdata ( pdev ) ;
int i ;
if ( dst - > link_poll_needed )
@ -813,7 +820,13 @@ static int dsa_remove(struct platform_device *pdev)
if ( ds ! = NULL )
dsa_switch_destroy ( ds ) ;
}
}
static int dsa_remove ( struct platform_device * pdev )
{
struct dsa_switch_tree * dst = platform_get_drvdata ( pdev ) ;
dsa_remove_dst ( dst ) ;
dsa_of_remove ( & pdev - > dev ) ;
return 0 ;