* [PATCH net-next v1 17/18] net: mlx4: identify predicate for debug messages
From: David Decotigny @ 2015-01-27 1:36 UTC (permalink / raw)
To: David S. Miller, Ben Hutchings, Amir Vadai, linux-kernel, netdev,
linux-api
Cc: Eric Dumazet, Eugenia Emantayev, Or Gerlitz, Ido Shamay,
Joe Perches, Saeed Mahameed, Govindarajulu Varadarajan,
Venkata Duvvuru, Jeff Kirsher, Eyal Perry, Pravin B Shelar,
Ed Swierk, David Decotigny
In-Reply-To: <1422322574-6188-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/mlx4_en.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 944a112..96bf728 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -869,9 +869,11 @@ __printf(3, 4)
void en_print(const char *level, const struct mlx4_en_priv *priv,
const char *format, ...);
+#define en_dbg_enabled(mlevel, priv) \
+ (NETIF_MSG_##mlevel & (priv)->msg_enable)
#define en_dbg(mlevel, priv, format, ...) \
do { \
- if (NETIF_MSG_##mlevel & (priv)->msg_enable) \
+ if (en_dbg_enabled(mlevel, priv)) \
en_print(KERN_DEBUG, priv, format, ##__VA_ARGS__); \
} while (0)
#define en_warn(priv, format, ...) \
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next v1 18/18] net: mlx4: use new ETHTOOL_G/SSETTINGS API
From: David Decotigny @ 2015-01-27 1:36 UTC (permalink / raw)
To: David S. Miller, Ben Hutchings, Amir Vadai, linux-kernel, netdev,
linux-api
Cc: Eric Dumazet, Eugenia Emantayev, Or Gerlitz, Ido Shamay,
Joe Perches, Saeed Mahameed, Govindarajulu Varadarajan,
Venkata Duvvuru, Jeff Kirsher, Eyal Perry, Pravin B Shelar,
Ed Swierk, David Decotigny
In-Reply-To: <1422322574-6188-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 | 326 ++++++++++++------------
drivers/net/ethernet/mellanox/mlx4/en_main.c | 1 +
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 +
3 files changed, 161 insertions(+), 167 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 569eda9..4ad34064 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -388,34 +388,30 @@ 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 void ptys2ethtool_update_supported_port(ethtool_link_mode_mask_t *mask,
+ struct mlx4_ptys_reg *ptys_reg)
{
u32 eth_proto = be32_to_cpu(ptys_reg->eth_proto_cap);
if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_T)
| MLX4_PROT_MASK(MLX4_1000BASE_T)
| MLX4_PROT_MASK(MLX4_100BASE_TX))) {
- return SUPPORTED_TP;
- }
-
- if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_CR)
+ ethtool_add_link_modes(mask, ETHTOOL_LINK_MODE_TP_BIT);
+ } else if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_CR)
| MLX4_PROT_MASK(MLX4_10GBASE_SR)
| MLX4_PROT_MASK(MLX4_56GBASE_SR4)
| MLX4_PROT_MASK(MLX4_40GBASE_CR4)
| MLX4_PROT_MASK(MLX4_40GBASE_SR4)
| MLX4_PROT_MASK(MLX4_1000BASE_CX_SGMII))) {
- return SUPPORTED_FIBRE;
- }
-
- if (eth_proto & (MLX4_PROT_MASK(MLX4_56GBASE_KR4)
+ ethtool_add_link_modes(mask, ETHTOOL_LINK_MODE_FIBRE_BIT);
+ } else if (eth_proto & (MLX4_PROT_MASK(MLX4_56GBASE_KR4)
| MLX4_PROT_MASK(MLX4_40GBASE_KR4)
| MLX4_PROT_MASK(MLX4_20GBASE_KR2)
| MLX4_PROT_MASK(MLX4_10GBASE_KR)
| MLX4_PROT_MASK(MLX4_10GBASE_KX4)
| MLX4_PROT_MASK(MLX4_1000BASE_KX))) {
- return SUPPORTED_Backplane;
+ ethtool_add_link_modes(mask, ETHTOOL_LINK_MODE_Backplane_BIT);
}
- return 0;
}
static u32 ptys_get_active_port(struct mlx4_ptys_reg *ptys_reg)
@@ -461,122 +457,91 @@ static u32 ptys_get_active_port(struct mlx4_ptys_reg *ptys_reg)
enum ethtool_report {
SUPPORTED = 0,
ADVERTISED = 1,
- SPEED = 2
};
+struct ptys2ethtool_config {
+ ethtool_link_mode_mask_t link_modes[2]; /* SUPPORTED/ADVERTISED */
+ u32 speed;
+};
+
+#define MLX4_BUILD_PTYS2ETHTOOL_CONFIG(reg_, speed_, ...) \
+ ({ \
+ struct ptys2ethtool_config *cfg; \
+ cfg = &ptys2ethtool_map[reg_]; \
+ cfg->speed = speed_; \
+ ethtool_build_link_mode(&cfg->link_modes[SUPPORTED], \
+ __VA_ARGS__); \
+ ethtool_build_link_mode(&cfg->link_modes[ADVERTISED], \
+ __VA_ARGS__); \
+ })
+
/* Translates mlx4 link mode to equivalent ethtool Link modes/speed */
-static u32 ptys2ethtool_map[MLX4_LINK_MODES_SZ][3] = {
- [MLX4_100BASE_TX] = {
- SUPPORTED_100baseT_Full,
- ADVERTISED_100baseT_Full,
- SPEED_100
- },
-
- [MLX4_1000BASE_T] = {
- SUPPORTED_1000baseT_Full,
- ADVERTISED_1000baseT_Full,
- SPEED_1000
- },
- [MLX4_1000BASE_CX_SGMII] = {
- SUPPORTED_1000baseKX_Full,
- ADVERTISED_1000baseKX_Full,
- SPEED_1000
- },
- [MLX4_1000BASE_KX] = {
- SUPPORTED_1000baseKX_Full,
- ADVERTISED_1000baseKX_Full,
- SPEED_1000
- },
-
- [MLX4_10GBASE_T] = {
- SUPPORTED_10000baseT_Full,
- ADVERTISED_10000baseT_Full,
- SPEED_10000
- },
- [MLX4_10GBASE_CX4] = {
- SUPPORTED_10000baseKX4_Full,
- ADVERTISED_10000baseKX4_Full,
- SPEED_10000
- },
- [MLX4_10GBASE_KX4] = {
- SUPPORTED_10000baseKX4_Full,
- ADVERTISED_10000baseKX4_Full,
- SPEED_10000
- },
- [MLX4_10GBASE_KR] = {
- SUPPORTED_10000baseKR_Full,
- ADVERTISED_10000baseKR_Full,
- SPEED_10000
- },
- [MLX4_10GBASE_CR] = {
- SUPPORTED_10000baseKR_Full,
- ADVERTISED_10000baseKR_Full,
- SPEED_10000
- },
- [MLX4_10GBASE_SR] = {
- SUPPORTED_10000baseKR_Full,
- ADVERTISED_10000baseKR_Full,
- SPEED_10000
- },
-
- [MLX4_20GBASE_KR2] = {
- SUPPORTED_20000baseMLD2_Full | SUPPORTED_20000baseKR2_Full,
- ADVERTISED_20000baseMLD2_Full | ADVERTISED_20000baseKR2_Full,
- SPEED_20000
- },
-
- [MLX4_40GBASE_CR4] = {
- SUPPORTED_40000baseCR4_Full,
- ADVERTISED_40000baseCR4_Full,
- SPEED_40000
- },
- [MLX4_40GBASE_KR4] = {
- SUPPORTED_40000baseKR4_Full,
- ADVERTISED_40000baseKR4_Full,
- SPEED_40000
- },
- [MLX4_40GBASE_SR4] = {
- SUPPORTED_40000baseSR4_Full,
- ADVERTISED_40000baseSR4_Full,
- SPEED_40000
- },
-
- [MLX4_56GBASE_KR4] = {
- SUPPORTED_56000baseKR4_Full,
- ADVERTISED_56000baseKR4_Full,
- SPEED_56000
- },
- [MLX4_56GBASE_CR4] = {
- SUPPORTED_56000baseCR4_Full,
- ADVERTISED_56000baseCR4_Full,
- SPEED_56000
- },
- [MLX4_56GBASE_SR4] = {
- SUPPORTED_56000baseSR4_Full,
- ADVERTISED_56000baseSR4_Full,
- SPEED_56000
- },
+static struct ptys2ethtool_config ptys2ethtool_map[MLX4_LINK_MODES_SZ];
+
+void __init mlx4_en_init_ptys2ethtool_map(void)
+{
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_100BASE_TX, SPEED_100,
+ ETHTOOL_LINK_MODE_100baseT_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_T, SPEED_1000,
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_CX_SGMII, SPEED_1000,
+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_KX, SPEED_1000,
+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_T, SPEED_10000,
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_CX4, SPEED_10000,
+ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_KX4, SPEED_10000,
+ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_KR, SPEED_10000,
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_CR, SPEED_10000,
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_SR, SPEED_10000,
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_20GBASE_KR2, SPEED_20000,
+ ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT,
+ ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_40GBASE_CR4, SPEED_40000,
+ ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_40GBASE_KR4, SPEED_40000,
+ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_40GBASE_SR4, SPEED_40000,
+ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_56GBASE_KR4, SPEED_56000,
+ ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_56GBASE_CR4, SPEED_56000,
+ ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT);
+ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_56GBASE_SR4, SPEED_56000,
+ ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT);
};
-static u32 ptys2ethtool_link_modes(u32 eth_proto, enum ethtool_report report)
+static void ptys2ethtool_update_link_modes(ethtool_link_mode_mask_t *link_modes,
+ u32 eth_proto,
+ enum ethtool_report report)
{
int i;
- u32 link_modes = 0;
-
for (i = 0; i < MLX4_LINK_MODES_SZ; i++) {
if (eth_proto & MLX4_PROT_MASK(i))
- link_modes |= ptys2ethtool_map[i][report];
+ bitmap_or(link_modes->mask,
+ link_modes->mask,
+ ptys2ethtool_map[i].link_modes[report].mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
}
- return link_modes;
}
-static u32 ethtool2ptys_link_modes(u32 link_modes, enum ethtool_report report)
+static u32 ethtool2ptys_link_modes(const ethtool_link_mode_mask_t *link_modes,
+ enum ethtool_report report)
{
int i;
u32 ptys_modes = 0;
for (i = 0; i < MLX4_LINK_MODES_SZ; i++) {
- if (ptys2ethtool_map[i][report] & link_modes)
+ if (bitmap_intersects(
+ ptys2ethtool_map[i].link_modes[report].mask,
+ link_modes->mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS))
ptys_modes |= 1 << i;
}
return ptys_modes;
@@ -589,14 +554,14 @@ static u32 speed2ptys_link_modes(u32 speed)
u32 ptys_modes = 0;
for (i = 0; i < MLX4_LINK_MODES_SZ; i++) {
- if (ptys2ethtool_map[i][SPEED] == speed)
+ if (ptys2ethtool_map[i].speed == speed)
ptys_modes |= 1 << i;
}
return ptys_modes;
}
-static int ethtool_get_ptys_settings(struct net_device *dev,
- struct ethtool_cmd *cmd)
+static int ethtool_get_ptys_ksettings(struct net_device *dev,
+ struct ethtool_ksettings *ksettings)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_ptys_reg ptys_reg;
@@ -624,79 +589,94 @@ 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;
+ /* reset supported/advertising masks */
+ ethtool_build_link_mode(&ksettings->link_modes.supported);
+ ethtool_build_link_mode(&ksettings->link_modes.advertising);
- cmd->supported |= ptys_get_supported_port(&ptys_reg);
+ ptys2ethtool_update_supported_port(&ksettings->link_modes.supported,
+ &ptys_reg);
eth_proto = be32_to_cpu(ptys_reg.eth_proto_cap);
- cmd->supported |= ptys2ethtool_link_modes(eth_proto, SUPPORTED);
+ ptys2ethtool_update_link_modes(&ksettings->link_modes.supported,
+ eth_proto, SUPPORTED);
eth_proto = be32_to_cpu(ptys_reg.eth_proto_admin);
- cmd->advertising |= ptys2ethtool_link_modes(eth_proto, ADVERTISED);
+ ptys2ethtool_update_link_modes(&ksettings->link_modes.advertising,
+ eth_proto, ADVERTISED);
- cmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
- cmd->advertising |= (priv->prof->tx_pause) ? ADVERTISED_Pause : 0;
+ ethtool_add_link_modes(&ksettings->link_modes.supported,
+ ETHTOOL_LINK_MODE_Pause_BIT,
+ ETHTOOL_LINK_MODE_Pause_BIT);
- cmd->advertising |= (priv->prof->tx_pause ^ priv->prof->rx_pause) ?
- ADVERTISED_Asym_Pause : 0;
+ if (priv->prof->tx_pause)
+ ethtool_add_link_modes(&ksettings->link_modes.advertising,
+ ETHTOOL_LINK_MODE_Pause_BIT);
+ if (priv->prof->tx_pause ^ priv->prof->rx_pause)
+ ethtool_add_link_modes(&ksettings->link_modes.advertising,
+ ETHTOOL_LINK_MODE_Asym_Pause_BIT);
- cmd->port = ptys_get_active_port(&ptys_reg);
- cmd->transceiver = (SUPPORTED_TP & cmd->supported) ?
- XCVR_EXTERNAL : XCVR_INTERNAL;
+ ksettings->parent.port = ptys_get_active_port(&ptys_reg);
if (mlx4_en_autoneg_get(dev)) {
- cmd->supported |= SUPPORTED_Autoneg;
- cmd->advertising |= ADVERTISED_Autoneg;
+ ethtool_add_link_modes(&ksettings->link_modes.supported,
+ ETHTOOL_LINK_MODE_Autoneg_BIT);
+ ethtool_add_link_modes(&ksettings->link_modes.advertising,
+ ETHTOOL_LINK_MODE_Autoneg_BIT);
}
- cmd->autoneg = (priv->port_state.flags & MLX4_EN_PORT_ANC) ?
+ ksettings->parent.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);
- cmd->lp_advertising |= (priv->port_state.flags & MLX4_EN_PORT_ANC) ?
- ADVERTISED_Autoneg : 0;
+ ethtool_build_link_mode(&ksettings->link_modes.lp_advertising);
+ ptys2ethtool_update_link_modes(&ksettings->link_modes.lp_advertising,
+ eth_proto, ADVERTISED);
+ if (priv->port_state.flags & MLX4_EN_PORT_ANC)
+ ethtool_add_link_modes(&ksettings->link_modes.lp_advertising,
+ ETHTOOL_LINK_MODE_Autoneg_BIT);
- cmd->phy_address = 0;
- cmd->mdio_support = 0;
- cmd->maxtxpkt = 0;
- cmd->maxrxpkt = 0;
- cmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
- cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
+ ksettings->parent.phy_address = 0;
+ ksettings->parent.mdio_support = 0;
+ ksettings->parent.eth_tp_mdix = ETH_TP_MDI_INVALID;
+ ksettings->parent.eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
return ret;
}
-static void ethtool_get_default_settings(struct net_device *dev,
- struct ethtool_cmd *cmd)
+static void ethtool_get_default_ksettings(struct net_device *dev,
+ struct ethtool_ksettings *ksettings)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
int trans_type;
- cmd->autoneg = AUTONEG_DISABLE;
- cmd->supported = SUPPORTED_10000baseT_Full;
- cmd->advertising = ADVERTISED_10000baseT_Full;
+ ksettings->parent.autoneg = AUTONEG_DISABLE;
+ ethtool_build_link_mode(&ksettings->link_modes.supported,
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT);
+ ethtool_build_link_mode(&ksettings->link_modes.advertising,
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT);
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;
+ ksettings->parent.port = PORT_FIBRE;
+ ethtool_add_link_modes(&ksettings->link_modes.supported,
+ ETHTOOL_LINK_MODE_FIBRE_BIT);
+ ethtool_add_link_modes(&ksettings->link_modes.advertising,
+ ETHTOOL_LINK_MODE_FIBRE_BIT);
} else if (trans_type == 0x80 || trans_type == 0) {
- cmd->port = PORT_TP;
- cmd->transceiver = XCVR_INTERNAL;
- cmd->supported |= SUPPORTED_TP;
- cmd->advertising |= ADVERTISED_TP;
+ ksettings->parent.port = PORT_TP;
+ ethtool_add_link_modes(&ksettings->link_modes.supported,
+ ETHTOOL_LINK_MODE_TP_BIT);
+ ethtool_add_link_modes(&ksettings->link_modes.advertising,
+ ETHTOOL_LINK_MODE_TP_BIT);
} else {
- cmd->port = -1;
- cmd->transceiver = -1;
+ ksettings->parent.port = -1;
}
}
-static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int mlx4_en_get_ksettings(struct net_device *dev,
+ struct ethtool_ksettings *ksettings)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
int ret = -EINVAL;
@@ -709,16 +689,16 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
priv->port_state.flags & MLX4_EN_PORT_ANE);
if (priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL)
- ret = ethtool_get_ptys_settings(dev, cmd);
+ ret = ethtool_get_ptys_ksettings(dev, ksettings);
if (ret) /* ETH PROT CRTL is not supported or PTYS CMD failed */
- ethtool_get_default_settings(dev, cmd);
+ ethtool_get_default_ksettings(dev, ksettings);
if (netif_carrier_ok(dev)) {
- ethtool_cmd_speed_set(cmd, priv->port_state.link_speed);
- cmd->duplex = DUPLEX_FULL;
+ ksettings->parent.speed = priv->port_state.link_speed;
+ ksettings->parent.duplex = DUPLEX_FULL;
} else {
- ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
- cmd->duplex = DUPLEX_UNKNOWN;
+ ksettings->parent.speed = SPEED_UNKNOWN;
+ ksettings->parent.duplex = DUPLEX_UNKNOWN;
}
return 0;
}
@@ -742,21 +722,33 @@ static __be32 speed_set_ptys_admin(struct mlx4_en_priv *priv, u32 speed,
return proto_admin;
}
-static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int mlx4_en_set_ksettings(struct net_device *dev,
+ const struct ethtool_ksettings *ksettings)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_ptys_reg ptys_reg;
__be32 proto_admin;
int ret;
- u32 ptys_adv = ethtool2ptys_link_modes(cmd->advertising, ADVERTISED);
- int speed = ethtool_cmd_speed(cmd);
+ u32 ptys_adv = ethtool2ptys_link_modes(
+ &ksettings->link_modes.advertising, ADVERTISED);
+ const int speed = ksettings->parent.speed;
+
+ if (en_dbg_enabled(DRV, priv)) {
+ char dbg_link_mode_buff[64];
- en_dbg(DRV, priv, "Set Speed=%d adv=0x%x autoneg=%d duplex=%d\n",
- speed, cmd->advertising, cmd->autoneg, cmd->duplex);
+ bitmap_scnprintf(dbg_link_mode_buff,
+ sizeof(dbg_link_mode_buff),
+ ksettings->link_modes.supported.mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ en_dbg(DRV, priv,
+ "Set Speed=%d adv={%s} autoneg=%d duplex=%d\n",
+ speed, dbg_link_mode_buff,
+ ksettings->parent.autoneg, ksettings->parent.duplex);
+ }
if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL) ||
- (cmd->duplex == DUPLEX_HALF))
+ (ksettings->parent.duplex == DUPLEX_HALF))
return -EINVAL;
memset(&ptys_reg, 0, sizeof(ptys_reg));
@@ -1822,8 +1814,8 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev,
const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_drvinfo = mlx4_en_get_drvinfo,
- .get_settings = mlx4_en_get_settings,
- .set_settings = mlx4_en_set_settings,
+ .get_ksettings = mlx4_en_get_ksettings,
+ .set_ksettings = mlx4_en_set_ksettings,
.get_link = ethtool_op_get_link,
.get_strings = mlx4_en_get_strings,
.get_sset_count = mlx4_en_get_sset_count,
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
index c643d2b..b435349 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -348,6 +348,7 @@ static void mlx4_en_verify_params(void)
static int __init mlx4_en_init(void)
{
mlx4_en_verify_params();
+ mlx4_en_init_ptys2ethtool_map();
return mlx4_register_interface(&mlx4_en_interface);
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 96bf728..609fc3e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -749,6 +749,7 @@ static inline bool mlx4_en_cq_busy_polling(struct mlx4_en_cq *cq)
#define MLX4_EN_WOL_DO_MODIFY (1ULL << 63)
+void mlx4_en_init_ptys2ethtool_map(void);
void mlx4_en_update_loopback_state(struct net_device *dev,
netdev_features_t features);
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* Re: [RFC][PATCH v2] procfs: Always expose /proc/<pid>/map_files/ and make it readable
From: Cyrill Gorcunov @ 2015-01-27 6:46 UTC (permalink / raw)
To: Andrew Morton
Cc: Kirill A. Shutemov, Calvin Owens, Alexey Dobriyan, Oleg Nesterov,
Eric W. Biederman, Al Viro, Kirill A. Shutemov, Peter Feiner,
Grant Likely, Siddhesh Poyarekar,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kernel-team-b10kYP2dOMg,
Pavel Emelyanov, linux-api-u79uwXL29TY76Z2rM5mHXA, Kees Cook
In-Reply-To: <20150126154346.c63c512e5821e9e0ea31f759-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
On Mon, Jan 26, 2015 at 03:43:46PM -0800, Andrew Morton wrote:
> >
> > Looks good to me, thanks! Though I would really appreciate if someone
> > from security camp take a look as well.
>
> hm, who's that. Kees comes to mind.
yup, I managed to forget CC him.
>
> And reviewers' task would be a heck of a lot easier if they knew what
> /proc/pid/map_files actually does. This:
>
> akpm3:/usr/src/25> grep -r map_files Documentation
> akpm3:/usr/src/25>
>
> does not help.
Sigh. Imagine, for some reason I though we've the docs for that
entry, probably i though that way because of many fdinfo snippets
i've putted into /proc docs. my bad, sorry. I'll try to prepare
docs today.
> The 640708a2cff7f81 changelog says:
>
> : This one behaves similarly to the /proc/<pid>/fd/ one - it contains
> : symlinks one for each mapping with file, the name of a symlink is
> : "vma->vm_start-vma->vm_end", the target is the file. Opening a symlink
> : results in a file that point exactly to the same inode as them vma's one.
> :
> : For example the ls -l of some arbitrary /proc/<pid>/map_files/
> :
> : | lr-x------ 1 root root 64 Aug 26 06:40 7f8f80403000-7f8f80404000 -> /lib64/libc-2.5.so
> : | lr-x------ 1 root root 64 Aug 26 06:40 7f8f8061e000-7f8f80620000 -> /lib64/libselinux.so.1
> : | lr-x------ 1 root root 64 Aug 26 06:40 7f8f80826000-7f8f80827000 -> /lib64/libacl.so.1.1.0
> : | lr-x------ 1 root root 64 Aug 26 06:40 7f8f80a2f000-7f8f80a30000 -> /lib64/librt-2.5.so
> : | lr-x------ 1 root root 64 Aug 26 06:40 7f8f80a30000-7f8f80a4c000 -> /lib64/ld-2.5.so
>
> afacit this info is also available in /proc/pid/maps, so things
> shouldn't get worse if the /proc/pid/map_files permissions are at least
> as restrictive as the /proc/pid/maps permissions. Is that the case?
> (Please add to changelog).
>
> There's one other problem here: we're assuming that the map_files
> implementation doesn't have bugs. If it does have bugs then relaxing
> permissions like this will create new vulnerabilities. And the
> map_files implementation is surprisingly complex. Is it bug-free?
I didn't find any bugs in map-files (and we use it for long time already)
so I think it is safe.
^ permalink raw reply
* Re: [RFC][PATCH v2] procfs: Always expose /proc/<pid>/map_files/ and make it readable
From: Andrew Morton @ 2015-01-27 6:50 UTC (permalink / raw)
To: Cyrill Gorcunov
Cc: Kirill A. Shutemov, Calvin Owens, Alexey Dobriyan, Oleg Nesterov,
Eric W. Biederman, Al Viro, Kirill A. Shutemov, Peter Feiner,
Grant Likely, Siddhesh Poyarekar, linux-kernel, kernel-team,
Pavel Emelyanov, linux-api, Kees Cook
In-Reply-To: <20150127064647.GH651@moon>
On Tue, 27 Jan 2015 09:46:47 +0300 Cyrill Gorcunov <gorcunov@gmail.com> wrote:
> > There's one other problem here: we're assuming that the map_files
> > implementation doesn't have bugs. If it does have bugs then relaxing
> > permissions like this will create new vulnerabilities. And the
> > map_files implementation is surprisingly complex. Is it bug-free?
>
> I didn't find any bugs in map-files (and we use it for long time already)
> so I think it is safe.
You've been using map_files the way it was supposed to be used so no,
any bugs won't show up. What happens if you don your evil black hat
and use map_files in ways that weren't anticipated? Attack it?
^ permalink raw reply
* Re: [PATCH 3/4] IB/uverbs: ex_query_device: check request's comp_mask
From: Haggai Eran @ 2015-01-27 6:50 UTC (permalink / raw)
To: Yann Droneaud
Cc: Sagi Grimberg, Shachar Raindel, Eli Cohen, Roland Dreier,
linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Tzahi Oved, Or Gerlitz,
Matan Barak
In-Reply-To: <1422271029.3133.68.camel-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org>
On 26/01/2015 13:17, Yann Droneaud wrote:
> ...
> Le dimanche 25 janvier 2015 à 17:23 +0200, Haggai Eran a écrit :
>> On 22/01/2015 15:28, Yann Droneaud wrote:
>>> This patch ensures the extended QUERY_DEVICE uverbs request's
>>> comp_mask has only known values. If userspace returns unknown
>>> features, -EINVAL will be returned, allowing to probe/discover
>>> which features are currently supported by the kernel.
>>
>> This probing process will be much more cumbersome than it needs to be
>> because userspace will have to call QUERY_DEVICE repetitively with
>> different comp_mask fields until it finds out the exact set of supported
>> bits.
>>
>
> O(log2(N))
I don't think user space developers will be happy having to do trial and
error to determine what features the kernel driver supports. It might be
even more then O(log2(N)). If my understanding of comp_mask bits usage is
correct it would O(N). But it's not the time complexity I'm worried about,
it's the fact that it requires user-space developers to go through hoops in
order to get information that can be much more easily exported.
> Or you had to add a different interface, dedicated to retrieve the exact
> supported feature mask.
>
>>> Moreover, it also ensure the requested features set in comp_mask
>>> are sequentially set, not skipping intermediate features, eg. the
>>> "highest" requested feature also request all the "lower" ones.
>>> This way each new feature will have to be stacked on top of the
>>> existing ones: this is especially important for the request and
>>> response data structures where fields are added after the
>>> current ones when expanded to support a new feature.
>>
>> I think it is perfectly acceptable that not all drivers will implement
>> all available features, and so you shouldn't enforce this requirement.
>
> With regard to QUERY_DEVICE: the data structure layout depends on the
> comp_mask value. So either you propose a way to express multipart data
> structure (see CMSG or NETLINK), or we have to ensure the data structure
> is ever-growing, with each new chunck stacked over the existing ones:
> that's the purpose of :
>
> if (cmd.comp_mask & (cmd.comp_mask + 1))
> return -EINVAL;
>
>> Also, it makes the comp_mask nothing more than a wasteful version number
>> between 0 and 63.
>
> That's what I've already explained earlier in "Re: [PATCH v3 06/17]
> IB/core: Add support for extended query device caps":
>
> http://mid.gmane.org/1421844612.13543.40.camel-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org
Yes, you wrote there:
> Regarding comp_mask (not for this particular verb):
>
> It's not clear whether request's comp_mask describe the request or the
> response, as such I'm puzzled.
>
> How would the kernel and the userspace be able to parse the request and
> the response if they ignore unknown bits ?
>
> How would they be able to skip the unrecognized chunk of the request and
> response buffer ?
>
> How one bit in a comp_mask is related to a chunk in the request or
> response ?
>
> It's likely the kernel or userspace would have to skip the remaining
> comp_mask's bits after encountering an unknown bit as the size of the
> corresponding chunk in request or response would be unknown, making
> impossible to locate the corresponding chunk for the next bit set in
> comp_mask. Having said that, comp_mask is just a complicated way of
> expressing a version, which is turn describe a size (ever growing).
It is my understanding that each comp_mask bit marks a set of fields in
the command or in the response struct as valid, so the struct format
remains the same and the kernel and userspace don't need to make
difficult calculation as to where each field is, but you can still pass
a high bit set in comp_mask with one of the lower bits cleared.
I couldn't find this explicit detail in the mailing list, but I did found
a presentation that was presented in OFA International Developer
Workshop 2013 [1], that gave an example of of an verb where each
comp_mask bit marked a different field as valid.
>
>>
>> In the specific case of QUERY_DEVICE you might argue that there isn't
>> any need for input comp_mask, only for output, and then you may enforce
>> the input comp_mask will always be zero.
>
> The extended QUERY_DEVICE uverbs as currently merged is using comp_mask
> from input to choose to report on-demand-paging related value. So it
> seems it's needed.
>
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/infiniband/core/uverbs_cmd.c?id=v3.19-rc6#n3297
>
>> However, you will in any case need to be able to extended the size of the response in the future.
>>
>
> That's already the case for on demand paging.
>
>>>
>>> Link: http://mid.gmane.org/cover.1421931555.git.ydroneaud-RlY5vtjFyJ1hl2p70BpVqQ@public.gmane.orgm
>>> Cc: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>> Cc: Shachar Raindel <raindel-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>> Cc: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>> Cc: Haggai Eran <haggaie-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>> Signed-off-by: Yann Droneaud <ydroneaud-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org>
>>> ---
>>> drivers/infiniband/core/uverbs_cmd.c | 6 ++++++
>>> 1 file changed, 6 insertions(+)
>>>
>>> diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
>>> index 8668b328b7e6..80a1c90f1dbf 100644
>>> --- a/drivers/infiniband/core/uverbs_cmd.c
>>> +++ b/drivers/infiniband/core/uverbs_cmd.c
>>> @@ -3313,6 +3313,12 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
>>> if (err)
>>> return err;
>>>
>>> + if (cmd.comp_mask & (cmd.comp_mask + 1))
>>> + return -EINVAL;
>>> +
>>> + if (cmd.comp_mask & ~(__u32)IB_USER_VERBS_EX_QUERY_DEVICE_ODP)
>>> + return -EINVAL;
>>> +
>
> If we keep the checks on output buffer size from patch 1, returning
> -ENOSPC in case of size mismatch, and if we are sure that no bit in
> input comp_mask will ever trigger a call to a kernel function that can
> make the uverb fail, the latter check on known value could be dropped,
> allowing the userspace to set the highest mask (-1): userspace
> will use -ENOSPC to probe the expected size of the response buffer
> to match the highest supported comp_mask. But it's going to hurt
> userspace application not ready to receive -ENOSPC on newer kernel
> with extended QUERY_DEVICE ABI ... Oops.
>
> So in this end, the safest way to ensure userspace is doing the correct
> thing so that we have backward and forward compatibility is to check
> for known values in comp_mask, check for response buffer size and ensure
> that data structure chunk are stacked.
>
> The tighter are the checks now, the easier the interface could be
> extended latter.
I understand this position, and I generally agree, but I think that
specifically for a verb like QUERY_DEVICE that only reads information from
the kernel driver to user-space, there is no harm in the kernel just
providing all the information it can fit in the response buffer provided
by user-space.
Let me explain: newer fields are added to the kernel response struct at the
end, together with a new comp_mask bit.
Older user-space with newer kernels will simply ask only for the buffer
size they care about. The fact that the struct is truncated doesn't affect
these programs because the truncated struct is a valid struct that was
presented by the kernel in an older version.
They may or may not receive a comp_mask bit they don't recognize, but that
only tells them that the kernel supports new features they don't know about.
Newer user-space with older kernel will give a larger buffer then the
kernel can fill. The kernel only fills in the beginning of the user-space
buffer, and provides user-space with the comp_mask bits that mark which
fields are valid. So user-space can tell that the end of the buffer isn't
valid.
In my implementation I also left the ending uninitialized, but the
kernel can zero it if you think it is important.
So I hope you agree this scheme is extendible and allows keeping backward
and forward compatibility. If you can think of another scheme that will be
more strict with the buffer sizes, but doesn't require user-space to do
extra work, I'll be happy to hear about it.
Regards,
Haggai
[1] Extending Verbs API, Tzahi Oved
https://www.openfabrics.org/images/docs/2013_Dev_Workshop/Tues_0423/2013_Workshop_Tues_0830_Tzahi_Oved-verbs_extensions_ofa_2013-tzahio.pdf
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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
* Re: [RFC][PATCH v2] procfs: Always expose /proc/<pid>/map_files/ and make it readable
From: Cyrill Gorcunov @ 2015-01-27 7:23 UTC (permalink / raw)
To: Andrew Morton
Cc: Kirill A. Shutemov, Calvin Owens, Alexey Dobriyan, Oleg Nesterov,
Eric W. Biederman, Al Viro, Kirill A. Shutemov, Peter Feiner,
Grant Likely, Siddhesh Poyarekar,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kernel-team-b10kYP2dOMg,
Pavel Emelyanov, linux-api-u79uwXL29TY76Z2rM5mHXA, Kees Cook
In-Reply-To: <20150126225023.df63f6ca.akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
On Mon, Jan 26, 2015 at 10:50:23PM -0800, Andrew Morton wrote:
> On Tue, 27 Jan 2015 09:46:47 +0300 Cyrill Gorcunov <gorcunov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> > > There's one other problem here: we're assuming that the map_files
> > > implementation doesn't have bugs. If it does have bugs then relaxing
> > > permissions like this will create new vulnerabilities. And the
> > > map_files implementation is surprisingly complex. Is it bug-free?
> >
> > I didn't find any bugs in map-files (and we use it for long time already)
> > so I think it is safe.
>
> You've been using map_files the way it was supposed to be used so no,
> any bugs won't show up. What happens if you don your evil black hat
> and use map_files in ways that weren't anticipated? Attack it?
Hard to say, Andrew. If I found a way to exploit this feature for
bad purpose for sure I would patch it out. At the moment I don't
see any. Touching another process memory via file descriptor
allows one to modify its contents but you have to be granted
ptrace-may-access which i consider as enough for security.
^ permalink raw reply
* Re: [RFC][PATCH v2] procfs: Always expose /proc/<pid>/map_files/ and make it readable
From: Cyrill Gorcunov @ 2015-01-27 7:37 UTC (permalink / raw)
To: Kees Cook
Cc: Andrew Morton, Kirill A. Shutemov, Calvin Owens, Alexey Dobriyan,
Oleg Nesterov, Eric W. Biederman, Al Viro, Kirill A. Shutemov,
Peter Feiner, Grant Likely, Siddhesh Poyarekar, LKML,
kernel-team-b10kYP2dOMg, Pavel Emelyanov, Linux API
In-Reply-To: <CAGXu5jLDkg0hJSMm3CdoO-77yiK5GQWHSe3+1h7mq76LERpNBA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, Jan 26, 2015 at 04:15:26PM -0800, Kees Cook wrote:
> >
> > akpm3:/usr/src/25> grep -r map_files Documentation
>
> If akpm's comments weren't clear: this needs to be fixed. Everything
> in /proc should appear in Documentation.
I'll do that.
> > The 640708a2cff7f81 changelog says:
> >
> > : This one behaves similarly to the /proc/<pid>/fd/ one - it contains
> > : symlinks one for each mapping with file, the name of a symlink is
> > : "vma->vm_start-vma->vm_end", the target is the file. Opening a symlink
> > : results in a file that point exactly to the same inode as them vma's one.
> > :
> > : For example the ls -l of some arbitrary /proc/<pid>/map_files/
> > :
> > : | lr-x------ 1 root root 64 Aug 26 06:40 7f8f80403000-7f8f80404000 -> /lib64/libc-2.5.so
> > : | lr-x------ 1 root root 64 Aug 26 06:40 7f8f8061e000-7f8f80620000 -> /lib64/libselinux.so.1
> > : | lr-x------ 1 root root 64 Aug 26 06:40 7f8f80826000-7f8f80827000 -> /lib64/libacl.so.1.1.0
> > : | lr-x------ 1 root root 64 Aug 26 06:40 7f8f80a2f000-7f8f80a30000 -> /lib64/librt-2.5.so
> > : | lr-x------ 1 root root 64 Aug 26 06:40 7f8f80a30000-7f8f80a4c000 -> /lib64/ld-2.5.so
>
> How is mmap offset represented in this output?
We're printing vm_area_struct:[vm_start;vm_end] only.
> > afacit this info is also available in /proc/pid/maps, so things
> > shouldn't get worse if the /proc/pid/map_files permissions are at least
> > as restrictive as the /proc/pid/maps permissions. Is that the case?
> > (Please add to changelog).
>
> Both maps and map_files uses ptrace_may_access (via mm_acces) with
> PTRACE_MODE_READ, so I'm happy from a info leak perspective.
>
> Are mount namespaces handled in this output?
Could you clarify this moment, i'm not sure i get it.
>
> > There's one other problem here: we're assuming that the map_files
> > implementation doesn't have bugs. If it does have bugs then relaxing
> > permissions like this will create new vulnerabilities. And the
> > map_files implementation is surprisingly complex. Is it bug-free?
^ permalink raw reply
* Re: futex(2) man page update help request
From: Michael Kerrisk (man-pages) @ 2015-01-27 7:48 UTC (permalink / raw)
To: Torvald Riegel, Thomas Gleixner
Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w, Carlos O'Donell,
Darren Hart, Ingo Molnar, Jakub Jelinek,
linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, lkml,
Arnd Bergmann, Steven Rostedt, Peter Zijlstra, Linux API,
Darren Hart, Anton Blanchard, Eric Dumazet, bill o gallmeister,
Jan Kiszka, Daniel Wagner, Rich Felker
In-Reply-To: <1422105142.29655.16.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
Hello Torvald,
On 01/24/2015 02:12 PM, Torvald Riegel wrote:
> On Sat, 2015-01-24 at 12:35 +0100, Thomas Gleixner wrote:
>> So we should never see -EINTR in the case of a spurious wakeup here.
>>
>> But, here is the not so good news:
>>
>> I did some archaeology. The restart handling of futex_wait() got
>> introduced in kernel 2.6.22, so anything older than that will have
>> the spurious -EINTR issues.
>>
>> futex_wait_pi() always had the restart handling and glibc folks back
>> then (2006) requested that it should never return -EINTR, so it
>> unconditionally restarts the syscall whether a signal had been
>> delivered or not.
>>
>> So kernels >= 2.6.22 should never return -EINTR spuriously. If that
>> happens it's a bug and needs to be fixed.
>
> Thanks for looking into this.
>
> Michael, can you include the above in the documentation please? This is
> useful for userspace code like glibc that expects a minimum kernel
> version. Thanks!
I've added some text to my draft to cover this point.
Cheers,
Michael
--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" 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
* [PATCH v8 0/2] Add Spreadtrum SoC bindings and serial driver support
From: Chunyan Zhang @ 2015-01-27 7:56 UTC (permalink / raw)
To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
arnd-r2nGTMty4D4, gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io,
peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8, pawel.moll-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, grant.likely-QSEj5FYQhm4dnm+yROfE0A
Cc: jslaby-AlSwsSmVLrQ, heiko-4mtYJXux2i+zQB+pC5nmwQ,
jason-NLaQJdtUoK4Be96aLqz0jA, florian.vaussard-p8DiymsW2f8,
andrew-g2DYL2Zd6BY, hytszk-Re5JQEeQqe8AvxtiuMwx3w,
antonynpavlov-Re5JQEeQqe8AvxtiuMwx3w,
shawn.guo-QSEj5FYQhm4dnm+yROfE0A,
orsonzhai-Re5JQEeQqe8AvxtiuMwx3w, geng.ren-lxIno14LUO0EEoCn2XhGlw,
zhizhou.zhang-lxIno14LUO0EEoCn2XhGlw,
lanqing.liu-lxIno14LUO0EEoCn2XhGlw,
zhang.lyra-Re5JQEeQqe8AvxtiuMwx3w,
wei.qiao-lxIno14LUO0EEoCn2XhGlw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <sc9836-serial-v8>
This patch-set split the last version, and addressed the review comments from
last version on serial driver code.
Changes from v7:
* Addressed review comments from Peter:
- Initialized the stack local with zero in sprd_set_termios()
- Used dev_get_drvdata() to get sprd_uart_port
Changes from v6:
- Setted SPRD_TIMEOUT with 256 rather than 2048
- Used u32 instead of uint32_t
- Removed inline of handle_lsr_errors which is a single call site function
- Removed unused parameter of sprd_tx & sprd_rx
- Used spin_lock_irqsave in sprd_startup() instead of spin_lock
- Added a check for port->sysrq in sprd_console_write()
- Used a global counter as a condition of calling uart_{un}register_driver
- Added pdev->id assignment in probe()
- Setted port->flags with UPF_BOOT_AUTOCONF instead of ASYNC_BOOT_AUTOCONF
Changes from v5:
- Used Spreadtrum instead of SPRD in menus
- Changed TTY name to 'ttyS'
- Moved uart_register_driver() to probe()
- Added spinlock as needed
- Removed register states saving and restoring in suspend() and resume()
Chunyan Zhang (2):
Documentation: DT: Add bindings for Spreadtrum SoC Platform
tty/serial: Add Spreadtrum sc9836-uart driver support
Documentation/devicetree/bindings/arm/sprd.txt | 11 +
.../devicetree/bindings/serial/sprd-uart.txt | 7 +
.../devicetree/bindings/vendor-prefixes.txt | 1 +
drivers/tty/serial/Kconfig | 18 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/sprd_serial.c | 797 ++++++++++++++++++++
include/uapi/linux/serial_core.h | 3 +
7 files changed, 838 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/sprd.txt
create mode 100644 Documentation/devicetree/bindings/serial/sprd-uart.txt
create mode 100644 drivers/tty/serial/sprd_serial.c
--
1.7.9.5
--
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
* [PATCH v8 1/2] Documentation: DT: Add bindings for Spreadtrum SoC Platform
From: Chunyan Zhang @ 2015-01-27 7:56 UTC (permalink / raw)
To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
arnd-r2nGTMty4D4, gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io,
peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8, pawel.moll-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, grant.likely-QSEj5FYQhm4dnm+yROfE0A
Cc: jslaby-AlSwsSmVLrQ, heiko-4mtYJXux2i+zQB+pC5nmwQ,
jason-NLaQJdtUoK4Be96aLqz0jA, florian.vaussard-p8DiymsW2f8,
andrew-g2DYL2Zd6BY, hytszk-Re5JQEeQqe8AvxtiuMwx3w,
antonynpavlov-Re5JQEeQqe8AvxtiuMwx3w,
shawn.guo-QSEj5FYQhm4dnm+yROfE0A,
orsonzhai-Re5JQEeQqe8AvxtiuMwx3w, geng.ren-lxIno14LUO0EEoCn2XhGlw,
zhizhou.zhang-lxIno14LUO0EEoCn2XhGlw,
lanqing.liu-lxIno14LUO0EEoCn2XhGlw,
zhang.lyra-Re5JQEeQqe8AvxtiuMwx3w,
wei.qiao-lxIno14LUO0EEoCn2XhGlw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1422345407-10037-1-git-send-email-chunyan.zhang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
Adds Spreadtrum's prefix "sprd" to vendor-prefixes file.
Adds the devicetree binding documentations for Spreadtrum's sc9836-uart
and SC9836 SoC based on the Sharkl64 Platform which is a 64-bit SoC
Platform of Spreadtrum.
Signed-off-by: Chunyan Zhang <chunyan.zhang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
---
Documentation/devicetree/bindings/arm/sprd.txt | 11 +++++++++++
.../devicetree/bindings/serial/sprd-uart.txt | 7 +++++++
.../devicetree/bindings/vendor-prefixes.txt | 1 +
3 files changed, 19 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/sprd.txt
create mode 100644 Documentation/devicetree/bindings/serial/sprd-uart.txt
diff --git a/Documentation/devicetree/bindings/arm/sprd.txt b/Documentation/devicetree/bindings/arm/sprd.txt
new file mode 100644
index 0000000..31a629d
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sprd.txt
@@ -0,0 +1,11 @@
+Spreadtrum SoC Platforms Device Tree Bindings
+----------------------------------------------------
+
+Sharkl64 is a Spreadtrum's SoC Platform which is based
+on ARM 64-bit processor.
+
+SC9836 openphone board with SC9836 SoC based on the
+Sharkl64 Platform shall have the following properties.
+
+Required root node properties:
+ - compatible = "sprd,sc9836-openphone", "sprd,sc9836";
diff --git a/Documentation/devicetree/bindings/serial/sprd-uart.txt b/Documentation/devicetree/bindings/serial/sprd-uart.txt
new file mode 100644
index 0000000..2aff0f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/sprd-uart.txt
@@ -0,0 +1,7 @@
+* Spreadtrum serial UART
+
+Required properties:
+- compatible: must be "sprd,sc9836-uart"
+- reg: offset and length of the register set for the device
+- interrupts: exactly one interrupt specifier
+- clocks: phandles to input clocks.
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index b1df0ad..0a8384f 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -153,6 +153,7 @@ snps Synopsys, Inc.
solidrun SolidRun
sony Sony Corporation
spansion Spansion Inc.
+sprd Spreadtrum Communications Inc.
st STMicroelectronics
ste ST-Ericsson
stericsson ST-Ericsson
--
1.7.9.5
--
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 v8 2/2] tty/serial: Add Spreadtrum sc9836-uart driver support
From: Chunyan Zhang @ 2015-01-27 7:56 UTC (permalink / raw)
To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
arnd-r2nGTMty4D4, gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io,
peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8, pawel.moll-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, grant.likely-QSEj5FYQhm4dnm+yROfE0A
Cc: jslaby-AlSwsSmVLrQ, heiko-4mtYJXux2i+zQB+pC5nmwQ,
jason-NLaQJdtUoK4Be96aLqz0jA, florian.vaussard-p8DiymsW2f8,
andrew-g2DYL2Zd6BY, hytszk-Re5JQEeQqe8AvxtiuMwx3w,
antonynpavlov-Re5JQEeQqe8AvxtiuMwx3w,
shawn.guo-QSEj5FYQhm4dnm+yROfE0A,
orsonzhai-Re5JQEeQqe8AvxtiuMwx3w, geng.ren-lxIno14LUO0EEoCn2XhGlw,
zhizhou.zhang-lxIno14LUO0EEoCn2XhGlw,
lanqing.liu-lxIno14LUO0EEoCn2XhGlw,
zhang.lyra-Re5JQEeQqe8AvxtiuMwx3w,
wei.qiao-lxIno14LUO0EEoCn2XhGlw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1422345407-10037-1-git-send-email-chunyan.zhang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
Add a full sc9836-uart driver for SC9836 SoC which is based on the
spreadtrum sharkl64 platform.
This driver also support earlycon.
Originally-by: Lanqing Liu <lanqing.liu-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
Signed-off-by: Orson Zhai <orson.zhai-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
Signed-off-by: Chunyan Zhang <chunyan.zhang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
Acked-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
drivers/tty/serial/Kconfig | 18 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/sprd_serial.c | 797 ++++++++++++++++++++++++++++++++++++++
include/uapi/linux/serial_core.h | 3 +
4 files changed, 819 insertions(+)
create mode 100644 drivers/tty/serial/sprd_serial.c
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index c79b43c..13211f7 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1577,6 +1577,24 @@ config SERIAL_MEN_Z135
This driver can also be build as a module. If so, the module will be called
men_z135_uart.ko
+config SERIAL_SPRD
+ tristate "Support for Spreadtrum serial"
+ depends on ARCH_SPRD
+ select SERIAL_CORE
+ help
+ This enables the driver for the Spreadtrum's serial.
+
+config SERIAL_SPRD_CONSOLE
+ bool "Spreadtrum UART console support"
+ depends on SERIAL_SPRD=y
+ select SERIAL_CORE_CONSOLE
+ select SERIAL_EARLYCON
+ help
+ Support for early debug console using Spreadtrum's serial. This enables
+ the console before standard serial driver is probed. This is enabled
+ with "earlycon" on the kernel command line. The console is
+ enabled when early_param is processed.
+
endmenu
config SERIAL_MCTRL_GPIO
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 9a548ac..4801aca 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_SERIAL_ARC) += arc_uart.o
obj-$(CONFIG_SERIAL_RP2) += rp2.o
obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o
obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o
+obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o
# GPIOLIB helpers for modem control lines
obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o
diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c
new file mode 100644
index 0000000..bbd0447
--- /dev/null
+++ b/drivers/tty/serial/sprd_serial.c
@@ -0,0 +1,797 @@
+/*
+ * Copyright (C) 2012-2015 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/clk.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+/* device name */
+#define UART_NR_MAX 8
+#define SPRD_TTY_NAME "ttyS"
+#define SPRD_FIFO_SIZE 128
+#define SPRD_DEF_RATE 26000000
+#define SPRD_BAUD_IO_LIMIT 3000000
+#define SPRD_TIMEOUT 256
+
+/* the offset of serial registers and BITs for them */
+/* data registers */
+#define SPRD_TXD 0x0000
+#define SPRD_RXD 0x0004
+
+/* line status register and its BITs */
+#define SPRD_LSR 0x0008
+#define SPRD_LSR_OE BIT(4)
+#define SPRD_LSR_FE BIT(3)
+#define SPRD_LSR_PE BIT(2)
+#define SPRD_LSR_BI BIT(7)
+#define SPRD_LSR_TX_OVER BIT(15)
+
+/* data number in TX and RX fifo */
+#define SPRD_STS1 0x000C
+
+/* interrupt enable register and its BITs */
+#define SPRD_IEN 0x0010
+#define SPRD_IEN_RX_FULL BIT(0)
+#define SPRD_IEN_TX_EMPTY BIT(1)
+#define SPRD_IEN_BREAK_DETECT BIT(7)
+#define SPRD_IEN_TIMEOUT BIT(13)
+
+/* interrupt clear register */
+#define SPRD_ICLR 0x0014
+
+/* line control register */
+#define SPRD_LCR 0x0018
+#define SPRD_LCR_STOP_1BIT 0x10
+#define SPRD_LCR_STOP_2BIT 0x30
+#define SPRD_LCR_DATA_LEN (BIT(2) | BIT(3))
+#define SPRD_LCR_DATA_LEN5 0x0
+#define SPRD_LCR_DATA_LEN6 0x4
+#define SPRD_LCR_DATA_LEN7 0x8
+#define SPRD_LCR_DATA_LEN8 0xc
+#define SPRD_LCR_PARITY (BIT(0) | BIT(1))
+#define SPRD_LCR_PARITY_EN 0x2
+#define SPRD_LCR_EVEN_PAR 0x0
+#define SPRD_LCR_ODD_PAR 0x1
+
+/* control register 1 */
+#define SPRD_CTL1 0x001C
+#define RX_HW_FLOW_CTL_THLD BIT(6)
+#define RX_HW_FLOW_CTL_EN BIT(7)
+#define TX_HW_FLOW_CTL_EN BIT(8)
+#define RX_TOUT_THLD_DEF 0x3E00
+#define RX_HFC_THLD_DEF 0x40
+
+/* fifo threshold register */
+#define SPRD_CTL2 0x0020
+#define THLD_TX_EMPTY 0x40
+#define THLD_RX_FULL 0x40
+
+/* config baud rate register */
+#define SPRD_CLKD0 0x0024
+#define SPRD_CLKD1 0x0028
+
+/* interrupt mask status register */
+#define SPRD_IMSR 0x002C
+#define SPRD_IMSR_RX_FIFO_FULL BIT(0)
+#define SPRD_IMSR_TX_FIFO_EMPTY BIT(1)
+#define SPRD_IMSR_BREAK_DETECT BIT(7)
+#define SPRD_IMSR_TIMEOUT BIT(13)
+
+struct reg_backup {
+ u32 ien;
+ u32 ctrl0;
+ u32 ctrl1;
+ u32 ctrl2;
+ u32 clkd0;
+ u32 clkd1;
+ u32 dspwait;
+};
+
+struct sprd_uart_port {
+ struct uart_port port;
+ struct reg_backup reg_bak;
+ char name[16];
+};
+
+static struct sprd_uart_port *sprd_port[UART_NR_MAX];
+static int sprd_ports_num;
+
+static inline unsigned int serial_in(struct uart_port *port, int offset)
+{
+ return readl_relaxed(port->membase + offset);
+}
+
+static inline void serial_out(struct uart_port *port, int offset, int value)
+{
+ writel_relaxed(value, port->membase + offset);
+}
+
+static unsigned int sprd_tx_empty(struct uart_port *port)
+{
+ if (serial_in(port, SPRD_STS1) & 0xff00)
+ return 0;
+ else
+ return TIOCSER_TEMT;
+}
+
+static unsigned int sprd_get_mctrl(struct uart_port *port)
+{
+ return TIOCM_DSR | TIOCM_CTS;
+}
+
+static void sprd_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ /* nothing to do */
+}
+
+static void sprd_stop_tx(struct uart_port *port)
+{
+ unsigned int ien, iclr;
+
+ iclr = serial_in(port, SPRD_ICLR);
+ ien = serial_in(port, SPRD_IEN);
+
+ iclr |= SPRD_IEN_TX_EMPTY;
+ ien &= ~SPRD_IEN_TX_EMPTY;
+
+ serial_out(port, SPRD_ICLR, iclr);
+ serial_out(port, SPRD_IEN, ien);
+}
+
+static void sprd_start_tx(struct uart_port *port)
+{
+ unsigned int ien;
+
+ ien = serial_in(port, SPRD_IEN);
+ if (!(ien & SPRD_IEN_TX_EMPTY)) {
+ ien |= SPRD_IEN_TX_EMPTY;
+ serial_out(port, SPRD_IEN, ien);
+ }
+}
+
+static void sprd_stop_rx(struct uart_port *port)
+{
+ unsigned int ien, iclr;
+
+ iclr = serial_in(port, SPRD_ICLR);
+ ien = serial_in(port, SPRD_IEN);
+
+ ien &= ~(SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT);
+ iclr |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT;
+
+ serial_out(port, SPRD_IEN, ien);
+ serial_out(port, SPRD_ICLR, iclr);
+}
+
+/* The Sprd serial does not support this function. */
+static void sprd_break_ctl(struct uart_port *port, int break_state)
+{
+ /* nothing to do */
+}
+
+static int handle_lsr_errors(struct uart_port *port,
+ unsigned int *flag,
+ unsigned int *lsr)
+{
+ int ret = 0;
+
+ /* statistics */
+ if (*lsr & SPRD_LSR_BI) {
+ *lsr &= ~(SPRD_LSR_FE | SPRD_LSR_PE);
+ port->icount.brk++;
+ ret = uart_handle_break(port);
+ if (ret)
+ return ret;
+ } else if (*lsr & SPRD_LSR_PE)
+ port->icount.parity++;
+ else if (*lsr & SPRD_LSR_FE)
+ port->icount.frame++;
+ if (*lsr & SPRD_LSR_OE)
+ port->icount.overrun++;
+
+ /* mask off conditions which should be ignored */
+ *lsr &= port->read_status_mask;
+ if (*lsr & SPRD_LSR_BI)
+ *flag = TTY_BREAK;
+ else if (*lsr & SPRD_LSR_PE)
+ *flag = TTY_PARITY;
+ else if (*lsr & SPRD_LSR_FE)
+ *flag = TTY_FRAME;
+
+ return ret;
+}
+
+static inline void sprd_rx(struct uart_port *port)
+{
+ struct tty_port *tty = &port->state->port;
+ unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT;
+
+ while ((serial_in(port, SPRD_STS1) & 0x00ff) && max_count--) {
+ lsr = serial_in(port, SPRD_LSR);
+ ch = serial_in(port, SPRD_RXD);
+ flag = TTY_NORMAL;
+ port->icount.rx++;
+
+ if (lsr & (SPRD_LSR_BI | SPRD_LSR_PE |
+ SPRD_LSR_FE | SPRD_LSR_OE))
+ if (handle_lsr_errors(port, &lsr, &flag))
+ continue;
+ if (uart_handle_sysrq_char(port, ch))
+ continue;
+
+ uart_insert_char(port, lsr, SPRD_LSR_OE, ch, flag);
+ }
+
+ tty_flip_buffer_push(tty);
+}
+
+static inline void sprd_tx(struct uart_port *port)
+{
+ struct circ_buf *xmit = &port->state->xmit;
+ int count;
+
+ if (port->x_char) {
+ serial_out(port, SPRD_TXD, port->x_char);
+ port->icount.tx++;
+ port->x_char = 0;
+ return;
+ }
+
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+ sprd_stop_tx(port);
+ return;
+ }
+
+ count = THLD_TX_EMPTY;
+ do {
+ serial_out(port, SPRD_TXD, xmit->buf[xmit->tail]);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ port->icount.tx++;
+ if (uart_circ_empty(xmit))
+ break;
+ } while (--count > 0);
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ if (uart_circ_empty(xmit))
+ sprd_stop_tx(port);
+}
+
+/* this handles the interrupt from one port */
+static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
+{
+ struct uart_port *port = dev_id;
+ unsigned int ims;
+
+ spin_lock(&port->lock);
+
+ ims = serial_in(port, SPRD_IMSR);
+
+ if (!ims)
+ return IRQ_NONE;
+
+ serial_out(port, SPRD_ICLR, ~0);
+
+ if (ims & (SPRD_IMSR_RX_FIFO_FULL |
+ SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT))
+ sprd_rx(port);
+
+ if (ims & SPRD_IMSR_TX_FIFO_EMPTY)
+ sprd_tx(port);
+
+ spin_unlock(&port->lock);
+
+ return IRQ_HANDLED;
+}
+
+static int sprd_startup(struct uart_port *port)
+{
+ int ret = 0;
+ unsigned int ien, fc;
+ unsigned int timeout;
+ struct sprd_uart_port *sp;
+ unsigned long flags;
+
+ serial_out(port, SPRD_CTL2, ((THLD_TX_EMPTY << 8) | THLD_RX_FULL));
+
+ /* clear rx fifo */
+ timeout = SPRD_TIMEOUT;
+ while (timeout-- && serial_in(port, SPRD_STS1) & 0x00ff)
+ serial_in(port, SPRD_RXD);
+
+ /* clear tx fifo */
+ timeout = SPRD_TIMEOUT;
+ while (timeout-- && serial_in(port, SPRD_STS1) & 0xff00)
+ cpu_relax();
+
+ /* clear interrupt */
+ serial_out(port, SPRD_IEN, 0);
+ serial_out(port, SPRD_ICLR, ~0);
+
+ /* allocate irq */
+ sp = container_of(port, struct sprd_uart_port, port);
+ snprintf(sp->name, sizeof(sp->name), "sprd_serial%d", port->line);
+ ret = devm_request_irq(port->dev, port->irq, sprd_handle_irq,
+ IRQF_SHARED, sp->name, port);
+ if (ret) {
+ dev_err(port->dev, "fail to request serial irq %d, ret=%d\n",
+ port->irq, ret);
+ return ret;
+ }
+ fc = serial_in(port, SPRD_CTL1);
+ fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF;
+ serial_out(port, SPRD_CTL1, fc);
+
+ /* enable interrupt */
+ spin_lock_irqsave(&port->lock, flags);
+ ien = serial_in(port, SPRD_IEN);
+ ien |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT;
+ serial_out(port, SPRD_IEN, ien);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ return 0;
+}
+
+static void sprd_shutdown(struct uart_port *port)
+{
+ serial_out(port, SPRD_IEN, 0);
+ serial_out(port, SPRD_ICLR, ~0);
+ devm_free_irq(port->dev, port->irq, port);
+}
+
+static void sprd_set_termios(struct uart_port *port,
+ struct ktermios *termios,
+ struct ktermios *old)
+{
+ unsigned int baud, quot;
+ unsigned int lcr = 0, fc;
+ unsigned long flags;
+
+ /* ask the core to calculate the divisor for us */
+ baud = uart_get_baud_rate(port, termios, old, 0, SPRD_BAUD_IO_LIMIT);
+
+ quot = (unsigned int)((port->uartclk + baud / 2) / baud);
+
+ /* set data length */
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ lcr |= SPRD_LCR_DATA_LEN5;
+ break;
+ case CS6:
+ lcr |= SPRD_LCR_DATA_LEN6;
+ break;
+ case CS7:
+ lcr |= SPRD_LCR_DATA_LEN7;
+ break;
+ case CS8:
+ default:
+ lcr |= SPRD_LCR_DATA_LEN8;
+ break;
+ }
+
+ /* calculate stop bits */
+ lcr &= ~(SPRD_LCR_STOP_1BIT | SPRD_LCR_STOP_2BIT);
+ if (termios->c_cflag & CSTOPB)
+ lcr |= SPRD_LCR_STOP_2BIT;
+ else
+ lcr |= SPRD_LCR_STOP_1BIT;
+
+ /* calculate parity */
+ lcr &= ~SPRD_LCR_PARITY;
+ termios->c_cflag &= ~CMSPAR; /* no support mark/space */
+ if (termios->c_cflag & PARENB) {
+ lcr |= SPRD_LCR_PARITY_EN;
+ if (termios->c_cflag & PARODD)
+ lcr |= SPRD_LCR_ODD_PAR;
+ else
+ lcr |= SPRD_LCR_EVEN_PAR;
+ }
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ /* update the per-port timeout */
+ uart_update_timeout(port, termios->c_cflag, baud);
+
+ port->read_status_mask = SPRD_LSR_OE;
+ if (termios->c_iflag & INPCK)
+ port->read_status_mask |= SPRD_LSR_FE | SPRD_LSR_PE;
+ if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
+ port->read_status_mask |= SPRD_LSR_BI;
+
+ /* characters to ignore */
+ port->ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= SPRD_LSR_PE | SPRD_LSR_FE;
+ if (termios->c_iflag & IGNBRK) {
+ port->ignore_status_mask |= SPRD_LSR_BI;
+ /*
+ * If we're ignoring parity and break indicators,
+ * ignore overruns too (for real raw support).
+ */
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= SPRD_LSR_OE;
+ }
+
+ /* flow control */
+ fc = serial_in(port, SPRD_CTL1);
+ fc &= ~(RX_HW_FLOW_CTL_THLD | RX_HW_FLOW_CTL_EN | TX_HW_FLOW_CTL_EN);
+ if (termios->c_cflag & CRTSCTS) {
+ fc |= RX_HW_FLOW_CTL_THLD;
+ fc |= RX_HW_FLOW_CTL_EN;
+ fc |= TX_HW_FLOW_CTL_EN;
+ }
+
+ /* clock divider bit0~bit15 */
+ serial_out(port, SPRD_CLKD0, quot & 0xffff);
+
+ /* clock divider bit16~bit20 */
+ serial_out(port, SPRD_CLKD1, (quot & 0x1f0000) >> 16);
+ serial_out(port, SPRD_LCR, lcr);
+ fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF;
+ serial_out(port, SPRD_CTL1, fc);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ /* Don't rewrite B0 */
+ if (tty_termios_baud_rate(termios))
+ tty_termios_encode_baud_rate(termios, baud, baud);
+}
+
+static const char *sprd_type(struct uart_port *port)
+{
+ return "SPX";
+}
+
+static void sprd_release_port(struct uart_port *port)
+{
+ /* nothing to do */
+}
+
+static int sprd_request_port(struct uart_port *port)
+{
+ return 0;
+}
+
+static void sprd_config_port(struct uart_port *port, int flags)
+{
+ if (flags & UART_CONFIG_TYPE)
+ port->type = PORT_SPRD;
+}
+
+static int sprd_verify_port(struct uart_port *port,
+ struct serial_struct *ser)
+{
+ if (ser->type != PORT_SPRD)
+ return -EINVAL;
+ if (port->irq != ser->irq)
+ return -EINVAL;
+ return 0;
+}
+
+static struct uart_ops serial_sprd_ops = {
+ .tx_empty = sprd_tx_empty,
+ .get_mctrl = sprd_get_mctrl,
+ .set_mctrl = sprd_set_mctrl,
+ .stop_tx = sprd_stop_tx,
+ .start_tx = sprd_start_tx,
+ .stop_rx = sprd_stop_rx,
+ .break_ctl = sprd_break_ctl,
+ .startup = sprd_startup,
+ .shutdown = sprd_shutdown,
+ .set_termios = sprd_set_termios,
+ .type = sprd_type,
+ .release_port = sprd_release_port,
+ .request_port = sprd_request_port,
+ .config_port = sprd_config_port,
+ .verify_port = sprd_verify_port,
+};
+
+#ifdef CONFIG_SERIAL_SPRD_CONSOLE
+static inline void wait_for_xmitr(struct uart_port *port)
+{
+ unsigned int status, tmout = 10000;
+
+ /* wait up to 10ms for the character(s) to be sent */
+ do {
+ status = serial_in(port, SPRD_STS1);
+ if (--tmout == 0)
+ break;
+ udelay(1);
+ } while (status & 0xff00);
+}
+
+static void sprd_console_putchar(struct uart_port *port, int ch)
+{
+ wait_for_xmitr(port);
+ serial_out(port, SPRD_TXD, ch);
+}
+
+static void sprd_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ struct uart_port *port = &sprd_port[co->index]->port;
+ int locked = 1;
+ unsigned long flags;
+
+ if (port->sysrq)
+ locked = 0;
+ else if (oops_in_progress)
+ locked = spin_trylock_irqsave(&port->lock, flags);
+ else
+ spin_lock_irqsave(&port->lock, flags);
+
+ uart_console_write(port, s, count, sprd_console_putchar);
+
+ /* wait for transmitter to become empty */
+ wait_for_xmitr(port);
+
+ if (locked)
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int __init sprd_console_setup(struct console *co, char *options)
+{
+ struct uart_port *port;
+ int baud = 115200;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ if (co->index >= UART_NR_MAX || co->index < 0)
+ co->index = 0;
+
+ port = &sprd_port[co->index]->port;
+ if (port == NULL) {
+ pr_info("serial port %d not yet initialized\n", co->index);
+ return -ENODEV;
+ }
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+ return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver sprd_uart_driver;
+static struct console sprd_console = {
+ .name = SPRD_TTY_NAME,
+ .write = sprd_console_write,
+ .device = uart_console_device,
+ .setup = sprd_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &sprd_uart_driver,
+};
+
+#define SPRD_CONSOLE (&sprd_console)
+
+/* Support for earlycon */
+static void sprd_putc(struct uart_port *port, int c)
+{
+ unsigned int timeout = SPRD_TIMEOUT;
+
+ while (timeout-- &&
+ !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER))
+ cpu_relax();
+
+ writeb(c, port->membase + SPRD_TXD);
+}
+
+static void sprd_early_write(struct console *con, const char *s,
+ unsigned n)
+{
+ struct earlycon_device *dev = con->data;
+
+ uart_console_write(&dev->port, s, n, sprd_putc);
+}
+
+static int __init sprd_early_console_setup(
+ struct earlycon_device *device,
+ const char *opt)
+{
+ if (!device->port.membase)
+ return -ENODEV;
+
+ device->con->write = sprd_early_write;
+ return 0;
+}
+
+EARLYCON_DECLARE(sprd_serial, sprd_early_console_setup);
+OF_EARLYCON_DECLARE(sprd_serial, "sprd,sc9836-uart",
+ sprd_early_console_setup);
+
+#else /* !CONFIG_SERIAL_SPRD_CONSOLE */
+#define SPRD_CONSOLE NULL
+#endif
+
+static struct uart_driver sprd_uart_driver = {
+ .owner = THIS_MODULE,
+ .driver_name = "sprd_serial",
+ .dev_name = SPRD_TTY_NAME,
+ .major = 0,
+ .minor = 0,
+ .nr = UART_NR_MAX,
+ .cons = SPRD_CONSOLE,
+};
+
+static int sprd_probe_dt_alias(int index, struct device *dev)
+{
+ struct device_node *np;
+ static bool seen_dev_with_alias;
+ static bool seen_dev_without_alias;
+ int ret = index;
+
+ if (!IS_ENABLED(CONFIG_OF))
+ return ret;
+
+ np = dev->of_node;
+ if (!np)
+ return ret;
+
+ ret = of_alias_get_id(np, "serial");
+ if (IS_ERR_VALUE(ret)) {
+ seen_dev_without_alias = true;
+ ret = index;
+ } else {
+ seen_dev_with_alias = true;
+ if (ret >= ARRAY_SIZE(sprd_port) || sprd_port[ret] != NULL) {
+ dev_warn(dev, "requested serial port %d not available.\n", ret);
+ ret = index;
+ }
+ }
+
+ return ret;
+}
+
+static int sprd_remove(struct platform_device *dev)
+{
+ struct sprd_uart_port *sup = platform_get_drvdata(dev);
+
+ if (sup) {
+ uart_remove_one_port(&sprd_uart_driver, &sup->port);
+ sprd_port[sup->port.line] = NULL;
+ sprd_ports_num--;
+ }
+
+ if (!sprd_ports_num)
+ uart_unregister_driver(&sprd_uart_driver);
+
+ return 0;
+}
+
+static int sprd_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct uart_port *up;
+ struct clk *clk;
+ int irq;
+ int index;
+ int ret;
+
+ for (index = 0; index < ARRAY_SIZE(sprd_port); index++)
+ if (sprd_port[index] == NULL)
+ break;
+
+ if (index == ARRAY_SIZE(sprd_port))
+ return -EBUSY;
+
+ index = sprd_probe_dt_alias(index, &pdev->dev);
+
+ sprd_port[index] = devm_kzalloc(&pdev->dev,
+ sizeof(*sprd_port[index]), GFP_KERNEL);
+ if (!sprd_port[index])
+ return -ENOMEM;
+
+ pdev->id = index;
+
+ up = &sprd_port[index]->port;
+ up->dev = &pdev->dev;
+ up->line = index;
+ up->type = PORT_SPRD;
+ up->iotype = SERIAL_IO_PORT;
+ up->uartclk = SPRD_DEF_RATE;
+ up->fifosize = SPRD_FIFO_SIZE;
+ up->ops = &serial_sprd_ops;
+ up->flags = UPF_BOOT_AUTOCONF;
+
+ clk = devm_clk_get(&pdev->dev, NULL);
+ if (!IS_ERR(clk))
+ up->uartclk = clk_get_rate(clk);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "not provide mem resource\n");
+ return -ENODEV;
+ }
+ up->mapbase = res->start;
+ up->membase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(up->membase))
+ return PTR_ERR(up->membase);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "not provide irq resource\n");
+ return -ENODEV;
+ }
+ up->irq = irq;
+
+ if (!sprd_ports_num) {
+ ret = uart_register_driver(&sprd_uart_driver);
+ if (ret < 0) {
+ pr_err("Failed to register SPRD-UART driver\n");
+ return ret;
+ }
+ }
+ sprd_ports_num++;
+
+ ret = uart_add_one_port(&sprd_uart_driver, up);
+ if (ret) {
+ sprd_port[index] = NULL;
+ sprd_remove(pdev);
+ }
+
+ platform_set_drvdata(pdev, up);
+
+ return ret;
+}
+
+static int sprd_suspend(struct device *dev)
+{
+ struct sprd_uart_port *sup = dev_get_drvdata(dev);
+
+ uart_suspend_port(&sprd_uart_driver, &sup->port);
+
+ return 0;
+}
+
+static int sprd_resume(struct device *dev)
+{
+ struct sprd_uart_port *sup = dev_get_drvdata(dev);
+
+ uart_resume_port(&sprd_uart_driver, &sup->port);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(sprd_pm_ops, sprd_suspend, sprd_resume);
+
+static const struct of_device_id serial_ids[] = {
+ {.compatible = "sprd,sc9836-uart",},
+ {}
+};
+
+static struct platform_driver sprd_platform_driver = {
+ .probe = sprd_probe,
+ .remove = sprd_remove,
+ .driver = {
+ .name = "sprd_serial",
+ .of_match_table = of_match_ptr(serial_ids),
+ .pm = &sprd_pm_ops,
+ },
+};
+
+module_platform_driver(sprd_platform_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Spreadtrum SoC serial driver series");
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index c172180..7e6eb39 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -248,4 +248,7 @@
/* MESON */
#define PORT_MESON 109
+/* SPRD SERIAL */
+#define PORT_SPRD 110
+
#endif /* _UAPILINUX_SERIAL_CORE_H */
--
1.7.9.5
--
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
* Re: [v8 4/5] ext4: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR interface support
From: Dave Chinner @ 2015-01-27 8:02 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Konstantin Khlebnikov, Li Xi, Linux FS Devel,
linux-ext4-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux API,
Theodore Ts'o, Andreas Dilger, Jan Kara, Al Viro,
Christoph Hellwig, dmonakhov-GEFAQzZX7r8dnm+yROfE0A,
Eric W. Biederman
In-Reply-To: <CALCETrXPCrOTrkoAMuW2os=z6anaEfv4F4D2yDxo6VtCuEtRZw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Fri, Jan 23, 2015 at 03:59:04PM -0800, Andy Lutomirski wrote:
> On Fri, Jan 23, 2015 at 3:30 PM, Dave Chinner <david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org> wrote:
> > On Fri, Jan 23, 2015 at 02:58:09PM +0300, Konstantin Khlebnikov wrote:
> >> On 23.01.2015 04:53, Dave Chinner wrote:
> >> >On Thu, Jan 22, 2015 at 06:28:51PM +0300, Konstantin Khlebnikov wrote:
> >> >>>+ kprojid = make_kprojid(&init_user_ns, (projid_t)projid);
> >> >>
> >> >>Maybe current_user_ns()?
> >> >>This code should be user-namespace aware from the beginning.
> >> >
> >> >No, the code is correct. Project quotas have nothing to do with
> >> >UIDs and so should never have been included in the uid/gid
> >> >namespace mapping infrastructure in the first place.
> >>
> >> Right, but user-namespace provides id mapping for project-id too.
> >> This infrastructure adds support for nested project quotas with
> >> virtualized ids in sub-containers. I couldn't say that this is
> >> must have feature but implementation is trivial because whole
> >> infrastructure is already here.
> >
> > This is an extremely common misunderstanding of project IDs. Project
> > IDs are completely separate to the UID/GID namespace. Project
> > quotas were originally designed specifically for
> > accounting/enforcing quotas in situations where uid/gid
> > accounting/enforcing is not possible. This design intent goes back
> > 25 years - it predates XFS...
> >
> > IOWs, mapping prids via user namespaces defeats the purpose
> > for which prids were originally intended for.
> >
> >> >Point in case: directory subtree quotas can be used as a resource
> >> >controller for limiting space usage within separate containers that
> >> >share the same underlying (large) filesystem via mount namespaces.
> >>
> >> That's exactly my use-case: 'sub-volumes' for containers with
> >> quota for space usage/inodes count.
> >
> > That doesn't require mapped project IDs. Hard container space limits
> > can only be controlled by the init namespace, and because inodes can
> > hold only one project ID the current ns cannot be allowed to change
> > the project ID on the inode because that allows them to escape the
> > resource limits set on the project ID associated with the sub-mount
> > set up by the init namespace...
> >
> > i.e.
> >
> > /mnt prid = 0, default for entire fs.
> > /mnt/container1/ prid = 1, inherit, 10GB space limit
> > /mnt/container2/ prid = 2, inherit, 50GB space limit
> > .....
> > /mnt/containerN/ prid = N, inherit, 20GB space limit
> >
> > And you clone the mount namespace for each container so the root is
> > at the appropriate /mnt/containerX/. Now the containers have a
> > fixed amount of space they can use in the parent filesystem they
> > know nothing about, and it is enforced by directory subquotas
> > controlled by the init namespace. This "fixed amount of space" is
> > reflected in the container namespace when "df" is run as it will
> > report the project quota space limits. Adding or removing space to a
> > container is as simple as changing the project quota limits from the
> > init namespace. i.e. an admin operation controlled by the host, not
> > the container....
> >
> > Allowing the container to modify the prid and/or the inherit bit of
> > inodes in it's namespace then means the user can define their own
> > space usage limits, even turn them off. It's not a resource
> > container at that point because the user can define their own
> > limits. Hence, only if the current_ns cannot change project quotas
> > will we have a hard fence on space usage that the container *cannot
> > exceed*.
>
> I think I must be missing something simple here. In a hypothetical
> world where the code used nsown_capable, if an admin wants to stick a
> container in /mnt/container1 with associated prid 1 and a userns,
> shouldn't it just map only prid 1 into the user ns? Then a user in
> that userns can't try to change the prid of a file to 2 because the
> number "2" is unmapped for that user and translation will fail.
You've effectively said "yes, project quotas are enabled, but you
only have a single ID, it's always turned on and you can't change it
to anything else.
So, why do they need to be mapped via user namespaces to enable
this? Think about it a little harder:
- Project IDs are not user IDs.
- Project IDs are not a security/permission mechanism.
- Project quotas only provide a mechanism for
resource usage control.
Think about that last one some more. Perhaps, as a hint, I should
relate it to control groups? :) i.e:
- Project quotas can be used as an effective mount ns space
usage controller.
But this can only be safely and reliably by keeping the project IDs
inaccessible from the containers themselves. I don't see why a
mechanism that controls the amount of filesystem space used by a
container should be considered any differently to a memory control
group that limits the amount of memory the container can use.
However, nobody on the container side of things would answer any of
my questions about how project quotas were going to be used,
limited, managed, etc back when we had to make a decision to enable
XFS user ns support, I did what was needed to support the obvious
container use case and close any possible loop hole that containers
might be able to use to subvert that use case.
If we want to do anything different, then there's a *lot* of
userns aware regression tests needed to be written for xfstests....
Cheers,
Dave.
--
Dave Chinner
david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org
^ permalink raw reply
* Re: [PATCH] arm: sunxi: input: RFC: Add sysfs voltage for sun4i-lradc driver
From: Hans de Goede @ 2015-01-27 9:03 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Priit Laes, linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Maxime Ripard,
ABI/API, moderated list:ARM/Allwinner A1X..., open list,
open list:SUN4I LOW RES ADC...
In-Reply-To: <20150126220622.GA16941@dtor-ws>
Hi,
On 26-01-15 23:06, Dmitry Torokhov wrote:
> On Mon, Jan 26, 2015 at 08:28:29PM +0100, Hans de Goede wrote:
>> Hi,
>>
>> On 26-01-15 17:58, Priit Laes wrote:
>>
>> No commit message? Please write an informative commit msg, like why we want this patch,
>> I guess it is to help figuring out the voltage levels for various buttons when creating
>> a dts, but I would prefer to not guess, which is where a good commit message would
>> come in handy ...
>>
>>> ---
>>> .../ABI/testing/sysfs-driver-input-sun4i-lradc | 4 ++
>>> drivers/input/keyboard/sun4i-lradc-keys.c | 49 +++++++++++++++++-----
>>> 2 files changed, 43 insertions(+), 10 deletions(-)
>>> create mode 100644 Documentation/ABI/testing/sysfs-driver-input-sun4i-lradc
>>>
>>> diff --git a/Documentation/ABI/testing/sysfs-driver-input-sun4i-lradc b/Documentation/ABI/testing/sysfs-driver-input-sun4i-lradc
>>> new file mode 100644
>>> index 0000000..e4e6448
>>> --- /dev/null
>>> +++ b/Documentation/ABI/testing/sysfs-driver-input-sun4i-lradc
>>> @@ -0,0 +1,4 @@
>>> +What: /sys/class/input/input(x)/device/voltage
>>> +Date: February 2015
>>> +Contact: Priit Laes <plaes-q/aMd4JkU83YtjvyW6yDsg@public.gmane.org>
>>> +Description: ADC output voltage in microvolts or 0 if device is not opened.
>>> diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c
>>> index cc8f7dd..c0ab8ec 100644
>>> --- a/drivers/input/keyboard/sun4i-lradc-keys.c
>>> +++ b/drivers/input/keyboard/sun4i-lradc-keys.c
>>> @@ -79,10 +79,27 @@ struct sun4i_lradc_data {
>>> u32 vref;
>>> };
>>>
>>> +static u32 sun4i_lradc_read_voltage(struct sun4i_lradc_data *lradc)
>>> +{
>>> + u32 val = readl(lradc->base + LRADC_DATA0) & 0x3f;
>>> + return val * lradc->vref / 63;
>>> +};
>>> +
>>> +static ssize_t
>>> +sun4i_lradc_dev_voltage_show(struct device *dev,
>>> + struct device_attribute *attr, char *buf)
>>> +{
>>> + struct sun4i_lradc_data *lradc = dev_get_drvdata(dev);
>>> +
>>> + return sprintf(buf, "%u\n", sun4i_lradc_read_voltage(lradc));
>>> +}
>>> +
>>> +static const DEVICE_ATTR(voltage, S_IRUGO, sun4i_lradc_dev_voltage_show, NULL);
>>> +
>>> static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id)
>>> {
>>> struct sun4i_lradc_data *lradc = dev_id;
>>> - u32 i, ints, val, voltage, diff, keycode = 0, closest = 0xffffffff;
>>> + u32 i, ints, voltage, diff, keycode = 0, closest = 0xffffffff;
>>>
>>> ints = readl(lradc->base + LRADC_INTS);
>>>
>>> @@ -97,8 +114,7 @@ static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id)
>>> }
>>>
>>> if ((ints & CHAN0_KEYDOWN_IRQ) && lradc->chan0_keycode == 0) {
>>> - val = readl(lradc->base + LRADC_DATA0) & 0x3f;
>>> - voltage = val * lradc->vref / 63;
>>> + voltage = sun4i_lradc_read_voltage(lradc);
>>>
>>> for (i = 0; i < lradc->chan0_map_count; i++) {
>>> diff = abs(lradc->chan0_map[i].voltage - voltage);
>>> @@ -156,7 +172,7 @@ static void sun4i_lradc_close(struct input_dev *dev)
>>> }
>>>
>>> static int sun4i_lradc_load_dt_keymap(struct device *dev,
>>> - struct sun4i_lradc_data *lradc)
>>> + struct sun4i_lradc_data *lradc)
>>> {
>>> struct device_node *np, *pp;
>>> int i;
>>
>> Why this identation change ?
>>
>>> @@ -168,8 +184,8 @@ static int sun4i_lradc_load_dt_keymap(struct device *dev,
>>>
>>> lradc->chan0_map_count = of_get_child_count(np);
>>> if (lradc->chan0_map_count == 0) {
>>> - dev_err(dev, "keymap is missing in device tree\n");
>>> - return -EINVAL;
>>> + dev_info(dev, "keymap is missing in device tree\n");
>>> + return 0;
>>> }
>>>
>>> lradc->chan0_map = devm_kmalloc_array(dev, lradc->chan0_map_count,
>>
>> I assume this is so that people can still use the sysfs node, to create a dts, right
>> not sure I like this, might be better to document to simple create a dts with
>> a single button mapping for 200 mV (most board use 200 mV steps between the buttons).
>>
>>> @@ -185,19 +201,19 @@ static int sun4i_lradc_load_dt_keymap(struct device *dev,
>>>
>>> error = of_property_read_u32(pp, "channel", &channel);
>>> if (error || channel != 0) {
>>> - dev_err(dev, "%s: Inval channel prop\n", pp->name);
>>> + dev_err(dev, "%s: Invalid 'channel' property\n", pp->name);
>>> return -EINVAL;
>>> }
>>>
>>> error = of_property_read_u32(pp, "voltage", &map->voltage);
>>> if (error) {
>>> - dev_err(dev, "%s: Inval voltage prop\n", pp->name);
>>> + dev_err(dev, "%s: Invalid 'voltage' property\n", pp->name);
>>> return -EINVAL;
>>> }
>>>
>>> error = of_property_read_u32(pp, "linux,code", &map->keycode);
>>> if (error) {
>>> - dev_err(dev, "%s: Inval linux,code prop\n", pp->name);
>>> + dev_err(dev, "%s: Invalid 'linux,code' property\n", pp->name);
>>> return -EINVAL;
>>> }
>>>
>>
>> This hunk / 3 changes belong in a separate patch. Also please run checkpatch, I think
>> you're running over 80 chars here.
>>
>>
>>> @@ -257,14 +273,26 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
>>> if (error)
>>> return error;
>>>
>>> - error = input_register_device(lradc->input);
>>> + error = device_create_file(dev, &dev_attr_voltage);
>>> if (error)
>>> return error;
>>>
>>> + error = input_register_device(lradc->input);
>>> + if (error) {
>>> + device_remove_file(&pdev->dev, &dev_attr_voltage);
>>> + return error;
>>> + }
>>> +
>>> platform_set_drvdata(pdev, lradc);
>>> return 0;
>>> }
>>>
>>> +static int sun4i_lradc_remove(struct platform_device *pdev)
>>> +{
>>> + device_remove_file(&pdev->dev, &dev_attr_voltage);
>>> + return 0;
>>> +}
>>> +
>>
>> This looks wrong, I think (*) that we've a bug here because we're not
>> unregistering the input device, so maybe do 2 patches, 1 fixing the
>> not unregistering bug, and then just add the device_remove_file()
>> in the sysfs patch.
>
> The unregister was not necessary since the input device is managed.
Ah right, looking at the code again I see we use devm_input_allocate_device()
is there no devm_create_file for creating sysfs entries ?
Regards,
Hans
^ permalink raw reply
* Re: [PATCH] arm: sunxi: input: RFC: Add sysfs voltage for sun4i-lradc driver
From: Maxime Ripard @ 2015-01-27 9:18 UTC (permalink / raw)
To: Priit Laes
Cc: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede,
Dmitry Torokhov, open list:ABI/API,
moderated list:ARM/Allwinner A1X..., open list,
open list:SUN4I LOW RES ADC...
In-Reply-To: <1422291516-24895-1-git-send-email-plaes-q/aMd4JkU83YtjvyW6yDsg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 4727 bytes --]
Hi,
On Mon, Jan 26, 2015 at 06:58:32PM +0200, Priit Laes wrote:
> ---
Like Hans was pointing out, commit log and signed-off-by please
> .../ABI/testing/sysfs-driver-input-sun4i-lradc | 4 ++
> drivers/input/keyboard/sun4i-lradc-keys.c | 49 +++++++++++++++++-----
> 2 files changed, 43 insertions(+), 10 deletions(-)
> create mode 100644 Documentation/ABI/testing/sysfs-driver-input-sun4i-lradc
>
> diff --git a/Documentation/ABI/testing/sysfs-driver-input-sun4i-lradc b/Documentation/ABI/testing/sysfs-driver-input-sun4i-lradc
> new file mode 100644
> index 0000000..e4e6448
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-driver-input-sun4i-lradc
> @@ -0,0 +1,4 @@
> +What: /sys/class/input/input(x)/device/voltage
> +Date: February 2015
> +Contact: Priit Laes <plaes-q/aMd4JkU83YtjvyW6yDsg@public.gmane.org>
> +Description: ADC output voltage in microvolts or 0 if device is not opened.
Why is it returning 0 when "device is not opened" ? What does that
even mean? You can't read that file without opening it.
> diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c
> index cc8f7dd..c0ab8ec 100644
> --- a/drivers/input/keyboard/sun4i-lradc-keys.c
> +++ b/drivers/input/keyboard/sun4i-lradc-keys.c
> @@ -79,10 +79,27 @@ struct sun4i_lradc_data {
> u32 vref;
> };
>
> +static u32 sun4i_lradc_read_voltage(struct sun4i_lradc_data *lradc)
> +{
> + u32 val = readl(lradc->base + LRADC_DATA0) & 0x3f;
> + return val * lradc->vref / 63;
> +};
> +
> +static ssize_t
> +sun4i_lradc_dev_voltage_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct sun4i_lradc_data *lradc = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "%u\n", sun4i_lradc_read_voltage(lradc));
> +}
> +
> +static const DEVICE_ATTR(voltage, S_IRUGO, sun4i_lradc_dev_voltage_show, NULL);
> +
> static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id)
> {
> struct sun4i_lradc_data *lradc = dev_id;
> - u32 i, ints, val, voltage, diff, keycode = 0, closest = 0xffffffff;
> + u32 i, ints, voltage, diff, keycode = 0, closest = 0xffffffff;
>
> ints = readl(lradc->base + LRADC_INTS);
>
> @@ -97,8 +114,7 @@ static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id)
> }
>
> if ((ints & CHAN0_KEYDOWN_IRQ) && lradc->chan0_keycode == 0) {
> - val = readl(lradc->base + LRADC_DATA0) & 0x3f;
> - voltage = val * lradc->vref / 63;
> + voltage = sun4i_lradc_read_voltage(lradc);
>
> for (i = 0; i < lradc->chan0_map_count; i++) {
> diff = abs(lradc->chan0_map[i].voltage - voltage);
> @@ -156,7 +172,7 @@ static void sun4i_lradc_close(struct input_dev *dev)
> }
>
> static int sun4i_lradc_load_dt_keymap(struct device *dev,
> - struct sun4i_lradc_data *lradc)
> + struct sun4i_lradc_data *lradc)
> {
> struct device_node *np, *pp;
> int i;
> @@ -168,8 +184,8 @@ static int sun4i_lradc_load_dt_keymap(struct device *dev,
>
> lradc->chan0_map_count = of_get_child_count(np);
> if (lradc->chan0_map_count == 0) {
> - dev_err(dev, "keymap is missing in device tree\n");
> - return -EINVAL;
> + dev_info(dev, "keymap is missing in device tree\n");
> + return 0;
> }
>
> lradc->chan0_map = devm_kmalloc_array(dev, lradc->chan0_map_count,
> @@ -185,19 +201,19 @@ static int sun4i_lradc_load_dt_keymap(struct device *dev,
>
> error = of_property_read_u32(pp, "channel", &channel);
> if (error || channel != 0) {
> - dev_err(dev, "%s: Inval channel prop\n", pp->name);
> + dev_err(dev, "%s: Invalid 'channel' property\n", pp->name);
> return -EINVAL;
> }
>
> error = of_property_read_u32(pp, "voltage", &map->voltage);
> if (error) {
> - dev_err(dev, "%s: Inval voltage prop\n", pp->name);
> + dev_err(dev, "%s: Invalid 'voltage' property\n", pp->name);
> return -EINVAL;
> }
>
> error = of_property_read_u32(pp, "linux,code", &map->keycode);
> if (error) {
> - dev_err(dev, "%s: Inval linux,code prop\n", pp->name);
> + dev_err(dev, "%s: Invalid 'linux,code' property\n", pp->name);
> return -EINVAL;
> }
>
> @@ -257,14 +273,26 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
> if (error)
> return error;
>
> - error = input_register_device(lradc->input);
> + error = device_create_file(dev, &dev_attr_voltage);
As I told you already, if you're going to expose this an ADC in the
end, the proper solution is to use the IIO framework, not adding a
custom sysfs file.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [v8 4/5] ext4: adds FS_IOC_FSSETXATTR/FS_IOC_FSGETXATTR interface support
From: Konstantin Khlebnikov @ 2015-01-27 10:45 UTC (permalink / raw)
To: Dave Chinner, Andy Lutomirski
Cc: Li Xi, Linux FS Devel,
linux-ext4-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux API,
Theodore Ts'o, Andreas Dilger, Jan Kara, Al Viro,
Christoph Hellwig, dmonakhov-GEFAQzZX7r8dnm+yROfE0A,
Eric W. Biederman
In-Reply-To: <20150127080239.GQ16552@dastard>
On 27.01.2015 11:02, Dave Chinner wrote:
> On Fri, Jan 23, 2015 at 03:59:04PM -0800, Andy Lutomirski wrote:
>> On Fri, Jan 23, 2015 at 3:30 PM, Dave Chinner <david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org> wrote:
>>> On Fri, Jan 23, 2015 at 02:58:09PM +0300, Konstantin Khlebnikov wrote:
>>>> On 23.01.2015 04:53, Dave Chinner wrote:
>>>>> On Thu, Jan 22, 2015 at 06:28:51PM +0300, Konstantin Khlebnikov wrote:
>>>>>>> + kprojid = make_kprojid(&init_user_ns, (projid_t)projid);
>>>>>>
>>>>>> Maybe current_user_ns()?
>>>>>> This code should be user-namespace aware from the beginning.
>>>>>
>>>>> No, the code is correct. Project quotas have nothing to do with
>>>>> UIDs and so should never have been included in the uid/gid
>>>>> namespace mapping infrastructure in the first place.
>>>>
>>>> Right, but user-namespace provides id mapping for project-id too.
>>>> This infrastructure adds support for nested project quotas with
>>>> virtualized ids in sub-containers. I couldn't say that this is
>>>> must have feature but implementation is trivial because whole
>>>> infrastructure is already here.
>>>
>>> This is an extremely common misunderstanding of project IDs. Project
>>> IDs are completely separate to the UID/GID namespace. Project
>>> quotas were originally designed specifically for
>>> accounting/enforcing quotas in situations where uid/gid
>>> accounting/enforcing is not possible. This design intent goes back
>>> 25 years - it predates XFS...
>>>
>>> IOWs, mapping prids via user namespaces defeats the purpose
>>> for which prids were originally intended for.
>>>
>>>>> Point in case: directory subtree quotas can be used as a resource
>>>>> controller for limiting space usage within separate containers that
>>>>> share the same underlying (large) filesystem via mount namespaces.
>>>>
>>>> That's exactly my use-case: 'sub-volumes' for containers with
>>>> quota for space usage/inodes count.
>>>
>>> That doesn't require mapped project IDs. Hard container space limits
>>> can only be controlled by the init namespace, and because inodes can
>>> hold only one project ID the current ns cannot be allowed to change
>>> the project ID on the inode because that allows them to escape the
>>> resource limits set on the project ID associated with the sub-mount
>>> set up by the init namespace...
>>>
>>> i.e.
>>>
>>> /mnt prid = 0, default for entire fs.
>>> /mnt/container1/ prid = 1, inherit, 10GB space limit
>>> /mnt/container2/ prid = 2, inherit, 50GB space limit
>>> .....
>>> /mnt/containerN/ prid = N, inherit, 20GB space limit
>>>
>>> And you clone the mount namespace for each container so the root is
>>> at the appropriate /mnt/containerX/. Now the containers have a
>>> fixed amount of space they can use in the parent filesystem they
>>> know nothing about, and it is enforced by directory subquotas
>>> controlled by the init namespace. This "fixed amount of space" is
>>> reflected in the container namespace when "df" is run as it will
>>> report the project quota space limits. Adding or removing space to a
>>> container is as simple as changing the project quota limits from the
>>> init namespace. i.e. an admin operation controlled by the host, not
>>> the container....
>>>
>>> Allowing the container to modify the prid and/or the inherit bit of
>>> inodes in it's namespace then means the user can define their own
>>> space usage limits, even turn them off. It's not a resource
>>> container at that point because the user can define their own
>>> limits. Hence, only if the current_ns cannot change project quotas
>>> will we have a hard fence on space usage that the container *cannot
>>> exceed*.
>>
>> I think I must be missing something simple here. In a hypothetical
>> world where the code used nsown_capable, if an admin wants to stick a
>> container in /mnt/container1 with associated prid 1 and a userns,
>> shouldn't it just map only prid 1 into the user ns? Then a user in
>> that userns can't try to change the prid of a file to 2 because the
>> number "2" is unmapped for that user and translation will fail.
>
> You've effectively said "yes, project quotas are enabled, but you
> only have a single ID, it's always turned on and you can't change it
> to anything else.
>
> So, why do they need to be mapped via user namespaces to enable
> this? Think about it a little harder:
>
> - Project IDs are not user IDs.
> - Project IDs are not a security/permission mechanism.
> - Project quotas only provide a mechanism for
> resource usage control.
>
> Think about that last one some more. Perhaps, as a hint, I should
> relate it to control groups? :) i.e:
>
> - Project quotas can be used as an effective mount ns space
> usage controller.
>
> But this can only be safely and reliably by keeping the project IDs
> inaccessible from the containers themselves. I don't see why a
> mechanism that controls the amount of filesystem space used by a
> container should be considered any differently to a memory control
> group that limits the amount of memory the container can use.
>
> However, nobody on the container side of things would answer any of
> my questions about how project quotas were going to be used,
> limited, managed, etc back when we had to make a decision to enable
> XFS user ns support, I did what was needed to support the obvious
> container use case and close any possible loop hole that containers
> might be able to use to subvert that use case.
I have a solution: Hierarchical Project Quota! Each project might have
parent project and so on. Each level keeps usage, limits and also keeps
some preallocation from parent level to reduce count of quota updates.
This might be useful even without containers : normal user quota has
two levels and admins might classify users into groups and set group
quota for them. Project quota is flat and cannot provide any control
if we want classify projects.
For containers hierarchy provide full virtualization: user-namespace
maps maps second-level and projects into subset of real projects.
Changing limits and other managing for second-level project quotas
could be done in user-space by system service (systemd I suppose. lol),
so we don't have to manage this stuff inside the kernel.
[ I'm already working on prototype for ext4 ]
>
> If we want to do anything different, then there's a *lot* of
> userns aware regression tests needed to be written for xfstests....
>
> Cheers,
>
> Dave.
>
^ permalink raw reply
* [PATCH] tpm: fix suspend/resume paths for TPM 2.0
From: Jarkko Sakkinen @ 2015-01-27 11:02 UTC (permalink / raw)
To: Peter Huewe, Ashley Lai, Marcel Selhorst
Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, josh-iaAMLnmF4UmaiuxdJuQwMA,
christophe.ricard-Re5JQEeQqe8AvxtiuMwx3w,
jason.gunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/,
stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
linux-api-u79uwXL29TY76Z2rM5mHXA,
trousers-tech-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
jmorris-gx6/JNMH7DfYtjvyW6yDsg, Jarkko Sakkinen
Fixed suspend/resume paths for TPM 2.0 and consolidated all the
associated code to the tpm_pm_suspend() and tpm_pm_resume()
functions. Resume path should be handled by the firmware, i.e.
Startup(CLEAR) for hibernate and Startup(STATE) for suspend.
There might be some non-PC embedded devices in the future where
Startup() is not the handled by the FW but fixing the code for
those IMHO should be postponed until there is hardware available
to test the fixes although extra Startup in the driver code is
essentially a NOP.
Reported-by: Peter Hüwe <PeterHuewe-Mmb7MZpHnFY@public.gmane.org>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
drivers/char/tpm/tpm-interface.c | 10 ++++++++--
drivers/char/tpm/tpm_crb.c | 16 +---------------
drivers/char/tpm/tpm_tis.c | 22 ++++++++++------------
3 files changed, 19 insertions(+), 29 deletions(-)
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index bf53a37..93c8b90fd 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -901,8 +901,13 @@ int tpm_pm_suspend(struct device *dev)
if (chip == NULL)
return -ENODEV;
- if (chip->flags & TPM_CHIP_FLAG_TPM2)
- return tpm2_shutdown(chip, TPM2_SU_CLEAR);
+ if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+ rc = tpm2_shutdown(chip, TPM2_SU_STATE);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+ }
/* for buggy tpm, flush pcrs with extend to selected dummy */
if (tpm_suspend_pcr) {
@@ -952,6 +957,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_suspend);
int tpm_pm_resume(struct device *dev)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
+ int ret;
if (chip == NULL)
return -ENODEV;
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 3dd23cf..3e080f5 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -95,21 +95,7 @@ struct crb_priv {
u8 __iomem *rsp;
};
-#ifdef CONFIG_PM_SLEEP
-static int crb_resume(struct device *dev)
-{
- int rc;
- struct tpm_chip *chip = dev_get_drvdata(dev);
-
- rc = tpm2_shutdown(chip, TPM2_SU_STATE);
- if (!rc)
- rc = tpm2_do_selftest(chip);
-
- return rc;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, crb_resume);
+static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, tpm_pm_resume);
static u8 crb_status(struct tpm_chip *chip)
{
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 6725bef..c105eb7 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -865,25 +865,23 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
static int tpm_tis_resume(struct device *dev)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
- int ret = 0;
+ int ret;
if (chip->vendor.irq)
tpm_tis_reenable_interrupts(chip);
- if (chip->flags & TPM_CHIP_FLAG_TPM2) {
- /* NOP if firmware properly does this. */
- tpm2_startup(chip, TPM2_SU_STATE);
+ ret = tpm_pm_resume(dev);
+ if (ret)
+ return ret;
- ret = tpm2_shutdown(chip, TPM2_SU_STATE);
- if (!ret)
- ret = tpm2_do_selftest(chip);
- } else {
- ret = tpm_pm_resume(dev);
- if (!ret)
- tpm_do_selftest(chip);
+ /* TPM 1.2 requires self-test on resume. */
+ if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
+ ret = tpm_do_selftest(chip);
+ if (ret < 0)
+ return ret;
}
- return ret;
+ return 0;
}
#endif
--
2.1.4
^ permalink raw reply related
* Re: [PATCH net-next v1 05/18] net: tx4939: use __ethtool_get_ksettings
From: Sergei Shtylyov @ 2015-01-27 12:32 UTC (permalink / raw)
To: David Decotigny, David S. Miller, Ben Hutchings, Amir Vadai,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-api-u79uwXL29TY76Z2rM5mHXA
Cc: Eric Dumazet, Eugenia Emantayev, Or Gerlitz, Ido Shamay,
Joe Perches, Saeed Mahameed, Govindarajulu Varadarajan,
Venkata Duvvuru, Jeff Kirsher, Eyal Perry, Pravin B Shelar,
Ed Swierk, David Decotigny
In-Reply-To: <1422322574-6188-6-git-send-email-ddecotig-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Hello.
On 1/27/2015 4:36 AM, 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>
> ---
> arch/mips/txx9/generic/setup_tx4939.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
I don't think "net: " prefix applies here.
And you should have CC'ed linux-mips-6z/3iImG2C/i7sgoIIk9UQ@public.gmane.org
WBR, Sergei
^ permalink raw reply
* Re: [PATCH v8 0/2] Add Spreadtrum SoC bindings and serial driver support
From: Arnd Bergmann @ 2015-01-27 13:24 UTC (permalink / raw)
To: Chunyan Zhang
Cc: gregkh, robh+dt, mark.rutland, gnomes, peter, pawel.moll,
ijc+devicetree, galak, grant.likely, jslaby, heiko, jason,
florian.vaussard, andrew, hytszk, antonynpavlov, shawn.guo,
orsonzhai, geng.ren, zhizhou.zhang, lanqing.liu, zhang.lyra,
wei.qiao, devicetree, linux-kernel, linux-serial, linux-api,
linux-arm-kernel
In-Reply-To: <1422345407-10037-1-git-send-email-chunyan.zhang@spreadtrum.com>
On Tuesday 27 January 2015 15:56:45 Chunyan Zhang wrote:
> This patch-set split the last version, and addressed the review comments from
> last version on serial driver code.
>
> Changes from v7:
> * Addressed review comments from Peter:
> - Initialized the stack local with zero in sprd_set_termios()
> - Used dev_get_drvdata() to get sprd_uart_port
>
Looks good to me, but you still have too many people on 'To', so Greg
might be missing that you expect him to merge it.
Greg, if there are no further comments, can you take both patches through
the tty git?
Arnd
^ permalink raw reply
* [PATCH v2] samsung-laptop: enable better lid handling
From: Julijonas Kikutis @ 2015-01-27 13:26 UTC (permalink / raw)
To: Darren Hart
Cc: Julijonas Kikutis, Corentin Chary, open list:ABI/API, open list,
open list:SAMSUNG LAPTOP DR...
In-Reply-To: <1418332715-10547-1-git-send-email-julijonas.kikutis-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Some Samsung laptops with SABI3 delay the sleep for 10 seconds after
the lid is closed and do not wake up from sleep after the lid is opened.
A SABI command is needed to enable the better behavior.
Command = 0x6e, d0 = 0x81 enables this behavior. Returns d0 = 0x01.
Command = 0x6e, d0 = 0x80 disables this behavior. Returns d0 = 0x00.
Command = 0x6d and any d0 queries the state. This returns:
d0 = 0x00000*01, d1 = 0x00, d2 = 0x00, d3 = 0x0* when it is enabled.
d0 = 0x00000*00, d1 = 0x00, d2 = 0x00, d3 = 0x0* when it is disabled.
Where * is 0 - laptop has never slept or hibernated after switch on,
1 - laptop has hibernated just before,
2 - laptop has slept just before.
Patch addresses bug https://bugzilla.kernel.org/show_bug.cgi?id=75901 .
It adds a sysfs attribute lid_handling with a description and also an
addition to the quirks structure to enable the mode by default.
A user with another laptop in the bug report says that "power button has
to be pressed twice to wake the machine" when he or she enabled the mode
manually using the SABI command. Therefore, it is enabled by default
only for the single laptop that I have tested.
Signed-off-by: Julijonas Kikutis <julijonas.kikutis-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
.../ABI/testing/sysfs-driver-samsung-laptop | 8 ++
drivers/platform/x86/samsung-laptop.c | 120 ++++++++++++++++++++-
2 files changed, 127 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-driver-samsung-laptop b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
index 678819a..63c1ad0 100644
--- a/Documentation/ABI/testing/sysfs-driver-samsung-laptop
+++ b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
@@ -35,3 +35,11 @@ Contact: Corentin Chary <corentin.chary-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Description: Use your USB ports to charge devices, even
when your laptop is powered off.
1 means enabled, 0 means disabled.
+
+What: /sys/devices/platform/samsung/lid_handling
+Date: December 11, 2014
+KernelVersion: 3.19
+Contact: Julijonas Kikutis <julijonas.kikutis-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+Description: Some Samsung laptops handle lid closing quicker and
+ only handle lid opening with this mode enabled.
+ 1 means enabled, 0 means disabled.
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
index ff765d8..fad928a 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -124,6 +124,10 @@ struct sabi_commands {
u16 get_wireless_status;
u16 set_wireless_status;
+ /* 0x80 is off, 0x81 is on */
+ u16 get_lid_handling;
+ u16 set_lid_handling;
+
/* 0x81 to read, (0x82 | level << 8) to set, 0xaabb to enable */
u16 kbd_backlight;
@@ -194,6 +198,9 @@ static const struct sabi_config sabi_configs[] = {
.get_wireless_status = 0xFFFF,
.set_wireless_status = 0xFFFF,
+ .get_lid_handling = 0xFFFF,
+ .set_lid_handling = 0xFFFF,
+
.kbd_backlight = 0xFFFF,
.set_linux = 0x0a,
@@ -254,6 +261,9 @@ static const struct sabi_config sabi_configs[] = {
.get_wireless_status = 0x69,
.set_wireless_status = 0x6a,
+ .get_lid_handling = 0x6d,
+ .set_lid_handling = 0x6e,
+
.kbd_backlight = 0x78,
.set_linux = 0xff,
@@ -353,6 +363,7 @@ struct samsung_quirks {
bool broken_acpi_video;
bool four_kbd_backlight_levels;
bool enable_kbd_backlight;
+ bool lid_handling;
};
static struct samsung_quirks samsung_unknown = {};
@@ -366,6 +377,10 @@ static struct samsung_quirks samsung_np740u3e = {
.enable_kbd_backlight = true,
};
+static struct samsung_quirks samsung_lid_handling = {
+ .lid_handling = true,
+};
+
static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force,
@@ -830,10 +845,76 @@ static ssize_t set_usb_charge(struct device *dev,
static DEVICE_ATTR(usb_charge, S_IWUSR | S_IRUGO,
get_usb_charge, set_usb_charge);
+static int read_lid_handling(struct samsung_laptop *samsung)
+{
+ const struct sabi_commands *commands = &samsung->config->commands;
+ struct sabi_data data;
+ int retval;
+
+ if (commands->get_lid_handling == 0xFFFF)
+ return -ENODEV;
+
+ memset(&data, 0, sizeof(data));
+ retval = sabi_command(samsung, commands->get_lid_handling,
+ &data, &data);
+
+ if (retval)
+ return retval;
+
+ return data.data[0] & 0x1;
+}
+
+static int write_lid_handling(struct samsung_laptop *samsung,
+ int enabled)
+{
+ const struct sabi_commands *commands = &samsung->config->commands;
+ struct sabi_data data;
+
+ memset(&data, 0, sizeof(data));
+ data.data[0] = 0x80 | enabled;
+ return sabi_command(samsung, commands->set_lid_handling,
+ &data, NULL);
+}
+
+static ssize_t get_lid_handling(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct samsung_laptop *samsung = dev_get_drvdata(dev);
+ int ret;
+
+ ret = read_lid_handling(samsung);
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%d\n", ret);
+}
+
+static ssize_t set_lid_handling(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct samsung_laptop *samsung = dev_get_drvdata(dev);
+ int ret, value;
+
+ if (!count || sscanf(buf, "%i", &value) != 1)
+ return -EINVAL;
+
+ ret = write_lid_handling(samsung, !!value);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(lid_handling, S_IWUSR | S_IRUGO,
+ get_lid_handling, set_lid_handling);
+
static struct attribute *platform_attributes[] = {
&dev_attr_performance_level.attr,
&dev_attr_battery_life_extender.attr,
&dev_attr_usb_charge.attr,
+ &dev_attr_lid_handling.attr,
NULL
};
@@ -956,6 +1037,22 @@ static int __init samsung_rfkill_init(struct samsung_laptop *samsung)
return 0;
}
+static void samsung_lid_handling_exit(struct samsung_laptop *samsung)
+{
+ if (samsung->quirks->lid_handling)
+ write_lid_handling(samsung, 0);
+}
+
+static int __init samsung_lid_handling_init(struct samsung_laptop *samsung)
+{
+ int retval = 0;
+
+ if (samsung->quirks->lid_handling)
+ retval = write_lid_handling(samsung, 1);
+
+ return retval;
+}
+
static int kbd_backlight_enable(struct samsung_laptop *samsung)
{
const struct sabi_commands *commands = &samsung->config->commands;
@@ -1111,7 +1208,7 @@ static int __init samsung_backlight_init(struct samsung_laptop *samsung)
}
static umode_t samsung_sysfs_is_visible(struct kobject *kobj,
- struct attribute *attr, int idx)
+ struct attribute *attr, int idx)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct platform_device *pdev = to_platform_device(dev);
@@ -1124,6 +1221,8 @@ static umode_t samsung_sysfs_is_visible(struct kobject *kobj,
ok = !!(read_battery_life_extender(samsung) >= 0);
if (attr == &dev_attr_usb_charge.attr)
ok = !!(read_usb_charge(samsung) >= 0);
+ if (attr == &dev_attr_lid_handling.attr)
+ ok = !!(read_lid_handling(samsung) >= 0);
return ok ? attr->mode : 0;
}
@@ -1436,6 +1535,9 @@ static int samsung_pm_notification(struct notifier_block *nb,
samsung->quirks->enable_kbd_backlight)
kbd_backlight_enable(samsung);
+ if (val == PM_POST_HIBERNATION && samsung->quirks->lid_handling)
+ write_lid_handling(samsung, 1);
+
return 0;
}
@@ -1578,6 +1680,15 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
},
.driver_data = &samsung_np740u3e,
},
+ {
+ .callback = samsung_dmi_matched,
+ .ident = "300V3Z/300V4Z/300V5Z",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "300V3Z/300V4Z/300V5Z"),
+ },
+ .driver_data = &samsung_lid_handling,
+ },
{ },
};
MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
@@ -1648,6 +1759,10 @@ static int __init samsung_init(void)
if (ret)
goto error_leds;
+ ret = samsung_lid_handling_init(samsung);
+ if (ret)
+ goto error_lid_handling;
+
ret = samsung_debugfs_init(samsung);
if (ret)
goto error_debugfs;
@@ -1659,6 +1774,8 @@ static int __init samsung_init(void)
return ret;
error_debugfs:
+ samsung_lid_handling_exit(samsung);
+error_lid_handling:
samsung_leds_exit(samsung);
error_leds:
samsung_rfkill_exit(samsung);
@@ -1683,6 +1800,7 @@ static void __exit samsung_exit(void)
unregister_pm_notifier(&samsung->pm_nb);
samsung_debugfs_exit(samsung);
+ samsung_lid_handling_exit(samsung);
samsung_leds_exit(samsung);
samsung_rfkill_exit(samsung);
samsung_backlight_exit(samsung);
--
2.2.2
^ permalink raw reply related
* Re: [PATCH v8 2/2] tty/serial: Add Spreadtrum sc9836-uart driver support
From: Peter Hurley @ 2015-01-27 14:47 UTC (permalink / raw)
To: Chunyan Zhang, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
arnd-r2nGTMty4D4, gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io,
pawel.moll-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, grant.likely-QSEj5FYQhm4dnm+yROfE0A,
jslaby-AlSwsSmVLrQ, heiko-4mtYJXux2i+zQB+pC5nmwQ,
jason-NLaQJdtUoK4Be96aLqz0jA, florian.vaussard-p8DiymsW2f8,
andrew-g2DYL2Zd6BY, hytszk-Re5JQEeQqe8AvxtiuMwx3w,
antonynpavlov-Re5JQEeQqe8AvxtiuMwx3w,
shawn.guo-QSEj5FYQhm4dnm+yROfE0A,
orsonzhai-Re5JQEeQqe8AvxtiuMwx3w, geng.ren-lxIno14LUO0EEoCn2XhGlw,
zhizhou.zhang-lxIno14LUO0EEoCn2XhGlw,
lanqing.liu-lxIno14LUO0EEoCn2XhGlw,
zhang.lyra-Re5JQEeQqe8AvxtiuMwx3w,
wei.qiao-lxIno14LUO0EEoCn2XhGlw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1422345407-10037-3-git-send-email-chunyan.zhang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
Hi Chunyan,
Minor but important fixes below.
And for the v9 version, please only use "To:" for
"Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>"
All other recipients should only be Cc:
Regards,
Peter Hurley
On 01/27/2015 02:56 AM, Chunyan Zhang wrote:
> Add a full sc9836-uart driver for SC9836 SoC which is based on the
> spreadtrum sharkl64 platform.
> This driver also support earlycon.
[...]
> +static int sprd_probe_dt_alias(int index, struct device *dev)
> +{
> + struct device_node *np;
> + static bool seen_dev_with_alias;
> + static bool seen_dev_without_alias;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
delete these two lines; these were used for the message deleted in a
previous patch version.
> + int ret = index;
> +
> + if (!IS_ENABLED(CONFIG_OF))
> + return ret;
> +
> + np = dev->of_node;
> + if (!np)
> + return ret;
> +
> + ret = of_alias_get_id(np, "serial");
> + if (IS_ERR_VALUE(ret)) {
> + seen_dev_without_alias = true;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
delete this line.
> + ret = index;
> + } else {
> + seen_dev_with_alias = true;
^^^^^^^^^^^^^^^^^^^^^^^^^^^
delete this line.
> + if (ret >= ARRAY_SIZE(sprd_port) || sprd_port[ret] != NULL) {
> + dev_warn(dev, "requested serial port %d not available.\n", ret);
> + ret = index;
> + }
> + }
Simplify the entire "if (IS_ERR_VALUE(ret))" statement to:
if (IS_ERR_VALUE(ret))
ret = index;
else if (ret >= ..................) {
dev_warn(.....);
ret = index;
}
> +
> + return ret;
> +}
> +
> +static int sprd_remove(struct platform_device *dev)
> +{
> + struct sprd_uart_port *sup = platform_get_drvdata(dev);
> +
> + if (sup) {
> + uart_remove_one_port(&sprd_uart_driver, &sup->port);
> + sprd_port[sup->port.line] = NULL;
> + sprd_ports_num--;
> + }
> +
> + if (!sprd_ports_num)
> + uart_unregister_driver(&sprd_uart_driver);
> +
> + return 0;
> +}
> +
> +static int sprd_probe(struct platform_device *pdev)
> +{
> + struct resource *res;
> + struct uart_port *up;
> + struct clk *clk;
> + int irq;
> + int index;
> + int ret;
> +
> + for (index = 0; index < ARRAY_SIZE(sprd_port); index++)
> + if (sprd_port[index] == NULL)
> + break;
> +
> + if (index == ARRAY_SIZE(sprd_port))
> + return -EBUSY;
> +
> + index = sprd_probe_dt_alias(index, &pdev->dev);
> +
> + sprd_port[index] = devm_kzalloc(&pdev->dev,
> + sizeof(*sprd_port[index]), GFP_KERNEL);
> + if (!sprd_port[index])
> + return -ENOMEM;
> +
> + pdev->id = index;
^^^^^^^^^^^^^^^^
delete this line.
The platform device id cannot be assigned by the driver.
(This was left over from trying to fix sprd_suspend/sprd_resume
but that's fixed correctly now.)
> +
> + up = &sprd_port[index]->port;
> + up->dev = &pdev->dev;
> + up->line = index;
> + up->type = PORT_SPRD;
> + up->iotype = SERIAL_IO_PORT;
> + up->uartclk = SPRD_DEF_RATE;
> + up->fifosize = SPRD_FIFO_SIZE;
> + up->ops = &serial_sprd_ops;
> + up->flags = UPF_BOOT_AUTOCONF;
> +
> + clk = devm_clk_get(&pdev->dev, NULL);
> + if (!IS_ERR(clk))
> + up->uartclk = clk_get_rate(clk);
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!res) {
> + dev_err(&pdev->dev, "not provide mem resource\n");
> + return -ENODEV;
> + }
> + up->mapbase = res->start;
> + up->membase = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(up->membase))
> + return PTR_ERR(up->membase);
> +
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0) {
> + dev_err(&pdev->dev, "not provide irq resource\n");
> + return -ENODEV;
> + }
> + up->irq = irq;
> +
> + if (!sprd_ports_num) {
> + ret = uart_register_driver(&sprd_uart_driver);
> + if (ret < 0) {
> + pr_err("Failed to register SPRD-UART driver\n");
> + return ret;
> + }
> + }
> + sprd_ports_num++;
> +
> + ret = uart_add_one_port(&sprd_uart_driver, up);
> + if (ret) {
> + sprd_port[index] = NULL;
> + sprd_remove(pdev);
> + }
> +
> + platform_set_drvdata(pdev, up);
> +
> + return ret;
> +}
^ permalink raw reply
* Re: [PATCH v8 0/2] Add Spreadtrum SoC bindings and serial driver support
From: Greg KH @ 2015-01-27 14:55 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Chunyan Zhang, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io,
peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8, pawel.moll-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, grant.likely-QSEj5FYQhm4dnm+yROfE0A,
jslaby-AlSwsSmVLrQ, heiko-4mtYJXux2i+zQB+pC5nmwQ,
jason-NLaQJdtUoK4Be96aLqz0jA, florian.vaussard-p8DiymsW2f8,
andrew-g2DYL2Zd6BY, hytszk-Re5JQEeQqe8AvxtiuMwx3w,
antonynpavlov-Re5JQEeQqe8AvxtiuMwx3w,
shawn.guo-QSEj5FYQhm4dnm+yROfE0A,
orsonzhai-Re5JQEeQqe8AvxtiuMwx3w, geng.ren-lxIno14LUO0EEoCn2XhGlw,
zhizhou.zhang-lxIno14LUO0EEoCn2XhGlw,
lanqing.liu-lxIno14LUO0EEoCn2XhGlw,
zhang.lyra-Re5JQEeQqe8AvxtiuMwx3w,
wei.qiao-lxIno14LUO0EEoCn2XhGlw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <2196748.ag4UzqF1Px@wuerfel>
On Tue, Jan 27, 2015 at 02:24:02PM +0100, Arnd Bergmann wrote:
> On Tuesday 27 January 2015 15:56:45 Chunyan Zhang wrote:
> > This patch-set split the last version, and addressed the review comments from
> > last version on serial driver code.
> >
> > Changes from v7:
> > * Addressed review comments from Peter:
> > - Initialized the stack local with zero in sprd_set_termios()
> > - Used dev_get_drvdata() to get sprd_uart_port
> >
>
> Looks good to me, but you still have too many people on 'To', so Greg
> might be missing that you expect him to merge it.
>
> Greg, if there are no further comments, can you take both patches through
> the tty git?
Will do, thanks.
greg k-h
^ permalink raw reply
* Re: [PATCH 01/13] kdbus: add documentation
From: David Herrmann @ 2015-01-27 15:05 UTC (permalink / raw)
To: Michael Kerrisk (man-pages)
Cc: Greg Kroah-Hartman, Austin S Hemmelgarn, Daniel Mack,
Arnd Bergmann, Eric W. Biederman, One Thousand Gnomes,
Tom Gundersen, Theodore T'so, Andy Lutomirski, Linux API,
linux-kernel, Djalal Harouni, Johannes Stezenbach,
Christoph Hellwig
In-Reply-To: <54C65346.5070504-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Hi
On Mon, Jan 26, 2015 at 3:46 PM, Michael Kerrisk (man-pages)
<mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Hello Greg,
>
> On 01/23/2015 05:08 PM, Greg Kroah-Hartman wrote:
>> On Thu, Jan 22, 2015 at 09:49:00AM -0500, Austin S Hemmelgarn wrote:
>>> While I agree that there should be a way for userspace to get the list of
>>> supported operations, userspace apps will only actually care about that
>>> once, when they begin talking to kdbus, because (ignoring the live kernel
>>> patching that people have been working on recently) the list of supported
>>> operations isn't going to change while the system is running. While a u64
>>> copy has relatively low overhead, it does have overhead, and that is very
>>> significant when you consider part of the reason some people want kdbus is
>>> for the performance gain. Especially for those automotive applications that
>>> have been mentioned which fire off thousands of messages during start-up,
>>> every little bit of performance is significant.
>>
>> A single u64 in a structure is not going to be measurable at all,
>> processors just copy memory too fast these days for 4 extra bytes to be
>> noticable.
>
> It depends on the definition of measurable, I suppose, but this statement
> appears incorrect to me. In some cases (e.g., kdbus_msg_info) we're talking
> about *two* u64 fields (kernel_gs, kernel_msg_flags) being used to pass back
> sets of valid flags. That's 16 bytes, and it definitely makes a difference.
> Simply running a loop that does a naive memcpy() in a tight user-space
> loop (code below), I see the following for the execution of 1e9 loops:
>
> Including the two extra u64 fields: 3.2 sec
> Without the two extra u64 fields: 2.6 sec
>
> On the same box, doing 1e9 calls to getppid() (i.e., pretty much the
> simplest syscall, giving us a rough measure of the context switch) takes
> 68 seconds. In other words, the cost of copying those 16 bytes is about 1%
> of the base context switch/syscall cost. I assume the costs of copying
> those 16 bytes across the kernel-user-space boundary would not be cheaper,
> but have not tested that. If my assumption is correct, then 1% seems a
> significant figure to me in an API whose raison d'être is speed.
I have no idea how this is related to any kdbus ioctl?
A 16byte copy does not affect the performance of kdbus message
transactions in any way that matters.
>> So let's make this as easy as possible for userspace, making
>> it simpler logic there, which is much more important than saving
>> theoretical time in the kernel.
>
> But this also missed the other part of the point. Copying these fields on
> every operation, when in fact they are only needed once, clutters the API,
> in my opinion. Good APIs are as simple as they can be to do their job.
> Redundancy is an enemy of simplicity. Simplest would have been a one time
> API that returns a structure containing all of the supported flags across
> the API. Alternatively, the traditional EINVAL approach is well understood,
> and suffices.
We're going to drop "kernel_flags" in favor of a new
KDBUS_FLAG_NEGOTIATE flag which asks the kernel to do feature
negotiation for this ioctl and return the supported flags/items inline
(overwriting the passed data). The ioctl will not be executed and will
not affect the state of the FD.
I hope this keeps the API simple.
Thanks
David
^ permalink raw reply
* Re: [PATCH 01/13] kdbus: add documentation
From: David Herrmann @ 2015-01-27 15:23 UTC (permalink / raw)
To: Michael Kerrisk (man-pages)
Cc: Tom Gundersen, Greg Kroah-Hartman, Daniel Mack, Arnd Bergmann,
Eric W. Biederman, One Thousand Gnomes, Jiri Kosina,
Andy Lutomirski, Linux API, LKML, Djalal Harouni,
Johannes Stezenbach, Theodore T'so, christoph Hellwig
In-Reply-To: <54C66F30.8050108@gmail.com>
Hi
On Mon, Jan 26, 2015 at 5:45 PM, Michael Kerrisk (man-pages)
<mtk.manpages@gmail.com> wrote:
> On 01/26/2015 04:26 PM, Tom Gundersen wrote:
>> On Mon, Jan 26, 2015 at 3:42 PM, Michael Kerrisk (man-pages)
>> <mtk.manpages@gmail.com> wrote:
>>> 2. Is the API to be invoked directly by applications or is intended to
>>> be used only behind specific libraries? You seem to be saying that
>>> the latter is the case (here, I'm referring to your comment above
>>> about sd-bus). However, when I asked David Herrmann a similar
>>> question I got this responser:
>>>
>>> "kdbus is in no way bound to systemd. There are ongoing efforts
>>> to port glib and qt to kdbus natively. The API is pretty simple
>>> and I don't see how a libkdbus would simplify things. In fact,
>>> even our tests only have slim wrappers around the ioctls to
>>> simplify error-handling in test-scenarios."
>>>
>>> To me, that implies that users will employ the raw kernel API.
>>
>> The way I read this is that there will (probably) be a handful of
>> users, namely the existing dbus libraries: libdus, sd-bus, glib, Qt,
>> ell, and maybe a few others. However, third-party developers will not
>> know/care about the details of kdbus, they'll just be coding against
>> the dbus libraries as before (might be minor changes, but they
>> certainly won't need to know anything about the kernel API). Similarly
>> to how userspace developers now code against their libc of choice,
>> rather than use kernel syscalls directly.
>
> Thanks, Tom, for the input. I'm still confused though, since elsewhere
> in this thread David Herrmann said in response to a question of mine:
>
> I think we can agree that we want it to be generically useful,
> like other ipc mechanisms, including UDS and netlink.
>
> Again, that sounds to me like the vision is not "a handful of users".
> Hopefully Greg and David can clarify.
I only expect a handful of users to call the ioctls directly. The
libraries that implement the payload-marshaling, in particular. It's a
similar situation with netlink.
Thanks
David
^ permalink raw reply
* Re: [PATCH v8 0/2] Add Spreadtrum SoC bindings and serial driver support
From: Lyra Zhang @ 2015-01-27 15:43 UTC (permalink / raw)
To: Greg KH
Cc: Arnd Bergmann, Chunyan Zhang,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org, Mark Rutland,
gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org,
Peter Hurley, Pawel Moll,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org,
Kumar Gala, Grant Likely, jslaby-AlSwsSmVLrQ@public.gmane.org,
Heiko Stübner, jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org,
florian.vaussard-p8DiymsW2f8@public.gmane.org,
andrew-g2DYL2Zd6BY@public.gmane.org, Hayato Suzuki,
antonynpavlov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org, Shawn Guo,
Orson Zhai, geng.ren-lxIno14LUO0EEoCn2XhGlw@public.gmane.org
In-Reply-To: <20150127145518.GA32531-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
On Tue, Jan 27, 2015 at 10:55 PM, Greg KH <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org> wrote:
> On Tue, Jan 27, 2015 at 02:24:02PM +0100, Arnd Bergmann wrote:
>> On Tuesday 27 January 2015 15:56:45 Chunyan Zhang wrote:
>> > This patch-set split the last version, and addressed the review comments from
>> > last version on serial driver code.
>> >
>> > Changes from v7:
>> > * Addressed review comments from Peter:
>> > - Initialized the stack local with zero in sprd_set_termios()
>> > - Used dev_get_drvdata() to get sprd_uart_port
>> >
>>
>> Looks good to me, but you still have too many people on 'To', so Greg
>> might be missing that you expect him to merge it.
>>
>> Greg, if there are no further comments, can you take both patches through
>> the tty git?
>
> Will do, thanks.
>
> greg k-h
To Arnd, Greg, Peter, and to all of others
thank you so much for your help.
You all gave us so many important comments and valuable suggestions
these months.
Best regards,
Chunyan
--
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
* Re: [PATCH v8 2/2] tty/serial: Add Spreadtrum sc9836-uart driver support
From: Lyra Zhang @ 2015-01-27 15:51 UTC (permalink / raw)
To: Peter Hurley, gregkh@linuxfoundation.org
Cc: Chunyan Zhang, robh+dt@kernel.org, Mark Rutland, Arnd Bergmann,
gnomes@lxorguk.ukuu.org.uk, Pawel Moll,
ijc+devicetree@hellion.org.uk, Kumar Gala, Grant Likely,
jslaby@suse.cz, Heiko Stübner, jason@lakedaemon.net,
florian.vaussard@epfl.ch, andrew@lunn.ch, Hayato Suzuki,
antonynpavlov@gmail.com, Shawn Guo, Orson Zhai,
geng.ren@spreadtrum.com, zhizhou.zhang
In-Reply-To: <54C7A514.6090206@hurleysoftware.com>
On Tue, Jan 27, 2015 at 10:47 PM, Peter Hurley <peter@hurleysoftware.com> wrote:
> Hi Chunyan,
>
> Minor but important fixes below.
>
> And for the v9 version, please only use "To:" for
> "Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
>
Ok, thank you, I'll address your comments below and send the v9 to Greg.
Greg,
sorry, I'll send you a updated version tomorrow.
> All other recipients should only be Cc:
>
> Regards,
> Peter Hurley
>
>
> On 01/27/2015 02:56 AM, Chunyan Zhang wrote:
>> Add a full sc9836-uart driver for SC9836 SoC which is based on the
>> spreadtrum sharkl64 platform.
>> This driver also support earlycon.
>
> [...]
>
>> +static int sprd_probe_dt_alias(int index, struct device *dev)
>> +{
>> + struct device_node *np;
>> + static bool seen_dev_with_alias;
>> + static bool seen_dev_without_alias;
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> delete these two lines; these were used for the message deleted in a
> previous patch version.
>
>> + int ret = index;
>> +
>> + if (!IS_ENABLED(CONFIG_OF))
>> + return ret;
>> +
>> + np = dev->of_node;
>> + if (!np)
>> + return ret;
>> +
>> + ret = of_alias_get_id(np, "serial");
>> + if (IS_ERR_VALUE(ret)) {
>> + seen_dev_without_alias = true;
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> delete this line.
>
>> + ret = index;
>> + } else {
>> + seen_dev_with_alias = true;
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> delete this line.
>
>> + if (ret >= ARRAY_SIZE(sprd_port) || sprd_port[ret] != NULL) {
>> + dev_warn(dev, "requested serial port %d not available.\n", ret);
>> + ret = index;
>> + }
>> + }
>
> Simplify the entire "if (IS_ERR_VALUE(ret))" statement to:
>
> if (IS_ERR_VALUE(ret))
> ret = index;
> else if (ret >= ..................) {
> dev_warn(.....);
> ret = index;
> }
>
>
>> +
>> + return ret;
>> +}
>> +
>> +static int sprd_remove(struct platform_device *dev)
>> +{
>> + struct sprd_uart_port *sup = platform_get_drvdata(dev);
>> +
>> + if (sup) {
>> + uart_remove_one_port(&sprd_uart_driver, &sup->port);
>> + sprd_port[sup->port.line] = NULL;
>> + sprd_ports_num--;
>> + }
>> +
>> + if (!sprd_ports_num)
>> + uart_unregister_driver(&sprd_uart_driver);
>> +
>> + return 0;
>> +}
>> +
>> +static int sprd_probe(struct platform_device *pdev)
>> +{
>> + struct resource *res;
>> + struct uart_port *up;
>> + struct clk *clk;
>> + int irq;
>> + int index;
>> + int ret;
>> +
>> + for (index = 0; index < ARRAY_SIZE(sprd_port); index++)
>> + if (sprd_port[index] == NULL)
>> + break;
>> +
>> + if (index == ARRAY_SIZE(sprd_port))
>> + return -EBUSY;
>> +
>> + index = sprd_probe_dt_alias(index, &pdev->dev);
>> +
>> + sprd_port[index] = devm_kzalloc(&pdev->dev,
>> + sizeof(*sprd_port[index]), GFP_KERNEL);
>> + if (!sprd_port[index])
>> + return -ENOMEM;
>> +
>> + pdev->id = index;
> ^^^^^^^^^^^^^^^^
> delete this line.
>
> The platform device id cannot be assigned by the driver.
> (This was left over from trying to fix sprd_suspend/sprd_resume
> but that's fixed correctly now.)
>
>> +
>> + up = &sprd_port[index]->port;
>> + up->dev = &pdev->dev;
>> + up->line = index;
>> + up->type = PORT_SPRD;
>> + up->iotype = SERIAL_IO_PORT;
>> + up->uartclk = SPRD_DEF_RATE;
>> + up->fifosize = SPRD_FIFO_SIZE;
>> + up->ops = &serial_sprd_ops;
>> + up->flags = UPF_BOOT_AUTOCONF;
>> +
>> + clk = devm_clk_get(&pdev->dev, NULL);
>> + if (!IS_ERR(clk))
>> + up->uartclk = clk_get_rate(clk);
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + if (!res) {
>> + dev_err(&pdev->dev, "not provide mem resource\n");
>> + return -ENODEV;
>> + }
>> + up->mapbase = res->start;
>> + up->membase = devm_ioremap_resource(&pdev->dev, res);
>> + if (IS_ERR(up->membase))
>> + return PTR_ERR(up->membase);
>> +
>> + irq = platform_get_irq(pdev, 0);
>> + if (irq < 0) {
>> + dev_err(&pdev->dev, "not provide irq resource\n");
>> + return -ENODEV;
>> + }
>> + up->irq = irq;
>> +
>> + if (!sprd_ports_num) {
>> + ret = uart_register_driver(&sprd_uart_driver);
>> + if (ret < 0) {
>> + pr_err("Failed to register SPRD-UART driver\n");
>> + return ret;
>> + }
>> + }
>> + sprd_ports_num++;
>> +
>> + ret = uart_add_one_port(&sprd_uart_driver, up);
>> + if (ret) {
>> + sprd_port[index] = NULL;
>> + sprd_remove(pdev);
>> + }
>> +
>> + platform_set_drvdata(pdev, up);
>> +
>> + return ret;
>> +}
>
^ 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