1 /** 2 * emac_arc.c - ARC EMAC specific glue layer 3 * 4 * Copyright (C) 2014 Romain Perier 5 * 6 * Romain Perier <romain.perier@gmail.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19 #include <linux/etherdevice.h> 20 #include <linux/module.h> 21 #include <linux/of_net.h> 22 #include <linux/platform_device.h> 23 24 #include "emac.h" 25 26 #define DRV_NAME "emac_arc" 27 #define DRV_VERSION "1.0" 28 29 static int emac_arc_probe(struct platform_device *pdev) 30 { 31 struct device *dev = &pdev->dev; 32 struct net_device *ndev; 33 struct arc_emac_priv *priv; 34 int interface, err; 35 36 if (!dev->of_node) 37 return -ENODEV; 38 39 ndev = alloc_etherdev(sizeof(struct arc_emac_priv)); 40 if (!ndev) 41 return -ENOMEM; 42 platform_set_drvdata(pdev, ndev); 43 SET_NETDEV_DEV(ndev, dev); 44 45 priv = netdev_priv(ndev); 46 priv->drv_name = DRV_NAME; 47 priv->drv_version = DRV_VERSION; 48 49 interface = of_get_phy_mode(dev->of_node); 50 if (interface < 0) 51 interface = PHY_INTERFACE_MODE_MII; 52 53 priv->clk = devm_clk_get(dev, "hclk"); 54 if (IS_ERR(priv->clk)) { 55 dev_err(dev, "failed to retrieve host clock from device tree\n"); 56 err = -EINVAL; 57 goto out_netdev; 58 } 59 60 err = arc_emac_probe(ndev, interface); 61 out_netdev: 62 if (err) 63 free_netdev(ndev); 64 return err; 65 } 66 67 static int emac_arc_remove(struct platform_device *pdev) 68 { 69 struct net_device *ndev = platform_get_drvdata(pdev); 70 int err; 71 72 err = arc_emac_remove(ndev); 73 free_netdev(ndev); 74 return err; 75 } 76 77 static const struct of_device_id emac_arc_dt_ids[] = { 78 { .compatible = "snps,arc-emac" }, 79 { /* Sentinel */ } 80 }; 81 MODULE_DEVICE_TABLE(of, emac_arc_dt_ids); 82 83 static struct platform_driver emac_arc_driver = { 84 .probe = emac_arc_probe, 85 .remove = emac_arc_remove, 86 .driver = { 87 .name = DRV_NAME, 88 .of_match_table = emac_arc_dt_ids, 89 }, 90 }; 91 92 module_platform_driver(emac_arc_driver); 93 94 MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>"); 95 MODULE_DESCRIPTION("ARC EMAC platform driver"); 96 MODULE_LICENSE("GPL"); 97