瀏覽代碼

net: stmmac: Allocate and pass soc/board specific data to callbacks

The current .init and .exit callbacks requires access to driver
private data structures. This is not a good seperation and abstraction.

Instead, we add a new .setup callback for allocating private data, and
pass the returned pointer to the other callbacks.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Chen-Yu Tsai 12 年之前
父節點
當前提交
938dfdaa3c
共有 3 個文件被更改,包括 26 次插入10 次删除
  1. 8 4
      Documentation/networking/stmmac.txt
  2. 14 4
      drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
  3. 4 2
      include/linux/stmmac.h

+ 8 - 4
Documentation/networking/stmmac.txt

@@ -127,8 +127,9 @@ struct plat_stmmacenet_data {
 	int riwt_off;
 	int riwt_off;
 	void (*fix_mac_speed)(void *priv, unsigned int speed);
 	void (*fix_mac_speed)(void *priv, unsigned int speed);
 	void (*bus_setup)(void __iomem *ioaddr);
 	void (*bus_setup)(void __iomem *ioaddr);
-	int (*init)(struct platform_device *pdev);
-	void (*exit)(struct platform_device *pdev);
+	void *(*setup)(struct platform_device *pdev);
+	int (*init)(struct platform_device *pdev, void *priv);
+	void (*exit)(struct platform_device *pdev, void *priv);
 	void *custom_cfg;
 	void *custom_cfg;
 	void *custom_data;
 	void *custom_data;
 	void *bsp_priv;
 	void *bsp_priv;
@@ -169,10 +170,13 @@ Where:
  o bus_setup: perform HW setup of the bus. For example, on some ST platforms
  o bus_setup: perform HW setup of the bus. For example, on some ST platforms
 	     this field is used to configure the AMBA  bridge to generate more
 	     this field is used to configure the AMBA  bridge to generate more
 	     efficient STBus traffic.
 	     efficient STBus traffic.
- o init/exit: callbacks used for calling a custom initialization;
+ o setup/init/exit: callbacks used for calling a custom initialization;
 	     this is sometime necessary on some platforms (e.g. ST boxes)
 	     this is sometime necessary on some platforms (e.g. ST boxes)
 	     where the HW needs to have set some PIO lines or system cfg
 	     where the HW needs to have set some PIO lines or system cfg
-	     registers.
+	     registers. setup should return a pointer to private data,
+	     which will be stored in bsp_priv, and then passed to init and
+	     exit callbacks. init/exit callbacks should not use or modify
+	     platform data.
  o custom_cfg/custom_data: this is a custom configuration that can be passed
  o custom_cfg/custom_data: this is a custom configuration that can be passed
 			   while initializing the resources.
 			   while initializing the resources.
  o bsp_priv: another private pointer.
  o bsp_priv: another private pointer.

+ 14 - 4
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c

@@ -144,9 +144,16 @@ static int stmmac_pltfr_probe(struct platform_device *pdev)
 		}
 		}
 	}
 	}
 
 
+	/* Custom setup (if needed) */
+	if (plat_dat->setup) {
+		plat_dat->bsp_priv = plat_dat->setup(pdev);
+		if (IS_ERR(plat_dat->bsp_priv))
+			return PTR_ERR(plat_dat->bsp_priv);
+	}
+
 	/* Custom initialisation (if needed)*/
 	/* Custom initialisation (if needed)*/
 	if (plat_dat->init) {
 	if (plat_dat->init) {
-		ret = plat_dat->init(pdev);
+		ret = plat_dat->init(pdev, plat_dat->bsp_priv);
 		if (unlikely(ret))
 		if (unlikely(ret))
 			return ret;
 			return ret;
 	}
 	}
@@ -203,7 +210,10 @@ static int stmmac_pltfr_remove(struct platform_device *pdev)
 	int ret = stmmac_dvr_remove(ndev);
 	int ret = stmmac_dvr_remove(ndev);
 
 
 	if (priv->plat->exit)
 	if (priv->plat->exit)
-		priv->plat->exit(pdev);
+		priv->plat->exit(pdev, priv->plat->bsp_priv);
+
+	if (priv->plat->free)
+		priv->plat->free(pdev, priv->plat->bsp_priv);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -218,7 +228,7 @@ static int stmmac_pltfr_suspend(struct device *dev)
 
 
 	ret = stmmac_suspend(ndev);
 	ret = stmmac_suspend(ndev);
 	if (priv->plat->exit)
 	if (priv->plat->exit)
-		priv->plat->exit(pdev);
+		priv->plat->exit(pdev, priv->plat->bsp_priv);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -230,7 +240,7 @@ static int stmmac_pltfr_resume(struct device *dev)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct platform_device *pdev = to_platform_device(dev);
 
 
 	if (priv->plat->init)
 	if (priv->plat->init)
-		priv->plat->init(pdev);
+		priv->plat->init(pdev, priv->plat->bsp_priv);
 
 
 	return stmmac_resume(ndev);
 	return stmmac_resume(ndev);
 }
 }

+ 4 - 2
include/linux/stmmac.h

@@ -113,8 +113,10 @@ struct plat_stmmacenet_data {
 	int max_speed;
 	int max_speed;
 	void (*fix_mac_speed)(void *priv, unsigned int speed);
 	void (*fix_mac_speed)(void *priv, unsigned int speed);
 	void (*bus_setup)(void __iomem *ioaddr);
 	void (*bus_setup)(void __iomem *ioaddr);
-	int (*init)(struct platform_device *pdev);
-	void (*exit)(struct platform_device *pdev);
+	void *(*setup)(struct platform_device *pdev);
+	void (*free)(struct platform_device *pdev, void *priv);
+	int (*init)(struct platform_device *pdev, void *priv);
+	void (*exit)(struct platform_device *pdev, void *priv);
 	void *custom_cfg;
 	void *custom_cfg;
 	void *custom_data;
 	void *custom_data;
 	void *bsp_priv;
 	void *bsp_priv;