cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sxgbe_platform.c (5986B)


      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
     27static int sxgbe_probe_config_dt(struct platform_device *pdev,
     28				 struct sxgbe_plat_data *plat)
     29{
     30	struct device_node *np = pdev->dev.of_node;
     31	struct sxgbe_dma_cfg *dma_cfg;
     32	int err;
     33
     34	if (!np)
     35		return -ENODEV;
     36
     37	err = of_get_phy_mode(np, &plat->interface);
     38	if (err && err != -ENODEV)
     39		return err;
     40
     41	plat->bus_id = of_alias_get_id(np, "ethernet");
     42	if (plat->bus_id < 0)
     43		plat->bus_id = 0;
     44
     45	plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
     46					   sizeof(*plat->mdio_bus_data),
     47					   GFP_KERNEL);
     48	if (!plat->mdio_bus_data)
     49		return -ENOMEM;
     50
     51	dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL);
     52	if (!dma_cfg)
     53		return -ENOMEM;
     54
     55	plat->dma_cfg = dma_cfg;
     56	of_property_read_u32(np, "samsung,pbl", &dma_cfg->pbl);
     57	if (of_property_read_u32(np, "samsung,burst-map", &dma_cfg->burst_map) == 0)
     58		dma_cfg->fixed_burst = true;
     59
     60	return 0;
     61}
     62#else
     63static int sxgbe_probe_config_dt(struct platform_device *pdev,
     64				 struct sxgbe_plat_data *plat)
     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 */
     77static 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	struct net_device *ndev = platform_get_drvdata(pdev);
     86	struct device_node *node = dev->of_node;
     87
     88	/* Get memory resource */
     89	addr = devm_platform_ioremap_resource(pdev, 0);
     90	if (IS_ERR(addr))
     91		return PTR_ERR(addr);
     92
     93	if (pdev->dev.of_node) {
     94		plat_dat = devm_kzalloc(&pdev->dev,
     95					sizeof(struct sxgbe_plat_data),
     96					GFP_KERNEL);
     97		if (!plat_dat)
     98			return  -ENOMEM;
     99
    100		ret = sxgbe_probe_config_dt(pdev, plat_dat);
    101		if (ret) {
    102			pr_err("%s: main dt probe failed\n", __func__);
    103			return ret;
    104		}
    105	}
    106
    107	priv = sxgbe_drv_probe(&(pdev->dev), plat_dat, addr);
    108	if (!priv) {
    109		pr_err("%s: main driver probe failed\n", __func__);
    110		goto err_out;
    111	}
    112
    113	/* Get the SXGBE common INT information */
    114	priv->irq  = irq_of_parse_and_map(node, 0);
    115	if (priv->irq <= 0) {
    116		dev_err(dev, "sxgbe common irq parsing failed\n");
    117		goto err_drv_remove;
    118	}
    119
    120	/* Get MAC address if available (DT) */
    121	of_get_ethdev_address(node, priv->dev);
    122
    123	/* Get the TX/RX IRQ numbers */
    124	for (i = 0, chan = 1; i < SXGBE_TX_QUEUES; i++) {
    125		priv->txq[i]->irq_no = irq_of_parse_and_map(node, chan++);
    126		if (priv->txq[i]->irq_no <= 0) {
    127			dev_err(dev, "sxgbe tx irq parsing failed\n");
    128			goto err_tx_irq_unmap;
    129		}
    130	}
    131
    132	for (i = 0; i < SXGBE_RX_QUEUES; i++) {
    133		priv->rxq[i]->irq_no = irq_of_parse_and_map(node, chan++);
    134		if (priv->rxq[i]->irq_no <= 0) {
    135			dev_err(dev, "sxgbe rx irq parsing failed\n");
    136			goto err_rx_irq_unmap;
    137		}
    138	}
    139
    140	priv->lpi_irq = irq_of_parse_and_map(node, chan);
    141	if (priv->lpi_irq <= 0) {
    142		dev_err(dev, "sxgbe lpi irq parsing failed\n");
    143		goto err_rx_irq_unmap;
    144	}
    145
    146	platform_set_drvdata(pdev, priv->dev);
    147
    148	pr_debug("platform driver registration completed\n");
    149
    150	return 0;
    151
    152err_rx_irq_unmap:
    153	while (i--)
    154		irq_dispose_mapping(priv->rxq[i]->irq_no);
    155	i = SXGBE_TX_QUEUES;
    156err_tx_irq_unmap:
    157	while (i--)
    158		irq_dispose_mapping(priv->txq[i]->irq_no);
    159	irq_dispose_mapping(priv->irq);
    160err_drv_remove:
    161	sxgbe_drv_remove(ndev);
    162err_out:
    163	return -ENODEV;
    164}
    165
    166/**
    167 * sxgbe_platform_remove
    168 * @pdev: platform device pointer
    169 * Description: this function calls the main to free the net resources
    170 * and calls the platforms hook and release the resources (e.g. mem).
    171 */
    172static int sxgbe_platform_remove(struct platform_device *pdev)
    173{
    174	struct net_device *ndev = platform_get_drvdata(pdev);
    175	int ret = sxgbe_drv_remove(ndev);
    176
    177	return ret;
    178}
    179
    180#ifdef CONFIG_PM
    181static int sxgbe_platform_suspend(struct device *dev)
    182{
    183	struct net_device *ndev = dev_get_drvdata(dev);
    184
    185	return sxgbe_suspend(ndev);
    186}
    187
    188static int sxgbe_platform_resume(struct device *dev)
    189{
    190	struct net_device *ndev = dev_get_drvdata(dev);
    191
    192	return sxgbe_resume(ndev);
    193}
    194
    195static int sxgbe_platform_freeze(struct device *dev)
    196{
    197	struct net_device *ndev = dev_get_drvdata(dev);
    198
    199	return sxgbe_freeze(ndev);
    200}
    201
    202static int sxgbe_platform_restore(struct device *dev)
    203{
    204	struct net_device *ndev = dev_get_drvdata(dev);
    205
    206	return sxgbe_restore(ndev);
    207}
    208
    209static const struct dev_pm_ops sxgbe_platform_pm_ops = {
    210	.suspend	= sxgbe_platform_suspend,
    211	.resume		= sxgbe_platform_resume,
    212	.freeze		= sxgbe_platform_freeze,
    213	.thaw		= sxgbe_platform_restore,
    214	.restore	= sxgbe_platform_restore,
    215};
    216#else
    217static const struct dev_pm_ops sxgbe_platform_pm_ops;
    218#endif /* CONFIG_PM */
    219
    220static const struct of_device_id sxgbe_dt_ids[] = {
    221	{ .compatible = "samsung,sxgbe-v2.0a"},
    222	{ /* sentinel */ }
    223};
    224MODULE_DEVICE_TABLE(of, sxgbe_dt_ids);
    225
    226static struct platform_driver sxgbe_platform_driver = {
    227	.probe	= sxgbe_platform_probe,
    228	.remove	= sxgbe_platform_remove,
    229	.driver	= {
    230		.name		= SXGBE_RESOURCE_NAME,
    231		.pm		= &sxgbe_platform_pm_ops,
    232		.of_match_table	= of_match_ptr(sxgbe_dt_ids),
    233	},
    234};
    235
    236int sxgbe_register_platform(void)
    237{
    238	int err;
    239
    240	err = platform_driver_register(&sxgbe_platform_driver);
    241	if (err)
    242		pr_err("failed to register the platform driver\n");
    243
    244	return err;
    245}
    246
    247void sxgbe_unregister_platform(void)
    248{
    249	platform_driver_unregister(&sxgbe_platform_driver);
    250}