aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-06-05 08:50:18 -0400
committerDavid S. Miller <davem@davemloft.net>2018-06-05 08:50:18 -0400
commit7a723099be325f6c5edd25c775b672a056907f75 (patch)
tree9a3188f34ac7db2ee7c749a80fc6beb40060950c
parent7d840a606515b04dfb4f13d1abb86dd59163799c (diff)
parent9107c05e2e55c1c7abd02ab38f7694e0da08b643 (diff)
Merge branch 'net-phy-improve-PM-handling-of-PHY-MDIO'
Heiner Kallweit says: ==================== net: phy: improve PM handling of PHY/MDIO Current implementation of MDIO bus PM ops doesn't actually implement bus-specific PM ops but just calls PM ops defined on a device level what doesn't seem to be fully in line with the core PM model. When looking e.g. at __device_suspend() the PM core looks for PM ops of a device in a specific order: 1. device PM domain 2. device type 3. device class 4. device bus I think it has good reason that there's no PM ops on device level. The situation can be improved by modeling PHY's as device type of a MDIO device. If for some other type of MDIO device PM ops are needed, it could be modeled as struct device_type as well. ==================== Tested-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/mdio_bus.c48
-rw-r--r--drivers/net/phy/phy_device.c96
-rw-r--r--include/linux/mdio.h1
3 files changed, 50 insertions, 95 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 24b5511222c8..98f4b1f706df 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -717,58 +717,10 @@ static int mdio_uevent(struct device *dev, struct kobj_uevent_env *env)
717 return 0; 717 return 0;
718} 718}
719 719
720#ifdef CONFIG_PM
721static int mdio_bus_suspend(struct device *dev)
722{
723 struct mdio_device *mdio = to_mdio_device(dev);
724
725 if (mdio->pm_ops && mdio->pm_ops->suspend)
726 return mdio->pm_ops->suspend(dev);
727
728 return 0;
729}
730
731static int mdio_bus_resume(struct device *dev)
732{
733 struct mdio_device *mdio = to_mdio_device(dev);
734
735 if (mdio->pm_ops && mdio->pm_ops->resume)
736 return mdio->pm_ops->resume(dev);
737
738 return 0;
739}
740
741static int mdio_bus_restore(struct device *dev)
742{
743 struct mdio_device *mdio = to_mdio_device(dev);
744
745 if (mdio->pm_ops && mdio->pm_ops->restore)
746 return mdio->pm_ops->restore(dev);
747
748 return 0;
749}
750
751static const struct dev_pm_ops mdio_bus_pm_ops = {
752 .suspend = mdio_bus_suspend,
753 .resume = mdio_bus_resume,
754 .freeze = mdio_bus_suspend,
755 .thaw = mdio_bus_resume,
756 .restore = mdio_bus_restore,
757};
758
759#define MDIO_BUS_PM_OPS (&mdio_bus_pm_ops)
760
761#else
762
763#define MDIO_BUS_PM_OPS NULL
764
765#endif /* CONFIG_PM */
766
767struct bus_type mdio_bus_type = { 720struct bus_type mdio_bus_type = {
768 .name = "mdio_bus", 721 .name = "mdio_bus",
769 .match = mdio_bus_match, 722 .match = mdio_bus_match,
770 .uevent = mdio_uevent, 723 .uevent = mdio_uevent,
771 .pm = MDIO_BUS_PM_OPS,
772}; 724};
773EXPORT_SYMBOL(mdio_bus_type); 725EXPORT_SYMBOL(mdio_bus_type);
774 726
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 9e4ba8e80a18..bd0f339f69fd 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -346,6 +346,55 @@ static int phy_bus_match(struct device *dev, struct device_driver *drv)
346 } 346 }
347} 347}
348 348
349static ssize_t
350phy_id_show(struct device *dev, struct device_attribute *attr, char *buf)
351{
352 struct phy_device *phydev = to_phy_device(dev);
353
354 return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id);
355}
356static DEVICE_ATTR_RO(phy_id);
357
358static ssize_t
359phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf)
360{
361 struct phy_device *phydev = to_phy_device(dev);
362 const char *mode = NULL;
363
364 if (phy_is_internal(phydev))
365 mode = "internal";
366 else
367 mode = phy_modes(phydev->interface);
368
369 return sprintf(buf, "%s\n", mode);
370}
371static DEVICE_ATTR_RO(phy_interface);
372
373static ssize_t
374phy_has_fixups_show(struct device *dev, struct device_attribute *attr,
375 char *buf)
376{
377 struct phy_device *phydev = to_phy_device(dev);
378
379 return sprintf(buf, "%d\n", phydev->has_fixups);
380}
381static DEVICE_ATTR_RO(phy_has_fixups);
382
383static struct attribute *phy_dev_attrs[] = {
384 &dev_attr_phy_id.attr,
385 &dev_attr_phy_interface.attr,
386 &dev_attr_phy_has_fixups.attr,
387 NULL,
388};
389ATTRIBUTE_GROUPS(phy_dev);
390
391static const struct device_type mdio_bus_phy_type = {
392 .name = "PHY",
393 .groups = phy_dev_groups,
394 .release = phy_device_release,
395 .pm = MDIO_BUS_PHY_PM_OPS,
396};
397
349struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, 398struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
350 bool is_c45, 399 bool is_c45,
351 struct phy_c45_device_ids *c45_ids) 400 struct phy_c45_device_ids *c45_ids)
@@ -359,11 +408,10 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
359 return ERR_PTR(-ENOMEM); 408 return ERR_PTR(-ENOMEM);
360 409
361 mdiodev = &dev->mdio; 410 mdiodev = &dev->mdio;
362 mdiodev->dev.release = phy_device_release;
363 mdiodev->dev.parent = &bus->dev; 411 mdiodev->dev.parent = &bus->dev;
364 mdiodev->dev.bus = &mdio_bus_type; 412 mdiodev->dev.bus = &mdio_bus_type;
413 mdiodev->dev.type = &mdio_bus_phy_type;
365 mdiodev->bus = bus; 414 mdiodev->bus = bus;
366 mdiodev->pm_ops = MDIO_BUS_PHY_PM_OPS;
367 mdiodev->bus_match = phy_bus_match; 415 mdiodev->bus_match = phy_bus_match;
368 mdiodev->addr = addr; 416 mdiodev->addr = addr;
369 mdiodev->flags = MDIO_DEVICE_FLAG_PHY; 417 mdiodev->flags = MDIO_DEVICE_FLAG_PHY;
@@ -587,48 +635,6 @@ struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
587} 635}
588EXPORT_SYMBOL(get_phy_device); 636EXPORT_SYMBOL(get_phy_device);
589 637
590static ssize_t
591phy_id_show(struct device *dev, struct device_attribute *attr, char *buf)
592{
593 struct phy_device *phydev = to_phy_device(dev);
594
595 return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id);
596}
597static DEVICE_ATTR_RO(phy_id);
598
599static ssize_t
600phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf)
601{
602 struct phy_device *phydev = to_phy_device(dev);
603 const char *mode = NULL;
604
605 if (phy_is_internal(phydev))
606 mode = "internal";
607 else
608 mode = phy_modes(phydev->interface);
609
610 return sprintf(buf, "%s\n", mode);
611}
612static DEVICE_ATTR_RO(phy_interface);
613
614static ssize_t
615phy_has_fixups_show(struct device *dev, struct device_attribute *attr,
616 char *buf)
617{
618 struct phy_device *phydev = to_phy_device(dev);
619
620 return sprintf(buf, "%d\n", phydev->has_fixups);
621}
622static DEVICE_ATTR_RO(phy_has_fixups);
623
624static struct attribute *phy_dev_attrs[] = {
625 &dev_attr_phy_id.attr,
626 &dev_attr_phy_interface.attr,
627 &dev_attr_phy_has_fixups.attr,
628 NULL,
629};
630ATTRIBUTE_GROUPS(phy_dev);
631
632/** 638/**
633 * phy_device_register - Register the phy device on the MDIO bus 639 * phy_device_register - Register the phy device on the MDIO bus
634 * @phydev: phy_device structure to be added to the MDIO bus 640 * @phydev: phy_device structure to be added to the MDIO bus
@@ -651,8 +657,6 @@ int phy_device_register(struct phy_device *phydev)
651 goto out; 657 goto out;
652 } 658 }
653 659
654 phydev->mdio.dev.groups = phy_dev_groups;
655
656 err = device_add(&phydev->mdio.dev); 660 err = device_add(&phydev->mdio.dev);
657 if (err) { 661 if (err) {
658 pr_err("PHY %d failed to add\n", phydev->mdio.addr); 662 pr_err("PHY %d failed to add\n", phydev->mdio.addr);
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 2cfffe586885..bfa7114167d7 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -29,7 +29,6 @@ enum mdio_mutex_lock_class {
29struct mdio_device { 29struct mdio_device {
30 struct device dev; 30 struct device dev;
31 31
32 const struct dev_pm_ops *pm_ops;
33 struct mii_bus *bus; 32 struct mii_bus *bus;
34 char modalias[MDIO_NAME_SIZE]; 33 char modalias[MDIO_NAME_SIZE];
35 34