Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: Add configuration interface

The phy framework is only allowing to configure the power state of the PHY
using the init and power_on hooks, and their power_off and exit
counterparts.

While it works for most, simple, PHYs supported so far, some more advanced
PHYs need some configuration depending on runtime parameters. These PHYs
have been supported by a number of means already, often by using ad-hoc
drivers in their consumer drivers.

That doesn't work too well however, when a consumer device needs to deal
with multiple PHYs, or when multiple consumers need to deal with the same
PHY (a DSI driver and a CSI driver for example).

So we'll add a new interface, through two funtions, phy_validate and
phy_configure. The first one will allow to check that a current
configuration, for a given mode, is applicable. It will also allow the PHY
driver to tune the settings given as parameters as it sees fit.

phy_configure will actually apply that configuration in the phy itself.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

authored by

Maxime Ripard and committed by
Kishon Vijay Abraham I
aeaac93d c8457828

+122
+64
drivers/phy/phy-core.c
··· 408 408 EXPORT_SYMBOL_GPL(phy_calibrate); 409 409 410 410 /** 411 + * phy_configure() - Changes the phy parameters 412 + * @phy: the phy returned by phy_get() 413 + * @opts: New configuration to apply 414 + * 415 + * Used to change the PHY parameters. phy_init() must have been called 416 + * on the phy. The configuration will be applied on the current phy 417 + * mode, that can be changed using phy_set_mode(). 418 + * 419 + * Returns: 0 if successful, an negative error code otherwise 420 + */ 421 + int phy_configure(struct phy *phy, union phy_configure_opts *opts) 422 + { 423 + int ret; 424 + 425 + if (!phy) 426 + return -EINVAL; 427 + 428 + if (!phy->ops->configure) 429 + return -EOPNOTSUPP; 430 + 431 + mutex_lock(&phy->mutex); 432 + ret = phy->ops->configure(phy, opts); 433 + mutex_unlock(&phy->mutex); 434 + 435 + return ret; 436 + } 437 + EXPORT_SYMBOL_GPL(phy_configure); 438 + 439 + /** 440 + * phy_validate() - Checks the phy parameters 441 + * @phy: the phy returned by phy_get() 442 + * @mode: phy_mode the configuration is applicable to. 443 + * @submode: PHY submode the configuration is applicable to. 444 + * @opts: Configuration to check 445 + * 446 + * Used to check that the current set of parameters can be handled by 447 + * the phy. Implementations are free to tune the parameters passed as 448 + * arguments if needed by some implementation detail or 449 + * constraints. It will not change any actual configuration of the 450 + * PHY, so calling it as many times as deemed fit will have no side 451 + * effect. 452 + * 453 + * Returns: 0 if successful, an negative error code otherwise 454 + */ 455 + int phy_validate(struct phy *phy, enum phy_mode mode, int submode, 456 + union phy_configure_opts *opts) 457 + { 458 + int ret; 459 + 460 + if (!phy) 461 + return -EINVAL; 462 + 463 + if (!phy->ops->validate) 464 + return -EOPNOTSUPP; 465 + 466 + mutex_lock(&phy->mutex); 467 + ret = phy->ops->validate(phy, mode, submode, opts); 468 + mutex_unlock(&phy->mutex); 469 + 470 + return ret; 471 + } 472 + EXPORT_SYMBOL_GPL(phy_validate); 473 + 474 + /** 411 475 * _of_phy_get() - lookup and obtain a reference to a phy by phandle 412 476 * @np: device_node for which to get the phy 413 477 * @index: the index of the phy
+58
include/linux/phy/phy.h
··· 43 43 }; 44 44 45 45 /** 46 + * union phy_configure_opts - Opaque generic phy configuration 47 + */ 48 + union phy_configure_opts { 49 + }; 50 + 51 + /** 46 52 * struct phy_ops - set of function pointers for performing phy operations 47 53 * @init: operation to be performed for initializing phy 48 54 * @exit: operation to be performed while exiting ··· 65 59 int (*power_on)(struct phy *phy); 66 60 int (*power_off)(struct phy *phy); 67 61 int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode); 62 + 63 + /** 64 + * @configure: 65 + * 66 + * Optional. 67 + * 68 + * Used to change the PHY parameters. phy_init() must have 69 + * been called on the phy. 70 + * 71 + * Returns: 0 if successful, an negative error code otherwise 72 + */ 73 + int (*configure)(struct phy *phy, union phy_configure_opts *opts); 74 + 75 + /** 76 + * @validate: 77 + * 78 + * Optional. 79 + * 80 + * Used to check that the current set of parameters can be 81 + * handled by the phy. Implementations are free to tune the 82 + * parameters passed as arguments if needed by some 83 + * implementation detail or constraints. It must not change 84 + * any actual configuration of the PHY, so calling it as many 85 + * times as deemed fit by the consumer must have no side 86 + * effect. 87 + * 88 + * Returns: 0 if the configuration can be applied, an negative 89 + * error code otherwise 90 + */ 91 + int (*validate)(struct phy *phy, enum phy_mode mode, int submode, 92 + union phy_configure_opts *opts); 68 93 int (*reset)(struct phy *phy); 69 94 int (*calibrate)(struct phy *phy); 70 95 struct module *owner; ··· 202 165 int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode); 203 166 #define phy_set_mode(phy, mode) \ 204 167 phy_set_mode_ext(phy, mode, 0) 168 + int phy_configure(struct phy *phy, union phy_configure_opts *opts); 169 + int phy_validate(struct phy *phy, enum phy_mode mode, int submode, 170 + union phy_configure_opts *opts); 205 171 206 172 static inline enum phy_mode phy_get_mode(struct phy *phy) 207 173 { ··· 346 306 { 347 307 if (!phy) 348 308 return 0; 309 + return -ENOSYS; 310 + } 311 + 312 + static inline int phy_configure(struct phy *phy, 313 + union phy_configure_opts *opts) 314 + { 315 + if (!phy) 316 + return 0; 317 + 318 + return -ENOSYS; 319 + } 320 + 321 + static inline int phy_validate(struct phy *phy, enum phy_mode mode, int submode, 322 + union phy_configure_opts *opts) 323 + { 324 + if (!phy) 325 + return 0; 326 + 349 327 return -ENOSYS; 350 328 } 351 329