0001
0002
0003
0004
0005
0006 #include <linux/device.h>
0007 #include <linux/etherdevice.h>
0008 #include <linux/netdevice.h>
0009
0010 struct net_device_devres {
0011 struct net_device *ndev;
0012 };
0013
0014 static void devm_free_netdev(struct device *dev, void *this)
0015 {
0016 struct net_device_devres *res = this;
0017
0018 free_netdev(res->ndev);
0019 }
0020
0021 struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
0022 unsigned int txqs, unsigned int rxqs)
0023 {
0024 struct net_device_devres *dr;
0025
0026 dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
0027 if (!dr)
0028 return NULL;
0029
0030 dr->ndev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
0031 if (!dr->ndev) {
0032 devres_free(dr);
0033 return NULL;
0034 }
0035
0036 devres_add(dev, dr);
0037
0038 return dr->ndev;
0039 }
0040 EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
0041
0042 static void devm_unregister_netdev(struct device *dev, void *this)
0043 {
0044 struct net_device_devres *res = this;
0045
0046 unregister_netdev(res->ndev);
0047 }
0048
0049 static int netdev_devres_match(struct device *dev, void *this, void *match_data)
0050 {
0051 struct net_device_devres *res = this;
0052 struct net_device *ndev = match_data;
0053
0054 return ndev == res->ndev;
0055 }
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 int devm_register_netdev(struct device *dev, struct net_device *ndev)
0068 {
0069 struct net_device_devres *dr;
0070 int ret;
0071
0072
0073
0074
0075
0076 if (WARN_ON(!devres_find(dev, devm_free_netdev,
0077 netdev_devres_match, ndev)))
0078 return -EINVAL;
0079
0080 dr = devres_alloc(devm_unregister_netdev, sizeof(*dr), GFP_KERNEL);
0081 if (!dr)
0082 return -ENOMEM;
0083
0084 ret = register_netdev(ndev);
0085 if (ret) {
0086 devres_free(dr);
0087 return ret;
0088 }
0089
0090 dr->ndev = ndev;
0091 devres_add(ndev->dev.parent, dr);
0092
0093 return 0;
0094 }
0095 EXPORT_SYMBOL(devm_register_netdev);