summaryrefslogtreecommitdiffstats
path: root/net/ieee802154/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee802154/core.c')
-rw-r--r--net/ieee802154/core.c64
1 files changed, 33 insertions, 31 deletions
diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c
index 620abc2ba5f..d1cd0edfb14 100644
--- a/net/ieee802154/core.c
+++ b/net/ieee802154/core.c
@@ -21,9 +21,7 @@
#include "ieee802154.h"
#include "sysfs.h"
-
-static DEFINE_MUTEX(wpan_phy_mutex);
-static int wpan_phy_idx;
+#include "core.h"
static int wpan_phy_match(struct device *dev, const void *data)
{
@@ -71,42 +69,41 @@ int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data),
}
EXPORT_SYMBOL(wpan_phy_for_each);
-static int wpan_phy_idx_valid(int idx)
+struct wpan_phy *
+wpan_phy_alloc(const struct cfg802154_ops *ops, size_t priv_size)
{
- return idx >= 0;
-}
+ static atomic_t wpan_phy_counter = ATOMIC_INIT(0);
+ struct cfg802154_registered_device *rdev;
+ size_t alloc_size;
-struct wpan_phy *wpan_phy_alloc(size_t priv_size)
-{
- struct wpan_phy *phy = kzalloc(sizeof(*phy) + priv_size,
- GFP_KERNEL);
-
- if (!phy)
- goto out;
- mutex_lock(&wpan_phy_mutex);
- phy->idx = wpan_phy_idx++;
- if (unlikely(!wpan_phy_idx_valid(phy->idx))) {
- wpan_phy_idx--;
- mutex_unlock(&wpan_phy_mutex);
- kfree(phy);
- goto out;
- }
- mutex_unlock(&wpan_phy_mutex);
+ alloc_size = sizeof(*rdev) + priv_size;
+ rdev = kzalloc(alloc_size, GFP_KERNEL);
+ if (!rdev)
+ return NULL;
+
+ rdev->ops = ops;
- mutex_init(&phy->pib_lock);
+ rdev->wpan_phy_idx = atomic_inc_return(&wpan_phy_counter);
- device_initialize(&phy->dev);
- dev_set_name(&phy->dev, "wpan-phy%d", phy->idx);
+ if (unlikely(rdev->wpan_phy_idx < 0)) {
+ /* ugh, wrapped! */
+ atomic_dec(&wpan_phy_counter);
+ kfree(rdev);
+ return NULL;
+ }
+
+ /* atomic_inc_return makes it start at 1, make it start at 0 */
+ rdev->wpan_phy_idx--;
- phy->dev.class = &wpan_phy_class;
+ mutex_init(&rdev->wpan_phy.pib_lock);
- phy->current_channel = -1; /* not initialised */
- phy->current_page = 0; /* for compatibility */
+ device_initialize(&rdev->wpan_phy.dev);
+ dev_set_name(&rdev->wpan_phy.dev, "wpan-phy%d", rdev->wpan_phy_idx);
- return phy;
+ rdev->wpan_phy.dev.class = &wpan_phy_class;
+ rdev->wpan_phy.dev.platform_data = rdev;
-out:
- return NULL;
+ return &rdev->wpan_phy;
}
EXPORT_SYMBOL(wpan_phy_alloc);
@@ -128,6 +125,11 @@ void wpan_phy_free(struct wpan_phy *phy)
}
EXPORT_SYMBOL(wpan_phy_free);
+void cfg802154_dev_free(struct cfg802154_registered_device *rdev)
+{
+ kfree(rdev);
+}
+
static int __init wpan_phy_class_init(void)
{
int rc;