root/drivers/net/ethernet/amd/xgbe/xgbe-platform.c

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

DEFINITIONS

This source file includes following definitions.
  1. xgbe_acpi_vdata
  2. xgbe_acpi_support
  3. xgbe_acpi_vdata
  4. xgbe_acpi_support
  5. xgbe_of_vdata
  6. xgbe_of_support
  7. xgbe_of_get_phy_pdev
  8. xgbe_of_vdata
  9. xgbe_of_support
  10. xgbe_of_get_phy_pdev
  11. xgbe_resource_count
  12. xgbe_get_phy_pdev
  13. xgbe_get_vdata
  14. xgbe_platform_probe
  15. xgbe_platform_remove
  16. xgbe_platform_suspend
  17. xgbe_platform_resume
  18. xgbe_platform_init
  19. xgbe_platform_exit

   1 /*
   2  * AMD 10Gb Ethernet driver
   3  *
   4  * This file is available to you under your choice of the following two
   5  * licenses:
   6  *
   7  * License 1: GPLv2
   8  *
   9  * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
  10  *
  11  * This file is free software; you may copy, redistribute and/or modify
  12  * it under the terms of the GNU General Public License as published by
  13  * the Free Software Foundation, either version 2 of the License, or (at
  14  * your option) any later version.
  15  *
  16  * This file is distributed in the hope that it will be useful, but
  17  * WITHOUT ANY WARRANTY; without even the implied warranty of
  18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19  * General Public License for more details.
  20  *
  21  * You should have received a copy of the GNU General Public License
  22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  23  *
  24  * This file incorporates work covered by the following copyright and
  25  * permission notice:
  26  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
  27  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  28  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
  29  *     and you.
  30  *
  31  *     The Software IS NOT an item of Licensed Software or Licensed Product
  32  *     under any End User Software License Agreement or Agreement for Licensed
  33  *     Product with Synopsys or any supplement thereto.  Permission is hereby
  34  *     granted, free of charge, to any person obtaining a copy of this software
  35  *     annotated with this license and the Software, to deal in the Software
  36  *     without restriction, including without limitation the rights to use,
  37  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  38  *     of the Software, and to permit persons to whom the Software is furnished
  39  *     to do so, subject to the following conditions:
  40  *
  41  *     The above copyright notice and this permission notice shall be included
  42  *     in all copies or substantial portions of the Software.
  43  *
  44  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
  45  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  46  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  47  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
  48  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  49  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  50  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  51  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  52  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  53  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  54  *     THE POSSIBILITY OF SUCH DAMAGE.
  55  *
  56  *
  57  * License 2: Modified BSD
  58  *
  59  * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
  60  * All rights reserved.
  61  *
  62  * Redistribution and use in source and binary forms, with or without
  63  * modification, are permitted provided that the following conditions are met:
  64  *     * Redistributions of source code must retain the above copyright
  65  *       notice, this list of conditions and the following disclaimer.
  66  *     * Redistributions in binary form must reproduce the above copyright
  67  *       notice, this list of conditions and the following disclaimer in the
  68  *       documentation and/or other materials provided with the distribution.
  69  *     * Neither the name of Advanced Micro Devices, Inc. nor the
  70  *       names of its contributors may be used to endorse or promote products
  71  *       derived from this software without specific prior written permission.
  72  *
  73  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  74  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  75  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  76  * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  77  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  79  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  80  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  81  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  82  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  83  *
  84  * This file incorporates work covered by the following copyright and
  85  * permission notice:
  86  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
  87  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  88  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
  89  *     and you.
  90  *
  91  *     The Software IS NOT an item of Licensed Software or Licensed Product
  92  *     under any End User Software License Agreement or Agreement for Licensed
  93  *     Product with Synopsys or any supplement thereto.  Permission is hereby
  94  *     granted, free of charge, to any person obtaining a copy of this software
  95  *     annotated with this license and the Software, to deal in the Software
  96  *     without restriction, including without limitation the rights to use,
  97  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  98  *     of the Software, and to permit persons to whom the Software is furnished
  99  *     to do so, subject to the following conditions:
 100  *
 101  *     The above copyright notice and this permission notice shall be included
 102  *     in all copies or substantial portions of the Software.
 103  *
 104  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
 105  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 106  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 107  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
 108  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 109  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 110  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 111  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 112  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 113  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 114  *     THE POSSIBILITY OF SUCH DAMAGE.
 115  */
 116 
 117 #include <linux/module.h>
 118 #include <linux/device.h>
 119 #include <linux/platform_device.h>
 120 #include <linux/spinlock.h>
 121 #include <linux/netdevice.h>
 122 #include <linux/etherdevice.h>
 123 #include <linux/io.h>
 124 #include <linux/of.h>
 125 #include <linux/of_net.h>
 126 #include <linux/of_address.h>
 127 #include <linux/of_platform.h>
 128 #include <linux/of_device.h>
 129 #include <linux/clk.h>
 130 #include <linux/property.h>
 131 #include <linux/acpi.h>
 132 #include <linux/mdio.h>
 133 
 134 #include "xgbe.h"
 135 #include "xgbe-common.h"
 136 
 137 #ifdef CONFIG_ACPI
 138 static const struct acpi_device_id xgbe_acpi_match[];
 139 
 140 static struct xgbe_version_data *xgbe_acpi_vdata(struct xgbe_prv_data *pdata)
 141 {
 142         const struct acpi_device_id *id;
 143 
 144         id = acpi_match_device(xgbe_acpi_match, pdata->dev);
 145 
 146         return id ? (struct xgbe_version_data *)id->driver_data : NULL;
 147 }
 148 
 149 static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
 150 {
 151         struct device *dev = pdata->dev;
 152         u32 property;
 153         int ret;
 154 
 155         /* Obtain the system clock setting */
 156         ret = device_property_read_u32(dev, XGBE_ACPI_DMA_FREQ, &property);
 157         if (ret) {
 158                 dev_err(dev, "unable to obtain %s property\n",
 159                         XGBE_ACPI_DMA_FREQ);
 160                 return ret;
 161         }
 162         pdata->sysclk_rate = property;
 163 
 164         /* Obtain the PTP clock setting */
 165         ret = device_property_read_u32(dev, XGBE_ACPI_PTP_FREQ, &property);
 166         if (ret) {
 167                 dev_err(dev, "unable to obtain %s property\n",
 168                         XGBE_ACPI_PTP_FREQ);
 169                 return ret;
 170         }
 171         pdata->ptpclk_rate = property;
 172 
 173         return 0;
 174 }
 175 #else   /* CONFIG_ACPI */
 176 static struct xgbe_version_data *xgbe_acpi_vdata(struct xgbe_prv_data *pdata)
 177 {
 178         return NULL;
 179 }
 180 
 181 static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
 182 {
 183         return -EINVAL;
 184 }
 185 #endif  /* CONFIG_ACPI */
 186 
 187 #ifdef CONFIG_OF
 188 static const struct of_device_id xgbe_of_match[];
 189 
 190 static struct xgbe_version_data *xgbe_of_vdata(struct xgbe_prv_data *pdata)
 191 {
 192         const struct of_device_id *id;
 193 
 194         id = of_match_device(xgbe_of_match, pdata->dev);
 195 
 196         return id ? (struct xgbe_version_data *)id->data : NULL;
 197 }
 198 
 199 static int xgbe_of_support(struct xgbe_prv_data *pdata)
 200 {
 201         struct device *dev = pdata->dev;
 202 
 203         /* Obtain the system clock setting */
 204         pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK);
 205         if (IS_ERR(pdata->sysclk)) {
 206                 dev_err(dev, "dma devm_clk_get failed\n");
 207                 return PTR_ERR(pdata->sysclk);
 208         }
 209         pdata->sysclk_rate = clk_get_rate(pdata->sysclk);
 210 
 211         /* Obtain the PTP clock setting */
 212         pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK);
 213         if (IS_ERR(pdata->ptpclk)) {
 214                 dev_err(dev, "ptp devm_clk_get failed\n");
 215                 return PTR_ERR(pdata->ptpclk);
 216         }
 217         pdata->ptpclk_rate = clk_get_rate(pdata->ptpclk);
 218 
 219         return 0;
 220 }
 221 
 222 static struct platform_device *xgbe_of_get_phy_pdev(struct xgbe_prv_data *pdata)
 223 {
 224         struct device *dev = pdata->dev;
 225         struct device_node *phy_node;
 226         struct platform_device *phy_pdev;
 227 
 228         phy_node = of_parse_phandle(dev->of_node, "phy-handle", 0);
 229         if (phy_node) {
 230                 /* Old style device tree:
 231                  *   The XGBE and PHY resources are separate
 232                  */
 233                 phy_pdev = of_find_device_by_node(phy_node);
 234                 of_node_put(phy_node);
 235         } else {
 236                 /* New style device tree:
 237                  *   The XGBE and PHY resources are grouped together with
 238                  *   the PHY resources listed last
 239                  */
 240                 get_device(dev);
 241                 phy_pdev = pdata->platdev;
 242         }
 243 
 244         return phy_pdev;
 245 }
 246 #else   /* CONFIG_OF */
 247 static struct xgbe_version_data *xgbe_of_vdata(struct xgbe_prv_data *pdata)
 248 {
 249         return NULL;
 250 }
 251 
 252 static int xgbe_of_support(struct xgbe_prv_data *pdata)
 253 {
 254         return -EINVAL;
 255 }
 256 
 257 static struct platform_device *xgbe_of_get_phy_pdev(struct xgbe_prv_data *pdata)
 258 {
 259         return NULL;
 260 }
 261 #endif  /* CONFIG_OF */
 262 
 263 static unsigned int xgbe_resource_count(struct platform_device *pdev,
 264                                         unsigned int type)
 265 {
 266         unsigned int count;
 267         int i;
 268 
 269         for (i = 0, count = 0; i < pdev->num_resources; i++) {
 270                 struct resource *res = &pdev->resource[i];
 271 
 272                 if (type == resource_type(res))
 273                         count++;
 274         }
 275 
 276         return count;
 277 }
 278 
 279 static struct platform_device *xgbe_get_phy_pdev(struct xgbe_prv_data *pdata)
 280 {
 281         struct platform_device *phy_pdev;
 282 
 283         if (pdata->use_acpi) {
 284                 get_device(pdata->dev);
 285                 phy_pdev = pdata->platdev;
 286         } else {
 287                 phy_pdev = xgbe_of_get_phy_pdev(pdata);
 288         }
 289 
 290         return phy_pdev;
 291 }
 292 
 293 static struct xgbe_version_data *xgbe_get_vdata(struct xgbe_prv_data *pdata)
 294 {
 295         return pdata->use_acpi ? xgbe_acpi_vdata(pdata)
 296                                : xgbe_of_vdata(pdata);
 297 }
 298 
 299 static int xgbe_platform_probe(struct platform_device *pdev)
 300 {
 301         struct xgbe_prv_data *pdata;
 302         struct device *dev = &pdev->dev;
 303         struct platform_device *phy_pdev;
 304         const char *phy_mode;
 305         unsigned int phy_memnum, phy_irqnum;
 306         unsigned int dma_irqnum, dma_irqend;
 307         enum dev_dma_attr attr;
 308         int ret;
 309 
 310         pdata = xgbe_alloc_pdata(dev);
 311         if (IS_ERR(pdata)) {
 312                 ret = PTR_ERR(pdata);
 313                 goto err_alloc;
 314         }
 315 
 316         pdata->platdev = pdev;
 317         pdata->adev = ACPI_COMPANION(dev);
 318         platform_set_drvdata(pdev, pdata);
 319 
 320         /* Check if we should use ACPI or DT */
 321         pdata->use_acpi = dev->of_node ? 0 : 1;
 322 
 323         /* Get the version data */
 324         pdata->vdata = xgbe_get_vdata(pdata);
 325 
 326         phy_pdev = xgbe_get_phy_pdev(pdata);
 327         if (!phy_pdev) {
 328                 dev_err(dev, "unable to obtain phy device\n");
 329                 ret = -EINVAL;
 330                 goto err_phydev;
 331         }
 332         pdata->phy_platdev = phy_pdev;
 333         pdata->phy_dev = &phy_pdev->dev;
 334 
 335         if (pdev == phy_pdev) {
 336                 /* New style device tree or ACPI:
 337                  *   The XGBE and PHY resources are grouped together with
 338                  *   the PHY resources listed last
 339                  */
 340                 phy_memnum = xgbe_resource_count(pdev, IORESOURCE_MEM) - 3;
 341                 phy_irqnum = xgbe_resource_count(pdev, IORESOURCE_IRQ) - 1;
 342                 dma_irqnum = 1;
 343                 dma_irqend = phy_irqnum;
 344         } else {
 345                 /* Old style device tree:
 346                  *   The XGBE and PHY resources are separate
 347                  */
 348                 phy_memnum = 0;
 349                 phy_irqnum = 0;
 350                 dma_irqnum = 1;
 351                 dma_irqend = xgbe_resource_count(pdev, IORESOURCE_IRQ);
 352         }
 353 
 354         /* Obtain the mmio areas for the device */
 355         pdata->xgmac_regs = devm_platform_ioremap_resource(pdev, 0);
 356         if (IS_ERR(pdata->xgmac_regs)) {
 357                 dev_err(dev, "xgmac ioremap failed\n");
 358                 ret = PTR_ERR(pdata->xgmac_regs);
 359                 goto err_io;
 360         }
 361         if (netif_msg_probe(pdata))
 362                 dev_dbg(dev, "xgmac_regs = %p\n", pdata->xgmac_regs);
 363 
 364         pdata->xpcs_regs = devm_platform_ioremap_resource(pdev, 1);
 365         if (IS_ERR(pdata->xpcs_regs)) {
 366                 dev_err(dev, "xpcs ioremap failed\n");
 367                 ret = PTR_ERR(pdata->xpcs_regs);
 368                 goto err_io;
 369         }
 370         if (netif_msg_probe(pdata))
 371                 dev_dbg(dev, "xpcs_regs  = %p\n", pdata->xpcs_regs);
 372 
 373         pdata->rxtx_regs = devm_platform_ioremap_resource(phy_pdev,
 374                                                           phy_memnum++);
 375         if (IS_ERR(pdata->rxtx_regs)) {
 376                 dev_err(dev, "rxtx ioremap failed\n");
 377                 ret = PTR_ERR(pdata->rxtx_regs);
 378                 goto err_io;
 379         }
 380         if (netif_msg_probe(pdata))
 381                 dev_dbg(dev, "rxtx_regs  = %p\n", pdata->rxtx_regs);
 382 
 383         pdata->sir0_regs = devm_platform_ioremap_resource(phy_pdev,
 384                                                           phy_memnum++);
 385         if (IS_ERR(pdata->sir0_regs)) {
 386                 dev_err(dev, "sir0 ioremap failed\n");
 387                 ret = PTR_ERR(pdata->sir0_regs);
 388                 goto err_io;
 389         }
 390         if (netif_msg_probe(pdata))
 391                 dev_dbg(dev, "sir0_regs  = %p\n", pdata->sir0_regs);
 392 
 393         pdata->sir1_regs = devm_platform_ioremap_resource(phy_pdev,
 394                                                           phy_memnum++);
 395         if (IS_ERR(pdata->sir1_regs)) {
 396                 dev_err(dev, "sir1 ioremap failed\n");
 397                 ret = PTR_ERR(pdata->sir1_regs);
 398                 goto err_io;
 399         }
 400         if (netif_msg_probe(pdata))
 401                 dev_dbg(dev, "sir1_regs  = %p\n", pdata->sir1_regs);
 402 
 403         /* Retrieve the MAC address */
 404         ret = device_property_read_u8_array(dev, XGBE_MAC_ADDR_PROPERTY,
 405                                             pdata->mac_addr,
 406                                             sizeof(pdata->mac_addr));
 407         if (ret || !is_valid_ether_addr(pdata->mac_addr)) {
 408                 dev_err(dev, "invalid %s property\n", XGBE_MAC_ADDR_PROPERTY);
 409                 if (!ret)
 410                         ret = -EINVAL;
 411                 goto err_io;
 412         }
 413 
 414         /* Retrieve the PHY mode - it must be "xgmii" */
 415         ret = device_property_read_string(dev, XGBE_PHY_MODE_PROPERTY,
 416                                           &phy_mode);
 417         if (ret || strcmp(phy_mode, phy_modes(PHY_INTERFACE_MODE_XGMII))) {
 418                 dev_err(dev, "invalid %s property\n", XGBE_PHY_MODE_PROPERTY);
 419                 if (!ret)
 420                         ret = -EINVAL;
 421                 goto err_io;
 422         }
 423         pdata->phy_mode = PHY_INTERFACE_MODE_XGMII;
 424 
 425         /* Check for per channel interrupt support */
 426         if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY)) {
 427                 pdata->per_channel_irq = 1;
 428                 pdata->channel_irq_mode = XGBE_IRQ_MODE_EDGE;
 429         }
 430 
 431         /* Obtain device settings unique to ACPI/OF */
 432         if (pdata->use_acpi)
 433                 ret = xgbe_acpi_support(pdata);
 434         else
 435                 ret = xgbe_of_support(pdata);
 436         if (ret)
 437                 goto err_io;
 438 
 439         /* Set the DMA coherency values */
 440         attr = device_get_dma_attr(dev);
 441         if (attr == DEV_DMA_NOT_SUPPORTED) {
 442                 dev_err(dev, "DMA is not supported");
 443                 ret = -ENODEV;
 444                 goto err_io;
 445         }
 446         pdata->coherent = (attr == DEV_DMA_COHERENT);
 447         if (pdata->coherent) {
 448                 pdata->arcr = XGBE_DMA_OS_ARCR;
 449                 pdata->awcr = XGBE_DMA_OS_AWCR;
 450         } else {
 451                 pdata->arcr = XGBE_DMA_SYS_ARCR;
 452                 pdata->awcr = XGBE_DMA_SYS_AWCR;
 453         }
 454 
 455         /* Set the maximum fifo amounts */
 456         pdata->tx_max_fifo_size = pdata->vdata->tx_max_fifo_size;
 457         pdata->rx_max_fifo_size = pdata->vdata->rx_max_fifo_size;
 458 
 459         /* Set the hardware channel and queue counts */
 460         xgbe_set_counts(pdata);
 461 
 462         /* Always have XGMAC and XPCS (auto-negotiation) interrupts */
 463         pdata->irq_count = 2;
 464 
 465         /* Get the device interrupt */
 466         ret = platform_get_irq(pdev, 0);
 467         if (ret < 0)
 468                 goto err_io;
 469         pdata->dev_irq = ret;
 470 
 471         /* Get the per channel DMA interrupts */
 472         if (pdata->per_channel_irq) {
 473                 unsigned int i, max = ARRAY_SIZE(pdata->channel_irq);
 474 
 475                 for (i = 0; (i < max) && (dma_irqnum < dma_irqend); i++) {
 476                         ret = platform_get_irq(pdata->platdev, dma_irqnum++);
 477                         if (ret < 0)
 478                                 goto err_io;
 479 
 480                         pdata->channel_irq[i] = ret;
 481                 }
 482 
 483                 pdata->channel_irq_count = max;
 484 
 485                 pdata->irq_count += max;
 486         }
 487 
 488         /* Get the auto-negotiation interrupt */
 489         ret = platform_get_irq(phy_pdev, phy_irqnum++);
 490         if (ret < 0)
 491                 goto err_io;
 492         pdata->an_irq = ret;
 493 
 494         /* Configure the netdev resource */
 495         ret = xgbe_config_netdev(pdata);
 496         if (ret)
 497                 goto err_io;
 498 
 499         netdev_notice(pdata->netdev, "net device enabled\n");
 500 
 501         return 0;
 502 
 503 err_io:
 504         platform_device_put(phy_pdev);
 505 
 506 err_phydev:
 507         xgbe_free_pdata(pdata);
 508 
 509 err_alloc:
 510         dev_notice(dev, "net device not enabled\n");
 511 
 512         return ret;
 513 }
 514 
 515 static int xgbe_platform_remove(struct platform_device *pdev)
 516 {
 517         struct xgbe_prv_data *pdata = platform_get_drvdata(pdev);
 518 
 519         xgbe_deconfig_netdev(pdata);
 520 
 521         platform_device_put(pdata->phy_platdev);
 522 
 523         xgbe_free_pdata(pdata);
 524 
 525         return 0;
 526 }
 527 
 528 #ifdef CONFIG_PM_SLEEP
 529 static int xgbe_platform_suspend(struct device *dev)
 530 {
 531         struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
 532         struct net_device *netdev = pdata->netdev;
 533         int ret = 0;
 534 
 535         DBGPR("-->xgbe_suspend\n");
 536 
 537         if (netif_running(netdev))
 538                 ret = xgbe_powerdown(netdev, XGMAC_DRIVER_CONTEXT);
 539 
 540         pdata->lpm_ctrl = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
 541         pdata->lpm_ctrl |= MDIO_CTRL1_LPOWER;
 542         XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
 543 
 544         DBGPR("<--xgbe_suspend\n");
 545 
 546         return ret;
 547 }
 548 
 549 static int xgbe_platform_resume(struct device *dev)
 550 {
 551         struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
 552         struct net_device *netdev = pdata->netdev;
 553         int ret = 0;
 554 
 555         DBGPR("-->xgbe_resume\n");
 556 
 557         pdata->lpm_ctrl &= ~MDIO_CTRL1_LPOWER;
 558         XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
 559 
 560         if (netif_running(netdev)) {
 561                 ret = xgbe_powerup(netdev, XGMAC_DRIVER_CONTEXT);
 562 
 563                 /* Schedule a restart in case the link or phy state changed
 564                  * while we were powered down.
 565                  */
 566                 schedule_work(&pdata->restart_work);
 567         }
 568 
 569         DBGPR("<--xgbe_resume\n");
 570 
 571         return ret;
 572 }
 573 #endif /* CONFIG_PM_SLEEP */
 574 
 575 static const struct xgbe_version_data xgbe_v1 = {
 576         .init_function_ptrs_phy_impl    = xgbe_init_function_ptrs_phy_v1,
 577         .xpcs_access                    = XGBE_XPCS_ACCESS_V1,
 578         .tx_max_fifo_size               = 81920,
 579         .rx_max_fifo_size               = 81920,
 580         .tx_tstamp_workaround           = 1,
 581 };
 582 
 583 #ifdef CONFIG_ACPI
 584 static const struct acpi_device_id xgbe_acpi_match[] = {
 585         { .id = "AMDI8001",
 586           .driver_data = (kernel_ulong_t)&xgbe_v1 },
 587         {},
 588 };
 589 
 590 MODULE_DEVICE_TABLE(acpi, xgbe_acpi_match);
 591 #endif
 592 
 593 #ifdef CONFIG_OF
 594 static const struct of_device_id xgbe_of_match[] = {
 595         { .compatible = "amd,xgbe-seattle-v1a",
 596           .data = &xgbe_v1 },
 597         {},
 598 };
 599 
 600 MODULE_DEVICE_TABLE(of, xgbe_of_match);
 601 #endif
 602 
 603 static SIMPLE_DEV_PM_OPS(xgbe_platform_pm_ops,
 604                          xgbe_platform_suspend, xgbe_platform_resume);
 605 
 606 static struct platform_driver xgbe_driver = {
 607         .driver = {
 608                 .name = XGBE_DRV_NAME,
 609 #ifdef CONFIG_ACPI
 610                 .acpi_match_table = xgbe_acpi_match,
 611 #endif
 612 #ifdef CONFIG_OF
 613                 .of_match_table = xgbe_of_match,
 614 #endif
 615                 .pm = &xgbe_platform_pm_ops,
 616         },
 617         .probe = xgbe_platform_probe,
 618         .remove = xgbe_platform_remove,
 619 };
 620 
 621 int xgbe_platform_init(void)
 622 {
 623         return platform_driver_register(&xgbe_driver);
 624 }
 625 
 626 void xgbe_platform_exit(void)
 627 {
 628         platform_driver_unregister(&xgbe_driver);
 629 }

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