2

Question:

I'm trying to find a way to retrieve the dev object for an mdio_bus that has been added to the device tree. I'm sure I'm going to be rapidly applying my palm to my forehead when I get past this, but for the life of me, I can't find the answer anywhere. I've seen how to find objects on the bus itself using bus_find_device_by_name(), but I can't seem to find how to get the bus itself.

Background:

We are providing network access to our host using a Micrel KSZ8863 Ethernet switch attached to the MACB on an at919g20. Rather than using the fixed PHY option, I've spoofed MDIO address 0 to be a "fake" PHY representing the fixed MII link to the switch. I'm writing a driver for the switch to receive its interrupts and monitor the outward facing PHYs and control the link state of the "fake" PHY to the host. In order to configure the switch beyond basic MIIM configuration, you need to use SMI on the MDIO bus to access the full array of registers in the switch. Through further tweaking of the mii_read/write functions in the MACB, adding a header to the reg address, I believe I can use the MACB's MDIO/MII controller to do the right thing for SMI requests. Because the bus no longer gets addressed by PHY:REG, I need to be able to issue raw read/write commands straight to the bus from the switch driver. And that brings me back to my question: How do I request the dev object of the mdio_bus from the device tree by name?

Thanks, Brian

Adrian Panasiuk
  • 7,249
  • 5
  • 33
  • 54
Brian K
  • 41
  • 4
  • 2
    This seems to be on topic and complete enough to answer - for someone sufficiently familiar with the subject matter. Those who are not familiar should please refrain from close voting on the basis of their unfamiliarity. – Chris Stratton May 21 '13 at 15:09

1 Answers1

2

After hunting around, fruitlessly, for a way to retrieve a device pointer to an mii_bus object, I ended up coming up with the following solution. I'm not sure its the best way to go about it, but it seems pretty clean. I basically ended up adding a helper function to mdio_bus.c that allows another driver to search for a bus by name using class_find_device(). I'm sure there is better way to do this, that doesn't involve adding onto the bus' driver, but it doesn't seem like the worst way either.

-Brian

Here are the functions I added to mdio_bus.c:

/**
 * mdiobus_match_name - compares specified string to the device name 
 * @dev: device object to be examined
 * @data: pointer to string to compare device name to
 *
 * Description: matching function used in call to class_find_device() to find
 *              a device with the specified name
 */
static int mdiobus_match_name( struct device * dev, void * data )
{
    const char * name = data;

    return sysfs_streq( name, dev_name( dev ) );
}

/**
 * mdiobus_find_by_name - Convenience function for retrieving an mii_bus pointer
 *                        by name
 * @name: name of the bus being searched for
 */
struct mii_bus * mdiobus_find_by_name( char * name )
{
    struct device * dev;

    /* search devices registered for with the mdio_bus_class using the device
       name as the matching criteria */
    dev = class_find_device( &mdio_bus_class,
                             NULL,
                             (void *)name,
                             mdiobus_match_name );

    /* return the mii_bus pointer or NULL if none was found */
    return dev ? container_of( dev, struct mii_bus, dev ) : NULL;
}
EXPORT_SYMBOL( mdiobus_find_by_name );
Brian K
  • 41
  • 4
  • @Brian_Karcz You should post this to one of the Linux kernel lists and see if the maintainer of this subsystem can pick it up. – Peter L. May 31 '13 at 20:28
  • @Peter_L I thought about it. I'm going to let it stew for a bit in case someone with more Linux kernel experience than me chimes in with a better way. I also have to figure out where such lists exist and how to go about posting to them. – Brian K May 31 '13 at 20:38
  • I should also note that I added the declaration of the new function to phy.h with the rest of the exported mdiobus_* functions. – Brian K May 31 '13 at 20:42
  • @Brian_K The archive for the list is https://lkml.org/ . You can subscribe at http://vger.kernel.org/vger-lists.html There are several subsystems with their own lists. The people on these lists are very technical and are likely to help with this, or at least point you in the right direction. – Peter L. May 31 '13 at 21:22
  • Brian - I want to thank you for posting your problem and the eventual solution. I too hit upon this exact same issue and found your post on Stack Exchange through Google. It seems to work like a charm! Thanks -- Andy – Andy Apr 25 '16 at 19:54