Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sh_eth: add device tree support

Add support of the device tree probing for the Renesas SH-Mobile SoCs
documenting the device tree binding as necessary.

This work is loosely based on the original patch by Nobuhiro Iwamatsu
<nobuhiro.iwamatsu.yj@renesas.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Sergei Shtylyov and committed by
David S. Miller
b356e978 e8f08ee0

+121 -3
+55
Documentation/devicetree/bindings/net/sh_eth.txt
··· 1 + * Renesas Electronics SH EtherMAC 2 + 3 + This file provides information on what the device node for the SH EtherMAC 4 + interface contains. 5 + 6 + Required properties: 7 + - compatible: "renesas,gether-r8a7740" if the device is a part of R8A7740 SoC. 8 + "renesas,ether-r8a7778" if the device is a part of R8A7778 SoC. 9 + "renesas,ether-r8a7779" if the device is a part of R8A7779 SoC. 10 + "renesas,ether-r8a7790" if the device is a part of R8A7790 SoC. 11 + "renesas,ether-r8a7791" if the device is a part of R8A7791 SoC. 12 + "renesas,ether-r7s72100" if the device is a part of R7S72100 SoC. 13 + - reg: offset and length of (1) the E-DMAC/feLic register block (required), 14 + (2) the TSU register block (optional). 15 + - interrupts: interrupt specifier for the sole interrupt. 16 + - phy-mode: see ethernet.txt file in the same directory. 17 + - phy-handle: see ethernet.txt file in the same directory. 18 + - #address-cells: number of address cells for the MDIO bus, must be equal to 1. 19 + - #size-cells: number of size cells on the MDIO bus, must be equal to 0. 20 + - clocks: clock phandle and specifier pair. 21 + - pinctrl-0: phandle, referring to a default pin configuration node. 22 + 23 + Optional properties: 24 + - interrupt-parent: the phandle for the interrupt controller that services 25 + interrupts for this device. 26 + - pinctrl-names: pin configuration state name ("default"). 27 + - renesas,no-ether-link: boolean, specify when a board does not provide a proper 28 + Ether LINK signal. 29 + - renesas,ether-link-active-low: boolean, specify when the Ether LINK signal is 30 + active-low instead of normal active-high. 31 + 32 + Example (Lager board): 33 + 34 + ethernet@ee700000 { 35 + compatible = "renesas,ether-r8a7790"; 36 + reg = <0 0xee700000 0 0x400>; 37 + interrupt-parent = <&gic>; 38 + interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; 39 + clocks = <&mstp8_clks R8A7790_CLK_ETHER>; 40 + phy-mode = "rmii"; 41 + phy-handle = <&phy1>; 42 + pinctrl-0 = <&ether_pins>; 43 + pinctrl-names = "default"; 44 + renesas,ether-link-active-low; 45 + #address-cells = <1>; 46 + #size-cells = <0>; 47 + 48 + phy1: ethernet-phy@1 { 49 + reg = <1>; 50 + interrupt-parent = <&irqc0>; 51 + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; 52 + pinctrl-0 = <&phy1_pins>; 53 + pinctrl-names = "default"; 54 + }; 55 + };
+66 -3
drivers/net/ethernet/renesas/sh_eth.c
··· 1 1 /* SuperH Ethernet device driver 2 2 * 3 3 * Copyright (C) 2006-2012 Nobuhiro Iwamatsu 4 - * Copyright (C) 2008-2013 Renesas Solutions Corp. 5 - * Copyright (C) 2013 Cogent Embedded, Inc. 4 + * Copyright (C) 2008-2014 Renesas Solutions Corp. 5 + * Copyright (C) 2013-2014 Cogent Embedded, Inc. 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify it 8 8 * under the terms and conditions of the GNU General Public License, ··· 27 27 #include <linux/platform_device.h> 28 28 #include <linux/mdio-bitbang.h> 29 29 #include <linux/netdevice.h> 30 + #include <linux/of.h> 31 + #include <linux/of_device.h> 32 + #include <linux/of_irq.h> 33 + #include <linux/of_net.h> 30 34 #include <linux/phy.h> 31 35 #include <linux/cache.h> 32 36 #include <linux/io.h> ··· 2714 2710 .ndo_change_mtu = eth_change_mtu, 2715 2711 }; 2716 2712 2713 + #ifdef CONFIG_OF 2714 + static struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev) 2715 + { 2716 + struct device_node *np = dev->of_node; 2717 + struct sh_eth_plat_data *pdata; 2718 + struct device_node *phy; 2719 + const char *mac_addr; 2720 + 2721 + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 2722 + if (!pdata) 2723 + return NULL; 2724 + 2725 + pdata->phy_interface = of_get_phy_mode(np); 2726 + 2727 + phy = of_parse_phandle(np, "phy-handle", 0); 2728 + if (of_property_read_u32(phy, "reg", &pdata->phy)) 2729 + return NULL; 2730 + pdata->phy_irq = irq_of_parse_and_map(phy, 0); 2731 + 2732 + mac_addr = of_get_mac_address(np); 2733 + if (mac_addr) 2734 + memcpy(pdata->mac_addr, mac_addr, ETH_ALEN); 2735 + 2736 + pdata->no_ether_link = 2737 + of_property_read_bool(np, "renesas,no-ether-link"); 2738 + pdata->ether_link_active_low = 2739 + of_property_read_bool(np, "renesas,ether-link-active-low"); 2740 + 2741 + return pdata; 2742 + } 2743 + 2744 + static const struct of_device_id sh_eth_match_table[] = { 2745 + { .compatible = "renesas,gether-r8a7740", .data = &r8a7740_data }, 2746 + { .compatible = "renesas,ether-r8a7778", .data = &r8a777x_data }, 2747 + { .compatible = "renesas,ether-r8a7779", .data = &r8a777x_data }, 2748 + { .compatible = "renesas,ether-r8a7790", .data = &r8a779x_data }, 2749 + { .compatible = "renesas,ether-r8a7791", .data = &r8a779x_data }, 2750 + { .compatible = "renesas,ether-r7s72100", .data = &r7s72100_data }, 2751 + { } 2752 + }; 2753 + MODULE_DEVICE_TABLE(of, sh_eth_match_table); 2754 + #else 2755 + static inline struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev) 2756 + { 2757 + return NULL; 2758 + } 2759 + #endif 2760 + 2717 2761 static int sh_eth_drv_probe(struct platform_device *pdev) 2718 2762 { 2719 2763 int ret, devno = 0; ··· 2815 2763 pm_runtime_enable(&pdev->dev); 2816 2764 pm_runtime_resume(&pdev->dev); 2817 2765 2766 + if (pdev->dev.of_node) 2767 + pd = sh_eth_parse_dt(&pdev->dev); 2818 2768 if (!pd) { 2819 2769 dev_err(&pdev->dev, "no platform data\n"); 2820 2770 ret = -EINVAL; ··· 2832 2778 mdp->ether_link_active_low = pd->ether_link_active_low; 2833 2779 2834 2780 /* set cpu data */ 2835 - mdp->cd = (struct sh_eth_cpu_data *)id->driver_data; 2781 + if (id) { 2782 + mdp->cd = (struct sh_eth_cpu_data *)id->driver_data; 2783 + } else { 2784 + const struct of_device_id *match; 2785 + 2786 + match = of_match_device(of_match_ptr(sh_eth_match_table), 2787 + &pdev->dev); 2788 + mdp->cd = (struct sh_eth_cpu_data *)match->data; 2789 + } 2836 2790 mdp->reg_offset = sh_eth_get_register_offset(mdp->cd->register_type); 2837 2791 sh_eth_set_default_cpu_data(mdp->cd); 2838 2792 ··· 2982 2920 .driver = { 2983 2921 .name = CARDNAME, 2984 2922 .pm = SH_ETH_PM_OPS, 2923 + .of_match_table = of_match_ptr(sh_eth_match_table), 2985 2924 }, 2986 2925 }; 2987 2926