1 /* This program is free software; you can redistribute it and/or modify 2 * it under the terms of the GNU General Public License version 2 3 * as published by the Free Software Foundation. 4 * 5 * This program is distributed in the hope that it will be useful, 6 * but WITHOUT ANY WARRANTY; without even the implied warranty of 7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8 * GNU General Public License for more details. 9 * 10 * Authors: 11 * Alexander Aring <aar@pengutronix.de> 12 * 13 * Based on: net/wireless/sysfs.c 14 */ 15 16 #include <linux/device.h> 17 #include <linux/rtnetlink.h> 18 19 #include <net/cfg802154.h> 20 21 #include "core.h" 22 #include "sysfs.h" 23 #include "rdev-ops.h" 24 25 static inline struct cfg802154_registered_device * 26 dev_to_rdev(struct device *dev) 27 { 28 return container_of(dev, struct cfg802154_registered_device, 29 wpan_phy.dev); 30 } 31 32 #define SHOW_FMT(name, fmt, member) \ 33 static ssize_t name ## _show(struct device *dev, \ 34 struct device_attribute *attr, \ 35 char *buf) \ 36 { \ 37 return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \ 38 } \ 39 static DEVICE_ATTR_RO(name) 40 41 SHOW_FMT(index, "%d", wpan_phy_idx); 42 43 static ssize_t name_show(struct device *dev, 44 struct device_attribute *attr, 45 char *buf) 46 { 47 struct wpan_phy *wpan_phy = &dev_to_rdev(dev)->wpan_phy; 48 49 return sprintf(buf, "%s\n", dev_name(&wpan_phy->dev)); 50 } 51 static DEVICE_ATTR_RO(name); 52 53 static void wpan_phy_release(struct device *dev) 54 { 55 struct cfg802154_registered_device *rdev = dev_to_rdev(dev); 56 57 cfg802154_dev_free(rdev); 58 } 59 60 static struct attribute *pmib_attrs[] = { 61 &dev_attr_index.attr, 62 &dev_attr_name.attr, 63 NULL, 64 }; 65 ATTRIBUTE_GROUPS(pmib); 66 67 #ifdef CONFIG_PM_SLEEP 68 static int wpan_phy_suspend(struct device *dev) 69 { 70 struct cfg802154_registered_device *rdev = dev_to_rdev(dev); 71 int ret = 0; 72 73 if (rdev->ops->suspend) { 74 rtnl_lock(); 75 ret = rdev_suspend(rdev); 76 rtnl_unlock(); 77 } 78 79 return ret; 80 } 81 82 static int wpan_phy_resume(struct device *dev) 83 { 84 struct cfg802154_registered_device *rdev = dev_to_rdev(dev); 85 int ret = 0; 86 87 if (rdev->ops->resume) { 88 rtnl_lock(); 89 ret = rdev_resume(rdev); 90 rtnl_unlock(); 91 } 92 93 return ret; 94 } 95 96 static SIMPLE_DEV_PM_OPS(wpan_phy_pm_ops, wpan_phy_suspend, wpan_phy_resume); 97 #define WPAN_PHY_PM_OPS (&wpan_phy_pm_ops) 98 #else 99 #define WPAN_PHY_PM_OPS NULL 100 #endif 101 102 struct class wpan_phy_class = { 103 .name = "ieee802154", 104 .dev_release = wpan_phy_release, 105 .dev_groups = pmib_groups, 106 .pm = WPAN_PHY_PM_OPS, 107 }; 108 109 int wpan_phy_sysfs_init(void) 110 { 111 return class_register(&wpan_phy_class); 112 } 113 114 void wpan_phy_sysfs_exit(void) 115 { 116 class_unregister(&wpan_phy_class); 117 } 118