60
60
#include <linux/types.h>
61
61
#include <linux/slab.h>
62
62
#include <linux/clk.h>
63
+ #include <linux/of.h>
64
+ #include <linux/of_irq.h>
65
+ #include <linux/of_net.h>
63
66
#include <linux/of_mdio.h>
64
67
65
68
static char mv643xx_eth_driver_name [] = "mv643xx_eth" ;
@@ -2453,13 +2456,148 @@ static void infer_hw_params(struct mv643xx_eth_shared_private *msp)
2453
2456
}
2454
2457
}
2455
2458
2459
+ #if defined(CONFIG_OF )
2460
+ static const struct of_device_id mv643xx_eth_shared_ids [] = {
2461
+ { .compatible = "marvell,orion-eth" , },
2462
+ { .compatible = "marvell,kirkwood-eth" , },
2463
+ { }
2464
+ };
2465
+ MODULE_DEVICE_TABLE (of , mv643xx_eth_shared_ids );
2466
+ #endif
2467
+
2468
+ #if defined(CONFIG_OF ) && !defined(CONFIG_MV64X60 )
2469
+ #define mv643xx_eth_property (_np , _name , _v ) \
2470
+ do { \
2471
+ u32 tmp; \
2472
+ if (!of_property_read_u32(_np, "marvell," _name, &tmp)) \
2473
+ _v = tmp; \
2474
+ } while (0)
2475
+
2476
+ static struct platform_device * port_platdev [3 ];
2477
+
2478
+ static int mv643xx_eth_shared_of_add_port (struct platform_device * pdev ,
2479
+ struct device_node * pnp )
2480
+ {
2481
+ struct platform_device * ppdev ;
2482
+ struct mv643xx_eth_platform_data ppd ;
2483
+ struct resource res ;
2484
+ const char * mac_addr ;
2485
+ int ret ;
2486
+
2487
+ memset (& ppd , 0 , sizeof (ppd ));
2488
+ ppd .shared = pdev ;
2489
+
2490
+ memset (& res , 0 , sizeof (res ));
2491
+ if (!of_irq_to_resource (pnp , 0 , & res )) {
2492
+ dev_err (& pdev -> dev , "missing interrupt on %s\n" , pnp -> name );
2493
+ return - EINVAL ;
2494
+ }
2495
+
2496
+ if (of_property_read_u32 (pnp , "reg" , & ppd .port_number )) {
2497
+ dev_err (& pdev -> dev , "missing reg property on %s\n" , pnp -> name );
2498
+ return - EINVAL ;
2499
+ }
2500
+
2501
+ if (ppd .port_number >= 3 ) {
2502
+ dev_err (& pdev -> dev , "invalid reg property on %s\n" , pnp -> name );
2503
+ return - EINVAL ;
2504
+ }
2505
+
2506
+ mac_addr = of_get_mac_address (pnp );
2507
+ if (mac_addr )
2508
+ memcpy (ppd .mac_addr , mac_addr , 6 );
2509
+
2510
+ mv643xx_eth_property (pnp , "tx-queue-size" , ppd .tx_queue_size );
2511
+ mv643xx_eth_property (pnp , "tx-sram-addr" , ppd .tx_sram_addr );
2512
+ mv643xx_eth_property (pnp , "tx-sram-size" , ppd .tx_sram_size );
2513
+ mv643xx_eth_property (pnp , "rx-queue-size" , ppd .rx_queue_size );
2514
+ mv643xx_eth_property (pnp , "rx-sram-addr" , ppd .rx_sram_addr );
2515
+ mv643xx_eth_property (pnp , "rx-sram-size" , ppd .rx_sram_size );
2516
+
2517
+ ppd .phy_node = of_parse_phandle (pnp , "phy-handle" , 0 );
2518
+ if (!ppd .phy_node ) {
2519
+ ppd .phy_addr = MV643XX_ETH_PHY_NONE ;
2520
+ of_property_read_u32 (pnp , "speed" , & ppd .speed );
2521
+ of_property_read_u32 (pnp , "duplex" , & ppd .duplex );
2522
+ }
2523
+
2524
+ ppdev = platform_device_alloc (MV643XX_ETH_NAME , ppd .port_number );
2525
+ if (!ppdev )
2526
+ return - ENOMEM ;
2527
+ ppdev -> dev .coherent_dma_mask = DMA_BIT_MASK (32 );
2528
+
2529
+ ret = platform_device_add_resources (ppdev , & res , 1 );
2530
+ if (ret )
2531
+ goto port_err ;
2532
+
2533
+ ret = platform_device_add_data (ppdev , & ppd , sizeof (ppd ));
2534
+ if (ret )
2535
+ goto port_err ;
2536
+
2537
+ ret = platform_device_add (ppdev );
2538
+ if (ret )
2539
+ goto port_err ;
2540
+
2541
+ port_platdev [ppd .port_number ] = ppdev ;
2542
+
2543
+ return 0 ;
2544
+
2545
+ port_err :
2546
+ platform_device_put (ppdev );
2547
+ return ret ;
2548
+ }
2549
+
2550
+ static int mv643xx_eth_shared_of_probe (struct platform_device * pdev )
2551
+ {
2552
+ struct mv643xx_eth_shared_platform_data * pd ;
2553
+ struct device_node * pnp , * np = pdev -> dev .of_node ;
2554
+ int ret ;
2555
+
2556
+ /* bail out if not registered from DT */
2557
+ if (!np )
2558
+ return 0 ;
2559
+
2560
+ pd = devm_kzalloc (& pdev -> dev , sizeof (* pd ), GFP_KERNEL );
2561
+ if (!pd )
2562
+ return - ENOMEM ;
2563
+ pdev -> dev .platform_data = pd ;
2564
+
2565
+ mv643xx_eth_property (np , "tx-checksum-limit" , pd -> tx_csum_limit );
2566
+
2567
+ for_each_available_child_of_node (np , pnp ) {
2568
+ ret = mv643xx_eth_shared_of_add_port (pdev , pnp );
2569
+ if (ret )
2570
+ return ret ;
2571
+ }
2572
+ return 0 ;
2573
+ }
2574
+
2575
+ static void mv643xx_eth_shared_of_remove (void )
2576
+ {
2577
+ int n ;
2578
+
2579
+ for (n = 0 ; n < 3 ; n ++ ) {
2580
+ platform_device_del (port_platdev [n ]);
2581
+ port_platdev [n ] = NULL ;
2582
+ }
2583
+ }
2584
+ #else
2585
+ static int mv643xx_eth_shared_of_probe (struct platform_device * pdev )
2586
+ {
2587
+ return 0
2588
+ }
2589
+
2590
+ #define mv643xx_eth_shared_of_remove ()
2591
+ #endif
2592
+
2456
2593
static int mv643xx_eth_shared_probe (struct platform_device * pdev )
2457
2594
{
2458
2595
static int mv643xx_eth_version_printed ;
2459
- struct mv643xx_eth_shared_platform_data * pd = pdev -> dev . platform_data ;
2596
+ struct mv643xx_eth_shared_platform_data * pd ;
2460
2597
struct mv643xx_eth_shared_private * msp ;
2461
2598
const struct mbus_dram_target_info * dram ;
2462
2599
struct resource * res ;
2600
+ int ret ;
2463
2601
2464
2602
if (!mv643xx_eth_version_printed ++ )
2465
2603
pr_notice ("MV-643xx 10/100/1000 ethernet driver version %s\n" ,
@@ -2472,6 +2610,7 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
2472
2610
msp = devm_kzalloc (& pdev -> dev , sizeof (* msp ), GFP_KERNEL );
2473
2611
if (msp == NULL )
2474
2612
return - ENOMEM ;
2613
+ platform_set_drvdata (pdev , msp );
2475
2614
2476
2615
msp -> base = devm_ioremap (& pdev -> dev , res -> start , resource_size (res ));
2477
2616
if (msp -> base == NULL )
@@ -2488,22 +2627,25 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
2488
2627
if (dram )
2489
2628
mv643xx_eth_conf_mbus_windows (msp , dram );
2490
2629
2630
+ ret = mv643xx_eth_shared_of_probe (pdev );
2631
+ if (ret )
2632
+ return ret ;
2633
+ pd = pdev -> dev .platform_data ;
2634
+
2491
2635
msp -> tx_csum_limit = (pd != NULL && pd -> tx_csum_limit ) ?
2492
2636
pd -> tx_csum_limit : 9 * 1024 ;
2493
2637
infer_hw_params (msp );
2494
2638
2495
- platform_set_drvdata (pdev , msp );
2496
-
2497
2639
return 0 ;
2498
2640
}
2499
2641
2500
2642
static int mv643xx_eth_shared_remove (struct platform_device * pdev )
2501
2643
{
2502
2644
struct mv643xx_eth_shared_private * msp = platform_get_drvdata (pdev );
2503
2645
2646
+ mv643xx_eth_shared_of_remove ();
2504
2647
if (!IS_ERR (msp -> clk ))
2505
2648
clk_disable_unprepare (msp -> clk );
2506
-
2507
2649
return 0 ;
2508
2650
}
2509
2651
@@ -2513,6 +2655,7 @@ static struct platform_driver mv643xx_eth_shared_driver = {
2513
2655
.driver = {
2514
2656
.name = MV643XX_ETH_SHARED_NAME ,
2515
2657
.owner = THIS_MODULE ,
2658
+ .of_match_table = of_match_ptr (mv643xx_eth_shared_ids ),
2516
2659
},
2517
2660
};
2518
2661
@@ -2721,6 +2864,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
2721
2864
if (!IS_ERR (mp -> clk )) {
2722
2865
clk_prepare_enable (mp -> clk );
2723
2866
mp -> t_clk = clk_get_rate (mp -> clk );
2867
+ } else if (!IS_ERR (mp -> shared -> clk )) {
2868
+ mp -> t_clk = clk_get_rate (mp -> shared -> clk );
2724
2869
}
2725
2870
2726
2871
set_params (mp , pd );
0 commit comments