root/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sxgbe_probe_config_dt
  2. sxgbe_probe_config_dt
  3. sxgbe_platform_probe
  4. sxgbe_platform_remove
  5. sxgbe_platform_suspend
  6. sxgbe_platform_resume
  7. sxgbe_platform_freeze
  8. sxgbe_platform_restore
  9. sxgbe_register_platform
  10. sxgbe_unregister_platform

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* 10G controller driver for Samsung SoCs
   3  *
   4  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
   5  *              http://www.samsung.com
   6  *
   7  * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
   8  */
   9 
  10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11 
  12 #include <linux/etherdevice.h>
  13 #include <linux/io.h>
  14 #include <linux/module.h>
  15 #include <linux/netdevice.h>
  16 #include <linux/of.h>
  17 #include <linux/of_irq.h>
  18 #include <linux/of_net.h>
  19 #include <linux/phy.h>
  20 #include <linux/platform_device.h>
  21 #include <linux/sxgbe_platform.h>
  22 
  23 #include "sxgbe_common.h"
  24 #include "sxgbe_reg.h"
  25 
  26 #ifdef CONFIG_OF
  27 static int sxgbe_probe_config_dt(struct platform_device *pdev,
  28                                  struct sxgbe_plat_data *plat,
  29                                  const char **mac)
  30 {
  31         struct device_node *np = pdev->dev.of_node;
  32         struct sxgbe_dma_cfg *dma_cfg;
  33 
  34         if (!np)
  35                 return -ENODEV;
  36 
  37         *mac = of_get_mac_address(np);
  38         plat->interface = of_get_phy_mode(np);
  39 
  40         plat->bus_id = of_alias_get_id(np, "ethernet");
  41         if (plat->bus_id < 0)
  42                 plat->bus_id = 0;
  43 
  44         plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
  45                                            sizeof(*plat->mdio_bus_data),
  46                                            GFP_KERNEL);
  47         if (!plat->mdio_bus_data)
  48                 return -ENOMEM;
  49 
  50         dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL);
  51         if (!dma_cfg)
  52                 return -ENOMEM;
  53 
  54         plat->dma_cfg = dma_cfg;
  55         of_property_read_u32(np, "samsung,pbl", &dma_cfg->pbl);
  56         if (of_property_read_u32(np, "samsung,burst-map", &dma_cfg->burst_map) == 0)
  57                 dma_cfg->fixed_burst = true;
  58 
  59         return 0;
  60 }
  61 #else
  62 static int sxgbe_probe_config_dt(struct platform_device *pdev,
  63                                  struct sxgbe_plat_data *plat,
  64                                  const char **mac)
  65 {
  66         return -ENOSYS;
  67 }
  68 #endif /* CONFIG_OF */
  69 
  70 /**
  71  * sxgbe_platform_probe
  72  * @pdev: platform device pointer
  73  * Description: platform_device probe function. It allocates
  74  * the necessary resources and invokes the main to init
  75  * the net device, register the mdio bus etc.
  76  */
  77 static int sxgbe_platform_probe(struct platform_device *pdev)
  78 {
  79         int ret;
  80         int i, chan;
  81         struct device *dev = &pdev->dev;
  82         void __iomem *addr;
  83         struct sxgbe_priv_data *priv = NULL;
  84         struct sxgbe_plat_data *plat_dat = NULL;
  85         const char *mac = NULL;
  86         struct net_device *ndev = platform_get_drvdata(pdev);
  87         struct device_node *node = dev->of_node;
  88 
  89         /* Get memory resource */
  90         addr = devm_platform_ioremap_resource(pdev, 0);
  91         if (IS_ERR(addr))
  92                 return PTR_ERR(addr);
  93 
  94         if (pdev->dev.of_node) {
  95                 plat_dat = devm_kzalloc(&pdev->dev,
  96                                         sizeof(struct sxgbe_plat_data),
  97                                         GFP_KERNEL);
  98                 if (!plat_dat)
  99                         return  -ENOMEM;
 100 
 101                 ret = sxgbe_probe_config_dt(pdev, plat_dat, &mac);
 102                 if (ret) {
 103                         pr_err("%s: main dt probe failed\n", __func__);
 104                         return ret;
 105                 }
 106         }
 107 
 108         priv = sxgbe_drv_probe(&(pdev->dev), plat_dat, addr);
 109         if (!priv) {
 110                 pr_err("%s: main driver probe failed\n", __func__);
 111                 goto err_out;
 112         }
 113 
 114         /* Get the SXGBE common INT information */
 115         priv->irq  = irq_of_parse_and_map(node, 0);
 116         if (priv->irq <= 0) {
 117                 dev_err(dev, "sxgbe common irq parsing failed\n");
 118                 goto err_drv_remove;
 119         }
 120 
 121         /* Get MAC address if available (DT) */
 122         if (!IS_ERR_OR_NULL(mac))
 123                 ether_addr_copy(priv->dev->dev_addr, mac);
 124 
 125         /* Get the TX/RX IRQ numbers */
 126         for (i = 0, chan = 1; i < SXGBE_TX_QUEUES; i++) {
 127                 priv->txq[i]->irq_no = irq_of_parse_and_map(node, chan++);
 128                 if (priv->txq[i]->irq_no <= 0) {
 129                         dev_err(dev, "sxgbe tx irq parsing failed\n");
 130                         goto err_tx_irq_unmap;
 131                 }
 132         }
 133 
 134         for (i = 0; i < SXGBE_RX_QUEUES; i++) {
 135                 priv->rxq[i]->irq_no = irq_of_parse_and_map(node, chan++);
 136                 if (priv->rxq[i]->irq_no <= 0) {
 137                         dev_err(dev, "sxgbe rx irq parsing failed\n");
 138                         goto err_rx_irq_unmap;
 139                 }
 140         }
 141 
 142         priv->lpi_irq = irq_of_parse_and_map(node, chan);
 143         if (priv->lpi_irq <= 0) {
 144                 dev_err(dev, "sxgbe lpi irq parsing failed\n");
 145                 goto err_rx_irq_unmap;
 146         }
 147 
 148         platform_set_drvdata(pdev, priv->dev);
 149 
 150         pr_debug("platform driver registration completed\n");
 151 
 152         return 0;
 153 
 154 err_rx_irq_unmap:
 155         while (i--)
 156                 irq_dispose_mapping(priv->rxq[i]->irq_no);
 157         i = SXGBE_TX_QUEUES;
 158 err_tx_irq_unmap:
 159         while (i--)
 160                 irq_dispose_mapping(priv->txq[i]->irq_no);
 161         irq_dispose_mapping(priv->irq);
 162 err_drv_remove:
 163         sxgbe_drv_remove(ndev);
 164 err_out:
 165         return -ENODEV;
 166 }
 167 
 168 /**
 169  * sxgbe_platform_remove
 170  * @pdev: platform device pointer
 171  * Description: this function calls the main to free the net resources
 172  * and calls the platforms hook and release the resources (e.g. mem).
 173  */
 174 static int sxgbe_platform_remove(struct platform_device *pdev)
 175 {
 176         struct net_device *ndev = platform_get_drvdata(pdev);
 177         int ret = sxgbe_drv_remove(ndev);
 178 
 179         return ret;
 180 }
 181 
 182 #ifdef CONFIG_PM
 183 static int sxgbe_platform_suspend(struct device *dev)
 184 {
 185         struct net_device *ndev = dev_get_drvdata(dev);
 186 
 187         return sxgbe_suspend(ndev);
 188 }
 189 
 190 static int sxgbe_platform_resume(struct device *dev)
 191 {
 192         struct net_device *ndev = dev_get_drvdata(dev);
 193 
 194         return sxgbe_resume(ndev);
 195 }
 196 
 197 static int sxgbe_platform_freeze(struct device *dev)
 198 {
 199         struct net_device *ndev = dev_get_drvdata(dev);
 200 
 201         return sxgbe_freeze(ndev);
 202 }
 203 
 204 static int sxgbe_platform_restore(struct device *dev)
 205 {
 206         struct net_device *ndev = dev_get_drvdata(dev);
 207 
 208         return sxgbe_restore(ndev);
 209 }
 210 
 211 static const struct dev_pm_ops sxgbe_platform_pm_ops = {
 212         .suspend        = sxgbe_platform_suspend,
 213         .resume         = sxgbe_platform_resume,
 214         .freeze         = sxgbe_platform_freeze,
 215         .thaw           = sxgbe_platform_restore,
 216         .restore        = sxgbe_platform_restore,
 217 };
 218 #else
 219 static const struct dev_pm_ops sxgbe_platform_pm_ops;
 220 #endif /* CONFIG_PM */
 221 
 222 static const struct of_device_id sxgbe_dt_ids[] = {
 223         { .compatible = "samsung,sxgbe-v2.0a"},
 224         { /* sentinel */ }
 225 };
 226 MODULE_DEVICE_TABLE(of, sxgbe_dt_ids);
 227 
 228 static struct platform_driver sxgbe_platform_driver = {
 229         .probe  = sxgbe_platform_probe,
 230         .remove = sxgbe_platform_remove,
 231         .driver = {
 232                 .name           = SXGBE_RESOURCE_NAME,
 233                 .pm             = &sxgbe_platform_pm_ops,
 234                 .of_match_table = of_match_ptr(sxgbe_dt_ids),
 235         },
 236 };
 237 
 238 int sxgbe_register_platform(void)
 239 {
 240         int err;
 241 
 242         err = platform_driver_register(&sxgbe_platform_driver);
 243         if (err)
 244                 pr_err("failed to register the platform driver\n");
 245 
 246         return err;
 247 }
 248 
 249 void sxgbe_unregister_platform(void)
 250 {
 251         platform_driver_unregister(&sxgbe_platform_driver);
 252 }

/* [<][>][^][v][top][bottom][index][help] */