generic: ar8216: add mdio-device probing support
currently only ar8327 and ar8236 are added since they are the only two I could verify. Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
This commit is contained in:
		 Chuanhong Guo
					Chuanhong Guo
				
			
				
					committed by
					
						 Petr Štetiar
						Petr Štetiar
					
				
			
			
				
	
			
			
			 Petr Štetiar
						Petr Štetiar
					
				
			
						parent
						
							da64a8c656
						
					
				
				
					commit
					7d504f68a6
				
			| @@ -24,6 +24,7 @@ | |||||||
| #include <linux/netdevice.h> | #include <linux/netdevice.h> | ||||||
| #include <linux/netlink.h> | #include <linux/netlink.h> | ||||||
| #include <linux/of_device.h> | #include <linux/of_device.h> | ||||||
|  | #include <linux/of_mdio.h> | ||||||
| #include <linux/bitops.h> | #include <linux/bitops.h> | ||||||
| #include <net/genetlink.h> | #include <net/genetlink.h> | ||||||
| #include <linux/switch.h> | #include <linux/switch.h> | ||||||
| @@ -2333,5 +2334,137 @@ static struct phy_driver ar8xxx_phy_driver[] = { | |||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| module_phy_driver(ar8xxx_phy_driver); | static const struct of_device_id ar8xxx_mdiodev_of_match[] = { | ||||||
|  | 	{ | ||||||
|  | 		.compatible = "qca,ar8236", | ||||||
|  | 		.data = &ar8236_chip, | ||||||
|  | 	}, { | ||||||
|  | 		.compatible = "qca,ar8327", | ||||||
|  | 		.data = &ar8327_chip, | ||||||
|  | 	}, | ||||||
|  | 	{ /* sentinel */ }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | ar8xxx_mdiodev_probe(struct mdio_device *mdiodev) | ||||||
|  | { | ||||||
|  | 	const struct of_device_id *match; | ||||||
|  | 	struct ar8xxx_priv *priv; | ||||||
|  | 	struct switch_dev *swdev; | ||||||
|  | 	int ret; | ||||||
|  |  | ||||||
|  | 	match = of_match_device(ar8xxx_mdiodev_of_match, &mdiodev->dev); | ||||||
|  | 	if (!match) | ||||||
|  | 		return -EINVAL; | ||||||
|  |  | ||||||
|  | 	priv = ar8xxx_create(); | ||||||
|  | 	if (priv == NULL) | ||||||
|  | 		return -ENOMEM; | ||||||
|  |  | ||||||
|  | 	priv->mii_bus = mdiodev->bus; | ||||||
|  | 	priv->pdev = &mdiodev->dev; | ||||||
|  | 	priv->chip = (const struct ar8xxx_chip *) match->data; | ||||||
|  |  | ||||||
|  | 	ret = ar8xxx_read_id(priv); | ||||||
|  | 	if (ret) | ||||||
|  | 		goto free_priv; | ||||||
|  |  | ||||||
|  | 	ret = ar8xxx_probe_switch(priv); | ||||||
|  | 	if (ret) | ||||||
|  | 		goto free_priv; | ||||||
|  |  | ||||||
|  | 	swdev = &priv->dev; | ||||||
|  | 	swdev->alias = dev_name(&mdiodev->dev); | ||||||
|  | 	ret = register_switch(swdev, NULL); | ||||||
|  | 	if (ret) | ||||||
|  | 		goto free_priv; | ||||||
|  |  | ||||||
|  | 	pr_info("%s: %s rev. %u switch registered on %s\n", | ||||||
|  | 		swdev->devname, swdev->name, priv->chip_rev, | ||||||
|  | 		dev_name(&priv->mii_bus->dev)); | ||||||
|  |  | ||||||
|  | 	mutex_lock(&ar8xxx_dev_list_lock); | ||||||
|  | 	list_add(&priv->list, &ar8xxx_dev_list); | ||||||
|  | 	mutex_unlock(&ar8xxx_dev_list_lock); | ||||||
|  |  | ||||||
|  | 	priv->use_count++; | ||||||
|  |  | ||||||
|  | 	ret = ar8xxx_start(priv); | ||||||
|  | 	if (ret) | ||||||
|  | 		goto err_unregister_switch; | ||||||
|  |  | ||||||
|  | 	dev_set_drvdata(&mdiodev->dev, priv); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  |  | ||||||
|  | err_unregister_switch: | ||||||
|  | 	if (--priv->use_count) | ||||||
|  | 		return ret; | ||||||
|  |  | ||||||
|  | 	unregister_switch(&priv->dev); | ||||||
|  |  | ||||||
|  | free_priv: | ||||||
|  | 	ar8xxx_free(priv); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | ar8xxx_mdiodev_remove(struct mdio_device *mdiodev) | ||||||
|  | { | ||||||
|  | 	struct ar8xxx_priv *priv = dev_get_drvdata(&mdiodev->dev); | ||||||
|  |  | ||||||
|  | 	if (WARN_ON(!priv)) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	mutex_lock(&ar8xxx_dev_list_lock); | ||||||
|  |  | ||||||
|  | 	if (--priv->use_count > 0) { | ||||||
|  | 		mutex_unlock(&ar8xxx_dev_list_lock); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	list_del(&priv->list); | ||||||
|  | 	mutex_unlock(&ar8xxx_dev_list_lock); | ||||||
|  |  | ||||||
|  | 	unregister_switch(&priv->dev); | ||||||
|  | 	ar8xxx_mib_stop(priv); | ||||||
|  | 	ar8xxx_free(priv); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static struct mdio_driver ar8xxx_mdio_driver = { | ||||||
|  | 	.probe  = ar8xxx_mdiodev_probe, | ||||||
|  | 	.remove = ar8xxx_mdiodev_remove, | ||||||
|  | 	.mdiodrv.driver = { | ||||||
|  | 		.name = "ar8xxx-switch", | ||||||
|  | 		.of_match_table = ar8xxx_mdiodev_of_match, | ||||||
|  | 	}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static int __init ar8216_init(void) | ||||||
|  | { | ||||||
|  | 	int ret; | ||||||
|  |  | ||||||
|  | 	ret = phy_drivers_register(ar8xxx_phy_driver, | ||||||
|  | 				   ARRAY_SIZE(ar8xxx_phy_driver), | ||||||
|  | 				   THIS_MODULE); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  |  | ||||||
|  | 	ret = mdio_driver_register(&ar8xxx_mdio_driver); | ||||||
|  | 	if (ret) | ||||||
|  | 		phy_drivers_unregister(ar8xxx_phy_driver, | ||||||
|  | 				       ARRAY_SIZE(ar8xxx_phy_driver)); | ||||||
|  |  | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | module_init(ar8216_init); | ||||||
|  |  | ||||||
|  | static void __exit ar8216_exit(void) | ||||||
|  | { | ||||||
|  | 	mdio_driver_unregister(&ar8xxx_mdio_driver); | ||||||
|  | 	phy_drivers_unregister(ar8xxx_phy_driver, | ||||||
|  | 			        ARRAY_SIZE(ar8xxx_phy_driver)); | ||||||
|  | } | ||||||
|  | module_exit(ar8216_exit); | ||||||
|  |  | ||||||
| MODULE_LICENSE("GPL"); | MODULE_LICENSE("GPL"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user