File Index
Files and directories
Sign in
FILE

mdio_bus.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/phy/mdio_bus.c C
   1// SPDX-License-Identifier: GPL-2.0+
   2/* MDIO Bus interface
   3 *
   4 * Author: Andy Fleming
   5 *
   6 * Copyright (c) 2004 Freescale Semiconductor, Inc.
   7 */
   8
   9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  10
  11#include <linux/device.h>
  12#include <linux/errno.h>
  13#include <linux/etherdevice.h>
  14#include <linux/ethtool.h>
  15#include <linux/gpio/consumer.h>
  16#include <linux/init.h>
  17#include <linux/io.h>
  18#include <linux/kernel.h>
  19#include <linux/mii.h>
  20#include <linux/mm.h>
  21#include <linux/module.h>
  22#include <linux/netdevice.h>
  23#include <linux/of_device.h>
  24#include <linux/of_mdio.h>
  25#include <linux/phy.h>
  26#include <linux/reset.h>
  27#include <linux/slab.h>
  28#include <linux/spinlock.h>
  29#include <linux/string.h>
  30#include <linux/uaccess.h>
  31#include <linux/unistd.h>
  32#include "mdio-private.h"
  33
  34#define CREATE_TRACE_POINTS
  35#include <trace/events/mdio.h>
  36
  37int mdiobus_register_device(struct mdio_device *mdiodev)
  38{
  39	int err;
  40
  41	if (mdiodev->bus->mdio_map[mdiodev->addr])
  42		return -EBUSY;
  43
  44	if (mdiodev->flags & MDIO_DEVICE_FLAG_PHY) {
  45		err = mdio_device_register_reset(mdiodev);
  46		if (err)
  47			return err;
  48
  49		/* Assert the reset signal */
  50		mdio_device_reset(mdiodev, 1);
  51	}
  52
  53	mdiodev->bus->mdio_map[mdiodev->addr] = mdiodev;
  54
  55	return 0;
  56}
  57EXPORT_SYMBOL(mdiobus_register_device);
  58
  59int mdiobus_unregister_device(struct mdio_device *mdiodev)
  60{
  61	if (mdiodev->bus->mdio_map[mdiodev->addr] != mdiodev)
  62		return -EINVAL;
  63
  64	mdio_device_unregister_reset(mdiodev);
  65
  66	mdiodev->bus->mdio_map[mdiodev->addr] = NULL;
  67
  68	return 0;
  69}
  70EXPORT_SYMBOL(mdiobus_unregister_device);
  71
  72static struct mdio_device *mdiobus_find_device(struct mii_bus *bus, int addr)
  73{
  74	bool addr_valid = addr >= 0 && addr < ARRAY_SIZE(bus->mdio_map);
  75
  76	if (WARN_ONCE(!addr_valid, "addr %d out of range\n", addr))
  77		return NULL;
  78
  79	return bus->mdio_map[addr];
  80}
  81
  82struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
  83{
  84	struct mdio_device *mdiodev;
  85
  86	mdiodev = mdiobus_find_device(bus, addr);
  87	if (!mdiodev)
  88		return NULL;
  89
  90	if (!(mdiodev->flags & MDIO_DEVICE_FLAG_PHY))
  91		return NULL;
  92
  93	return container_of(mdiodev, struct phy_device, mdio);
  94}
  95EXPORT_SYMBOL(mdiobus_get_phy);
  96
  97bool mdiobus_is_registered_device(struct mii_bus *bus, int addr)
  98{
  99	return mdiobus_find_device(bus, addr) != NULL;
 100}
 101EXPORT_SYMBOL(mdiobus_is_registered_device);
 102
 103/**
 104 * mdiobus_release - mii_bus device release callback
 105 * @d: the target struct device that contains the mii_bus
 106 *
 107 * Description: called when the last reference to an mii_bus is
 108 * dropped, to free the underlying memory.
 109 */
 110static void mdiobus_release(struct device *d)
 111{
 112	struct mii_bus *bus = to_mii_bus(d);
 113
 114	WARN(bus->state != MDIOBUS_RELEASED &&
 115	     /* for compatibility with error handling in drivers */
 116	     bus->state != MDIOBUS_ALLOCATED,
 117	     "%s: not in RELEASED or ALLOCATED state\n",
 118	     bus->id);
 119
 120	if (bus->state == MDIOBUS_RELEASED)
 121		fwnode_handle_put(dev_fwnode(d));
 122
 123	kfree(bus);
 124}
 125
 126struct mdio_bus_stat_attr {
 127	int addr;
 128	unsigned int field_offset;
 129};
 130
 131static u64 mdio_bus_get_stat(struct mdio_bus_stats *s, unsigned int offset)
 132{
 133	const char *p = (const char *)s + offset;
 134	unsigned int start;
 135	u64 val = 0;
 136
 137	do {
 138		start = u64_stats_fetch_begin(&s->syncp);
 139		val = u64_stats_read((const u64_stats_t *)p);
 140	} while (u64_stats_fetch_retry(&s->syncp, start));
 141
 142	return val;
 143}
 144
 145static u64 mdio_bus_get_global_stat(struct mii_bus *bus, unsigned int offset)
 146{
 147	unsigned int i;
 148	u64 val = 0;
 149
 150	for (i = 0; i < PHY_MAX_ADDR; i++)
 151		val += mdio_bus_get_stat(&bus->stats[i], offset);
 152
 153	return val;
 154}
 155
 156static ssize_t mdio_bus_stat_field_show(struct device *dev,
 157					struct device_attribute *attr,
 158					char *buf)
 159{
 160	struct mii_bus *bus = to_mii_bus(dev);
 161	struct mdio_bus_stat_attr *sattr;
 162	struct dev_ext_attribute *eattr;
 163	u64 val;
 164
 165	eattr = container_of(attr, struct dev_ext_attribute, attr);
 166	sattr = eattr->var;
 167
 168	if (sattr->addr < 0)
 169		val = mdio_bus_get_global_stat(bus, sattr->field_offset);
 170	else
 171		val = mdio_bus_get_stat(&bus->stats[sattr->addr],
 172					sattr->field_offset);
 173
 174	return sysfs_emit(buf, "%llu\n", val);
 175}
 176
 177static ssize_t mdio_bus_device_stat_field_show(struct device *dev,
 178					       struct device_attribute *attr,
 179					       char *buf)
 180{
 181	struct mdio_device *mdiodev = to_mdio_device(dev);
 182	struct mii_bus *bus = mdiodev->bus;
 183	struct mdio_bus_stat_attr *sattr;
 184	struct dev_ext_attribute *eattr;
 185	int addr = mdiodev->addr;
 186	u64 val;
 187
 188	eattr = container_of(attr, struct dev_ext_attribute, attr);
 189	sattr = eattr->var;
 190
 191	val = mdio_bus_get_stat(&bus->stats[addr], sattr->field_offset);
 192
 193	return sysfs_emit(buf, "%llu\n", val);
 194}
 195
 196#define MDIO_BUS_STATS_ATTR_DECL(field, file)				\
 197static struct dev_ext_attribute dev_attr_mdio_bus_##field = {		\
 198	.attr = { .attr = { .name = file, .mode = 0444 },		\
 199		     .show = mdio_bus_stat_field_show,			\
 200	},								\
 201	.var = &((struct mdio_bus_stat_attr) {				\
 202		-1, offsetof(struct mdio_bus_stats, field)		\
 203	}),								\
 204};									\
 205static struct dev_ext_attribute dev_attr_mdio_bus_device_##field = {	\
 206	.attr = { .attr = { .name = file, .mode = 0444 },		\
 207		     .show = mdio_bus_device_stat_field_show,		\
 208	},								\
 209	.var = &((struct mdio_bus_stat_attr) {				\
 210		-1, offsetof(struct mdio_bus_stats, field)		\
 211	}),								\
 212};
 213
 214#define MDIO_BUS_STATS_ATTR(field)					\
 215	MDIO_BUS_STATS_ATTR_DECL(field, __stringify(field))
 216
 217MDIO_BUS_STATS_ATTR(transfers);
 218MDIO_BUS_STATS_ATTR(errors);
 219MDIO_BUS_STATS_ATTR(writes);
 220MDIO_BUS_STATS_ATTR(reads);
 221
 222#define MDIO_BUS_STATS_ADDR_ATTR_DECL(field, addr, file)		\
 223static struct dev_ext_attribute dev_attr_mdio_bus_addr_##field##_##addr = { \
 224	.attr = { .attr = { .name = file, .mode = 0444 },		\
 225		     .show = mdio_bus_stat_field_show,			\
 226	},								\
 227	.var = &((struct mdio_bus_stat_attr) {				\
 228		addr, offsetof(struct mdio_bus_stats, field)		\
 229	}),								\
 230}
 231
 232#define MDIO_BUS_STATS_ADDR_ATTR(field, addr)				\
 233	MDIO_BUS_STATS_ADDR_ATTR_DECL(field, addr,			\
 234				 __stringify(field) "_" __stringify(addr))
 235
 236#define MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(addr)			\
 237	MDIO_BUS_STATS_ADDR_ATTR(transfers, addr);			\
 238	MDIO_BUS_STATS_ADDR_ATTR(errors, addr);				\
 239	MDIO_BUS_STATS_ADDR_ATTR(writes, addr);				\
 240	MDIO_BUS_STATS_ADDR_ATTR(reads, addr)				\
 241
 242MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(0);
 243MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(1);
 244MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(2);
 245MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(3);
 246MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(4);
 247MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(5);
 248MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(6);
 249MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(7);
 250MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(8);
 251MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(9);
 252MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(10);
 253MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(11);
 254MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(12);
 255MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(13);
 256MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(14);
 257MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(15);
 258MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(16);
 259MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(17);
 260MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(18);
 261MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(19);
 262MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(20);
 263MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(21);
 264MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(22);
 265MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(23);
 266MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(24);
 267MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(25);
 268MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(26);
 269MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(27);
 270MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(28);
 271MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(29);
 272MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(30);
 273MDIO_BUS_STATS_ADDR_ATTR_GROUP_DECL(31);
 274
 275#define MDIO_BUS_STATS_ADDR_ATTR_GROUP(addr)				\
 276	&dev_attr_mdio_bus_addr_transfers_##addr.attr.attr,		\
 277	&dev_attr_mdio_bus_addr_errors_##addr.attr.attr,		\
 278	&dev_attr_mdio_bus_addr_writes_##addr.attr.attr,		\
 279	&dev_attr_mdio_bus_addr_reads_##addr.attr.attr			\
 280
 281static struct attribute *mdio_bus_statistics_attrs[] = {
 282	&dev_attr_mdio_bus_transfers.attr.attr,
 283	&dev_attr_mdio_bus_errors.attr.attr,
 284	&dev_attr_mdio_bus_writes.attr.attr,
 285	&dev_attr_mdio_bus_reads.attr.attr,
 286	MDIO_BUS_STATS_ADDR_ATTR_GROUP(0),
 287	MDIO_BUS_STATS_ADDR_ATTR_GROUP(1),
 288	MDIO_BUS_STATS_ADDR_ATTR_GROUP(2),
 289	MDIO_BUS_STATS_ADDR_ATTR_GROUP(3),
 290	MDIO_BUS_STATS_ADDR_ATTR_GROUP(4),
 291	MDIO_BUS_STATS_ADDR_ATTR_GROUP(5),
 292	MDIO_BUS_STATS_ADDR_ATTR_GROUP(6),
 293	MDIO_BUS_STATS_ADDR_ATTR_GROUP(7),
 294	MDIO_BUS_STATS_ADDR_ATTR_GROUP(8),
 295	MDIO_BUS_STATS_ADDR_ATTR_GROUP(9),
 296	MDIO_BUS_STATS_ADDR_ATTR_GROUP(10),
 297	MDIO_BUS_STATS_ADDR_ATTR_GROUP(11),
 298	MDIO_BUS_STATS_ADDR_ATTR_GROUP(12),
 299	MDIO_BUS_STATS_ADDR_ATTR_GROUP(13),
 300	MDIO_BUS_STATS_ADDR_ATTR_GROUP(14),
 301	MDIO_BUS_STATS_ADDR_ATTR_GROUP(15),
 302	MDIO_BUS_STATS_ADDR_ATTR_GROUP(16),
 303	MDIO_BUS_STATS_ADDR_ATTR_GROUP(17),
 304	MDIO_BUS_STATS_ADDR_ATTR_GROUP(18),
 305	MDIO_BUS_STATS_ADDR_ATTR_GROUP(19),
 306	MDIO_BUS_STATS_ADDR_ATTR_GROUP(20),
 307	MDIO_BUS_STATS_ADDR_ATTR_GROUP(21),
 308	MDIO_BUS_STATS_ADDR_ATTR_GROUP(22),
 309	MDIO_BUS_STATS_ADDR_ATTR_GROUP(23),
 310	MDIO_BUS_STATS_ADDR_ATTR_GROUP(24),
 311	MDIO_BUS_STATS_ADDR_ATTR_GROUP(25),
 312	MDIO_BUS_STATS_ADDR_ATTR_GROUP(26),
 313	MDIO_BUS_STATS_ADDR_ATTR_GROUP(27),
 314	MDIO_BUS_STATS_ADDR_ATTR_GROUP(28),
 315	MDIO_BUS_STATS_ADDR_ATTR_GROUP(29),
 316	MDIO_BUS_STATS_ADDR_ATTR_GROUP(30),
 317	MDIO_BUS_STATS_ADDR_ATTR_GROUP(31),
 318	NULL,
 319};
 320
 321static const struct attribute_group mdio_bus_statistics_group = {
 322	.name	= "statistics",
 323	.attrs	= mdio_bus_statistics_attrs,
 324};
 325
 326static const struct attribute_group *mdio_bus_groups[] = {
 327	&mdio_bus_statistics_group,
 328	NULL,
 329};
 330
 331const struct class mdio_bus_class = {
 332	.name		= "mdio_bus",
 333	.dev_release	= mdiobus_release,
 334	.dev_groups	= mdio_bus_groups,
 335};
 336EXPORT_SYMBOL_GPL(mdio_bus_class);
 337
 338/**
 339 * mdio_find_bus - Given the name of a mdiobus, find the mii_bus.
 340 * @mdio_name: The name of a mdiobus.
 341 *
 342 * Return: a reference to the mii_bus, or NULL if none found. The
 343 * embedded struct device will have its reference count incremented,
 344 * and this must be put_deviced'ed once the bus is finished with.
 345 */
 346struct mii_bus *mdio_find_bus(const char *mdio_name)
 347{
 348	struct device *d;
 349
 350	d = class_find_device_by_name(&mdio_bus_class, mdio_name);
 351	return d ? to_mii_bus(d) : NULL;
 352}
 353EXPORT_SYMBOL(mdio_find_bus);
 354
 355#if IS_ENABLED(CONFIG_OF_MDIO)
 356/**
 357 * of_mdio_find_bus - Given an mii_bus node, find the mii_bus.
 358 * @mdio_bus_np: Pointer to the mii_bus.
 359 *
 360 * Return: a reference to the mii_bus, or NULL if none found. The
 361 * embedded struct device will have its reference count incremented,
 362 * and this must be put once the bus is finished with.
 363 *
 364 * Because the association of a device_node and mii_bus is made via
 365 * of_mdiobus_register(), the mii_bus cannot be found before it is
 366 * registered with of_mdiobus_register().
 367 *
 368 */
 369struct mii_bus *of_mdio_find_bus(struct device_node *mdio_bus_np)
 370{
 371	struct device *d;
 372
 373	if (!mdio_bus_np)
 374		return NULL;
 375
 376	d = class_find_device_by_of_node(&mdio_bus_class, mdio_bus_np);
 377	return d ? to_mii_bus(d) : NULL;
 378}
 379EXPORT_SYMBOL(of_mdio_find_bus);
 380#endif
 381
 382static void mdiobus_stats_acct(struct mdio_bus_stats *stats, bool op, int ret)
 383{
 384	preempt_disable();
 385	u64_stats_update_begin(&stats->syncp);
 386
 387	u64_stats_inc(&stats->transfers);
 388	if (ret < 0) {
 389		u64_stats_inc(&stats->errors);
 390		goto out;
 391	}
 392
 393	if (op)
 394		u64_stats_inc(&stats->reads);
 395	else
 396		u64_stats_inc(&stats->writes);
 397out:
 398	u64_stats_update_end(&stats->syncp);
 399	preempt_enable();
 400}
 401
 402/**
 403 * __mdiobus_read - Unlocked version of the mdiobus_read function
 404 * @bus: the mii_bus struct
 405 * @addr: the phy address
 406 * @regnum: register number to read
 407 *
 408 * Return: The register value if successful, negative error code on failure
 409 *
 410 * Read a MDIO bus register. Caller must hold the mdio bus lock.
 411 *
 412 * NOTE: MUST NOT be called from interrupt context.
 413 */
 414int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum)
 415{
 416	int retval;
 417
 418	lockdep_assert_held_once(&bus->mdio_lock);
 419
 420	if (addr >= PHY_MAX_ADDR)
 421		return -ENXIO;
 422
 423	if (bus->read)
 424		retval = bus->read(bus, addr, regnum);
 425	else
 426		retval = -EOPNOTSUPP;
 427
 428	trace_mdio_access(bus, 1, addr, regnum, retval, retval);
 429	mdiobus_stats_acct(&bus->stats[addr], true, retval);
 430
 431	return retval;
 432}
 433EXPORT_SYMBOL(__mdiobus_read);
 434
 435/**
 436 * __mdiobus_write - Unlocked version of the mdiobus_write function
 437 * @bus: the mii_bus struct
 438 * @addr: the phy address
 439 * @regnum: register number to write
 440 * @val: value to write to @regnum
 441 *
 442 * Return: Zero if successful, negative error code on failure
 443 *
 444 * Write a MDIO bus register. Caller must hold the mdio bus lock.
 445 *
 446 * NOTE: MUST NOT be called from interrupt context.
 447 */
 448int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val)
 449{
 450	int err;
 451
 452	lockdep_assert_held_once(&bus->mdio_lock);
 453
 454	if (addr >= PHY_MAX_ADDR)
 455		return -ENXIO;
 456
 457	if (bus->write)
 458		err = bus->write(bus, addr, regnum, val);
 459	else
 460		err = -EOPNOTSUPP;
 461
 462	trace_mdio_access(bus, 0, addr, regnum, val, err);
 463	mdiobus_stats_acct(&bus->stats[addr], false, err);
 464
 465	return err;
 466}
 467EXPORT_SYMBOL(__mdiobus_write);
 468
 469/**
 470 * __mdiobus_modify_changed - Unlocked version of the mdiobus_modify function
 471 * @bus: the mii_bus struct
 472 * @addr: the phy address
 473 * @regnum: register number to modify
 474 * @mask: bit mask of bits to clear
 475 * @set: bit mask of bits to set
 476 *
 477 * Return: 1 if the register was modified, 0 if no change was needed,
 478 *	   negative on any error condition
 479 *
 480 * Read, modify, and if any change, write the register value back to the
 481 * device.
 482 *
 483 * NOTE: MUST NOT be called from interrupt context.
 484 */
 485int __mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum,
 486			     u16 mask, u16 set)
 487{
 488	int new, ret;
 489
 490	ret = __mdiobus_read(bus, addr, regnum);
 491	if (ret < 0)
 492		return ret;
 493
 494	new = (ret & ~mask) | set;
 495	if (new == ret)
 496		return 0;
 497
 498	ret = __mdiobus_write(bus, addr, regnum, new);
 499
 500	return ret < 0 ? ret : 1;
 501}
 502EXPORT_SYMBOL_GPL(__mdiobus_modify_changed);
 503
 504/**
 505 * __mdiobus_c45_read - Unlocked version of the mdiobus_c45_read function
 506 * @bus: the mii_bus struct
 507 * @addr: the phy address
 508 * @devad: device address to read
 509 * @regnum: register number to read
 510 *
 511 * Return: The register value if successful, negative error code on failure
 512 *
 513 * Read a MDIO bus register. Caller must hold the mdio bus lock.
 514 *
 515 * NOTE: MUST NOT be called from interrupt context.
 516 */
 517int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
 518{
 519	int retval;
 520
 521	lockdep_assert_held_once(&bus->mdio_lock);
 522
 523	if (addr >= PHY_MAX_ADDR)
 524		return -ENXIO;
 525
 526	if (bus->read_c45)
 527		retval = bus->read_c45(bus, addr, devad, regnum);
 528	else
 529		retval = -EOPNOTSUPP;
 530
 531	trace_mdio_access(bus, 1, addr, regnum, retval, retval);
 532	mdiobus_stats_acct(&bus->stats[addr], true, retval);
 533
 534	return retval;
 535}
 536EXPORT_SYMBOL(__mdiobus_c45_read);
 537
 538/**
 539 * __mdiobus_c45_write - Unlocked version of the mdiobus_write function
 540 * @bus: the mii_bus struct
 541 * @addr: the phy address
 542 * @devad: device address to read
 543 * @regnum: register number to write
 544 * @val: value to write to @regnum
 545 *
 546 * Return: Zero if successful, negative error code on failure
 547 *
 548 * Write a MDIO bus register. Caller must hold the mdio bus lock.
 549 *
 550 * NOTE: MUST NOT be called from interrupt context.
 551 */
 552int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
 553			u16 val)
 554{
 555	int err;
 556
 557	lockdep_assert_held_once(&bus->mdio_lock);
 558
 559	if (addr >= PHY_MAX_ADDR)
 560		return -ENXIO;
 561
 562	if (bus->write_c45)
 563		err = bus->write_c45(bus, addr, devad, regnum, val);
 564	else
 565		err = -EOPNOTSUPP;
 566
 567	trace_mdio_access(bus, 0, addr, regnum, val, err);
 568	mdiobus_stats_acct(&bus->stats[addr], false, err);
 569
 570	return err;
 571}
 572EXPORT_SYMBOL(__mdiobus_c45_write);
 573
 574/**
 575 * __mdiobus_c45_modify_changed - Unlocked version of the mdiobus_modify function
 576 * @bus: the mii_bus struct
 577 * @addr: the phy address
 578 * @devad: device address to read
 579 * @regnum: register number to modify
 580 * @mask: bit mask of bits to clear
 581 * @set: bit mask of bits to set
 582 *
 583 * Return: 1 if the register was modified, 0 if no change was needed,
 584 *	   negative on any error condition
 585 *
 586 * Read, modify, and if any change, write the register value back to the
 587 * device. Any error returns a negative number.
 588 *
 589 * NOTE: MUST NOT be called from interrupt context.
 590 */
 591static int __mdiobus_c45_modify_changed(struct mii_bus *bus, int addr,
 592					int devad, u32 regnum, u16 mask,
 593					u16 set)
 594{
 595	int new, ret;
 596
 597	ret = __mdiobus_c45_read(bus, addr, devad, regnum);
 598	if (ret < 0)
 599		return ret;
 600
 601	new = (ret & ~mask) | set;
 602	if (new == ret)
 603		return 0;
 604
 605	ret = __mdiobus_c45_write(bus, addr, devad, regnum, new);
 606
 607	return ret < 0 ? ret : 1;
 608}
 609
 610/**
 611 * mdiobus_read_nested - Nested version of the mdiobus_read function
 612 * @bus: the mii_bus struct
 613 * @addr: the phy address
 614 * @regnum: register number to read
 615 *
 616 * Return: The register value if successful, negative error code on failure
 617 *
 618 * In case of nested MDIO bus access avoid lockdep false positives by
 619 * using mutex_lock_nested().
 620 *
 621 * NOTE: MUST NOT be called from interrupt context,
 622 * because the bus read/write functions may wait for an interrupt
 623 * to conclude the operation.
 624 */
 625int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum)
 626{
 627	int retval;
 628
 629	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
 630	retval = __mdiobus_read(bus, addr, regnum);
 631	mutex_unlock(&bus->mdio_lock);
 632
 633	return retval;
 634}
 635EXPORT_SYMBOL(mdiobus_read_nested);
 636
 637/**
 638 * mdiobus_read - Convenience function for reading a given MII mgmt register
 639 * @bus: the mii_bus struct
 640 * @addr: the phy address
 641 * @regnum: register number to read
 642 *
 643 * Return: The register value if successful, negative error code on failure
 644 *
 645 * NOTE: MUST NOT be called from interrupt context,
 646 * because the bus read/write functions may wait for an interrupt
 647 * to conclude the operation.
 648 */
 649int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum)
 650{
 651	int retval;
 652
 653	mutex_lock(&bus->mdio_lock);
 654	retval = __mdiobus_read(bus, addr, regnum);
 655	mutex_unlock(&bus->mdio_lock);
 656
 657	return retval;
 658}
 659EXPORT_SYMBOL(mdiobus_read);
 660
 661/**
 662 * mdiobus_c45_read - Convenience function for reading a given MII mgmt register
 663 * @bus: the mii_bus struct
 664 * @addr: the phy address
 665 * @devad: device address to read
 666 * @regnum: register number to read
 667 *
 668 * Return: The register value if successful, negative error code on failure
 669 *
 670 * NOTE: MUST NOT be called from interrupt context,
 671 * because the bus read/write functions may wait for an interrupt
 672 * to conclude the operation.
 673 */
 674int mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
 675{
 676	int retval;
 677
 678	mutex_lock(&bus->mdio_lock);
 679	retval = __mdiobus_c45_read(bus, addr, devad, regnum);
 680	mutex_unlock(&bus->mdio_lock);
 681
 682	return retval;
 683}
 684EXPORT_SYMBOL(mdiobus_c45_read);
 685
 686/**
 687 * mdiobus_c45_read_nested - Nested version of the mdiobus_c45_read function
 688 * @bus: the mii_bus struct
 689 * @addr: the phy address
 690 * @devad: device address to read
 691 * @regnum: register number to read
 692 *
 693 * Return: The register value if successful, negative error code on failure
 694 *
 695 * In case of nested MDIO bus access avoid lockdep false positives by
 696 * using mutex_lock_nested().
 697 *
 698 * NOTE: MUST NOT be called from interrupt context,
 699 * because the bus read/write functions may wait for an interrupt
 700 * to conclude the operation.
 701 */
 702int mdiobus_c45_read_nested(struct mii_bus *bus, int addr, int devad,
 703			    u32 regnum)
 704{
 705	int retval;
 706
 707	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
 708	retval = __mdiobus_c45_read(bus, addr, devad, regnum);
 709	mutex_unlock(&bus->mdio_lock);
 710
 711	return retval;
 712}
 713EXPORT_SYMBOL(mdiobus_c45_read_nested);
 714
 715/**
 716 * mdiobus_write_nested - Nested version of the mdiobus_write function
 717 * @bus: the mii_bus struct
 718 * @addr: the phy address
 719 * @regnum: register number to write
 720 * @val: value to write to @regnum
 721 *
 722 * Return: Zero if successful, negative error code on failure
 723 *
 724 * In case of nested MDIO bus access avoid lockdep false positives by
 725 * using mutex_lock_nested().
 726 *
 727 * NOTE: MUST NOT be called from interrupt context,
 728 * because the bus read/write functions may wait for an interrupt
 729 * to conclude the operation.
 730 */
 731int mdiobus_write_nested(struct mii_bus *bus, int addr, u32 regnum, u16 val)
 732{
 733	int err;
 734
 735	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
 736	err = __mdiobus_write(bus, addr, regnum, val);
 737	mutex_unlock(&bus->mdio_lock);
 738
 739	return err;
 740}
 741EXPORT_SYMBOL(mdiobus_write_nested);
 742
 743/**
 744 * mdiobus_write - Convenience function for writing a given MII mgmt register
 745 * @bus: the mii_bus struct
 746 * @addr: the phy address
 747 * @regnum: register number to write
 748 * @val: value to write to @regnum
 749 *
 750 * Return: Zero if successful, negative error code on failure
 751 *
 752 * NOTE: MUST NOT be called from interrupt context,
 753 * because the bus read/write functions may wait for an interrupt
 754 * to conclude the operation.
 755 */
 756int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val)
 757{
 758	int err;
 759
 760	mutex_lock(&bus->mdio_lock);
 761	err = __mdiobus_write(bus, addr, regnum, val);
 762	mutex_unlock(&bus->mdio_lock);
 763
 764	return err;
 765}
 766EXPORT_SYMBOL(mdiobus_write);
 767
 768/**
 769 * mdiobus_c45_write - Convenience function for writing a given MII mgmt register
 770 * @bus: the mii_bus struct
 771 * @addr: the phy address
 772 * @devad: device address to read
 773 * @regnum: register number to write
 774 * @val: value to write to @regnum
 775 *
 776 * Return: Zero if successful, negative error code on failure
 777 *
 778 * NOTE: MUST NOT be called from interrupt context,
 779 * because the bus read/write functions may wait for an interrupt
 780 * to conclude the operation.
 781 */
 782int mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
 783		      u16 val)
 784{
 785	int err;
 786
 787	mutex_lock(&bus->mdio_lock);
 788	err = __mdiobus_c45_write(bus, addr, devad, regnum, val);
 789	mutex_unlock(&bus->mdio_lock);
 790
 791	return err;
 792}
 793EXPORT_SYMBOL(mdiobus_c45_write);
 794
 795/**
 796 * mdiobus_c45_write_nested - Nested version of the mdiobus_c45_write function
 797 * @bus: the mii_bus struct
 798 * @addr: the phy address
 799 * @devad: device address to read
 800 * @regnum: register number to write
 801 * @val: value to write to @regnum
 802 *
 803 * Return: Zero if successful, negative error code on failure
 804 *
 805 * In case of nested MDIO bus access avoid lockdep false positives by
 806 * using mutex_lock_nested().
 807 *
 808 * NOTE: MUST NOT be called from interrupt context,
 809 * because the bus read/write functions may wait for an interrupt
 810 * to conclude the operation.
 811 */
 812int mdiobus_c45_write_nested(struct mii_bus *bus, int addr, int devad,
 813			     u32 regnum, u16 val)
 814{
 815	int err;
 816
 817	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
 818	err = __mdiobus_c45_write(bus, addr, devad, regnum, val);
 819	mutex_unlock(&bus->mdio_lock);
 820
 821	return err;
 822}
 823EXPORT_SYMBOL(mdiobus_c45_write_nested);
 824
 825/*
 826 * __mdiobus_modify - Convenience function for modifying a given mdio device
 827 *	register
 828 * @bus: the mii_bus struct
 829 * @addr: the phy address
 830 * @regnum: register number to write
 831 * @mask: bit mask of bits to clear
 832 * @set: bit mask of bits to set
 833 *
 834 * Return: 0 on success, negative on any error condition
 835 */
 836int __mdiobus_modify(struct mii_bus *bus, int addr, u32 regnum, u16 mask,
 837		     u16 set)
 838{
 839	int err;
 840
 841	err = __mdiobus_modify_changed(bus, addr, regnum, mask, set);
 842
 843	return err < 0 ? err : 0;
 844}
 845EXPORT_SYMBOL_GPL(__mdiobus_modify);
 846
 847/**
 848 * mdiobus_modify - Convenience function for modifying a given mdio device
 849 *	register
 850 * @bus: the mii_bus struct
 851 * @addr: the phy address
 852 * @regnum: register number to write
 853 * @mask: bit mask of bits to clear
 854 * @set: bit mask of bits to set
 855 *
 856 * Return: 0 on success, negative on any error condition
 857 */
 858int mdiobus_modify(struct mii_bus *bus, int addr, u32 regnum, u16 mask, u16 set)
 859{
 860	int err;
 861
 862	mutex_lock(&bus->mdio_lock);
 863	err = __mdiobus_modify(bus, addr, regnum, mask, set);
 864	mutex_unlock(&bus->mdio_lock);
 865
 866	return err;
 867}
 868EXPORT_SYMBOL_GPL(mdiobus_modify);
 869
 870/**
 871 * mdiobus_c45_modify - Convenience function for modifying a given mdio device
 872 *	register
 873 * @bus: the mii_bus struct
 874 * @addr: the phy address
 875 * @devad: device address to read
 876 * @regnum: register number to write
 877 * @mask: bit mask of bits to clear
 878 * @set: bit mask of bits to set
 879 *
 880 * Return: 0 on success, negative on any error condition
 881 */
 882int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum,
 883		       u16 mask, u16 set)
 884{
 885	int err;
 886
 887	mutex_lock(&bus->mdio_lock);
 888	err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum,
 889					   mask, set);
 890	mutex_unlock(&bus->mdio_lock);
 891
 892	return err < 0 ? err : 0;
 893}
 894EXPORT_SYMBOL_GPL(mdiobus_c45_modify);
 895
 896/**
 897 * mdiobus_modify_changed - Convenience function for modifying a given mdio
 898 *	device register and returning if it changed
 899 * @bus: the mii_bus struct
 900 * @addr: the phy address
 901 * @regnum: register number to write
 902 * @mask: bit mask of bits to clear
 903 * @set: bit mask of bits to set
 904 *
 905 * Return: 1 if the register was modified, 0 if no change was needed,
 906 *	   negative on any error condition
 907 */
 908int mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum,
 909			   u16 mask, u16 set)
 910{
 911	int err;
 912
 913	mutex_lock(&bus->mdio_lock);
 914	err = __mdiobus_modify_changed(bus, addr, regnum, mask, set);
 915	mutex_unlock(&bus->mdio_lock);
 916
 917	return err;
 918}
 919EXPORT_SYMBOL_GPL(mdiobus_modify_changed);
 920
 921/**
 922 * mdiobus_c45_modify_changed - Convenience function for modifying a given mdio
 923 *	device register and returning if it changed
 924 * @bus: the mii_bus struct
 925 * @addr: the phy address
 926 * @devad: device address to read
 927 * @regnum: register number to write
 928 * @mask: bit mask of bits to clear
 929 * @set: bit mask of bits to set
 930 *
 931 * Return: 1 if the register was modified, 0 if no change was needed,
 932 *	   negative on any error condition
 933 */
 934int mdiobus_c45_modify_changed(struct mii_bus *bus, int addr, int devad,
 935			       u32 regnum, u16 mask, u16 set)
 936{
 937	int err;
 938
 939	mutex_lock(&bus->mdio_lock);
 940	err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum, mask, set);
 941	mutex_unlock(&bus->mdio_lock);
 942
 943	return err;
 944}
 945EXPORT_SYMBOL_GPL(mdiobus_c45_modify_changed);
 946
 947/**
 948 * mdio_bus_match - determine if given MDIO driver supports the given
 949 *		    MDIO device
 950 * @dev: target MDIO device
 951 * @drv: given MDIO driver
 952 *
 953 * Return: 1 if the driver supports the device, 0 otherwise
 954 *
 955 * Description: This may require calling the devices own match function,
 956 *   since different classes of MDIO devices have different match criteria.
 957 */
 958static int mdio_bus_match(struct device *dev, const struct device_driver *drv)
 959{
 960	const struct mdio_driver *mdiodrv = to_mdio_driver(drv);
 961	struct mdio_device *mdio = to_mdio_device(dev);
 962
 963	/* Both the driver and device must type-match */
 964	if (!(mdiodrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY) !=
 965	    !(mdio->flags & MDIO_DEVICE_FLAG_PHY))
 966		return 0;
 967
 968	if (of_driver_match_device(dev, drv))
 969		return 1;
 970
 971	if (mdio->bus_match)
 972		return mdio->bus_match(dev, drv);
 973
 974	return 0;
 975}
 976
 977static int mdio_uevent(const struct device *dev, struct kobj_uevent_env *env)
 978{
 979	int rc;
 980
 981	/* Some devices have extra OF data and an OF-style MODALIAS */
 982	rc = of_device_uevent_modalias(dev, env);
 983	if (rc != -ENODEV)
 984		return rc;
 985
 986	return 0;
 987}
 988
 989static struct attribute *mdio_bus_device_statistics_attrs[] = {
 990	&dev_attr_mdio_bus_device_transfers.attr.attr,
 991	&dev_attr_mdio_bus_device_errors.attr.attr,
 992	&dev_attr_mdio_bus_device_writes.attr.attr,
 993	&dev_attr_mdio_bus_device_reads.attr.attr,
 994	NULL,
 995};
 996
 997static const struct attribute_group mdio_bus_device_statistics_group = {
 998	.name	= "statistics",
 999	.attrs	= mdio_bus_device_statistics_attrs,
1000};
1001
1002static const struct attribute_group *mdio_bus_dev_groups[] = {
1003	&mdio_bus_device_statistics_group,
1004	NULL,
1005};
1006
1007const struct bus_type mdio_bus_type = {
1008	.name		= "mdio_bus",
1009	.dev_groups	= mdio_bus_dev_groups,
1010	.match		= mdio_bus_match,
1011	.uevent		= mdio_uevent,
1012};
1013EXPORT_SYMBOL(mdio_bus_type);
1014
1015static int __init mdio_bus_init(void)
1016{
1017	int ret;
1018
1019	ret = class_register(&mdio_bus_class);
1020	if (!ret) {
1021		ret = bus_register(&mdio_bus_type);
1022		if (ret)
1023			class_unregister(&mdio_bus_class);
1024	}
1025
1026	return ret;
1027}
1028
1029static void __exit mdio_bus_exit(void)
1030{
1031	class_unregister(&mdio_bus_class);
1032	bus_unregister(&mdio_bus_type);
1033}
1034
1035subsys_initcall(mdio_bus_init);
1036module_exit(mdio_bus_exit);
1037
1038MODULE_LICENSE("GPL");
1039MODULE_DESCRIPTION("MDIO bus/device layer");
~/ Read-only file preview.