// SPDX-License-Identifier: GPL-2.0-or-later
/*
* phy-core.c -- Generic Phy framework.
*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
*
* Author: Kishon Vijay Abraham I <kishon@ti.com>
*/
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/idr.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
static void phy_release(struct device *dev);
static const struct class phy_class = {
.name = "phy",
.dev_release = phy_release,
};
static struct dentry *phy_debugfs_root;
static DEFINE_MUTEX(phy_provider_mutex);
static LIST_HEAD(phy_provider_list);
static LIST_HEAD(phys);
static DEFINE_IDA(phy_ida);
static void devm_phy_release(struct device *dev, void *res)
{
struct phy *phy = *(struct phy **)res;
phy_put(dev, phy);
}
static void devm_phy_provider_release(struct device *dev, void *res)
{
struct phy_provider *phy_provider = *(struct phy_provider **)res;
of_phy_provider_unregister(phy_provider);
}
static void devm_phy_consume(struct device *dev, void *res)
{
struct phy *phy = *(struct phy **)res;
phy_destroy(phy);
}
static int devm_phy_match(struct device *dev, void *res, void *match_data)
{
struct phy **phy = res;
return *phy == match_data;
}
/**
* phy_create_lookup() - allocate and register PHY/device association
* @phy: the phy of the association
* @con_id: connection ID string on device
* @dev_id: the device of the association
*
* Creates and registers phy_lookup entry.
*/
int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id)
{
struct phy_lookup *pl;
if (!phy || !dev_id || !con_id)
return -EINVAL;
pl = kzalloc(sizeof(*pl), GFP_KERNEL);
if (!pl)
return -ENOMEM;
pl->dev_id = dev_id;
pl->con_id = con_id;
pl->phy = phy;
mutex_lock(&phy_provider_mutex);
list_add_tail(&pl->node, &phys);
mutex_unlock(&phy_provider_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(phy_create_lookup);
/**
* phy_remove_lookup() - find and remove PHY/device association
* @phy: the phy of the association
* @con_id: connection ID string on device
* @dev_id: the device of the association
*
* Finds and unregisters phy_lookup entry that was created with
* phy_create_lookup().
*/
void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id