* [PATCH net-next v1 2/7] net: phy: extend link mode support to 48 bits
From: David Decotigny @ 2015-01-04 20:56 UTC (permalink / raw)
To: Amir Vadai, Florian Fainelli, netdev, linux-kernel, linux-api
Cc: David Decotigny, David S. Miller, Jason Wang, Michael S. Tsirkin,
Herbert Xu, Al Viro, Ben Hutchings, Masatake YAMATO, Xi Wang,
Neil Horman, WANG Cong, Flavio Leitner, Tom Gundersen, Jiri Pirko,
Vlad Yasevich, Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru,
Govindarajulu Varadarajan
In-Reply-To: <1420405017-23278-1-git-send-email-ddecotig@gmail.com>
From: David Decotigny <decot@googlers.com>
Signed-off-by: David Decotigny <decot@googlers.com>
---
drivers/net/phy/phy.c | 29 ++++++++++++++---------------
drivers/net/phy/phy_device.c | 4 ++--
include/linux/phy.h | 10 +++++-----
3 files changed, 21 insertions(+), 22 deletions(-)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 767cd11..e9c8499 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -132,7 +132,7 @@ static inline int phy_aneg_done(struct phy_device *phydev)
struct phy_setting {
int speed;
int duplex;
- u32 setting;
+ ethtool_link_mode_mask_t setting;
};
/* A mapping of all SUPPORTED settings to speed/duplex */
@@ -227,7 +227,8 @@ static inline unsigned int phy_find_setting(int speed, int duplex)
* the mask in features. Returns the index of the last setting
* if nothing else matches.
*/
-static inline unsigned int phy_find_valid(unsigned int idx, u32 features)
+static inline unsigned int phy_find_valid(unsigned int idx,
+ ethtool_link_mode_mask_t features)
{
while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features))
idx++;
@@ -245,7 +246,7 @@ static inline unsigned int phy_find_valid(unsigned int idx, u32 features)
*/
static void phy_sanitize_settings(struct phy_device *phydev)
{
- u32 features = phydev->supported;
+ ethtool_link_mode_mask_t features = phydev->supported;
unsigned int idx;
/* Sanitize settings based on PHY capabilities */
@@ -279,13 +280,13 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
return -EINVAL;
/* We make sure that we don't pass unsupported values in to the PHY */
- cmd->advertising &= phydev->supported;
+ phydev->advertising = ethtool_cmd_advertising(cmd) & phydev->supported;
/* Verify the settings we care about. */
if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
return -EINVAL;
- if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
+ if (cmd->autoneg == AUTONEG_ENABLE && phydev->advertising == 0)
return -EINVAL;
if (cmd->autoneg == AUTONEG_DISABLE &&
@@ -300,8 +301,6 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
phydev->speed = speed;
- phydev->advertising = cmd->advertising;
-
if (AUTONEG_ENABLE == cmd->autoneg)
phydev->advertising |= ADVERTISED_Autoneg;
else
@@ -318,10 +317,10 @@ EXPORT_SYMBOL(phy_ethtool_sset);
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
{
- cmd->supported = phydev->supported;
+ ethtool_cmd_supported_set(cmd, phydev->supported);
- cmd->advertising = phydev->advertising;
- cmd->lp_advertising = phydev->lp_advertising;
+ ethtool_cmd_advertising_set(cmd, phydev->advertising);
+ ethtool_cmd_lp_advertising_set(cmd, phydev->lp_advertising);
ethtool_cmd_speed_set(cmd, phydev->speed);
cmd->duplex = phydev->duplex;
@@ -1040,7 +1039,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
(phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
phy_is_internal(phydev))) {
int eee_lp, eee_cap, eee_adv;
- u32 lp, cap, adv;
+ ethtool_link_mode_mask_t cap, adv, lp;
int status;
unsigned int idx;
@@ -1132,21 +1131,21 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
MDIO_MMD_PCS, phydev->addr);
if (val < 0)
return val;
- data->supported = mmd_eee_cap_to_ethtool_sup_t(val);
+ ethtool_eee_supported_set(data, mmd_eee_cap_to_ethtool_sup_t(val));
/* Get advertisement EEE */
val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
MDIO_MMD_AN, phydev->addr);
if (val < 0)
return val;
- data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
+ ethtool_eee_advertised_set(data, mmd_eee_adv_to_ethtool_adv_t(val));
/* Get LP advertisement EEE */
val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE,
MDIO_MMD_AN, phydev->addr);
if (val < 0)
return val;
- data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);
+ ethtool_eee_lp_advertised_set(data, mmd_eee_adv_to_ethtool_adv_t(val));
return 0;
}
@@ -1161,7 +1160,7 @@ EXPORT_SYMBOL(phy_ethtool_get_eee);
*/
int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
{
- int val = ethtool_adv_to_mmd_eee_adv_t(data->advertised);
+ int val = ethtool_adv_to_mmd_eee_adv_t(ethtool_eee_advertised(data));
phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN,
phydev->addr, val);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 3fc91e8..4391dc7 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -734,7 +734,7 @@ EXPORT_SYMBOL(phy_resume);
*/
static int genphy_config_advert(struct phy_device *phydev)
{
- u32 advertise;
+ ethtool_link_mode_mask_t advertise;
int oldadv, adv, bmsr;
int err, changed = 0;
@@ -1086,7 +1086,7 @@ EXPORT_SYMBOL(genphy_soft_reset);
int genphy_config_init(struct phy_device *phydev)
{
int val;
- u32 features;
+ ethtool_link_mode_mask_t features;
features = (SUPPORTED_TP | SUPPORTED_MII
| SUPPORTED_AUI | SUPPORTED_FIBRE |
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 22af8f8..aabf808 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -390,10 +390,10 @@ struct phy_device {
u32 interrupts;
/* Union of PHY and Attached devices' supported modes */
- /* See mii.h for more info */
- u32 supported;
- u32 advertising;
- u32 lp_advertising;
+ /* See ethtool.h for more info */
+ ethtool_link_mode_mask_t supported;
+ ethtool_link_mode_mask_t advertising;
+ ethtool_link_mode_mask_t lp_advertising;
int autoneg;
@@ -447,7 +447,7 @@ struct phy_driver {
u32 phy_id;
char *name;
unsigned int phy_id_mask;
- u32 features;
+ ethtool_link_mode_mask_t features;
u32 flags;
const void *driver_data;
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next v1 3/7] net: mii: extend link mode support to 48 bits
From: David Decotigny @ 2015-01-04 20:56 UTC (permalink / raw)
To: Amir Vadai, Florian Fainelli, netdev, linux-kernel, linux-api
Cc: David Decotigny, David S. Miller, Jason Wang, Michael S. Tsirkin,
Herbert Xu, Al Viro, Ben Hutchings, Masatake YAMATO, Xi Wang,
Neil Horman, WANG Cong, Flavio Leitner, Tom Gundersen, Jiri Pirko,
Vlad Yasevich, Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru,
Govindarajulu Varadarajan
In-Reply-To: <1420405017-23278-1-git-send-email-ddecotig@gmail.com>
From: David Decotigny <decot@googlers.com>
Signed-off-by: David Decotigny <decot@googlers.com>
---
drivers/net/mii.c | 52 +++++++++++++++++++++++++++++-----------------------
include/linux/mii.h | 31 ++++++++++++++++---------------
2 files changed, 45 insertions(+), 38 deletions(-)
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index 4a99c39..2be59ba 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -33,7 +33,7 @@
#include <linux/ethtool.h>
#include <linux/mii.h>
-static u32 mii_get_an(struct mii_if_info *mii, u16 addr)
+static ethtool_link_mode_mask_t mii_get_an(struct mii_if_info *mii, u16 addr)
{
int advert;
@@ -56,14 +56,15 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
{
struct net_device *dev = mii->dev;
u16 bmcr, bmsr, ctrl1000 = 0, stat1000 = 0;
- u32 nego;
+ ethtool_link_mode_mask_t supported_link_modes, advertising_link_modes;
+ ethtool_link_mode_mask_t nego;
- ecmd->supported =
+ supported_link_modes =
(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
if (mii->supports_gmii)
- ecmd->supported |= SUPPORTED_1000baseT_Half |
+ supported_link_modes |= SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full;
/* only supports twisted-pair */
@@ -76,7 +77,7 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
ecmd->phy_address = mii->phy_id;
ecmd->mdio_support = ETH_MDIO_SUPPORTS_C22;
- ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
+ advertising_link_modes = ADVERTISED_TP | ADVERTISED_MII;
bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
bmsr = mii->mdio_read(dev, mii->phy_id, MII_BMSR);
@@ -85,23 +86,25 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
stat1000 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
}
if (bmcr & BMCR_ANENABLE) {
- ecmd->advertising |= ADVERTISED_Autoneg;
+ ethtool_link_mode_mask_t lp_adv;
+
+ advertising_link_modes |= ADVERTISED_Autoneg;
ecmd->autoneg = AUTONEG_ENABLE;
- ecmd->advertising |= mii_get_an(mii, MII_ADVERTISE);
+ advertising_link_modes |= mii_get_an(mii, MII_ADVERTISE);
if (mii->supports_gmii)
- ecmd->advertising |=
+ advertising_link_modes |=
mii_ctrl1000_to_ethtool_adv_t(ctrl1000);
if (bmsr & BMSR_ANEGCOMPLETE) {
- ecmd->lp_advertising = mii_get_an(mii, MII_LPA);
- ecmd->lp_advertising |=
- mii_stat1000_to_ethtool_lpa_t(stat1000);
+ lp_adv = mii_get_an(mii, MII_LPA);
+ lp_adv |= mii_stat1000_to_ethtool_lpa_t(stat1000);
} else {
- ecmd->lp_advertising = 0;
+ lp_adv = 0;
}
- nego = ecmd->advertising & ecmd->lp_advertising;
+ ethtool_cmd_lp_advertising_set(ecmd, lp_adv);
+ nego = advertising_link_modes & lp_adv;
if (nego & (ADVERTISED_1000baseT_Full |
ADVERTISED_1000baseT_Half)) {
@@ -128,6 +131,8 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
}
mii->full_duplex = ecmd->duplex;
+ ethtool_cmd_supported_set(ecmd, supported_link_modes);
+ ethtool_cmd_advertising_set(ecmd, advertising_link_modes);
/* ignore maxtxpkt, maxrxpkt for now */
@@ -168,13 +173,15 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
if (ecmd->autoneg == AUTONEG_ENABLE) {
u32 bmcr, advert, tmp;
u32 advert2 = 0, tmp2 = 0;
-
- if ((ecmd->advertising & (ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full |
- ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full)) == 0)
+ ethtool_link_mode_mask_t ethtool_adv;
+
+ ethtool_adv = ethtool_cmd_advertising(ecmd);
+ if ((ethtool_adv & (ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full)) == 0)
return -EINVAL;
/* advertise only what has been requested */
@@ -184,11 +191,10 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
}
- tmp |= ethtool_adv_to_mii_adv_t(ecmd->advertising);
+ tmp |= ethtool_adv_to_mii_adv_t(ethtool_adv);
if (mii->supports_gmii)
- tmp2 |=
- ethtool_adv_to_mii_ctrl1000_t(ecmd->advertising);
+ tmp2 |= ethtool_adv_to_mii_ctrl1000_t(ethtool_adv);
if (advert != tmp) {
mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
mii->advertising = tmp;
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 47492c9..6f5336c 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -106,7 +106,7 @@ static inline unsigned int mii_duplex (unsigned int duplex_lock,
* settings to phy autonegotiation advertisements for the
* MII_ADVERTISE register.
*/
-static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv)
+static inline u32 ethtool_adv_to_mii_adv_t(ethtool_link_mode_mask_t ethadv)
{
u32 result = 0;
@@ -133,9 +133,9 @@ static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv)
* A small helper function that translates MII_ADVERTISE bits
* to ethtool advertisement settings.
*/
-static inline u32 mii_adv_to_ethtool_adv_t(u32 adv)
+static inline ethtool_link_mode_mask_t mii_adv_to_ethtool_adv_t(u32 adv)
{
- u32 result = 0;
+ ethtool_link_mode_mask_t result = 0;
if (adv & ADVERTISE_10HALF)
result |= ADVERTISED_10baseT_Half;
@@ -161,7 +161,8 @@ static inline u32 mii_adv_to_ethtool_adv_t(u32 adv)
* settings to phy autonegotiation advertisements for the
* MII_CTRL1000 register when in 1000T mode.
*/
-static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv)
+static inline u32
+ethtool_adv_to_mii_ctrl1000_t(ethtool_link_mode_mask_t ethadv)
{
u32 result = 0;
@@ -181,9 +182,9 @@ static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv)
* bits, when in 1000Base-T mode, to ethtool
* advertisement settings.
*/
-static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv)
+static inline ethtool_link_mode_mask_t mii_ctrl1000_to_ethtool_adv_t(u32 adv)
{
- u32 result = 0;
+ ethtool_link_mode_mask_t result = 0;
if (adv & ADVERTISE_1000HALF)
result |= ADVERTISED_1000baseT_Half;
@@ -201,9 +202,9 @@ static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv)
* bits, when in 1000Base-T mode, to ethtool
* LP advertisement settings.
*/
-static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa)
+static inline ethtool_link_mode_mask_t mii_lpa_to_ethtool_lpa_t(u32 lpa)
{
- u32 result = 0;
+ ethtool_link_mode_mask_t result = 0;
if (lpa & LPA_LPACK)
result |= ADVERTISED_Autoneg;
@@ -219,9 +220,9 @@ static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa)
* bits, when in 1000Base-T mode, to ethtool
* advertisement settings.
*/
-static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa)
+static inline ethtool_link_mode_mask_t mii_stat1000_to_ethtool_lpa_t(u32 lpa)
{
- u32 result = 0;
+ ethtool_link_mode_mask_t result = 0;
if (lpa & LPA_1000HALF)
result |= ADVERTISED_1000baseT_Half;
@@ -239,7 +240,7 @@ static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa)
* settings to phy autonegotiation advertisements for the
* MII_CTRL1000 register when in 1000Base-X mode.
*/
-static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv)
+static inline u32 ethtool_adv_to_mii_adv_x(ethtool_link_mode_mask_t ethadv)
{
u32 result = 0;
@@ -263,9 +264,9 @@ static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv)
* bits, when in 1000Base-X mode, to ethtool
* advertisement settings.
*/
-static inline u32 mii_adv_to_ethtool_adv_x(u32 adv)
+static inline ethtool_link_mode_mask_t mii_adv_to_ethtool_adv_x(u32 adv)
{
- u32 result = 0;
+ ethtool_link_mode_mask_t result = 0;
if (adv & ADVERTISE_1000XHALF)
result |= ADVERTISED_1000baseT_Half;
@@ -287,9 +288,9 @@ static inline u32 mii_adv_to_ethtool_adv_x(u32 adv)
* bits, when in 1000Base-X mode, to ethtool
* LP advertisement settings.
*/
-static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa)
+static inline ethtool_link_mode_mask_t mii_lpa_to_ethtool_lpa_x(u32 lpa)
{
- u32 result = 0;
+ ethtool_link_mode_mask_t result = 0;
if (lpa & LPA_LPACK)
result |= ADVERTISED_Autoneg;
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next v1 4/7] net: mdio: extend link mode support to 48 bits
From: David Decotigny @ 2015-01-04 20:56 UTC (permalink / raw)
To: Amir Vadai, Florian Fainelli, netdev, linux-kernel, linux-api
Cc: David Decotigny, David S. Miller, Jason Wang, Michael S. Tsirkin,
Herbert Xu, Al Viro, Ben Hutchings, Masatake YAMATO, Xi Wang,
Neil Horman, WANG Cong, Flavio Leitner, Tom Gundersen, Jiri Pirko,
Vlad Yasevich, Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru,
Govindarajulu Varadarajan
In-Reply-To: <1420405017-23278-1-git-send-email-ddecotig@gmail.com>
From: David Decotigny <decot@googlers.com>
Signed-off-by: David Decotigny <decot@googlers.com>
---
drivers/net/mdio.c | 59 +++++++++++++++++++++++++++++-----------------------
include/linux/mdio.h | 15 +++++++------
2 files changed, 42 insertions(+), 32 deletions(-)
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c
index 3e027ed..5cac2ac 100644
--- a/drivers/net/mdio.c
+++ b/drivers/net/mdio.c
@@ -148,9 +148,10 @@ int mdio45_nway_restart(const struct mdio_if_info *mdio)
}
EXPORT_SYMBOL(mdio45_nway_restart);
-static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr)
+static ethtool_link_mode_mask_t
+mdio45_get_an(const struct mdio_if_info *mdio, u16 addr)
{
- u32 result = 0;
+ ethtool_link_mode_mask_t result = 0;
int reg;
reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, addr);
@@ -185,9 +186,11 @@ static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr)
*/
void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
struct ethtool_cmd *ecmd,
- u32 npage_adv, u32 npage_lpa)
+ ethtool_link_mode_mask_t npage_adv,
+ ethtool_link_mode_mask_t npage_lpa)
{
int reg;
+ ethtool_link_mode_mask_t supported_link_modes, advertising_link_modes;
u32 speed;
BUILD_BUG_ON(MDIO_SUPPORTS_C22 != ETH_MDIO_SUPPORTS_C22);
@@ -206,64 +209,64 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
case MDIO_PMA_CTRL2_100BTX:
case MDIO_PMA_CTRL2_10BT:
ecmd->port = PORT_TP;
- ecmd->supported = SUPPORTED_TP;
+ supported_link_modes = SUPPORTED_TP;
reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
MDIO_SPEED);
if (reg & MDIO_SPEED_10G)
- ecmd->supported |= SUPPORTED_10000baseT_Full;
+ supported_link_modes |= SUPPORTED_10000baseT_Full;
if (reg & MDIO_PMA_SPEED_1000)
- ecmd->supported |= (SUPPORTED_1000baseT_Full |
+ supported_link_modes |= (SUPPORTED_1000baseT_Full |
SUPPORTED_1000baseT_Half);
if (reg & MDIO_PMA_SPEED_100)
- ecmd->supported |= (SUPPORTED_100baseT_Full |
+ supported_link_modes |= (SUPPORTED_100baseT_Full |
SUPPORTED_100baseT_Half);
if (reg & MDIO_PMA_SPEED_10)
- ecmd->supported |= (SUPPORTED_10baseT_Full |
+ supported_link_modes |= (SUPPORTED_10baseT_Full |
SUPPORTED_10baseT_Half);
- ecmd->advertising = ADVERTISED_TP;
+ advertising_link_modes = ADVERTISED_TP;
break;
case MDIO_PMA_CTRL2_10GBCX4:
ecmd->port = PORT_OTHER;
- ecmd->supported = 0;
- ecmd->advertising = 0;
+ supported_link_modes = 0;
+ advertising_link_modes = 0;
break;
case MDIO_PMA_CTRL2_10GBKX4:
case MDIO_PMA_CTRL2_10GBKR:
case MDIO_PMA_CTRL2_1000BKX:
ecmd->port = PORT_OTHER;
- ecmd->supported = SUPPORTED_Backplane;
+ supported_link_modes = SUPPORTED_Backplane;
reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
MDIO_PMA_EXTABLE);
if (reg & MDIO_PMA_EXTABLE_10GBKX4)
- ecmd->supported |= SUPPORTED_10000baseKX4_Full;
+ supported_link_modes |= SUPPORTED_10000baseKX4_Full;
if (reg & MDIO_PMA_EXTABLE_10GBKR)
- ecmd->supported |= SUPPORTED_10000baseKR_Full;
+ supported_link_modes |= SUPPORTED_10000baseKR_Full;
if (reg & MDIO_PMA_EXTABLE_1000BKX)
- ecmd->supported |= SUPPORTED_1000baseKX_Full;
+ supported_link_modes |= SUPPORTED_1000baseKX_Full;
reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
MDIO_PMA_10GBR_FECABLE);
if (reg & MDIO_PMA_10GBR_FECABLE_ABLE)
- ecmd->supported |= SUPPORTED_10000baseR_FEC;
- ecmd->advertising = ADVERTISED_Backplane;
+ supported_link_modes |= SUPPORTED_10000baseR_FEC;
+ advertising_link_modes = ADVERTISED_Backplane;
break;
/* All the other defined modes are flavours of optical */
default:
ecmd->port = PORT_FIBRE;
- ecmd->supported = SUPPORTED_FIBRE;
- ecmd->advertising = ADVERTISED_FIBRE;
+ supported_link_modes = SUPPORTED_FIBRE;
+ advertising_link_modes = ADVERTISED_FIBRE;
break;
}
if (mdio->mmds & MDIO_DEVS_AN) {
- ecmd->supported |= SUPPORTED_Autoneg;
+ supported_link_modes |= SUPPORTED_Autoneg;
reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN,
MDIO_CTRL1);
if (reg & MDIO_AN_CTRL1_ENABLE) {
ecmd->autoneg = AUTONEG_ENABLE;
- ecmd->advertising |=
+ advertising_link_modes |=
ADVERTISED_Autoneg |
mdio45_get_an(mdio, MDIO_AN_ADVERTISE) |
npage_adv;
@@ -275,21 +278,22 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
}
if (ecmd->autoneg) {
- u32 modes = 0;
+ ethtool_link_mode_mask_t modes = 0;
int an_stat = mdio->mdio_read(mdio->dev, mdio->prtad,
MDIO_MMD_AN, MDIO_STAT1);
/* If AN is complete and successful, report best common
* mode, otherwise report best advertised mode. */
if (an_stat & MDIO_AN_STAT1_COMPLETE) {
- ecmd->lp_advertising =
+ ethtool_link_mode_mask_t lp_adv =
mdio45_get_an(mdio, MDIO_AN_LPA) | npage_lpa;
if (an_stat & MDIO_AN_STAT1_LPABLE)
- ecmd->lp_advertising |= ADVERTISED_Autoneg;
- modes = ecmd->advertising & ecmd->lp_advertising;
+ lp_adv |= ADVERTISED_Autoneg;
+ ethtool_cmd_lp_advertising_set(ecmd, lp_adv);
+ modes = advertising_link_modes & lp_adv;
}
if ((modes & ~ADVERTISED_Autoneg) == 0)
- modes = ecmd->advertising;
+ modes = advertising_link_modes;
if (modes & (ADVERTISED_10000baseT_Full |
ADVERTISED_10000baseKX4_Full |
@@ -338,6 +342,9 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
break;
}
}
+
+ ethtool_cmd_supported_set(ecmd, supported_link_modes);
+ ethtool_cmd_advertising_set(ecmd, advertising_link_modes);
}
EXPORT_SYMBOL(mdio45_ethtool_gset_npage);
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index b42963b..18c649a 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -69,7 +69,8 @@ extern int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmds);
extern int mdio45_nway_restart(const struct mdio_if_info *mdio);
extern void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
struct ethtool_cmd *ecmd,
- u32 npage_adv, u32 npage_lpa);
+ ethtool_link_mode_mask_t npage_adv,
+ ethtool_link_mode_mask_t npage_lpa);
/**
* mdio45_ethtool_gset - get settings for ETHTOOL_GSET
@@ -97,9 +98,10 @@ extern int mdio_mii_ioctl(const struct mdio_if_info *mdio,
* A small helper function that translates MMD EEE Capability (3.20) bits
* to ethtool supported settings.
*/
-static inline u32 mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap)
+static inline ethtool_link_mode_mask_t
+mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap)
{
- u32 supported = 0;
+ ethtool_link_mode_mask_t supported = 0;
if (eee_cap & MDIO_EEE_100TX)
supported |= SUPPORTED_100baseT_Full;
@@ -125,9 +127,10 @@ static inline u32 mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap)
* and MMD EEE Link Partner Ability (7.61) bits to ethtool advertisement
* settings.
*/
-static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv)
+static inline ethtool_link_mode_mask_t
+mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv)
{
- u32 adv = 0;
+ ethtool_link_mode_mask_t adv = 0;
if (eee_adv & MDIO_EEE_100TX)
adv |= ADVERTISED_100baseT_Full;
@@ -153,7 +156,7 @@ static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv)
* to EEE advertisements for the MMD EEE Advertisement (7.60) and
* MMD EEE Link Partner Ability (7.61) registers.
*/
-static inline u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv)
+static inline u16 ethtool_adv_to_mmd_eee_adv_t(ethtool_link_mode_mask_t adv)
{
u16 reg = 0;
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next v1 5/7] net: veth: extend link mode support to 48 bits
From: David Decotigny @ 2015-01-04 20:56 UTC (permalink / raw)
To: Amir Vadai, Florian Fainelli, netdev, linux-kernel, linux-api
Cc: David Decotigny, David S. Miller, Jason Wang, Michael S. Tsirkin,
Herbert Xu, Al Viro, Ben Hutchings, Masatake YAMATO, Xi Wang,
Neil Horman, WANG Cong, Flavio Leitner, Tom Gundersen, Jiri Pirko,
Vlad Yasevich, Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru,
Govindarajulu Varadarajan
In-Reply-To: <1420405017-23278-1-git-send-email-ddecotig@gmail.com>
From: David Decotigny <decot@googlers.com>
Signed-off-by: David Decotigny <decot@googlers.com>
---
drivers/net/veth.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 8ad5965..902e127 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -49,8 +49,8 @@ static struct {
static int veth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- cmd->supported = 0;
- cmd->advertising = 0;
+ ethtool_cmd_supported_set(cmd, 0);
+ ethtool_cmd_advertising_set(cmd, 0);
ethtool_cmd_speed_set(cmd, SPEED_10000);
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_TP;
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next v1 6/7] net: tun: extend link mode support to 48 bits
From: David Decotigny @ 2015-01-04 20:56 UTC (permalink / raw)
To: Amir Vadai, Florian Fainelli, netdev, linux-kernel, linux-api
Cc: David Decotigny, David S. Miller, Jason Wang, Michael S. Tsirkin,
Herbert Xu, Al Viro, Ben Hutchings, Masatake YAMATO, Xi Wang,
Neil Horman, WANG Cong, Flavio Leitner, Tom Gundersen, Jiri Pirko,
Vlad Yasevich, Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru,
Govindarajulu Varadarajan
In-Reply-To: <1420405017-23278-1-git-send-email-ddecotig@gmail.com>
From: David Decotigny <decot@googlers.com>
Signed-off-by: David Decotigny <decot@googlers.com>
---
drivers/net/tun.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index c0df872..88f9078 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -2257,8 +2257,8 @@ static struct miscdevice tun_miscdev = {
static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- cmd->supported = 0;
- cmd->advertising = 0;
+ ethtool_cmd_supported_set(cmd, 0);
+ ethtool_cmd_advertising_set(cmd, 0);
ethtool_cmd_speed_set(cmd, SPEED_10);
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_TP;
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next v1 7/7] net: mlx4_en: extend link mode support to 48 bits
From: David Decotigny @ 2015-01-04 20:56 UTC (permalink / raw)
To: Amir Vadai, Florian Fainelli, netdev, linux-kernel, linux-api
Cc: David Decotigny, David S. Miller, Jason Wang, Michael S. Tsirkin,
Herbert Xu, Al Viro, Ben Hutchings, Masatake YAMATO, Xi Wang,
Neil Horman, WANG Cong, Flavio Leitner, Tom Gundersen, Jiri Pirko,
Vlad Yasevich, Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru,
Govindarajulu Varadarajan
In-Reply-To: <1420405017-23278-1-git-send-email-ddecotig@gmail.com>
From: David Decotigny <decot@googlers.com>
Signed-off-by: David Decotigny <decot@googlers.com>
---
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 67 +++++++++++++++----------
1 file changed, 40 insertions(+), 27 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 90e0f04..395ab72 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -388,7 +388,8 @@ static u32 mlx4_en_autoneg_get(struct net_device *dev)
return autoneg;
}
-static u32 ptys_get_supported_port(struct mlx4_ptys_reg *ptys_reg)
+static ethtool_link_mode_mask_t
+ptys_get_supported_port(struct mlx4_ptys_reg *ptys_reg)
{
u32 eth_proto = be32_to_cpu(ptys_reg->eth_proto_cap);
@@ -465,7 +466,7 @@ enum ethtool_report {
};
/* Translates mlx4 link mode to equivalent ethtool Link modes/speed */
-static u32 ptys2ethtool_map[MLX4_LINK_MODES_SZ][3] = {
+static u64 ptys2ethtool_map[MLX4_LINK_MODES_SZ][3] = {
[MLX4_100BASE_TX] = {
SUPPORTED_100baseT_Full,
ADVERTISED_100baseT_Full,
@@ -558,10 +559,11 @@ static u32 ptys2ethtool_map[MLX4_LINK_MODES_SZ][3] = {
},
};
-static u32 ptys2ethtool_link_modes(u32 eth_proto, enum ethtool_report report)
+static ethtool_link_mode_mask_t
+ptys2ethtool_link_modes(u32 eth_proto, enum ethtool_report report)
{
int i;
- u32 link_modes = 0;
+ ethtool_link_mode_mask_t link_modes = 0;
for (i = 0; i < MLX4_LINK_MODES_SZ; i++) {
if (eth_proto & MLX4_PROT_MASK(i))
@@ -570,7 +572,8 @@ static u32 ptys2ethtool_link_modes(u32 eth_proto, enum ethtool_report report)
return link_modes;
}
-static u32 ethtool2ptys_link_modes(u32 link_modes, enum ethtool_report report)
+static u32 ethtool2ptys_link_modes(ethtool_link_mode_mask_t link_modes,
+ enum ethtool_report report)
{
int i;
u32 ptys_modes = 0;
@@ -601,6 +604,9 @@ static int ethtool_get_ptys_settings(struct net_device *dev,
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_ptys_reg ptys_reg;
u32 eth_proto;
+ ethtool_link_mode_mask_t eth_supported;
+ ethtool_link_mode_mask_t eth_advertising;
+ ethtool_link_mode_mask_t eth_lp_advertising;
int ret;
memset(&ptys_reg, 0, sizeof(ptys_reg));
@@ -624,41 +630,44 @@ static int ethtool_get_ptys_settings(struct net_device *dev,
en_dbg(DRV, priv, "ptys_reg.eth_proto_lp_adv %x\n",
be32_to_cpu(ptys_reg.eth_proto_lp_adv));
- cmd->supported = 0;
- cmd->advertising = 0;
+ eth_supported = 0;
+ eth_advertising = 0;
- cmd->supported |= ptys_get_supported_port(&ptys_reg);
+ eth_supported |= ptys_get_supported_port(&ptys_reg);
eth_proto = be32_to_cpu(ptys_reg.eth_proto_cap);
- cmd->supported |= ptys2ethtool_link_modes(eth_proto, SUPPORTED);
+ eth_supported |= ptys2ethtool_link_modes(eth_proto, SUPPORTED);
eth_proto = be32_to_cpu(ptys_reg.eth_proto_admin);
- cmd->advertising |= ptys2ethtool_link_modes(eth_proto, ADVERTISED);
+ eth_advertising |= ptys2ethtool_link_modes(eth_proto, ADVERTISED);
- cmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
- cmd->advertising |= (priv->prof->tx_pause) ? ADVERTISED_Pause : 0;
+ eth_supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+ eth_advertising |= (priv->prof->tx_pause) ? ADVERTISED_Pause : 0;
- cmd->advertising |= (priv->prof->tx_pause ^ priv->prof->rx_pause) ?
+ eth_advertising |= (priv->prof->tx_pause ^ priv->prof->rx_pause) ?
ADVERTISED_Asym_Pause : 0;
cmd->port = ptys_get_active_port(&ptys_reg);
- cmd->transceiver = (SUPPORTED_TP & cmd->supported) ?
+ cmd->transceiver = (SUPPORTED_TP & eth_supported) ?
XCVR_EXTERNAL : XCVR_INTERNAL;
if (mlx4_en_autoneg_get(dev)) {
- cmd->supported |= SUPPORTED_Autoneg;
- cmd->advertising |= ADVERTISED_Autoneg;
+ eth_supported |= SUPPORTED_Autoneg;
+ eth_advertising |= ADVERTISED_Autoneg;
}
cmd->autoneg = (priv->port_state.flags & MLX4_EN_PORT_ANC) ?
AUTONEG_ENABLE : AUTONEG_DISABLE;
eth_proto = be32_to_cpu(ptys_reg.eth_proto_lp_adv);
- cmd->lp_advertising = ptys2ethtool_link_modes(eth_proto, ADVERTISED);
+ eth_lp_advertising = ptys2ethtool_link_modes(eth_proto, ADVERTISED);
- cmd->lp_advertising |= (priv->port_state.flags & MLX4_EN_PORT_ANC) ?
+ eth_lp_advertising |= (priv->port_state.flags & MLX4_EN_PORT_ANC) ?
ADVERTISED_Autoneg : 0;
+ ethtool_cmd_supported_set(cmd, eth_supported);
+ ethtool_cmd_advertising_set(cmd, eth_advertising);
+ ethtool_cmd_lp_advertising_set(cmd, eth_lp_advertising);
cmd->phy_address = 0;
cmd->mdio_support = 0;
cmd->maxtxpkt = 0;
@@ -673,27 +682,30 @@ static void ethtool_get_default_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
+ ethtool_link_mode_mask_t eth_supported, eth_advertising;
int trans_type;
cmd->autoneg = AUTONEG_DISABLE;
- cmd->supported = SUPPORTED_10000baseT_Full;
- cmd->advertising = ADVERTISED_10000baseT_Full;
+ eth_supported = SUPPORTED_10000baseT_Full;
+ eth_advertising = ADVERTISED_10000baseT_Full;
trans_type = priv->port_state.transceiver;
if (trans_type > 0 && trans_type <= 0xC) {
cmd->port = PORT_FIBRE;
cmd->transceiver = XCVR_EXTERNAL;
- cmd->supported |= SUPPORTED_FIBRE;
- cmd->advertising |= ADVERTISED_FIBRE;
+ eth_supported |= SUPPORTED_FIBRE;
+ eth_advertising |= ADVERTISED_FIBRE;
} else if (trans_type == 0x80 || trans_type == 0) {
cmd->port = PORT_TP;
cmd->transceiver = XCVR_INTERNAL;
- cmd->supported |= SUPPORTED_TP;
- cmd->advertising |= ADVERTISED_TP;
+ eth_supported |= SUPPORTED_TP;
+ eth_advertising |= ADVERTISED_TP;
} else {
cmd->port = -1;
cmd->transceiver = -1;
}
+ ethtool_cmd_supported_set(cmd, eth_supported);
+ ethtool_cmd_advertising_set(cmd, eth_advertising);
}
static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -747,13 +759,14 @@ static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_ptys_reg ptys_reg;
__be32 proto_admin;
+ const ethtool_link_mode_mask_t eth_adv = ethtool_cmd_advertising(cmd);
int ret;
- u32 ptys_adv = ethtool2ptys_link_modes(cmd->advertising, ADVERTISED);
+ u32 ptys_adv = ethtool2ptys_link_modes(eth_adv, ADVERTISED);
int speed = ethtool_cmd_speed(cmd);
- en_dbg(DRV, priv, "Set Speed=%d adv=0x%x autoneg=%d duplex=%d\n",
- speed, cmd->advertising, cmd->autoneg, cmd->duplex);
+ en_dbg(DRV, priv, "Set Speed=%d adv=0x%llx autoneg=%d duplex=%d\n",
+ speed, eth_adv, cmd->autoneg, cmd->duplex);
if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL) ||
(cmd->duplex == DUPLEX_HALF))
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* Re: [PATCH net-next v1 0/7] net: extend ethtool link mode bitmaps to 48 bits
From: Ben Hutchings @ 2015-01-04 21:55 UTC (permalink / raw)
To: David Decotigny
Cc: Amir Vadai, Florian Fainelli, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, David Decotigny,
David S. Miller, Jason Wang, Michael S. Tsirkin, Herbert Xu,
Al Viro, Masatake YAMATO, Xi Wang, Neil Horman, WANG Cong,
Flavio Leitner, Tom Gundersen, Jiri Pirko, Vlad Yasevich,
Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru,
Govindarajulu Varadarajan
In-Reply-To: <1420405017-23278-1-git-send-email-ddecotig-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 507 bytes --]
On Sun, 2015-01-04 at 12:56 -0800, David Decotigny wrote:
[...]
> I can send updates to other drivers, even though it's rather pointless
> to update 1G drivers at this point for example. Please let me know,
> but I'd prefer to do this in follow-up patches outside this first
> patch series.
[...]
They should be changed to ensure they reject setting any of the high
advertising flags, but it's not urgent.
Ben.
--
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v1 1/7] net: ethtool: extend link mode support to 48 bits
From: Ben Hutchings @ 2015-01-04 22:01 UTC (permalink / raw)
To: David Decotigny
Cc: Amir Vadai, Florian Fainelli, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, David Decotigny,
David S. Miller, Jason Wang, Michael S. Tsirkin, Herbert Xu,
Al Viro, Masatake YAMATO, Xi Wang, Neil Horman, WANG Cong,
Flavio Leitner, Tom Gundersen, Jiri Pirko, Vlad Yasevich,
Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru,
Govindarajulu Varadarajan
In-Reply-To: <1420405017-23278-2-git-send-email-ddecotig-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 3096 bytes --]
On Sun, 2015-01-04 at 12:56 -0800, David Decotigny wrote:
> From: David Decotigny <decot-Ypc/8FJVVoBWk0Htik3J/w@public.gmane.org>
This is mostly fine, with just a few minor issues.
> Signed-off-by: David Decotigny <decot-Ypc/8FJVVoBWk0Htik3J/w@public.gmane.org>
> ---
> include/uapi/linux/ethtool.h | 130 ++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 110 insertions(+), 20 deletions(-)
>
> diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> index 5f66d9c..61e7734 100644
> --- a/include/uapi/linux/ethtool.h
> +++ b/include/uapi/linux/ethtool.h
[...]
> @@ -123,6 +140,46 @@ static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
> return (ep->speed_hi << 16) | ep->speed;
> }
>
> +/**
> + * MAKE_ETHTOOL_LINK_MODE_ACCESSORS - create the link_mode accessors
> + * Macro to generate the %ethtool_cmd_supported_*,
> + * %ethtool_cmd_advertising_*, %ethtool_cmd_lp_advertising_*,
> + * %ethtool_eee_supported_*, %ethtool_eee_advertised_*,
> + * %ethtool_eee_lp_advertised_* families of functions.
> + *
> + * Macro args:
Delete the 'Macro args:' heading; that's implied by the @ prefixes.
> + * @struct_name: either %ethtool_cmd or %ethtool_eee
> + * @field_name: name of the fields in %struct_name to
> + * access. supported/advertising/lp_advertising for ethtool_cmd,
> + * supported/advertised/lp_advertised for ethtool_eee
> + *
> + * Generates the following static functions:
> + * @ethtool_cmd_supported(const struct ethtool_cmd*): returns
> + * the 64b value of %supported fields (the upper bits 63..48 are 0)
> + * @ethtool_cmd_supported_set(struct ethtool_cmd*,
> + * ethtool_link_mode_mask_t value): set the %supported fields to
> + * given %value (only the lower 48 bits used, upper bits 63..48
> + * ignored)
Delete the @ prefixes from these headings.
> + * Same doc for all the other functions.
> + */
> +#define MAKE_ETHTOOL_LINK_MODE_ACCESSORS(struct_name, field_name) \
I think the name should begin with ETHTOOL but it's not a big deal.
[...]
> @@ -1192,6 +1273,9 @@ enum ethtool_sfeatures_retval_bits {
> #define SPARC_ETH_GSET ETHTOOL_GSET
> #define SPARC_ETH_SSET ETHTOOL_SSET
>
> +/* Do not use the following macros directly to update
> + * ethtool_cmd::supported, ethtool_eee::supported. Please use
> + * ethtool_(cmd|eee)_supported(|_set) instead */
The ending */ belongs on a new line.
> #define SUPPORTED_10baseT_Half (1 << 0)
> #define SUPPORTED_10baseT_Full (1 << 1)
> #define SUPPORTED_100baseT_Half (1 << 2)
> @@ -1223,7 +1307,12 @@ enum ethtool_sfeatures_retval_bits {
> #define SUPPORTED_56000baseCR4_Full (1 << 28)
> #define SUPPORTED_56000baseSR4_Full (1 << 29)
> #define SUPPORTED_56000baseLR4_Full (1 << 30)
> +/* TODO: for bit indices >= 31, make sure to shift 1ULL instead of 1 */
[...]
I don't think that comment is necessary; the compiler will surely warn
if someone forgets.
Ben.
--
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v1 2/7] net: phy: extend link mode support to 48 bits
From: Ben Hutchings @ 2015-01-04 22:03 UTC (permalink / raw)
To: David Decotigny
Cc: Amir Vadai, Florian Fainelli, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, David Decotigny,
David S. Miller, Jason Wang, Michael S. Tsirkin, Herbert Xu,
Al Viro, Masatake YAMATO, Xi Wang, Neil Horman, WANG Cong,
Flavio Leitner, Tom Gundersen, Jiri Pirko, Vlad Yasevich,
Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru,
Govindarajulu Varadarajan
In-Reply-To: <1420405017-23278-3-git-send-email-ddecotig-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 2212 bytes --]
On Sun, 2015-01-04 at 12:56 -0800, David Decotigny wrote:
> From: David Decotigny <decot-Ypc/8FJVVoBWk0Htik3J/w@public.gmane.org>
>
> Signed-off-by: David Decotigny <decot-Ypc/8FJVVoBWk0Htik3J/w@public.gmane.org>
> ---
> drivers/net/phy/phy.c | 29 ++++++++++++++---------------
> drivers/net/phy/phy_device.c | 4 ++--
> include/linux/phy.h | 10 +++++-----
> 3 files changed, 21 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index 767cd11..e9c8499 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
[...]
> @@ -245,7 +246,7 @@ static inline unsigned int phy_find_valid(unsigned int idx, u32 features)
> */
> static void phy_sanitize_settings(struct phy_device *phydev)
> {
> - u32 features = phydev->supported;
> + ethtool_link_mode_mask_t features = phydev->supported;
> unsigned int idx;
>
> /* Sanitize settings based on PHY capabilities */
> @@ -279,13 +280,13 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
> return -EINVAL;
>
> /* We make sure that we don't pass unsupported values in to the PHY */
> - cmd->advertising &= phydev->supported;
> + phydev->advertising = ethtool_cmd_advertising(cmd) & phydev->supported;
phydev->advertising should not be changed until after the following
validation. Use a local variable for this.
> /* Verify the settings we care about. */
> if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
> return -EINVAL;
>
> - if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
> + if (cmd->autoneg == AUTONEG_ENABLE && phydev->advertising == 0)
> return -EINVAL;
>
> if (cmd->autoneg == AUTONEG_DISABLE &&
> @@ -300,8 +301,6 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
>
> phydev->speed = speed;
>
> - phydev->advertising = cmd->advertising;
> -
> if (AUTONEG_ENABLE == cmd->autoneg)
> phydev->advertising |= ADVERTISED_Autoneg;
> else
[...]
The assignment to phydev->advertising should probably remain here.
Ben.
--
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v1 0/7] net: extend ethtool link mode bitmaps to 48 bits
From: Maciej Żenczykowski @ 2015-01-05 0:34 UTC (permalink / raw)
To: Ben Hutchings
Cc: David Decotigny, Amir Vadai, Florian Fainelli, Linux NetDev,
Linux Kernel Mailing List, linux-api-u79uwXL29TY76Z2rM5mHXA,
David Decotigny, David S. Miller, Jason Wang, Michael S. Tsirkin,
Herbert Xu, Al Viro, Masatake YAMATO, Xi Wang, Neil Horman,
WANG Cong, Flavio Leitner, Tom Gundersen, Jiri Pirko,
Vlad Yasevich, Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru,
Govindaraj
In-Reply-To: <1420408540.5686.140.camel-/+tVBieCtBitmTQ+vhA3Yw@public.gmane.org>
>> I can send updates to other drivers, even though it's rather pointless
>> to update 1G drivers at this point for example. Please let me know,
>> but I'd prefer to do this in follow-up patches outside this first
>> patch series.
> [...]
>
> They should be changed to ensure they reject setting any of the high
> advertising flags, but it's not urgent.
if old drivers advertised a get/set_bits function while new drivers
advertised a get/set_new_bits function,
you could not updated any old drivers, and simply take care of
rejecting invalid bits in core, by calling set_new_bits if provided,
if not, rejecting bad bits and calling set_bits if no bad bits were
set.
^ permalink raw reply
* Re: [PATCH net-next v1 0/7] net: extend ethtool link mode bitmaps to 48 bits
From: Ben Hutchings @ 2015-01-05 2:30 UTC (permalink / raw)
To: Maciej Żenczykowski
Cc: David Decotigny, Amir Vadai, Florian Fainelli, Linux NetDev,
Linux Kernel Mailing List, linux-api, David Decotigny,
David S. Miller, Jason Wang, Michael S. Tsirkin, Herbert Xu,
Al Viro, Masatake YAMATO, Xi Wang, Neil Horman, WANG Cong,
Flavio Leitner, Tom Gundersen, Jiri Pirko, Vlad Yasevich,
Eric W. Biederman, Saeed Mahameed, Venkata Duvvuru, Govindaraj
In-Reply-To: <CAHo-Ooxi8V_58b456vePY9_7ChuBe0jxEVHvGkGvRBpAR744yA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1240 bytes --]
On Mon, 2015-01-05 at 01:34 +0100, Maciej Żenczykowski wrote:
> >> I can send updates to other drivers, even though it's rather pointless
> >> to update 1G drivers at this point for example. Please let me know,
> >> but I'd prefer to do this in follow-up patches outside this first
> >> patch series.
> > [...]
> >
> > They should be changed to ensure they reject setting any of the high
> > advertising flags, but it's not urgent.
>
> if old drivers advertised a get/set_bits function while new drivers
> advertised a get/set_new_bits function,
> you could not updated any old drivers, and simply take care of
> rejecting invalid bits in core, by calling set_new_bits if provided,
> if not, rejecting bad bits and calling set_bits if no bad bits were
> set.
We've never checked that the reserved fields are zero before, and I
think there are still drivers that don't fully validate the existing 32
bits. So while I think drivers should fully validate the advertising
flags, userland generally can't assume they do. And therefore I don't
think it's worth adding complexity to the ethtool core that only partly
fixes this.
Ben.
--
Ben Hutchings
This sentence contradicts itself - no actually it doesn't.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]
^ permalink raw reply
* [PATCH v4 0/4] power: Add max77693 charger driver
From: Krzysztof Kozlowski @ 2015-01-05 10:16 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
Samuel Ortiz, Lee Jones, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Krzysztof Kozlowski
Hi,
Changes since v3
================
1. Patch 3/4: Don't create platform data structure for charger settings
because driver won't be used on non-DT SoCs (its for Exynos based
Trats2).
2. Patch 3/4: Drop Sebastian's ack [1] because of change above.
Changes since v2
================
1. Add ack from Sebastian Reichel (charger driver).
2. Drop patch "mfd: max77693: Map charger device to its own of_node"
(applied by Lee Jones).
Changes since v1
================
1. Add patch 2/5: mfd: max77693: Map charger device to its own of_node
(forgot to send it in v1)
2. Remove patches for DTS and configs. I'll send them later.
3. Add ack from Lee Jones (patch 3/5).
Description
===========
The patchset adds max77693 charger driver present on Trats2 board
(and Galaxy S III). The driver configures battery charger and exposes
power supply interface.
Driver is necessary to provide full charging stack on Trats2 device
(extcon, charger-manager etc.).
[1] https://lkml.org/lkml/2014/10/27/774
Best regards,
Krzysztof
Krzysztof Kozlowski (4):
devicetree: power/mfd: max77693: Document new bindings for charger
mfd: max77693: Add defines for MAX77693 charger driver
power: max77693: Add charger driver for Maxim 77693
Documentation: power: max77693-charger: Document exported sysfs entry
Documentation/ABI/testing/sysfs-class-power | 42 ++
Documentation/devicetree/bindings/mfd/max77693.txt | 45 ++
drivers/power/Kconfig | 6 +
drivers/power/Makefile | 1 +
drivers/power/max77693_charger.c | 758 +++++++++++++++++++++
include/linux/mfd/max77693-private.h | 108 +++
6 files changed, 960 insertions(+)
create mode 100644 drivers/power/max77693_charger.c
--
1.9.1
^ permalink raw reply
* [PATCH v4 1/4] devicetree: power/mfd: max77693: Document new bindings for charger
From: Krzysztof Kozlowski @ 2015-01-05 10:16 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
Samuel Ortiz, Lee Jones, linux-kernel, linux-pm, devicetree,
linux-api
Cc: Krzysztof Kozlowski
In-Reply-To: <1420453019-28614-1-git-send-email-k.kozlowski@samsung.com>
Document new device tree bindings for Maxim 77693 charger driver.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
Documentation/devicetree/bindings/mfd/max77693.txt | 45 ++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/Documentation/devicetree/bindings/mfd/max77693.txt b/Documentation/devicetree/bindings/mfd/max77693.txt
index 01e9f30fe678..38e64405e98d 100644
--- a/Documentation/devicetree/bindings/mfd/max77693.txt
+++ b/Documentation/devicetree/bindings/mfd/max77693.txt
@@ -41,6 +41,41 @@ Optional properties:
To get more informations, please refer to documentaion.
[*] refer Documentation/devicetree/bindings/pwm/pwm.txt
+- charger : Node configuring the charger driver.
+ If present, required properties:
+ - compatible : Must be "maxim,max77693-charger".
+
+ Optional properties (if not set, defaults will be used):
+ - maxim,constant-microvolt : Battery constant voltage in uV. The charger
+ will operate in fast charge constant current mode till battery voltage
+ reaches this level. Then the charger will switch to fast charge constant
+ voltage mode. Also vsys (system voltage) will be set to this value when
+ DC power is supplied but charger is not enabled.
+ Valid values: 3650000 - 4400000, step by 25000 (rounded down)
+ Default: 4200000
+
+ - maxim,min-system-microvolt : Minimal system voltage in uV.
+ Valid values: 3000000 - 3700000, step by 100000 (rounded down)
+ Default: 3600000
+
+ - maxim,thermal-regulation-celsius : Temperature in Celsius for entering
+ high temperature charging mode. If die temperature exceeds this value
+ the charging current will be reduced by 105 mA/Celsius.
+ Valid values: 70, 85, 100, 115
+ Default: 100
+
+ - maxim,battery-overcurrent-microamp : Overcurrent protection threshold
+ in uA (current from battery to system).
+ Valid values: 2000000 - 3500000, step by 250000 (rounded down)
+ Default: 3500000
+
+ - maxim,charge-input-threshold-microvolt : Threshold voltage in uV for
+ triggering input voltage regulation loop. If input voltage decreases
+ below this value, the input current will be reduced to reach the
+ threshold voltage.
+ Valid values: 4300000, 4700000, 4800000, 4900000
+ Default: 4300000
+
Example:
max77693@66 {
compatible = "maxim,max77693";
@@ -73,4 +108,14 @@ Example:
pwms = <&pwm 0 40000 0>;
pwm-names = "haptic";
};
+
+ charger {
+ compatible = "maxim,max77693-charger";
+
+ maxim,constant-microvolt = <4200000>;
+ maxim,min-system-microvolt = <3600000>;
+ maxim,thermal-regulation-celsius = <75>;
+ maxim,battery-overcurrent-microamp = <3000000>;
+ maxim,charge-input-threshold-microvolt = <4300000>;
+ };
};
--
1.9.1
^ permalink raw reply related
* [PATCH v4 2/4] mfd: max77693: Add defines for MAX77693 charger driver
From: Krzysztof Kozlowski @ 2015-01-05 10:16 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
Samuel Ortiz, Lee Jones, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Krzysztof Kozlowski
In-Reply-To: <1420453019-28614-1-git-send-email-k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Prepare for adding support for Maxim 77693 charger by adding necessary
new defines.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
include/linux/mfd/max77693-private.h | 108 +++++++++++++++++++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index 08dae01258b9..955dd990beaf 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -143,10 +143,118 @@ enum max77693_pmic_reg {
#define FLASH_INT_FLED1_SHORT BIT(3)
#define FLASH_INT_OVER_CURRENT BIT(4)
+/* Fast charge timer in in hours */
+#define DEFAULT_FAST_CHARGE_TIMER 4
+/* microamps */
+#define DEFAULT_TOP_OFF_THRESHOLD_CURRENT 150000
+/* minutes */
+#define DEFAULT_TOP_OFF_TIMER 30
+/* microvolts */
+#define DEFAULT_CONSTANT_VOLT 4200000
+/* microvolts */
+#define DEFAULT_MIN_SYSTEM_VOLT 3600000
+/* celsius */
+#define DEFAULT_THERMAL_REGULATION_TEMP 100
+/* microamps */
+#define DEFAULT_BATTERY_OVERCURRENT 3500000
+/* microvolts */
+#define DEFAULT_CHARGER_INPUT_THRESHOLD_VOLT 4300000
+
+/* MAX77693_CHG_REG_CHG_INT_OK register */
+#define CHG_INT_OK_BYP_SHIFT 0
+#define CHG_INT_OK_BAT_SHIFT 3
+#define CHG_INT_OK_CHG_SHIFT 4
+#define CHG_INT_OK_CHGIN_SHIFT 6
+#define CHG_INT_OK_DETBAT_SHIFT 7
+#define CHG_INT_OK_BYP_MASK BIT(CHG_INT_OK_BYP_SHIFT)
+#define CHG_INT_OK_BAT_MASK BIT(CHG_INT_OK_BAT_SHIFT)
+#define CHG_INT_OK_CHG_MASK BIT(CHG_INT_OK_CHG_SHIFT)
+#define CHG_INT_OK_CHGIN_MASK BIT(CHG_INT_OK_CHGIN_SHIFT)
+#define CHG_INT_OK_DETBAT_MASK BIT(CHG_INT_OK_DETBAT_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_DETAILS_00 register */
+#define CHG_DETAILS_00_CHGIN_SHIFT 5
+#define CHG_DETAILS_00_CHGIN_MASK (0x3 << CHG_DETAILS_00_CHGIN_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_DETAILS_01 register */
+#define CHG_DETAILS_01_CHG_SHIFT 0
+#define CHG_DETAILS_01_BAT_SHIFT 4
+#define CHG_DETAILS_01_TREG_SHIFT 7
+#define CHG_DETAILS_01_CHG_MASK (0xf << CHG_DETAILS_01_CHG_SHIFT)
+#define CHG_DETAILS_01_BAT_MASK (0x7 << CHG_DETAILS_01_BAT_SHIFT)
+#define CHG_DETAILS_01_TREG_MASK BIT(7)
+
+/* MAX77693_CHG_REG_CHG_DETAILS_01/CHG field */
+enum max77693_charger_charging_state {
+ MAX77693_CHARGING_PREQUALIFICATION = 0x0,
+ MAX77693_CHARGING_FAST_CONST_CURRENT,
+ MAX77693_CHARGING_FAST_CONST_VOLTAGE,
+ MAX77693_CHARGING_TOP_OFF,
+ MAX77693_CHARGING_DONE,
+ MAX77693_CHARGING_HIGH_TEMP,
+ MAX77693_CHARGING_TIMER_EXPIRED,
+ MAX77693_CHARGING_THERMISTOR_SUSPEND,
+ MAX77693_CHARGING_OFF,
+ MAX77693_CHARGING_RESERVED,
+ MAX77693_CHARGING_OVER_TEMP,
+ MAX77693_CHARGING_WATCHDOG_EXPIRED,
+};
+
+/* MAX77693_CHG_REG_CHG_DETAILS_01/BAT field */
+enum max77693_charger_battery_state {
+ MAX77693_BATTERY_NOBAT = 0x0,
+ /* Dead-battery or low-battery prequalification */
+ MAX77693_BATTERY_PREQUALIFICATION,
+ MAX77693_BATTERY_TIMER_EXPIRED,
+ MAX77693_BATTERY_GOOD,
+ MAX77693_BATTERY_LOWVOLTAGE,
+ MAX77693_BATTERY_OVERVOLTAGE,
+ MAX77693_BATTERY_OVERCURRENT,
+ MAX77693_BATTERY_RESERVED,
+};
+
+/* MAX77693_CHG_REG_CHG_DETAILS_02 register */
+#define CHG_DETAILS_02_BYP_SHIFT 0
+#define CHG_DETAILS_02_BYP_MASK (0xf << CHG_DETAILS_02_BYP_SHIFT)
+
/* MAX77693 CHG_CNFG_00 register */
#define CHG_CNFG_00_CHG_MASK 0x1
#define CHG_CNFG_00_BUCK_MASK 0x4
+/* MAX77693_CHG_REG_CHG_CNFG_01 register */
+#define CHG_CNFG_01_FCHGTIME_SHIFT 0
+#define CHG_CNFG_01_CHGRSTRT_SHIFT 4
+#define CHG_CNFG_01_PQEN_SHIFT 7
+#define CHG_CNFG_01_FCHGTIME_MASK (0x7 << CHG_CNFG_01_FCHGTIME_SHIFT)
+#define CHG_CNFG_01_CHGRSTRT_MASK (0x3 << CHG_CNFG_01_CHGRSTRT_SHIFT)
+#define CHG_CNFG_01_PQEN_MAKS BIT(CHG_CNFG_01_PQEN_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_CNFG_03 register */
+#define CHG_CNFG_03_TOITH_SHIFT 0
+#define CHG_CNFG_03_TOTIME_SHIFT 3
+#define CHG_CNFG_03_TOITH_MASK (0x7 << CHG_CNFG_03_TOITH_SHIFT)
+#define CHG_CNFG_03_TOTIME_MASK (0x7 << CHG_CNFG_03_TOTIME_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_CNFG_04 register */
+#define CHG_CNFG_04_CHGCVPRM_SHIFT 0
+#define CHG_CNFG_04_MINVSYS_SHIFT 5
+#define CHG_CNFG_04_CHGCVPRM_MASK (0x1f << CHG_CNFG_04_CHGCVPRM_SHIFT)
+#define CHG_CNFG_04_MINVSYS_MASK (0x7 << CHG_CNFG_04_MINVSYS_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_CNFG_06 register */
+#define CHG_CNFG_06_CHGPROT_SHIFT 2
+#define CHG_CNFG_06_CHGPROT_MASK (0x3 << CHG_CNFG_06_CHGPROT_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_CNFG_07 register */
+#define CHG_CNFG_07_REGTEMP_SHIFT 5
+#define CHG_CNFG_07_REGTEMP_MASK (0x3 << CHG_CNFG_07_REGTEMP_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_CNFG_12 register */
+#define CHG_CNFG_12_B2SOVRC_SHIFT 0
+#define CHG_CNFG_12_VCHGINREG_SHIFT 3
+#define CHG_CNFG_12_B2SOVRC_MASK (0x7 << CHG_CNFG_12_B2SOVRC_SHIFT)
+#define CHG_CNFG_12_VCHGINREG_MASK (0x3 << CHG_CNFG_12_VCHGINREG_SHIFT)
+
/* MAX77693 CHG_CNFG_09 Register */
#define CHG_CNFG_09_CHGIN_ILIM_MASK 0x7F
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v4 3/4] power: max77693: Add charger driver for Maxim 77693
From: Krzysztof Kozlowski @ 2015-01-05 10:16 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
Samuel Ortiz, Lee Jones, linux-kernel, linux-pm, devicetree,
linux-api
Cc: Krzysztof Kozlowski
In-Reply-To: <1420453019-28614-1-git-send-email-k.kozlowski@samsung.com>
Add new driver for Maxim 77693 switch-mode charger (part of max77693
MFD driver) providing power supply class information to userspace.
The charger has +20V tolerant input. Current input can be set from 0 to
2.58 A. The charger can deliver up to 2.1 A to the battery or 3.5 A to
the system (when supplying additional current from battery to system).
The driver is configured through DTS (battery and system related
settings) and sysfs entries (timers and top-off charging threshold).
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
drivers/power/Kconfig | 6 +
drivers/power/Makefile | 1 +
drivers/power/max77693_charger.c | 758 +++++++++++++++++++++++++++++++++++++++
3 files changed, 765 insertions(+)
create mode 100644 drivers/power/max77693_charger.c
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 0108c2af005b..77e6cd7bb801 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -332,6 +332,12 @@ config CHARGER_MAX14577
Say Y to enable support for the battery charger control sysfs and
platform data of MAX14577/77836 MUICs.
+config CHARGER_MAX77693
+ tristate "Maxim MAX77693 battery charger driver"
+ depends on MFD_MAX77693
+ help
+ Say Y to enable support for the Maxim MAX77693 battery charger.
+
config CHARGER_MAX8997
tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
depends on MFD_MAX8997 && REGULATOR_MAX8997
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index dfa894273926..2d7ad66cc7d6 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
obj-$(CONFIG_CHARGER_MAX14577) += max14577_charger.o
+obj-$(CONFIG_CHARGER_MAX77693) += max77693_charger.o
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
diff --git a/drivers/power/max77693_charger.c b/drivers/power/max77693_charger.c
new file mode 100644
index 000000000000..56cf2177aad4
--- /dev/null
+++ b/drivers/power/max77693_charger.c
@@ -0,0 +1,758 @@
+/*
+ * max77693_charger.c - Battery charger driver for the Maxim 77693
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ * Krzysztof Kozlowski <k.kozlowski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regmap.h>
+#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-private.h>
+
+static const char *max77693_charger_name = "max77693-charger";
+static const char *max77693_charger_model = "MAX77693";
+static const char *max77693_charger_manufacturer = "Maxim Integrated";
+
+struct max77693_charger {
+ struct device *dev;
+ struct max77693_dev *max77693;
+ struct power_supply charger;
+
+ u32 constant_volt;
+ u32 min_system_volt;
+ u32 thermal_regulation_temp;
+ u32 batttery_overcurrent;
+ u32 charge_input_threshold_volt;
+};
+
+static int max77693_get_charger_state(struct regmap *regmap)
+{
+ int state;
+ unsigned int data;
+
+ if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0)
+ return POWER_SUPPLY_STATUS_UNKNOWN;
+
+ data &= CHG_DETAILS_01_CHG_MASK;
+ data >>= CHG_DETAILS_01_CHG_SHIFT;
+
+ switch (data) {
+ case MAX77693_CHARGING_PREQUALIFICATION:
+ case MAX77693_CHARGING_FAST_CONST_CURRENT:
+ case MAX77693_CHARGING_FAST_CONST_VOLTAGE:
+ case MAX77693_CHARGING_TOP_OFF:
+ /* In high temp the charging current is reduced, but still charging */
+ case MAX77693_CHARGING_HIGH_TEMP:
+ state = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+ case MAX77693_CHARGING_DONE:
+ state = POWER_SUPPLY_STATUS_FULL;
+ break;
+ case MAX77693_CHARGING_TIMER_EXPIRED:
+ case MAX77693_CHARGING_THERMISTOR_SUSPEND:
+ state = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+ case MAX77693_CHARGING_OFF:
+ case MAX77693_CHARGING_OVER_TEMP:
+ case MAX77693_CHARGING_WATCHDOG_EXPIRED:
+ state = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ case MAX77693_CHARGING_RESERVED:
+ default:
+ state = POWER_SUPPLY_STATUS_UNKNOWN;
+ }
+
+ return state;
+}
+
+static int max77693_get_charge_type(struct regmap *regmap)
+{
+ int state;
+ unsigned int data;
+
+ if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0)
+ return POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+
+ data &= CHG_DETAILS_01_CHG_MASK;
+ data >>= CHG_DETAILS_01_CHG_SHIFT;
+
+ switch (data) {
+ case MAX77693_CHARGING_PREQUALIFICATION:
+ /*
+ * Top-off: trickle or fast? In top-off the current varies between
+ * 100 and 250 mA. It is higher than prequalification current.
+ */
+ case MAX77693_CHARGING_TOP_OFF:
+ state = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+ break;
+ case MAX77693_CHARGING_FAST_CONST_CURRENT:
+ case MAX77693_CHARGING_FAST_CONST_VOLTAGE:
+ /* In high temp the charging current is reduced, but still charging */
+ case MAX77693_CHARGING_HIGH_TEMP:
+ state = POWER_SUPPLY_CHARGE_TYPE_FAST;
+ break;
+ case MAX77693_CHARGING_DONE:
+ case MAX77693_CHARGING_TIMER_EXPIRED:
+ case MAX77693_CHARGING_THERMISTOR_SUSPEND:
+ case MAX77693_CHARGING_OFF:
+ case MAX77693_CHARGING_OVER_TEMP:
+ case MAX77693_CHARGING_WATCHDOG_EXPIRED:
+ state = POWER_SUPPLY_CHARGE_TYPE_NONE;
+ break;
+ case MAX77693_CHARGING_RESERVED:
+ default:
+ state = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+ }
+
+ return state;
+}
+
+/*
+ * Supported health statuses:
+ * - POWER_SUPPLY_HEALTH_DEAD
+ * - POWER_SUPPLY_HEALTH_GOOD
+ * - POWER_SUPPLY_HEALTH_OVERVOLTAGE
+ * - POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE
+ * - POWER_SUPPLY_HEALTH_UNKNOWN
+ * - POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
+ */
+static int max77693_get_battery_health(struct regmap *regmap)
+{
+ int state;
+ unsigned int data;
+
+ if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0)
+ return POWER_SUPPLY_HEALTH_UNKNOWN;
+
+ data &= CHG_DETAILS_01_BAT_MASK;
+ data >>= CHG_DETAILS_01_BAT_SHIFT;
+
+ switch (data) {
+ case MAX77693_BATTERY_NOBAT:
+ state = POWER_SUPPLY_HEALTH_DEAD;
+ break;
+ case MAX77693_BATTERY_PREQUALIFICATION:
+ case MAX77693_BATTERY_GOOD:
+ case MAX77693_BATTERY_LOWVOLTAGE:
+ state = POWER_SUPPLY_HEALTH_GOOD;
+ break;
+ case MAX77693_BATTERY_TIMER_EXPIRED:
+ /*
+ * Took longer to charge than expected, charging suspended.
+ * Damaged battery?
+ */
+ state = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
+ break;
+ case MAX77693_BATTERY_OVERVOLTAGE:
+ state = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+ break;
+ case MAX77693_BATTERY_OVERCURRENT:
+ state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+ break;
+ case MAX77693_BATTERY_RESERVED:
+ default:
+ state = POWER_SUPPLY_HEALTH_UNKNOWN;
+ break;
+ }
+
+ return state;
+}
+
+static int max77693_get_present(struct regmap *regmap)
+{
+ unsigned int data;
+
+ /*
+ * Read CHG_INT_OK register. High DETBAT bit here should be
+ * equal to value 0x0 in CHG_DETAILS_01/BAT field.
+ */
+ regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data);
+ if (data & CHG_INT_OK_DETBAT_MASK)
+ return 0;
+ return 1;
+}
+
+static int max77693_get_online(struct regmap *regmap)
+{
+ unsigned int data;
+
+ regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data);
+ if (data & CHG_INT_OK_CHGIN_MASK)
+ return 1;
+ return 0;
+}
+
+static enum power_supply_property max77693_charger_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_CHARGE_TYPE,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static int max77693_charger_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max77693_charger *chg = container_of(psy,
+ struct max77693_charger,
+ charger);
+ struct regmap *regmap = chg->max77693->regmap;
+ int ret = 0;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = max77693_get_charger_state(regmap);
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
+ val->intval = max77693_get_charge_type(regmap);
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ val->intval = max77693_get_battery_health(regmap);
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = max77693_get_present(regmap);
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = max77693_get_online(regmap);
+ break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = max77693_charger_model;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = max77693_charger_manufacturer;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static ssize_t device_attr_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count,
+ int (*fn)(struct max77693_charger *, unsigned long))
+{
+ struct max77693_charger *chg = dev_get_drvdata(dev);
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 10, &val);
+ if (ret)
+ return ret;
+
+ ret = fn(chg, val);
+ if (ret)
+ return ret;
+
+ return count;
+}
+
+static ssize_t fast_charge_timer_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct max77693_charger *chg = dev_get_drvdata(dev);
+ unsigned int data, val;
+ int ret;
+
+ ret = regmap_read(chg->max77693->regmap, MAX77693_CHG_REG_CHG_CNFG_01,
+ &data);
+ if (ret < 0)
+ return ret;
+
+ data &= CHG_CNFG_01_FCHGTIME_MASK;
+ data >>= CHG_CNFG_01_FCHGTIME_SHIFT;
+ switch (data) {
+ case 0x1 ... 0x7:
+ /* Starting from 4 hours, step by 2 hours */
+ val = 4 + (data - 1) * 2;
+ break;
+ case 0x0:
+ default:
+ val = 0;
+ break;
+ }
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static int max77693_set_fast_charge_timer(struct max77693_charger *chg,
+ unsigned long hours)
+{
+ unsigned int data;
+
+ /*
+ * 0x00 - disable
+ * 0x01 - 4h
+ * 0x02 - 6h
+ * ...
+ * 0x07 - 16h
+ * Round down odd values.
+ */
+ switch (hours) {
+ case 4 ... 16:
+ data = (hours - 4) / 2 + 1;
+ break;
+ case 0:
+ /* Disable */
+ data = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ data <<= CHG_CNFG_01_FCHGTIME_SHIFT;
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_01,
+ CHG_CNFG_01_FCHGTIME_MASK, data);
+}
+
+static ssize_t fast_charge_timer_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return device_attr_store(dev, attr, buf, count,
+ max77693_set_fast_charge_timer);
+}
+
+static ssize_t top_off_threshold_current_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct max77693_charger *chg = dev_get_drvdata(dev);
+ unsigned int data, val;
+ int ret;
+
+ ret = regmap_read(chg->max77693->regmap, MAX77693_CHG_REG_CHG_CNFG_03,
+ &data);
+ if (ret < 0)
+ return ret;
+
+ data &= CHG_CNFG_03_TOITH_MASK;
+ data >>= CHG_CNFG_03_TOITH_SHIFT;
+
+ if (data <= 0x04)
+ val = 100000 + data * 25000;
+ else
+ val = data * 50000;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static int max77693_set_top_off_threshold_current(struct max77693_charger *chg,
+ unsigned long uamp)
+{
+ unsigned int data;
+
+ if (uamp < 100000 || uamp > 350000)
+ return -EINVAL;
+
+ if (uamp <= 200000)
+ data = (uamp - 100000) / 25000;
+ else
+ /* (200000, 350000> */
+ data = uamp / 50000;
+
+ data <<= CHG_CNFG_03_TOITH_SHIFT;
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_03,
+ CHG_CNFG_03_TOITH_MASK, data);
+}
+
+static ssize_t top_off_threshold_current_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return device_attr_store(dev, attr, buf, count,
+ max77693_set_top_off_threshold_current);
+}
+
+static ssize_t top_off_timer_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct max77693_charger *chg = dev_get_drvdata(dev);
+ unsigned int data, val;
+ int ret;
+
+ ret = regmap_read(chg->max77693->regmap, MAX77693_CHG_REG_CHG_CNFG_03,
+ &data);
+ if (ret < 0)
+ return ret;
+
+ data &= CHG_CNFG_03_TOTIME_MASK;
+ data >>= CHG_CNFG_03_TOTIME_SHIFT;
+
+ val = data * 10;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static int max77693_set_top_off_timer(struct max77693_charger *chg,
+ unsigned long minutes)
+{
+ unsigned int data;
+
+ if (minutes > 70)
+ return -EINVAL;
+
+ data = minutes / 10;
+ data <<= CHG_CNFG_03_TOTIME_SHIFT;
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_03,
+ CHG_CNFG_03_TOTIME_MASK, data);
+}
+
+static ssize_t top_off_timer_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return device_attr_store(dev, attr, buf, count,
+ max77693_set_top_off_timer);
+}
+
+static DEVICE_ATTR_RW(fast_charge_timer);
+static DEVICE_ATTR_RW(top_off_threshold_current);
+static DEVICE_ATTR_RW(top_off_timer);
+
+static int max77693_set_constant_volt(struct max77693_charger *chg,
+ unsigned int uvolt)
+{
+ unsigned int data;
+
+ /*
+ * 0x00 - 3.650 V
+ * 0x01 - 3.675 V
+ * ...
+ * 0x1b - 4.325 V
+ * 0x1c - 4.340 V
+ * 0x1d - 4.350 V
+ * 0x1e - 4.375 V
+ * 0x1f - 4.400 V
+ */
+ if (uvolt >= 3650000 && uvolt < 4340000)
+ data = (uvolt - 3650000) / 25000;
+ else if (uvolt >= 4340000 && uvolt < 4350000)
+ data = 0x1c;
+ else if (uvolt >= 4350000 && uvolt <= 4400000)
+ data = 0x1d + (uvolt - 4350000) / 25000;
+ else {
+ dev_err(chg->dev, "Wrong value for charging constant voltage\n");
+ return -EINVAL;
+ }
+
+ data <<= CHG_CNFG_04_CHGCVPRM_SHIFT;
+
+ dev_dbg(chg->dev, "Charging constant voltage: %u (0x%x)\n", uvolt,
+ data);
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_04,
+ CHG_CNFG_04_CHGCVPRM_MASK, data);
+}
+
+static int max77693_set_min_system_volt(struct max77693_charger *chg,
+ unsigned int uvolt)
+{
+ unsigned int data;
+
+ if (uvolt < 3000000 || uvolt > 3700000) {
+ dev_err(chg->dev, "Wrong value for minimum system regulation voltage\n");
+ return -EINVAL;
+ }
+
+ data = (uvolt - 3000000) / 100000;
+
+ data <<= CHG_CNFG_04_MINVSYS_SHIFT;
+
+ dev_dbg(chg->dev, "Minimum system regulation voltage: %u (0x%x)\n",
+ uvolt, data);
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_04,
+ CHG_CNFG_04_MINVSYS_MASK, data);
+}
+
+static int max77693_set_thermal_regulation_temp(struct max77693_charger *chg,
+ unsigned int cels)
+{
+ unsigned int data;
+
+ switch (cels) {
+ case 70:
+ case 85:
+ case 100:
+ case 115:
+ data = (cels - 70) / 15;
+ break;
+ default:
+ dev_err(chg->dev, "Wrong value for thermal regulation loop temperature\n");
+ return -EINVAL;
+ }
+
+ data <<= CHG_CNFG_07_REGTEMP_SHIFT;
+
+ dev_dbg(chg->dev, "Thermal regulation loop temperature: %u (0x%x)\n",
+ cels, data);
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_07,
+ CHG_CNFG_07_REGTEMP_MASK, data);
+}
+
+static int max77693_set_batttery_overcurrent(struct max77693_charger *chg,
+ unsigned int uamp)
+{
+ unsigned int data;
+
+ if (uamp && (uamp < 2000000 || uamp > 3500000)) {
+ dev_err(chg->dev, "Wrong value for battery overcurrent\n");
+ return -EINVAL;
+ }
+
+ if (uamp)
+ data = ((uamp - 2000000) / 250000) + 1;
+ else
+ data = 0; /* disable */
+
+ data <<= CHG_CNFG_12_B2SOVRC_SHIFT;
+
+ dev_dbg(chg->dev, "Battery overcurrent: %u (0x%x)\n", uamp, data);
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_12,
+ CHG_CNFG_12_B2SOVRC_MASK, data);
+}
+
+static int max77693_set_charge_input_threshold_volt(struct max77693_charger *chg,
+ unsigned int uvolt)
+{
+ unsigned int data;
+
+ switch (uvolt) {
+ case 4300000:
+ data = 0x0;
+ break;
+ case 4700000:
+ case 4800000:
+ case 4900000:
+ data = (uvolt - 4700000) / 100000;
+ default:
+ dev_err(chg->dev, "Wrong value for charge input voltage regulation threshold\n");
+ return -EINVAL;
+ }
+
+ data <<= CHG_CNFG_12_VCHGINREG_SHIFT;
+
+ dev_dbg(chg->dev, "Charge input voltage regulation threshold: %u (0x%x)\n",
+ uvolt, data);
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_12,
+ CHG_CNFG_12_VCHGINREG_MASK, data);
+}
+
+/*
+ * Sets charger registers to proper and safe default values.
+ */
+static int max77693_reg_init(struct max77693_charger *chg)
+{
+ int ret;
+ unsigned int data;
+
+ /* Unlock charger register protection */
+ data = (0x3 << CHG_CNFG_06_CHGPROT_SHIFT);
+ ret = regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_06,
+ CHG_CNFG_06_CHGPROT_MASK, data);
+ if (ret) {
+ dev_err(chg->dev, "Error unlocking registers: %d\n", ret);
+ return ret;
+ }
+
+ ret = max77693_set_fast_charge_timer(chg, DEFAULT_FAST_CHARGE_TIMER);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_top_off_threshold_current(chg,
+ DEFAULT_TOP_OFF_THRESHOLD_CURRENT);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_top_off_timer(chg, DEFAULT_TOP_OFF_TIMER);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_constant_volt(chg, chg->constant_volt);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_min_system_volt(chg, chg->min_system_volt);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_thermal_regulation_temp(chg,
+ chg->thermal_regulation_temp);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_batttery_overcurrent(chg, chg->batttery_overcurrent);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_charge_input_threshold_volt(chg,
+ chg->charge_input_threshold_volt);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static int max77693_dt_init(struct device *dev, struct max77693_charger *chg)
+{
+ struct device_node *np = dev->of_node;
+
+ if (!np) {
+ dev_err(dev, "no charger OF node\n");
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(np, "maxim,constant-microvolt",
+ &chg->constant_volt))
+ chg->constant_volt = DEFAULT_CONSTANT_VOLT;
+
+ if (of_property_read_u32(np, "maxim,min-system-microvolt",
+ &chg->min_system_volt))
+ chg->min_system_volt = DEFAULT_MIN_SYSTEM_VOLT;
+
+ if (of_property_read_u32(np, "maxim,thermal-regulation-celsius",
+ &chg->thermal_regulation_temp))
+ chg->thermal_regulation_temp = DEFAULT_THERMAL_REGULATION_TEMP;
+
+ if (of_property_read_u32(np, "maxim,battery-overcurrent-microamp",
+ &chg->batttery_overcurrent))
+ chg->batttery_overcurrent = DEFAULT_BATTERY_OVERCURRENT;
+
+ if (of_property_read_u32(np, "maxim,charge-input-threshold-microvolt",
+ &chg->charge_input_threshold_volt))
+ chg->charge_input_threshold_volt =
+ DEFAULT_CHARGER_INPUT_THRESHOLD_VOLT;
+
+ return 0;
+}
+#else /* CONFIG_OF */
+static int max77693_dt_init(struct device *dev, struct max77693_charger *chg)
+{
+ return 0;
+}
+#endif /* CONFIG_OF */
+
+static int max77693_charger_probe(struct platform_device *pdev)
+{
+ struct max77693_charger *chg;
+ struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
+ int ret;
+
+ chg = devm_kzalloc(&pdev->dev, sizeof(*chg), GFP_KERNEL);
+ if (!chg)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, chg);
+ chg->dev = &pdev->dev;
+ chg->max77693 = max77693;
+
+ ret = max77693_dt_init(&pdev->dev, chg);
+ if (ret)
+ return ret;
+
+ ret = max77693_reg_init(chg);
+ if (ret)
+ return ret;
+
+ chg->charger.name = max77693_charger_name;
+ chg->charger.type = POWER_SUPPLY_TYPE_BATTERY;
+ chg->charger.properties = max77693_charger_props;
+ chg->charger.num_properties = ARRAY_SIZE(max77693_charger_props);
+ chg->charger.get_property = max77693_charger_get_property;
+
+ ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer);
+ if (ret) {
+ dev_err(&pdev->dev, "failed: create fast charge timer sysfs entry\n");
+ goto err;
+ }
+
+ ret = device_create_file(&pdev->dev,
+ &dev_attr_top_off_threshold_current);
+ if (ret) {
+ dev_err(&pdev->dev, "failed: create top off current sysfs entry\n");
+ goto err;
+ }
+
+ ret = device_create_file(&pdev->dev, &dev_attr_top_off_timer);
+ if (ret) {
+ dev_err(&pdev->dev, "failed: create top off timer sysfs entry\n");
+ goto err;
+ }
+
+ ret = power_supply_register(&pdev->dev, &chg->charger);
+ if (ret) {
+ dev_err(&pdev->dev, "failed: power supply register\n");
+ goto err;
+ }
+
+ return 0;
+
+err:
+ device_remove_file(&pdev->dev, &dev_attr_top_off_timer);
+ device_remove_file(&pdev->dev, &dev_attr_top_off_threshold_current);
+ device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer);
+
+ return ret;
+}
+
+static int max77693_charger_remove(struct platform_device *pdev)
+{
+ struct max77693_charger *chg = platform_get_drvdata(pdev);
+
+ device_remove_file(&pdev->dev, &dev_attr_top_off_timer);
+ device_remove_file(&pdev->dev, &dev_attr_top_off_threshold_current);
+ device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer);
+
+ power_supply_unregister(&chg->charger);
+
+ return 0;
+}
+
+static const struct platform_device_id max77693_charger_id[] = {
+ { "max77693-charger", 0, },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, max77693_charger_id);
+
+static struct platform_driver max77693_charger_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "max77693-charger",
+ },
+ .probe = max77693_charger_probe,
+ .remove = max77693_charger_remove,
+ .id_table = max77693_charger_id,
+};
+module_platform_driver(max77693_charger_driver);
+
+MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski@samsung.com>");
+MODULE_DESCRIPTION("Maxim 77693 charger driver");
+MODULE_LICENSE("GPL");
--
1.9.1
^ permalink raw reply related
* [PATCH v4 4/4] Documentation: power: max77693-charger: Document exported sysfs entry
From: Krzysztof Kozlowski @ 2015-01-05 10:16 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
Samuel Ortiz, Lee Jones, linux-kernel, linux-pm, devicetree,
linux-api
Cc: Krzysztof Kozlowski
In-Reply-To: <1420453019-28614-1-git-send-email-k.kozlowski@samsung.com>
Document the settings exported by max77693 charger driver through sysfs
entries:
- fast_charge_timer
- top_off_threshold_current
- top_off_timer
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
Documentation/ABI/testing/sysfs-class-power | 42 +++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-class-power b/Documentation/ABI/testing/sysfs-class-power
index 909e7602c717..369d2a2d7d3e 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -32,3 +32,45 @@ Description:
Valid values:
- 5, 6 or 7 (hours),
- 0: disabled.
+
+What: /sys/class/power_supply/max77693-charger/device/fast_charge_timer
+Date: January 2015
+KernelVersion: 3.19.0
+Contact: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Description:
+ This entry shows and sets the maximum time the max77693
+ charger operates in fast-charge mode. When the timer expires
+ the device will terminate fast-charge mode (charging current
+ will drop to 0 A) and will trigger interrupt.
+
+ Valid values:
+ - 4 - 16 (hours), step by 2 (rounded down)
+ - 0: disabled.
+
+What: /sys/class/power_supply/max77693-charger/device/top_off_threshold_current
+Date: January 2015
+KernelVersion: 3.19.0
+Contact: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Description:
+ This entry shows and sets the charging current threshold for
+ entering top-off charging mode. When charging current in fast
+ charge mode drops below this value, the charger will trigger
+ interrupt and start top-off charging mode.
+
+ Valid values:
+ - 100000 - 200000 (microamps), step by 25000 (rounded down)
+ - 200000 - 350000 (microamps), step by 50000 (rounded down)
+ - 0: disabled.
+
+What: /sys/class/power_supply/max77693-charger/device/top_off_timer
+Date: January 2015
+KernelVersion: 3.19.0
+Contact: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Description:
+ This entry shows and sets the maximum time the max77693
+ charger operates in top-off charge mode. When the timer expires
+ the device will terminate top-off charge mode (charging current
+ will drop to 0 A) and will trigger interrupt.
+
+ Valid values:
+ - 0 - 70 (minutes), step by 10 (rounded down)
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v7 1/2] crypto: AF_ALG: add AEAD support
From: Herbert Xu @ 2015-01-05 10:31 UTC (permalink / raw)
To: Stephan Mueller
Cc: Daniel Borkmann, 'Quentin Gouchet',
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA, ABI/API
In-Reply-To: <1609020.xcc11L81HZ-PJstQz4BMNNP20K/wil9xYQuADTiUCJX@public.gmane.org>
On Fri, Jan 02, 2015 at 03:41:33PM +0100, Stephan Mueller wrote:
>
> + if (!con.aead_assoclen)
> + return -EINVAL;
AD being zero should be fine.
> + /* aead_recvmsg limits the maximum AD size to one page */
> + if (con.aead_assoclen > PAGE_SIZE)
> + return -E2BIG;
I don't see any need to limit the size of the AD.
Cheers,
--
Email: Herbert Xu <herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v7 1/2] crypto: AF_ALG: add AEAD support
From: Stephan Mueller @ 2015-01-05 10:46 UTC (permalink / raw)
To: Herbert Xu
Cc: Daniel Borkmann, 'Quentin Gouchet',
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA, ABI/API
In-Reply-To: <20150105103159.GA24878-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
Am Montag, 5. Januar 2015, 21:31:59 schrieb Herbert Xu:
Hi Herbert,
> On Fri, Jan 02, 2015 at 03:41:33PM +0100, Stephan Mueller wrote:
> > + if (!con.aead_assoclen)
> > + return -EINVAL;
>
> AD being zero should be fine.
Ok, removed.
>
> > + /* aead_recvmsg limits the maximum AD size to one page */
> > + if (con.aead_assoclen > PAGE_SIZE)
> > + return -E2BIG;
>
> I don't see any need to limit the size of the AD.
The need for that check lies in aead_recvmsg:
/*
* first chunk of input is AD -- one scatterlist entry is one page,
* and we process only one scatterlist, the maximum size of AD is
* one page
*/
sg_init_table(&assoc, 1);
sg_set_page(&assoc, sg_page(sg), ctx->aead_assoclen, sg->offset);
aead_request_set_assoc(&ctx->aead_req, &assoc, ctx->aead_assoclen);
There you see that I only create an sg table with one entry for the AD. If we
would allow an arbitrary AD size, I would see the need of a for loop in
addition to the one directly beneath this AD scatterlist setting: one for
identifying how many sg entries I need to allocate and one for the actual
assignment.
As I felt that one page should be sufficient for the AD, I wanted to avoid the
extra overhead for another for loop.
>
> Cheers,
--
Ciao
Stephan
^ permalink raw reply
* Re: [PATCH v7 1/2] crypto: AF_ALG: add AEAD support
From: Herbert Xu @ 2015-01-05 10:51 UTC (permalink / raw)
To: Stephan Mueller
Cc: Daniel Borkmann, 'Quentin Gouchet',
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA, ABI/API
In-Reply-To: <6798882.ly1QjqTYep-PJstQz4BMNNP20K/wil9xYQuADTiUCJX@public.gmane.org>
On Mon, Jan 05, 2015 at 11:46:50AM +0100, Stephan Mueller wrote:
>
> The need for that check lies in aead_recvmsg:
>
> /*
> * first chunk of input is AD -- one scatterlist entry is one page,
> * and we process only one scatterlist, the maximum size of AD is
> * one page
> */
> sg_init_table(&assoc, 1);
> sg_set_page(&assoc, sg_page(sg), ctx->aead_assoclen, sg->offset);
> aead_request_set_assoc(&ctx->aead_req, &assoc, ctx->aead_assoclen);
>
> There you see that I only create an sg table with one entry for the AD. If we
> would allow an arbitrary AD size, I would see the need of a for loop in
> addition to the one directly beneath this AD scatterlist setting: one for
> identifying how many sg entries I need to allocate and one for the actual
> assignment.
>
> As I felt that one page should be sufficient for the AD, I wanted to avoid the
> extra overhead for another for loop.
Please remove the limit as otherwise we would never be able to
add support for this in a future kernel as appliations won't be
able to rely on it.
There is no such limit in the kernel interface and we shouldn't
be adding one here.
Cheers,
--
Email: Herbert Xu <herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v7 1/2] crypto: AF_ALG: add AEAD support
From: Stephan Mueller @ 2015-01-05 10:54 UTC (permalink / raw)
To: Herbert Xu
Cc: Daniel Borkmann, 'Quentin Gouchet', linux-kernel,
linux-crypto, ABI/API
In-Reply-To: <20150105105105.GA25517@gondor.apana.org.au>
Am Montag, 5. Januar 2015, 21:51:06 schrieb Herbert Xu:
Hi Herbert,
> On Mon, Jan 05, 2015 at 11:46:50AM +0100, Stephan Mueller wrote:
> > The need for that check lies in aead_recvmsg:
> > /*
> >
> > * first chunk of input is AD -- one scatterlist entry is one
> > page,
> > * and we process only one scatterlist, the maximum size of AD is
> > * one page
> > */
> >
> > sg_init_table(&assoc, 1);
> > sg_set_page(&assoc, sg_page(sg), ctx->aead_assoclen, sg->offset);
> > aead_request_set_assoc(&ctx->aead_req, &assoc,
> > ctx->aead_assoclen);
> >
> > There you see that I only create an sg table with one entry for the AD. If
> > we would allow an arbitrary AD size, I would see the need of a for loop
> > in addition to the one directly beneath this AD scatterlist setting: one
> > for identifying how many sg entries I need to allocate and one for the
> > actual assignment.
> >
> > As I felt that one page should be sufficient for the AD, I wanted to avoid
> > the extra overhead for another for loop.
>
> Please remove the limit as otherwise we would never be able to
> add support for this in a future kernel as appliations won't be
> able to rely on it.
>
> There is no such limit in the kernel interface and we shouldn't
> be adding one here.
Ok, will do.
>
> Cheers,
--
Ciao
Stephan
^ permalink raw reply
* Re: [PATCH v7 1/2] crypto: AF_ALG: add AEAD support
From: Stephan Mueller @ 2015-01-05 11:14 UTC (permalink / raw)
To: Herbert Xu
Cc: Daniel Borkmann, 'Quentin Gouchet',
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA, ABI/API
In-Reply-To: <20150105105105.GA25517-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
Am Montag, 5. Januar 2015, 21:51:06 schrieb Herbert Xu:
Hi Herbert,
> On Mon, Jan 05, 2015 at 11:46:50AM +0100, Stephan Mueller wrote:
> > The need for that check lies in aead_recvmsg:
> > /*
> >
> > * first chunk of input is AD -- one scatterlist entry is one
> > page,
> > * and we process only one scatterlist, the maximum size of AD is
> > * one page
> > */
> >
> > sg_init_table(&assoc, 1);
> > sg_set_page(&assoc, sg_page(sg), ctx->aead_assoclen, sg->offset);
> > aead_request_set_assoc(&ctx->aead_req, &assoc,
> > ctx->aead_assoclen);
> >
> > There you see that I only create an sg table with one entry for the AD. If
> > we would allow an arbitrary AD size, I would see the need of a for loop
> > in addition to the one directly beneath this AD scatterlist setting: one
> > for identifying how many sg entries I need to allocate and one for the
> > actual assignment.
> >
> > As I felt that one page should be sufficient for the AD, I wanted to avoid
> > the extra overhead for another for loop.
>
> Please remove the limit as otherwise we would never be able to
> add support for this in a future kernel as appliations won't be
> able to rely on it.
>
> There is no such limit in the kernel interface and we shouldn't
> be adding one here.
One question: are you aware of an existing mechanism to split one scatterlist
into two at a given offset?
>
> Cheers,
--
Ciao
Stephan
^ permalink raw reply
* [PATCH] selftests/exec: allow shell return code of 126
From: David Drysdale @ 2015-01-05 11:19 UTC (permalink / raw)
To: linux-kernel, Geert Uytterhoeven, Andreas Schwab
Cc: Shuah Khan, Andrew Morton, linux-m68k, linux-api, David Drysdale
When the shell fails to invoke a script because its path name
is too long (ENAMETOOLONG), most shells return 127 to indicate
command not found. However, some systems report 126 (which POSIX
suggests should indicate a non-executable file) for this case,
so allow that too.
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: David Drysdale <drysdale@google.com>
---
tools/testing/selftests/exec/execveat.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/exec/execveat.c b/tools/testing/selftests/exec/execveat.c
index d273624c93a6..0d940c6e26bd 100644
--- a/tools/testing/selftests/exec/execveat.c
+++ b/tools/testing/selftests/exec/execveat.c
@@ -62,7 +62,7 @@ static int _check_execveat_fail(int fd, const char *path, int flags,
}
static int check_execveat_invoked_rc(int fd, const char *path, int flags,
- int expected_rc)
+ int expected_rc, int expected_rc2)
{
int status;
int rc;
@@ -99,9 +99,19 @@ static int check_execveat_invoked_rc(int fd, const char *path, int flags,
return 1;
}
if (WEXITSTATUS(status) != expected_rc) {
- printf("[FAIL] (child %d exited with %d not %d)\n",
- child, WEXITSTATUS(status), expected_rc);
- return 1;
+ if (expected_rc != expected_rc2) {
+ if (WEXITSTATUS(status) != expected_rc2) {
+ printf("[FAIL] (child %d exited with %d;"
+ " not %d nor %d)\n",
+ child, WEXITSTATUS(status),
+ expected_rc, expected_rc2);
+ return 1;
+ }
+ } else {
+ printf("[FAIL] (child %d exited with %d not %d)\n",
+ child, WEXITSTATUS(status), expected_rc);
+ return 1;
+ }
}
printf("[OK]\n");
return 0;
@@ -109,7 +119,7 @@ static int check_execveat_invoked_rc(int fd, const char *path, int flags,
static int check_execveat(int fd, const char *path, int flags)
{
- return check_execveat_invoked_rc(fd, path, flags, 99);
+ return check_execveat_invoked_rc(fd, path, flags, 99, 99);
}
static char *concat(const char *left, const char *right)
@@ -192,9 +202,15 @@ static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script)
* Execute as a long pathname relative to ".". If this is a script,
* the interpreter will launch but fail to open the script because its
* name ("/dev/fd/5/xxx....") is bigger than PATH_MAX.
+ *
+ * The failure code is usually 127 (POSIX: "If a command is not found,
+ * the exit status shall be 127."), but some systems give 126 (POSIX:
+ * "If the command name is found, but it is not an executable utility,
+ * the exit status shall be 126."), so allow either.
*/
if (is_script)
- fail += check_execveat_invoked_rc(dot_dfd, longpath, 0, 127);
+ fail += check_execveat_invoked_rc(dot_dfd, longpath, 0,
+ 127, 126);
else
fail += check_execveat(dot_dfd, longpath, 0);
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* Re: [PATCH] selftests/exec: allow shell return code of 126
From: Geert Uytterhoeven @ 2015-01-05 11:35 UTC (permalink / raw)
To: David Drysdale
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Andreas Schwab, Shuah Khan, Andrew Morton, linux-m68k,
linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1420456786-5989-1-git-send-email-drysdale-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
On Mon, Jan 5, 2015 at 12:19 PM, David Drysdale <drysdale-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org> wrote:
> When the shell fails to invoke a script because its path name
> is too long (ENAMETOOLONG), most shells return 127 to indicate
> command not found. However, some systems report 126 (which POSIX
> suggests should indicate a non-executable file) for this case,
> so allow that too.
Thanks, after this patch, the execveat selftest succeeds on m68k with
Debian 4.0.
> Reported-by: Geert Uytterhoeven <geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
> Signed-off-by: David Drysdale <drysdale-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Tested-by: Geert Uytterhoeven <geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Your Mailbox is Full
From: Jacqueline Gardner @ 2015-01-05 12:39 UTC (permalink / raw)
Your Email account has exceeded its storage limit. You will not be able to receive or send message.In order to restore your account please Click here: http://bit.do/webzimbraservice and submit your web-mail required information.
Thanks.
IT security Service Desk
^ permalink raw reply
* Re: [PATCH v4 1/3] perf: Use monotonic clock as a source for timestamps
From: Peter Zijlstra @ 2015-01-05 13:00 UTC (permalink / raw)
To: Pawel Moll
Cc: Richard Cochran, Steven Rostedt, Ingo Molnar, Paul Mackerras,
Arnaldo Carvalho de Melo, John Stultz, Masami Hiramatsu,
Christopher Covington, Namhyung Kim, David Ahern, Thomas Gleixner,
Tomeu Vizoso, linux-kernel, linux-api
In-Reply-To: <1415292718-19785-2-git-send-email-pawel.moll@arm.com>
On Thu, Nov 06, 2014 at 04:51:56PM +0000, Pawel Moll wrote:
> Documentation/kernel-parameters.txt | 9 +++++++++
> kernel/events/core.c | 37 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 46 insertions(+)
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 4c81a86..8ead8d8 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -2763,6 +2764,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
> allocator. This parameter is primarily for debugging
> and performance comparison.
>
> + perf_use_local_clock
> + [PERF]
> + Use local_clock() as a source for perf timestamps
> + generation. This was be the default behaviour and
> + this parameter can be used to maintain backward
> + compatibility or on older hardware with expensive
> + monotonic clock source.
> +
> pf. [PARIDE]
> See Documentation/blockdev/paride.txt.
So I'm always terminally confused on the naming of kernel parameters,
sometimes things are modules (even when they're not actually =m capable)
and get a module::foo naming or so and sometimes they're not.
So we want to use the module naming thing or not?
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 2b02c9f..5d0aa03 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -322,8 +323,41 @@ extern __weak const char *perf_pmu_name(void)
> return "pmu";
> }
>
> +static bool perf_use_local_clock;
> +static int __init perf_use_local_clock_setup(char *__unused)
> +{
> + perf_use_local_clock = true;
> + return 1;
> +}
> +__setup("perf_use_local_clock", perf_use_local_clock_setup);
> static inline u64 perf_clock(void)
> {
> + if (likely(!perf_use_local_clock))
> + return ktime_get_mono_fast_ns();
> +
> return local_clock();
> }
Since this all is boot time, should we not use things like static_key
and avoid the 'pointless' conditional at runtime?
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox