LCOV - code coverage report
Current view: top level - drivers/net/phy - mdio_device.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 0 71 0.0 %
Date: 2020-09-30 20:25:40 Functions: 0 11 0.0 %
Branches: 0 30 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0+
       2                 :            : /* Framework for MDIO devices, other than PHYs.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
       5                 :            :  */
       6                 :            : 
       7                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
       8                 :            : 
       9                 :            : #include <linux/errno.h>
      10                 :            : #include <linux/gpio.h>
      11                 :            : #include <linux/gpio/consumer.h>
      12                 :            : #include <linux/init.h>
      13                 :            : #include <linux/interrupt.h>
      14                 :            : #include <linux/kernel.h>
      15                 :            : #include <linux/mdio.h>
      16                 :            : #include <linux/mii.h>
      17                 :            : #include <linux/module.h>
      18                 :            : #include <linux/phy.h>
      19                 :            : #include <linux/reset.h>
      20                 :            : #include <linux/slab.h>
      21                 :            : #include <linux/string.h>
      22                 :            : #include <linux/unistd.h>
      23                 :            : #include <linux/delay.h>
      24                 :            : 
      25                 :          0 : void mdio_device_free(struct mdio_device *mdiodev)
      26                 :            : {
      27                 :          0 :         put_device(&mdiodev->dev);
      28                 :          0 : }
      29                 :            : EXPORT_SYMBOL(mdio_device_free);
      30                 :            : 
      31                 :          0 : static void mdio_device_release(struct device *dev)
      32                 :            : {
      33                 :          0 :         kfree(to_mdio_device(dev));
      34                 :          0 : }
      35                 :            : 
      36                 :          0 : int mdio_device_bus_match(struct device *dev, struct device_driver *drv)
      37                 :            : {
      38                 :            :         struct mdio_device *mdiodev = to_mdio_device(dev);
      39                 :            :         struct mdio_driver *mdiodrv = to_mdio_driver(drv);
      40                 :            : 
      41         [ #  # ]:          0 :         if (mdiodrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY)
      42                 :            :                 return 0;
      43                 :            : 
      44                 :          0 :         return strcmp(mdiodev->modalias, drv->name) == 0;
      45                 :            : }
      46                 :            : 
      47                 :          0 : struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr)
      48                 :            : {
      49                 :            :         struct mdio_device *mdiodev;
      50                 :            : 
      51                 :            :         /* We allocate the device, and initialize the default values */
      52                 :          0 :         mdiodev = kzalloc(sizeof(*mdiodev), GFP_KERNEL);
      53         [ #  # ]:          0 :         if (!mdiodev)
      54                 :            :                 return ERR_PTR(-ENOMEM);
      55                 :            : 
      56                 :          0 :         mdiodev->dev.release = mdio_device_release;
      57                 :          0 :         mdiodev->dev.parent = &bus->dev;
      58                 :          0 :         mdiodev->dev.bus = &mdio_bus_type;
      59                 :          0 :         mdiodev->device_free = mdio_device_free;
      60                 :          0 :         mdiodev->device_remove = mdio_device_remove;
      61                 :          0 :         mdiodev->bus = bus;
      62                 :          0 :         mdiodev->addr = addr;
      63                 :            : 
      64                 :          0 :         dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr);
      65                 :            : 
      66                 :          0 :         device_initialize(&mdiodev->dev);
      67                 :            : 
      68                 :          0 :         return mdiodev;
      69                 :            : }
      70                 :            : EXPORT_SYMBOL(mdio_device_create);
      71                 :            : 
      72                 :            : /**
      73                 :            :  * mdio_device_register - Register the mdio device on the MDIO bus
      74                 :            :  * @mdiodev: mdio_device structure to be added to the MDIO bus
      75                 :            :  */
      76                 :          0 : int mdio_device_register(struct mdio_device *mdiodev)
      77                 :            : {
      78                 :            :         int err;
      79                 :            : 
      80                 :            :         dev_dbg(&mdiodev->dev, "mdio_device_register\n");
      81                 :            : 
      82                 :          0 :         err = mdiobus_register_device(mdiodev);
      83         [ #  # ]:          0 :         if (err)
      84                 :            :                 return err;
      85                 :            : 
      86                 :          0 :         err = device_add(&mdiodev->dev);
      87         [ #  # ]:          0 :         if (err) {
      88                 :          0 :                 pr_err("MDIO %d failed to add\n", mdiodev->addr);
      89                 :            :                 goto out;
      90                 :            :         }
      91                 :            : 
      92                 :            :         return 0;
      93                 :            : 
      94                 :            :  out:
      95                 :          0 :         mdiobus_unregister_device(mdiodev);
      96                 :          0 :         return err;
      97                 :            : }
      98                 :            : EXPORT_SYMBOL(mdio_device_register);
      99                 :            : 
     100                 :            : /**
     101                 :            :  * mdio_device_remove - Remove a previously registered mdio device from the
     102                 :            :  *                      MDIO bus
     103                 :            :  * @mdiodev: mdio_device structure to remove
     104                 :            :  *
     105                 :            :  * This doesn't free the mdio_device itself, it merely reverses the effects
     106                 :            :  * of mdio_device_register(). Use mdio_device_free() to free the device
     107                 :            :  * after calling this function.
     108                 :            :  */
     109                 :          0 : void mdio_device_remove(struct mdio_device *mdiodev)
     110                 :            : {
     111                 :          0 :         device_del(&mdiodev->dev);
     112                 :          0 :         mdiobus_unregister_device(mdiodev);
     113                 :          0 : }
     114                 :            : EXPORT_SYMBOL(mdio_device_remove);
     115                 :            : 
     116                 :          0 : void mdio_device_reset(struct mdio_device *mdiodev, int value)
     117                 :            : {
     118                 :            :         unsigned int d;
     119                 :            : 
     120   [ #  #  #  # ]:          0 :         if (!mdiodev->reset_gpio && !mdiodev->reset_ctrl)
     121                 :          0 :                 return;
     122                 :            : 
     123         [ #  # ]:          0 :         if (mdiodev->reset_gpio)
     124                 :          0 :                 gpiod_set_value_cansleep(mdiodev->reset_gpio, value);
     125                 :            : 
     126         [ #  # ]:          0 :         if (mdiodev->reset_ctrl) {
     127         [ #  # ]:          0 :                 if (value)
     128                 :          0 :                         reset_control_assert(mdiodev->reset_ctrl);
     129                 :            :                 else
     130                 :          0 :                         reset_control_deassert(mdiodev->reset_ctrl);
     131                 :            :         }
     132                 :            : 
     133         [ #  # ]:          0 :         d = value ? mdiodev->reset_assert_delay : mdiodev->reset_deassert_delay;
     134         [ #  # ]:          0 :         if (d)
     135                 :          0 :                 usleep_range(d, d + max_t(unsigned int, d / 10, 100));
     136                 :            : }
     137                 :            : EXPORT_SYMBOL(mdio_device_reset);
     138                 :            : 
     139                 :            : /**
     140                 :            :  * mdio_probe - probe an MDIO device
     141                 :            :  * @dev: device to probe
     142                 :            :  *
     143                 :            :  * Description: Take care of setting up the mdio_device structure
     144                 :            :  * and calling the driver to probe the device.
     145                 :            :  */
     146                 :          0 : static int mdio_probe(struct device *dev)
     147                 :            : {
     148                 :            :         struct mdio_device *mdiodev = to_mdio_device(dev);
     149                 :          0 :         struct device_driver *drv = mdiodev->dev.driver;
     150                 :            :         struct mdio_driver *mdiodrv = to_mdio_driver(drv);
     151                 :            :         int err = 0;
     152                 :            : 
     153         [ #  # ]:          0 :         if (mdiodrv->probe) {
     154                 :            :                 /* Deassert the reset signal */
     155                 :          0 :                 mdio_device_reset(mdiodev, 0);
     156                 :            : 
     157                 :          0 :                 err = mdiodrv->probe(mdiodev);
     158         [ #  # ]:          0 :                 if (err) {
     159                 :            :                         /* Assert the reset signal */
     160                 :          0 :                         mdio_device_reset(mdiodev, 1);
     161                 :            :                 }
     162                 :            :         }
     163                 :            : 
     164                 :          0 :         return err;
     165                 :            : }
     166                 :            : 
     167                 :          0 : static int mdio_remove(struct device *dev)
     168                 :            : {
     169                 :            :         struct mdio_device *mdiodev = to_mdio_device(dev);
     170                 :          0 :         struct device_driver *drv = mdiodev->dev.driver;
     171                 :            :         struct mdio_driver *mdiodrv = to_mdio_driver(drv);
     172                 :            : 
     173         [ #  # ]:          0 :         if (mdiodrv->remove) {
     174                 :          0 :                 mdiodrv->remove(mdiodev);
     175                 :            : 
     176                 :            :                 /* Assert the reset signal */
     177                 :          0 :                 mdio_device_reset(mdiodev, 1);
     178                 :            :         }
     179                 :            : 
     180                 :          0 :         return 0;
     181                 :            : }
     182                 :            : 
     183                 :            : /**
     184                 :            :  * mdio_driver_register - register an mdio_driver with the MDIO layer
     185                 :            :  * @new_driver: new mdio_driver to register
     186                 :            :  */
     187                 :          0 : int mdio_driver_register(struct mdio_driver *drv)
     188                 :            : {
     189                 :            :         struct mdio_driver_common *mdiodrv = &drv->mdiodrv;
     190                 :            :         int retval;
     191                 :            : 
     192                 :            :         pr_debug("mdio_driver_register: %s\n", mdiodrv->driver.name);
     193                 :            : 
     194                 :          0 :         mdiodrv->driver.bus = &mdio_bus_type;
     195                 :          0 :         mdiodrv->driver.probe = mdio_probe;
     196                 :          0 :         mdiodrv->driver.remove = mdio_remove;
     197                 :            : 
     198                 :          0 :         retval = driver_register(&mdiodrv->driver);
     199         [ #  # ]:          0 :         if (retval) {
     200                 :          0 :                 pr_err("%s: Error %d in registering driver\n",
     201                 :            :                        mdiodrv->driver.name, retval);
     202                 :            : 
     203                 :          0 :                 return retval;
     204                 :            :         }
     205                 :            : 
     206                 :            :         return 0;
     207                 :            : }
     208                 :            : EXPORT_SYMBOL(mdio_driver_register);
     209                 :            : 
     210                 :          0 : void mdio_driver_unregister(struct mdio_driver *drv)
     211                 :            : {
     212                 :            :         struct mdio_driver_common *mdiodrv = &drv->mdiodrv;
     213                 :            : 
     214                 :          0 :         driver_unregister(&mdiodrv->driver);
     215                 :          0 : }
     216                 :            : EXPORT_SYMBOL(mdio_driver_unregister);

Generated by: LCOV version 1.14