721-phy-mdio-bitbang-prevent-rescheduling-during-command.patch 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. From 66e584435ac0de6e0abeb6d7166fe4fe25d6bb73 Mon Sep 17 00:00:00 2001
  2. From: Jonas Gorski <[email protected]>
  3. Date: Tue, 16 Jun 2015 13:15:08 +0200
  4. Subject: [PATCH] phy/mdio-bitbang: prevent rescheduling during command
  5. It seems some phys have some maximum timings for accessing the MDIO line,
  6. resulting in bit errors under cpu stress. Prevent this from happening by
  7. disabling interrupts when sending commands.
  8. Signed-off-by: Jonas Gorski <[email protected]>
  9. ---
  10. drivers/net/mdio/mdio-bitbang.c | 9 +++++++++
  11. 1 file changed, 9 insertions(+)
  12. --- a/drivers/net/mdio/mdio-bitbang.c
  13. +++ b/drivers/net/mdio/mdio-bitbang.c
  14. @@ -14,6 +14,7 @@
  15. * Vitaly Bordug <[email protected]>
  16. */
  17. +#include <linux/irqflags.h>
  18. #include <linux/delay.h>
  19. #include <linux/mdio-bitbang.h>
  20. #include <linux/module.h>
  21. @@ -153,7 +154,9 @@ int mdiobb_read(struct mii_bus *bus, int
  22. {
  23. struct mdiobb_ctrl *ctrl = bus->priv;
  24. int ret;
  25. + unsigned long flags;
  26. + local_irq_save(flags);
  27. if (reg & MII_ADDR_C45) {
  28. reg = mdiobb_cmd_addr(ctrl, phy, reg);
  29. mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
  30. @@ -166,6 +169,7 @@ int mdiobb_read(struct mii_bus *bus, int
  31. ret = mdiobb_get_num(ctrl, 16);
  32. mdiobb_get_bit(ctrl);
  33. + local_irq_restore(flags);
  34. return ret;
  35. }
  36. EXPORT_SYMBOL(mdiobb_read);
  37. @@ -173,7 +177,9 @@ EXPORT_SYMBOL(mdiobb_read);
  38. int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
  39. {
  40. struct mdiobb_ctrl *ctrl = bus->priv;
  41. + unsigned long flags;
  42. + local_irq_save(flags);
  43. if (reg & MII_ADDR_C45) {
  44. reg = mdiobb_cmd_addr(ctrl, phy, reg);
  45. mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
  46. @@ -188,6 +194,8 @@ int mdiobb_write(struct mii_bus *bus, in
  47. ctrl->ops->set_mdio_dir(ctrl, 0);
  48. mdiobb_get_bit(ctrl);
  49. + local_irq_restore(flags);
  50. +
  51. return 0;
  52. }
  53. EXPORT_SYMBOL(mdiobb_write);