Merge branch 'dsa-next'
Florian Fainelli says: ==================== net: dsa: remove restriction on platform_device This patch series removes the restriction in DSA to operate exclusively with platform_device Ethernet MAC drivers when using Device Tree. This basically allows arbitrary Ethernet MAC drivers to be used now in conjunction with Device Tree. The reason was that DSA was using a of_find_device_by_node() which limits the device_node to device pointer search exclusively to platform_device, in our case, we are interested in doing a "class" research and lookup the net_device. Thanks to Chris Packham for testing this on his platform. Changes in v2: - fix build for !CONFIG_OF_NET ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
bf0b211256
4 changed files with 45 additions and 5 deletions
|
@ -9,8 +9,11 @@
|
|||
|
||||
#ifdef CONFIG_OF_NET
|
||||
#include <linux/of.h>
|
||||
|
||||
struct net_device;
|
||||
extern int of_get_phy_mode(struct device_node *np);
|
||||
extern const void *of_get_mac_address(struct device_node *np);
|
||||
extern struct net_device *of_find_net_device_by_node(struct device_node *np);
|
||||
#else
|
||||
static inline int of_get_phy_mode(struct device_node *np)
|
||||
{
|
||||
|
@ -21,6 +24,11 @@ static inline const void *of_get_mac_address(struct device_node *np)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct net_device *of_find_net_device_by_node(struct device_node *np)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LINUX_OF_NET_H */
|
||||
|
|
|
@ -72,6 +72,7 @@ struct dsa_platform_data {
|
|||
* to the root switch chip of the tree.
|
||||
*/
|
||||
struct device *netdev;
|
||||
struct net_device *of_netdev;
|
||||
|
||||
/*
|
||||
* Info structs describing each of the switch chips
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <linux/export.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "net-sysfs.h"
|
||||
|
||||
|
@ -1374,6 +1375,30 @@ static struct class net_class = {
|
|||
.namespace = net_namespace,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF_NET
|
||||
static int of_dev_node_match(struct device *dev, const void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (dev->parent)
|
||||
ret = dev->parent->of_node == data;
|
||||
|
||||
return ret == 0 ? dev->of_node == data : ret;
|
||||
}
|
||||
|
||||
struct net_device *of_find_net_device_by_node(struct device_node *np)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = class_find_device(&net_class, NULL, np, of_dev_node_match);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
return to_net_dev(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_net_device_by_node);
|
||||
#endif
|
||||
|
||||
/* Delete sysfs entries but hold kobject reference until after all
|
||||
* netdev references are gone.
|
||||
*/
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include "dsa_priv.h"
|
||||
|
||||
|
@ -583,7 +584,7 @@ static int dsa_of_probe(struct device *dev)
|
|||
struct device_node *np = dev->of_node;
|
||||
struct device_node *child, *mdio, *ethernet, *port, *link;
|
||||
struct mii_bus *mdio_bus;
|
||||
struct platform_device *ethernet_dev;
|
||||
struct net_device *ethernet_dev;
|
||||
struct dsa_platform_data *pd;
|
||||
struct dsa_chip_data *cd;
|
||||
const char *port_name;
|
||||
|
@ -604,7 +605,7 @@ static int dsa_of_probe(struct device *dev)
|
|||
if (!ethernet)
|
||||
return -EINVAL;
|
||||
|
||||
ethernet_dev = of_find_device_by_node(ethernet);
|
||||
ethernet_dev = of_find_net_device_by_node(ethernet);
|
||||
if (!ethernet_dev)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
|
@ -613,7 +614,7 @@ static int dsa_of_probe(struct device *dev)
|
|||
return -ENOMEM;
|
||||
|
||||
dev->platform_data = pd;
|
||||
pd->netdev = ðernet_dev->dev;
|
||||
pd->of_netdev = ethernet_dev;
|
||||
pd->nr_chips = of_get_available_child_count(np);
|
||||
if (pd->nr_chips > DSA_MAX_SWITCHES)
|
||||
pd->nr_chips = DSA_MAX_SWITCHES;
|
||||
|
@ -771,10 +772,15 @@ static int dsa_probe(struct platform_device *pdev)
|
|||
pd = pdev->dev.platform_data;
|
||||
}
|
||||
|
||||
if (pd == NULL || pd->netdev == NULL)
|
||||
if (pd == NULL || (pd->netdev == NULL && pd->of_netdev == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
dev = dev_to_net_device(pd->netdev);
|
||||
if (pd->of_netdev) {
|
||||
dev = pd->of_netdev;
|
||||
dev_hold(dev);
|
||||
} else {
|
||||
dev = dev_to_net_device(pd->netdev);
|
||||
}
|
||||
if (dev == NULL) {
|
||||
ret = -EPROBE_DEFER;
|
||||
goto out;
|
||||
|
|
Loading…
Reference in a new issue