Merge tag 'sunxi-fixes-for-4.3' of https://git.kernel.org/pub/scm/linux/kernel/git...
[linux-drm-fsl-dcu.git] / drivers / net / ethernet / arc / emac_arc.c
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");