X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=target%2Flinux%2Fgeneric%2Ffiles%2Fdrivers%2Fnet%2Fphy%2Frtl8366_smi.c;h=44074633e2a9e64babe1fdaa6e88ce9d581913fb;hb=d8678644f9b18f36bdd5e7825e09c65dfcd049dc;hp=9903269390e452a5279db68b8ab3ee029eb630bd;hpb=e2782eae8ee17143d0506078fcf5c0a44b2302fe;p=lede.git diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c index 9903269390..44074633e2 100644 --- a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c +++ b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #ifdef CONFIG_RTL8366_SMI_DEBUG_FS @@ -25,6 +27,9 @@ #define RTL8366_SMI_ACK_RETRY_COUNT 5 +#define RTL8366_SMI_HW_STOP_DELAY 25 /* msecs */ +#define RTL8366_SMI_HW_START_DELAY 100 /* msecs */ + static inline void rtl8366_smi_clk_delay(struct rtl8366_smi *smi) { ndelay(smi->clk_delay); @@ -312,9 +317,9 @@ static int rtl8366_reset(struct rtl8366_smi *smi) { if (smi->hw_reset) { smi->hw_reset(true); - msleep(25); + msleep(RTL8366_SMI_HW_STOP_DELAY); smi->hw_reset(false); - msleep(25); + msleep(RTL8366_SMI_HW_START_DELAY); return 0; } @@ -1244,7 +1249,7 @@ static int __rtl8366_smi_init(struct rtl8366_smi *smi, const char *name) /* start the switch */ if (smi->hw_reset) { smi->hw_reset(false); - msleep(25); + msleep(RTL8366_SMI_HW_START_DELAY); } return 0; @@ -1367,6 +1372,71 @@ void rtl8366_smi_cleanup(struct rtl8366_smi *smi) } EXPORT_SYMBOL_GPL(rtl8366_smi_cleanup); +#ifdef CONFIG_OF +int rtl8366_smi_probe_of(struct platform_device *pdev, struct rtl8366_smi *smi) +{ + int sck = of_get_named_gpio(pdev->dev.of_node, "gpio-sck", 0); + int sda = of_get_named_gpio(pdev->dev.of_node, "gpio-sda", 0); + + if (!sck || !sda) { + dev_err(&pdev->dev, "gpios missing in devictree\n"); + return -EINVAL; + } + + smi->gpio_sda = sda; + smi->gpio_sck = sck; + + return 0; +} +#else +static inline int rtl8366_smi_probe_of(struct device_node *np, struct rtl8366_smi *smi) +{ + return -ENODEV; +} +#endif + +int rtl8366_smi_probe_plat(struct platform_device *pdev, struct rtl8366_smi *smi) +{ + struct rtl8366_platform_data *pdata = pdev->dev.platform_data; + + if (!pdev->dev.platform_data) { + dev_err(&pdev->dev, "no platform data specified\n"); + return -EINVAL; + } + + smi->gpio_sda = pdata->gpio_sda; + smi->gpio_sck = pdata->gpio_sck; + smi->hw_reset = pdata->hw_reset; + + return 0; +} + + +struct rtl8366_smi *rtl8366_smi_probe(struct platform_device *pdev) +{ + struct rtl8366_smi *smi; + int err; + + smi = rtl8366_smi_alloc(&pdev->dev); + if (!smi) + return NULL; + + if (pdev->dev.of_node) + err = rtl8366_smi_probe_of(pdev, smi); + else + err = rtl8366_smi_probe_plat(pdev, smi); + + if (err) + goto free_smi; + + return smi; + +free_smi: + kfree(smi); + return NULL; +} +EXPORT_SYMBOL_GPL(rtl8366_smi_probe); + MODULE_DESCRIPTION("Realtek RTL8366 SMI interface driver"); MODULE_AUTHOR("Gabor Juhos "); MODULE_LICENSE("GPL v2");