net: dsa: mv88e6xxx: Add minimal platform_data support
Not all the world uses device tree. Some parts of the world still use platform devices and platform data. Add basic support for probing a Marvell switch via platform data. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									577941eb56
								
							
						
					
					
						commit
						877b7cb0b6
					
				| @ -8466,6 +8466,7 @@ M:	Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||||
| L:	netdev@vger.kernel.org | ||||
| S:	Maintained | ||||
| F:	drivers/net/dsa/mv88e6xxx/ | ||||
| F:	linux/platform_data/mv88e6xxx.h | ||||
| F:	Documentation/devicetree/bindings/net/dsa/marvell.txt | ||||
| 
 | ||||
| MARVELL ARMADA DRM SUPPORT | ||||
|  | ||||
| @ -28,6 +28,7 @@ | ||||
| #include <linux/of_device.h> | ||||
| #include <linux/of_irq.h> | ||||
| #include <linux/of_mdio.h> | ||||
| #include <linux/platform_data/mv88e6xxx.h> | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/gpio/consumer.h> | ||||
| #include <linux/phy.h> | ||||
| @ -4350,6 +4351,7 @@ static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	ds->priv = chip; | ||||
| 	ds->dev = dev; | ||||
| 	ds->ops = &mv88e6xxx_switch_ops; | ||||
| 	ds->ageing_time_min = chip->info->age_time_coeff; | ||||
| 	ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; | ||||
| @ -4364,36 +4366,73 @@ static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip) | ||||
| 	dsa_unregister_switch(chip->ds); | ||||
| } | ||||
| 
 | ||||
| static const void *pdata_device_get_match_data(struct device *dev) | ||||
| { | ||||
| 	const struct of_device_id *matches = dev->driver->of_match_table; | ||||
| 	const struct dsa_mv88e6xxx_pdata *pdata = dev->platform_data; | ||||
| 
 | ||||
| 	for (; matches->name[0] || matches->type[0] || matches->compatible[0]; | ||||
| 	     matches++) { | ||||
| 		if (!strcmp(pdata->compatible, matches->compatible)) | ||||
| 			return matches->data; | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| static int mv88e6xxx_probe(struct mdio_device *mdiodev) | ||||
| { | ||||
| 	struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data; | ||||
| 	struct device *dev = &mdiodev->dev; | ||||
| 	struct device_node *np = dev->of_node; | ||||
| 	const struct mv88e6xxx_info *compat_info; | ||||
| 	struct mv88e6xxx_chip *chip; | ||||
| 	u32 eeprom_len; | ||||
| 	int port; | ||||
| 	int err; | ||||
| 
 | ||||
| 	compat_info = of_device_get_match_data(dev); | ||||
| 	if (np) | ||||
| 		compat_info = of_device_get_match_data(dev); | ||||
| 
 | ||||
| 	if (pdata) { | ||||
| 		compat_info = pdata_device_get_match_data(dev); | ||||
| 
 | ||||
| 		if (!pdata->netdev) | ||||
| 			return -EINVAL; | ||||
| 
 | ||||
| 		for (port = 0; port < DSA_MAX_PORTS; port++) { | ||||
| 			if (!(pdata->enabled_ports & (1 << port))) | ||||
| 				continue; | ||||
| 			if (strcmp(pdata->cd.port_names[port], "cpu")) | ||||
| 				continue; | ||||
| 			pdata->cd.netdev[port] = &pdata->netdev->dev; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (!compat_info) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	chip = mv88e6xxx_alloc_chip(dev); | ||||
| 	if (!chip) | ||||
| 		return -ENOMEM; | ||||
| 	if (!chip) { | ||||
| 		err = -ENOMEM; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	chip->info = compat_info; | ||||
| 
 | ||||
| 	err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr); | ||||
| 	if (err) | ||||
| 		return err; | ||||
| 		goto out; | ||||
| 
 | ||||
| 	chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); | ||||
| 	if (IS_ERR(chip->reset)) | ||||
| 		return PTR_ERR(chip->reset); | ||||
| 	if (IS_ERR(chip->reset)) { | ||||
| 		err = PTR_ERR(chip->reset); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	err = mv88e6xxx_detect(chip); | ||||
| 	if (err) | ||||
| 		return err; | ||||
| 		goto out; | ||||
| 
 | ||||
| 	mv88e6xxx_phy_init(chip); | ||||
| 
 | ||||
| @ -4468,6 +4507,9 @@ out_g1_irq: | ||||
| 		mv88e6xxx_irq_poll_free(chip); | ||||
| 	mutex_unlock(&chip->reg_lock); | ||||
| out: | ||||
| 	if (pdata) | ||||
| 		dev_put(pdata->netdev); | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										17
									
								
								include/linux/platform_data/mv88e6xxx.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								include/linux/platform_data/mv88e6xxx.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||||
| #ifndef __DSA_MV88E6XXX_H | ||||
| #define __DSA_MV88E6XXX_H | ||||
| 
 | ||||
| #include <net/dsa.h> | ||||
| 
 | ||||
| struct dsa_mv88e6xxx_pdata { | ||||
| 	/* Must be first, such that dsa_register_switch() can access this
 | ||||
| 	 * without gory pointer manipulations | ||||
| 	 */ | ||||
| 	struct dsa_chip_data cd; | ||||
| 	const char *compatible; | ||||
| 	unsigned int enabled_ports; | ||||
| 	struct net_device *netdev; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user