Message ID | 1274096214.21352.735.camel@pasglop |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
> The problem is that the fixups are called -after- the config_init() > callback of the PHY driver. However, the marvell m88e1118 PHY driver > will unconditionally reset the LEDs setting. Haven't checked, just an idea: Is it possible to change the init of the driver to use Read-Modify-Write and thus keep your settings?
On Mon, 2010-05-17 at 14:00 +0200, Wolfram Sang wrote: > > The problem is that the fixups are called -after- the config_init() > > callback of the PHY driver. However, the marvell m88e1118 PHY driver > > will unconditionally reset the LEDs setting. > > Haven't checked, just an idea: Is it possible to change the init of > the driver to use Read-Modify-Write and thus keep your settings? Well, the driver just unconditionally blasts the whole register and the value I want to put there is also a "raw" value of the whole register based on what the vendor code puts in there (in their old 2.6.12 based port). So with only that at hand and no documentation for the actual PHY chip, I don't see a simple solution here. Cheers, Ben. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 64be466..48436e6 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -353,10 +353,9 @@ int phy_mii_ioctl(struct phy_device *phydev, phy_write(phydev, mii_data->reg_num, val); if (mii_data->reg_num == MII_BMCR && - val & BMCR_RESET && - phydev->drv->config_init) { - phy_scan_fixups(phydev); - phydev->drv->config_init(phydev); + val & BMCR_RESET && phydev->drv->config_init) { + if (phy_scan_fixups(phydev) != PHY_FIXUP_SKIP_INIT) + phydev->drv->config_init(phydev); } break; diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index db17945..44ab890 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -126,6 +126,7 @@ static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup) int phy_scan_fixups(struct phy_device *phydev) { struct phy_fixup *fixup; + int rc = 0; mutex_lock(&phy_fixup_lock); list_for_each_entry(fixup, &phy_fixup_list, list) { @@ -138,11 +139,13 @@ int phy_scan_fixups(struct phy_device *phydev) mutex_unlock(&phy_fixup_lock); return err; } + if (err == PHY_FIXUP_SKIP_INIT) + rc = err; } } mutex_unlock(&phy_fixup_lock); - return 0; + return rc; } EXPORT_SYMBOL(phy_scan_fixups); @@ -405,6 +408,8 @@ int phy_init_hw(struct phy_device *phydev) ret = phy_scan_fixups(phydev); if (ret < 0) return ret; + if (ret == PHY_FIXUP_SKIP_INIT) + return 0; return phydev->drv->config_init(phydev); } diff --git a/include/linux/phy.h b/include/linux/phy.h index 14d7fdf..5e2b026 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -413,6 +413,12 @@ struct phy_fixup { int (*run)(struct phy_device *phydev); }; +/* The fixup can return this to skip the PHY driver init routine + * (ie. the fixup effectively replaces the init routine) + */ +#define PHY_FIXUP_SKIP_INIT 1 + + /** * phy_read - Convenience function for reading a given PHY register * @phydev: the phy_device struct