[PATCH v3 3/6] libertas: do not confirm sleep if commands are pending
If the main thread gets one PS AWAKE event and one PS SLEEP event in one iteration over event_fifo there will never be checks for commands to be processed, since psstate will always be PS_STATE_SLEEP or PS_STATE_PRE_SLEEP Signed-off-by: Andreas Kemnade --- changes in v3: corrected paths changes in v2: reordered: was 4/6 drivers/net/wireless/marvell/libertas/cmdresp.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/marvell/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 701125f..c95bf6d 100644 --- a/drivers/net/wireless/marvell/libertas/cmdresp.c +++ b/drivers/net/wireless/marvell/libertas/cmdresp.c @@ -257,6 +257,10 @@ int lbs_process_event(struct lbs_private *priv, u32 event) "EVENT: in FULL POWER mode, ignoring PS_SLEEP\n"); break; } + if (!list_empty(>cmdpendingq)) { + lbs_deb_cmd("EVENT: commands in queue, do not sleep\n"); + break; + } priv->psstate = PS_STATE_PRE_SLEEP; lbs_ps_confirm_sleep(priv); -- 2.1.4
[PATCH v3 5/6] libertas: fix ps-mode related removal problems
When the device is remove e.g. because of going to suspend mode with powersaving enabled, lbs_remove_card tries to exit powersaving state even when already woken up. That command is not processed properly in that situation, since the command processing queue is already stopped, so it waits forever for the command being processed, so disable it. Signed-off-by: Andreas Kemnade --- changes in v3: corrected paths changes in v2: improved commit message, reordered: was 6/6 drivers/net/wireless/marvell/libertas/main.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/libertas/main.c index 8079560..b35b8bc 100644 --- a/drivers/net/wireless/marvell/libertas/main.c +++ b/drivers/net/wireless/marvell/libertas/main.c @@ -1060,7 +1060,12 @@ void lbs_remove_card(struct lbs_private *priv) if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { priv->psmode = LBS802_11POWERMODECAM; - lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); + /* no need to wakeup if already woken up, +* on suspend, this exit ps command is not processed +* the driver hangs +*/ + if (priv->psstate != PS_STATE_FULL_POWER) + lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); } if (priv->is_deep_sleep) { -- 2.1.4
[PATCH v3 0/6] libertas: ieee80211 powersave mode
This series makes IEEE 80211 powersave mode work again so that power usage is dramatically reduced when the device is connected. It does not include other power saving methods which are working when the device is not connected (like enabling deep sleep modus) Tested on GTA04 which includes a W2CBW003 chip (Marvel 8686) with sdio interface Changes in v3: s/wireless:libertas/libertas/ s|net/wireless/libertas|net/wireless/marvell/libertas| Changes in v2: improved some commit messages, order changed, former 6/6 was too late it needs to be before implementing the cfg80211 power saving interface to have it git-bisectable. moving the former 3/6 to the end fixes all bisect problems [PATCH v3 1/6] libertas: fix pointer bugs for PS_MODE [PATCH v3 2/6] libertas: check whether bus can do more than [PATCH v3 3/6] libertas: do not confirm sleep if commands [PATCH v3 4/6] libertas: go back to ps mode without commands [PATCH v3 5/6] libertas: fix ps-mode related removal [PATCH v3 6/6] libertas: add an cfg80211 interface for
[PATCH v3 6/6] libertas: add an cfg80211 interface for powersaving
This patch adds an interface for handling commands like iwconfig wlanX power on/off. Such an interface formerly existed when the driver used wext. While performance with sdio in polling mode without using powersave mode is quite bad, powersaving mode is unusable, so do not enable it under such conditions. Signed-off-by: Andreas Kemnade --- changes in v3: corrected paths changes in v2: reordered, was 3/6 drivers/net/wireless/marvell/libertas/cfg.c | 38 + 1 file changed, 38 insertions(+) diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 8317afd..fd18d03 100644 --- a/drivers/net/wireless/marvell/libertas/cfg.c +++ b/drivers/net/wireless/marvell/libertas/cfg.c @@ -2038,6 +2038,43 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) +int lbs_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, + bool enabled, int timeout) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + + if (!(priv->fwcapinfo & FW_CAPINFO_PS)) { + if (!enabled) + return 0; + else + return -EINVAL; + } + /* firmware does not work well with too long latency with power saving +* enabled, so do not enable it if there is only polling, no +* interrupts (like in some sdio hosts which can only +* poll for sdio irqs) +*/ + if (priv->is_polling) { + if (!enabled) + return 0; + else + return -EINVAL; + } + if (!enabled) { + priv->psmode = LBS802_11POWERMODECAM; + if (priv->psstate != PS_STATE_FULL_POWER) + lbs_set_ps_mode(priv, + PS_MODE_ACTION_EXIT_PS, + true); + return 0; + } + if (priv->psmode != LBS802_11POWERMODECAM) + return 0; + priv->psmode = LBS802_11POWERMODEMAX_PSP; + if (priv->connect_status == LBS_CONNECTED) + lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, true); + return 0; +} /* * Initialization @@ -2056,6 +2093,7 @@ static struct cfg80211_ops lbs_cfg80211_ops = { .change_virtual_intf = lbs_change_intf, .join_ibss = lbs_join_ibss, .leave_ibss = lbs_leave_ibss, + .set_power_mgmt = lbs_set_power_mgmt, }; -- 2.1.4
[PATCH v3 2/6] libertas: check whether bus can do more than polling
If a sdio host does not support sdio irqs, polling is used instead. That has an impact on performance. Some functionality should not be enabled then. This add a variable in libertas_priv to indicate that. Signed-off-by: Andreas Kemnade --- changes in v3: corrected paths drivers/net/wireless/marvell/libertas/dev.h | 1 + drivers/net/wireless/marvell/libertas/if_sdio.c | 2 +- drivers/net/wireless/marvell/libertas/if_usb.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 6bd1608..edf710b 100644 --- a/drivers/net/wireless/marvell/libertas/dev.h +++ b/drivers/net/wireless/marvell/libertas/dev.h @@ -99,6 +99,7 @@ struct lbs_private { /* Hardware access */ void *card; bool iface_running; + u8 is_polling; /* host has to poll the card irq */ u8 fw_ready; u8 surpriseremoved; u8 setup_fw_on_resume; diff --git a/drivers/net/wireless/marvell/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index f1f31a2..13db8b5 100644 --- a/drivers/net/wireless/marvell/libertas/if_sdio.c +++ b/drivers/net/wireless/marvell/libertas/if_sdio.c @@ -1271,7 +1271,7 @@ static int if_sdio_probe(struct sdio_func *func, priv->reset_card = if_sdio_reset_card; priv->power_save = if_sdio_power_save; priv->power_restore = if_sdio_power_restore; - + priv->is_polling = !(func->card->host->caps & MMC_CAP_SDIO_IRQ); ret = if_sdio_power_on(card); if (ret) goto err_activate_card; diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index dff08a2..aba0c99 100644 --- a/drivers/net/wireless/marvell/libertas/if_usb.c +++ b/drivers/net/wireless/marvell/libertas/if_usb.c @@ -267,6 +267,7 @@ static int if_usb_probe(struct usb_interface *intf, priv->enter_deep_sleep = NULL; priv->exit_deep_sleep = NULL; priv->reset_deep_sleep_wakeup = NULL; + priv->is_polling = false; #ifdef CONFIG_OLPC if (machine_is_olpc()) priv->reset_card = if_usb_reset_olpc_card; -- 2.1.4
[PATCH v3 4/6] libertas: go back to ps mode without commands pending
Removes the old todo block and checks only whether ieee powersave mode is requested. We still have to check for being connected as this powersave mode includes logic for regularly waking up and checking for packets which only makes sense when connected. For not being connected, another mode is needed. Signed-off-by: Andreas Kemnade --- changes in v3: corrected paths changes in v2: reordered, was 5/6 drivers/net/wireless/marvell/libertas/cmd.c | 36 +--- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/marvell/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 40467d6..4ddd0e5 100644 --- a/drivers/net/wireless/marvell/libertas/cmd.c +++ b/drivers/net/wireless/marvell/libertas/cmd.c @@ -1428,40 +1428,14 @@ int lbs_execute_next_command(struct lbs_private *priv) * check if in power save mode, if yes, put the device back * to PS mode */ -#ifdef TODO - /* -* This was the old code for libertas+wext. Someone that -* understands this beast should re-code it in a sane way. -* -* I actually don't understand why this is related to WPA -* and to connection status, shouldn't powering should be -* independ of such things? -*/ if ((priv->psmode != LBS802_11POWERMODECAM) && (priv->psstate == PS_STATE_FULL_POWER) && - ((priv->connect_status == LBS_CONNECTED) || - lbs_mesh_connected(priv))) { - if (priv->secinfo.WPAenabled || - priv->secinfo.WPA2enabled) { - /* check for valid WPA group keys */ - if (priv->wpa_mcast_key.len || - priv->wpa_unicast_key.len) { - lbs_deb_host( - "EXEC_NEXT_CMD: WPA enabled and GTK_SET" - " go back to PS_SLEEP"); - lbs_set_ps_mode(priv, - PS_MODE_ACTION_ENTER_PS, - false); - } - } else { - lbs_deb_host( - "EXEC_NEXT_CMD: cmdpendingq empty, " - "go back to PS_SLEEP"); - lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, - false); - } + (priv->connect_status == LBS_CONNECTED)) { + lbs_deb_host( + "EXEC_NEXT_CMD: cmdpendingq empty, go back to PS_SLEEP"); + lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, + false); } -#endif } ret = 0; -- 2.1.4
[PATCH v3 1/6] libertas: fix pointer bugs for PS_MODE commands
struct cmd_ds_802_11_ps_mode contains the command header and a pointer to it was initialized with data points to the body which leads to mis-interpretation of the cmd_ds_802_11_ps_mode.action member. cmd[0] contains the header, [1] points beyond that. cmdnode->cmdbuf is a pointer to the command buffer This piece of code was unused since power saving was not enabled. Signed-off-by: Andreas Kemnade --- changes in v3: corrected paths changes in v2: improved commit message drivers/net/wireless/marvell/libertas/cmd.c | 4 ++-- drivers/net/wireless/marvell/libertas/cmdresp.c | 5 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/marvell/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 0387a5b..40467d6 100644 --- a/drivers/net/wireless/marvell/libertas/cmd.c +++ b/drivers/net/wireless/marvell/libertas/cmd.c @@ -957,7 +957,7 @@ static void lbs_queue_cmd(struct lbs_private *priv, /* Exit_PS command needs to be queued in the header always. */ if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { - struct cmd_ds_802_11_ps_mode *psm = (void *) >cmdbuf; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmdnode->cmdbuf; if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { if (priv->psstate != PS_STATE_FULL_POWER) @@ -1387,7 +1387,7 @@ int lbs_execute_next_command(struct lbs_private *priv) * PS command. Ignore it if it is not Exit_PS. * otherwise send it down immediately. */ - struct cmd_ds_802_11_ps_mode *psm = (void *)[1]; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmd; lbs_deb_host( "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", diff --git a/drivers/net/wireless/marvell/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index e5442e8..701125f 100644 --- a/drivers/net/wireless/marvell/libertas/cmdresp.c +++ b/drivers/net/wireless/marvell/libertas/cmdresp.c @@ -123,7 +123,10 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) priv->cmd_timed_out = 0; if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { - struct cmd_ds_802_11_ps_mode *psmode = (void *) [1]; + /* struct cmd_ds_802_11_ps_mode also contains +* the header +*/ + struct cmd_ds_802_11_ps_mode *psmode = (void *)resp; u16 action = le16_to_cpu(psmode->action); lbs_deb_host( -- 2.1.4
[PATCH v3 4/6] libertas: go back to ps mode without commands pending
Removes the old todo block and checks only whether ieee powersave mode is requested. We still have to check for being connected as this powersave mode includes logic for regularly waking up and checking for packets which only makes sense when connected. For not being connected, another mode is needed. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- changes in v3: corrected paths changes in v2: reordered, was 5/6 drivers/net/wireless/marvell/libertas/cmd.c | 36 +--- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/marvell/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 40467d6..4ddd0e5 100644 --- a/drivers/net/wireless/marvell/libertas/cmd.c +++ b/drivers/net/wireless/marvell/libertas/cmd.c @@ -1428,40 +1428,14 @@ int lbs_execute_next_command(struct lbs_private *priv) * check if in power save mode, if yes, put the device back * to PS mode */ -#ifdef TODO - /* -* This was the old code for libertas+wext. Someone that -* understands this beast should re-code it in a sane way. -* -* I actually don't understand why this is related to WPA -* and to connection status, shouldn't powering should be -* independ of such things? -*/ if ((priv->psmode != LBS802_11POWERMODECAM) && (priv->psstate == PS_STATE_FULL_POWER) && - ((priv->connect_status == LBS_CONNECTED) || - lbs_mesh_connected(priv))) { - if (priv->secinfo.WPAenabled || - priv->secinfo.WPA2enabled) { - /* check for valid WPA group keys */ - if (priv->wpa_mcast_key.len || - priv->wpa_unicast_key.len) { - lbs_deb_host( - "EXEC_NEXT_CMD: WPA enabled and GTK_SET" - " go back to PS_SLEEP"); - lbs_set_ps_mode(priv, - PS_MODE_ACTION_ENTER_PS, - false); - } - } else { - lbs_deb_host( - "EXEC_NEXT_CMD: cmdpendingq empty, " - "go back to PS_SLEEP"); - lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, - false); - } + (priv->connect_status == LBS_CONNECTED)) { + lbs_deb_host( + "EXEC_NEXT_CMD: cmdpendingq empty, go back to PS_SLEEP"); + lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, + false); } -#endif } ret = 0; -- 2.1.4
[PATCH v3 1/6] libertas: fix pointer bugs for PS_MODE commands
struct cmd_ds_802_11_ps_mode contains the command header and a pointer to it was initialized with data points to the body which leads to mis-interpretation of the cmd_ds_802_11_ps_mode.action member. cmd[0] contains the header, [1] points beyond that. cmdnode->cmdbuf is a pointer to the command buffer This piece of code was unused since power saving was not enabled. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- changes in v3: corrected paths changes in v2: improved commit message drivers/net/wireless/marvell/libertas/cmd.c | 4 ++-- drivers/net/wireless/marvell/libertas/cmdresp.c | 5 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/marvell/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 0387a5b..40467d6 100644 --- a/drivers/net/wireless/marvell/libertas/cmd.c +++ b/drivers/net/wireless/marvell/libertas/cmd.c @@ -957,7 +957,7 @@ static void lbs_queue_cmd(struct lbs_private *priv, /* Exit_PS command needs to be queued in the header always. */ if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { - struct cmd_ds_802_11_ps_mode *psm = (void *) >cmdbuf; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmdnode->cmdbuf; if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { if (priv->psstate != PS_STATE_FULL_POWER) @@ -1387,7 +1387,7 @@ int lbs_execute_next_command(struct lbs_private *priv) * PS command. Ignore it if it is not Exit_PS. * otherwise send it down immediately. */ - struct cmd_ds_802_11_ps_mode *psm = (void *)[1]; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmd; lbs_deb_host( "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", diff --git a/drivers/net/wireless/marvell/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index e5442e8..701125f 100644 --- a/drivers/net/wireless/marvell/libertas/cmdresp.c +++ b/drivers/net/wireless/marvell/libertas/cmdresp.c @@ -123,7 +123,10 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) priv->cmd_timed_out = 0; if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { - struct cmd_ds_802_11_ps_mode *psmode = (void *) [1]; + /* struct cmd_ds_802_11_ps_mode also contains +* the header +*/ + struct cmd_ds_802_11_ps_mode *psmode = (void *)resp; u16 action = le16_to_cpu(psmode->action); lbs_deb_host( -- 2.1.4
[PATCH v3 2/6] libertas: check whether bus can do more than polling
If a sdio host does not support sdio irqs, polling is used instead. That has an impact on performance. Some functionality should not be enabled then. This add a variable in libertas_priv to indicate that. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- changes in v3: corrected paths drivers/net/wireless/marvell/libertas/dev.h | 1 + drivers/net/wireless/marvell/libertas/if_sdio.c | 2 +- drivers/net/wireless/marvell/libertas/if_usb.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 6bd1608..edf710b 100644 --- a/drivers/net/wireless/marvell/libertas/dev.h +++ b/drivers/net/wireless/marvell/libertas/dev.h @@ -99,6 +99,7 @@ struct lbs_private { /* Hardware access */ void *card; bool iface_running; + u8 is_polling; /* host has to poll the card irq */ u8 fw_ready; u8 surpriseremoved; u8 setup_fw_on_resume; diff --git a/drivers/net/wireless/marvell/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index f1f31a2..13db8b5 100644 --- a/drivers/net/wireless/marvell/libertas/if_sdio.c +++ b/drivers/net/wireless/marvell/libertas/if_sdio.c @@ -1271,7 +1271,7 @@ static int if_sdio_probe(struct sdio_func *func, priv->reset_card = if_sdio_reset_card; priv->power_save = if_sdio_power_save; priv->power_restore = if_sdio_power_restore; - + priv->is_polling = !(func->card->host->caps & MMC_CAP_SDIO_IRQ); ret = if_sdio_power_on(card); if (ret) goto err_activate_card; diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index dff08a2..aba0c99 100644 --- a/drivers/net/wireless/marvell/libertas/if_usb.c +++ b/drivers/net/wireless/marvell/libertas/if_usb.c @@ -267,6 +267,7 @@ static int if_usb_probe(struct usb_interface *intf, priv->enter_deep_sleep = NULL; priv->exit_deep_sleep = NULL; priv->reset_deep_sleep_wakeup = NULL; + priv->is_polling = false; #ifdef CONFIG_OLPC if (machine_is_olpc()) priv->reset_card = if_usb_reset_olpc_card; -- 2.1.4
[PATCH v3 0/6] libertas: ieee80211 powersave mode
This series makes IEEE 80211 powersave mode work again so that power usage is dramatically reduced when the device is connected. It does not include other power saving methods which are working when the device is not connected (like enabling deep sleep modus) Tested on GTA04 which includes a W2CBW003 chip (Marvel 8686) with sdio interface Changes in v3: s/wireless:libertas/libertas/ s|net/wireless/libertas|net/wireless/marvell/libertas| Changes in v2: improved some commit messages, order changed, former 6/6 was too late it needs to be before implementing the cfg80211 power saving interface to have it git-bisectable. moving the former 3/6 to the end fixes all bisect problems [PATCH v3 1/6] libertas: fix pointer bugs for PS_MODE [PATCH v3 2/6] libertas: check whether bus can do more than [PATCH v3 3/6] libertas: do not confirm sleep if commands [PATCH v3 4/6] libertas: go back to ps mode without commands [PATCH v3 5/6] libertas: fix ps-mode related removal [PATCH v3 6/6] libertas: add an cfg80211 interface for
[PATCH v3 6/6] libertas: add an cfg80211 interface for powersaving
This patch adds an interface for handling commands like iwconfig wlanX power on/off. Such an interface formerly existed when the driver used wext. While performance with sdio in polling mode without using powersave mode is quite bad, powersaving mode is unusable, so do not enable it under such conditions. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- changes in v3: corrected paths changes in v2: reordered, was 3/6 drivers/net/wireless/marvell/libertas/cfg.c | 38 + 1 file changed, 38 insertions(+) diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 8317afd..fd18d03 100644 --- a/drivers/net/wireless/marvell/libertas/cfg.c +++ b/drivers/net/wireless/marvell/libertas/cfg.c @@ -2038,6 +2038,43 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) +int lbs_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, + bool enabled, int timeout) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + + if (!(priv->fwcapinfo & FW_CAPINFO_PS)) { + if (!enabled) + return 0; + else + return -EINVAL; + } + /* firmware does not work well with too long latency with power saving +* enabled, so do not enable it if there is only polling, no +* interrupts (like in some sdio hosts which can only +* poll for sdio irqs) +*/ + if (priv->is_polling) { + if (!enabled) + return 0; + else + return -EINVAL; + } + if (!enabled) { + priv->psmode = LBS802_11POWERMODECAM; + if (priv->psstate != PS_STATE_FULL_POWER) + lbs_set_ps_mode(priv, + PS_MODE_ACTION_EXIT_PS, + true); + return 0; + } + if (priv->psmode != LBS802_11POWERMODECAM) + return 0; + priv->psmode = LBS802_11POWERMODEMAX_PSP; + if (priv->connect_status == LBS_CONNECTED) + lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, true); + return 0; +} /* * Initialization @@ -2056,6 +2093,7 @@ static struct cfg80211_ops lbs_cfg80211_ops = { .change_virtual_intf = lbs_change_intf, .join_ibss = lbs_join_ibss, .leave_ibss = lbs_leave_ibss, + .set_power_mgmt = lbs_set_power_mgmt, }; -- 2.1.4
[PATCH v3 3/6] libertas: do not confirm sleep if commands are pending
If the main thread gets one PS AWAKE event and one PS SLEEP event in one iteration over event_fifo there will never be checks for commands to be processed, since psstate will always be PS_STATE_SLEEP or PS_STATE_PRE_SLEEP Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- changes in v3: corrected paths changes in v2: reordered: was 4/6 drivers/net/wireless/marvell/libertas/cmdresp.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/marvell/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 701125f..c95bf6d 100644 --- a/drivers/net/wireless/marvell/libertas/cmdresp.c +++ b/drivers/net/wireless/marvell/libertas/cmdresp.c @@ -257,6 +257,10 @@ int lbs_process_event(struct lbs_private *priv, u32 event) "EVENT: in FULL POWER mode, ignoring PS_SLEEP\n"); break; } + if (!list_empty(>cmdpendingq)) { + lbs_deb_cmd("EVENT: commands in queue, do not sleep\n"); + break; + } priv->psstate = PS_STATE_PRE_SLEEP; lbs_ps_confirm_sleep(priv); -- 2.1.4
[PATCH v3 5/6] libertas: fix ps-mode related removal problems
When the device is remove e.g. because of going to suspend mode with powersaving enabled, lbs_remove_card tries to exit powersaving state even when already woken up. That command is not processed properly in that situation, since the command processing queue is already stopped, so it waits forever for the command being processed, so disable it. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- changes in v3: corrected paths changes in v2: improved commit message, reordered: was 6/6 drivers/net/wireless/marvell/libertas/main.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/libertas/main.c index 8079560..b35b8bc 100644 --- a/drivers/net/wireless/marvell/libertas/main.c +++ b/drivers/net/wireless/marvell/libertas/main.c @@ -1060,7 +1060,12 @@ void lbs_remove_card(struct lbs_private *priv) if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { priv->psmode = LBS802_11POWERMODECAM; - lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); + /* no need to wakeup if already woken up, +* on suspend, this exit ps command is not processed +* the driver hangs +*/ + if (priv->psstate != PS_STATE_FULL_POWER) + lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); } if (priv->is_deep_sleep) { -- 2.1.4
Re: [Gta04-owner] [PATCH 0/4] UART slave device support - version 4
On Fri, 22 Jan 2016 20:12:29 + One Thousand Gnomes wrote: > > I would have expected that the main (and IMO sufficient) reason why > > the kernel should do it is because the particular bus used to connect > > a BT chip to the CPU is a hw detail that a kernel that does its job > > should keep to itself. Same as userspace not needing to care if a BT > > chip is behind SDIO or USB, why does it have to tell the kernel behind > > which UART a BT chip is sitting? > > Lots of reasons, some historic some not > > 1. Different BT chips have different interfaces, especially when it gets > to stuff like firmware reprogramming > > 2. In many cases we don't know at the kernel level where there are BT > uarts. It's improving with recent ACPI but for many systems it's simply > not available to the OS > Same is true for i2c devices. The solution there is that you have various methods for providing the information to the kernel, some are autoprobed, some are via board files and you can also tell via sysfs that there is one device. > 3. The power management for a lot of BT (especially on device tree) is > not actually expressed, so you need a slightly customised daemon for each > device - that one is ugly but the serial and bt layers can't fix it. > That boils down to a circular it is not there because it is not there. If we express the power management, it can be done in kernel. > 4. Because you don't want to just automatically load and turn on > bluetooth just because it is there - it burns power > Exactly the same is true for wifi and for many other devices for which drivers are automatically handled in kernel, too. Well, do you have a list of devices which do not burn power? I would be highly interested in those. Regards, Andreas pgpPEGBL_N0Da.pgp Description: OpenPGP digital signature
Re: [Gta04-owner] [PATCH 0/4] UART slave device support - version 4
On Fri, 22 Jan 2016 20:12:29 + One Thousand Gnomeswrote: > > I would have expected that the main (and IMO sufficient) reason why > > the kernel should do it is because the particular bus used to connect > > a BT chip to the CPU is a hw detail that a kernel that does its job > > should keep to itself. Same as userspace not needing to care if a BT > > chip is behind SDIO or USB, why does it have to tell the kernel behind > > which UART a BT chip is sitting? > > Lots of reasons, some historic some not > > 1. Different BT chips have different interfaces, especially when it gets > to stuff like firmware reprogramming > > 2. In many cases we don't know at the kernel level where there are BT > uarts. It's improving with recent ACPI but for many systems it's simply > not available to the OS > Same is true for i2c devices. The solution there is that you have various methods for providing the information to the kernel, some are autoprobed, some are via board files and you can also tell via sysfs that there is one device. > 3. The power management for a lot of BT (especially on device tree) is > not actually expressed, so you need a slightly customised daemon for each > device - that one is ugly but the serial and bt layers can't fix it. > That boils down to a circular it is not there because it is not there. If we express the power management, it can be done in kernel. > 4. Because you don't want to just automatically load and turn on > bluetooth just because it is there - it burns power > Exactly the same is true for wifi and for many other devices for which drivers are automatically handled in kernel, too. Well, do you have a list of devices which do not burn power? I would be highly interested in those. Regards, Andreas pgpPEGBL_N0Da.pgp Description: OpenPGP digital signature
Re: [PATCH RFC] wireless:libertas: enable auto deep sleep
On Wed, 20 Jan 2016 14:42:47 +0200 Kalle Valo wrote: > Andreas Kemnade writes: > > > Enables auto deep sleep whenever the interface is up and > > power managament is enabled, so there is also power management > > when there is no connection > > That reduces power consumption between scanning > > intervals. Deep sleep mode is entered when there is > > no activity for 1s. > > > > The code looks a bit different to how things were done > > with the wext interface in earlier times. > > > > Signed-off-by: Andreas Kemnade > > Please use just "libertas: " as the prefix and drop the "wireless:". > Hmm, is there any rule for that or do I just find that out by analysing git log output? BTW: That patch depends on my ieee80211 powersave mode series where I sent a second version today. Has that series found the way into your review queue? Regards, Andreas Kemnade pgpNMS1UtaSwX.pgp Description: OpenPGP digital signature
Re: [PATCH RFC] wireless:libertas: enable auto deep sleep
On Wed, 20 Jan 2016 14:42:47 +0200 Kalle Valo <kv...@codeaurora.org> wrote: > Andreas Kemnade <andr...@kemnade.info> writes: > > > Enables auto deep sleep whenever the interface is up and > > power managament is enabled, so there is also power management > > when there is no connection > > That reduces power consumption between scanning > > intervals. Deep sleep mode is entered when there is > > no activity for 1s. > > > > The code looks a bit different to how things were done > > with the wext interface in earlier times. > > > > Signed-off-by: Andreas Kemnade <andr...@kemnade.info> > > Please use just "libertas: " as the prefix and drop the "wireless:". > Hmm, is there any rule for that or do I just find that out by analysing git log output? BTW: That patch depends on my ieee80211 powersave mode series where I sent a second version today. Has that series found the way into your review queue? Regards, Andreas Kemnade pgpNMS1UtaSwX.pgp Description: OpenPGP digital signature
[PATCH 4/6] wireless:libertas: do not confirm sleep if commands are pending
If the main thread gets one PS AWAKE event and one PS SLEEP event in one iteration over event_fifo there will never be checks for commands to be processed, since psstate will always be PS_STATE_SLEEP or PS_STATE_PRE_SLEEP Signed-off-by: Andreas Kemnade --- drivers/net/wireless/libertas/cmdresp.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 701125f..c95bf6d 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -257,6 +257,10 @@ int lbs_process_event(struct lbs_private *priv, u32 event) "EVENT: in FULL POWER mode, ignoring PS_SLEEP\n"); break; } + if (!list_empty(>cmdpendingq)) { + lbs_deb_cmd("EVENT: commands in queue, do not sleep\n"); + break; + } priv->psstate = PS_STATE_PRE_SLEEP; lbs_ps_confirm_sleep(priv); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 6/6] wireless:libertas: fix suspend problems
When the device goes to suspend mode with powersaving enabled, lbs_remove_card tries to exit powersaving state even when already woken up. That command is not processed properly in that situation, so the system hangs at suspend, so disable it. Signed-off-by: Andreas Kemnade --- drivers/net/wireless/libertas/main.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 8079560..b35b8bc 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -1060,7 +1060,12 @@ void lbs_remove_card(struct lbs_private *priv) if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { priv->psmode = LBS802_11POWERMODECAM; - lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); + /* no need to wakeup if already woken up, +* on suspend, this exit ps command is not processed +* the driver hangs +*/ + if (priv->psstate != PS_STATE_FULL_POWER) + lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); } if (priv->is_deep_sleep) { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 5/6] wireless:libertas: go back to ps mode without commands pending
Removes the old todo block and checks only whether ieee powersave mode is requested. We still have to check for being connected as this powersave mode includes logic for regularly waking up and checking for packets which only makes sense when connected. For not being connected, another mode is needed. Signed-off-by: Andreas Kemnade --- drivers/net/wireless/libertas/cmd.c | 36 +--- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 40467d6..4ddd0e5 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1428,40 +1428,14 @@ int lbs_execute_next_command(struct lbs_private *priv) * check if in power save mode, if yes, put the device back * to PS mode */ -#ifdef TODO - /* -* This was the old code for libertas+wext. Someone that -* understands this beast should re-code it in a sane way. -* -* I actually don't understand why this is related to WPA -* and to connection status, shouldn't powering should be -* independ of such things? -*/ if ((priv->psmode != LBS802_11POWERMODECAM) && (priv->psstate == PS_STATE_FULL_POWER) && - ((priv->connect_status == LBS_CONNECTED) || - lbs_mesh_connected(priv))) { - if (priv->secinfo.WPAenabled || - priv->secinfo.WPA2enabled) { - /* check for valid WPA group keys */ - if (priv->wpa_mcast_key.len || - priv->wpa_unicast_key.len) { - lbs_deb_host( - "EXEC_NEXT_CMD: WPA enabled and GTK_SET" - " go back to PS_SLEEP"); - lbs_set_ps_mode(priv, - PS_MODE_ACTION_ENTER_PS, - false); - } - } else { - lbs_deb_host( - "EXEC_NEXT_CMD: cmdpendingq empty, " - "go back to PS_SLEEP"); - lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, - false); - } + (priv->connect_status == LBS_CONNECTED)) { + lbs_deb_host( + "EXEC_NEXT_CMD: cmdpendingq empty, go back to PS_SLEEP"); + lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, + false); } -#endif } ret = 0; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/6] wireless:libertas: add an cfg80211 interface for powersaving
This patch adds an interface for handling commands like iwconfig wlanX power on/off. Such an interface formerly existed when the driver used wext. While performance with sdio in polling mode without using powersave mode is quite bad, powersaving mode is unusable, so do not enable it under such conditions. Signed-off-by: Andreas Kemnade --- drivers/net/wireless/libertas/cfg.c | 38 + 1 file changed, 38 insertions(+) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 8317afd..fd18d03 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -2038,6 +2038,43 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) +int lbs_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, + bool enabled, int timeout) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + + if (!(priv->fwcapinfo & FW_CAPINFO_PS)) { + if (!enabled) + return 0; + else + return -EINVAL; + } + /* firmware does not work well with too long latency with power saving +* enabled, so do not enable it if there is only polling, no +* interrupts (like in some sdio hosts which can only +* poll for sdio irqs) +*/ + if (priv->is_polling) { + if (!enabled) + return 0; + else + return -EINVAL; + } + if (!enabled) { + priv->psmode = LBS802_11POWERMODECAM; + if (priv->psstate != PS_STATE_FULL_POWER) + lbs_set_ps_mode(priv, + PS_MODE_ACTION_EXIT_PS, + true); + return 0; + } + if (priv->psmode != LBS802_11POWERMODECAM) + return 0; + priv->psmode = LBS802_11POWERMODEMAX_PSP; + if (priv->connect_status == LBS_CONNECTED) + lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, true); + return 0; +} /* * Initialization @@ -2056,6 +2093,7 @@ static struct cfg80211_ops lbs_cfg80211_ops = { .change_virtual_intf = lbs_change_intf, .join_ibss = lbs_join_ibss, .leave_ibss = lbs_leave_ibss, + .set_power_mgmt = lbs_set_power_mgmt, }; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/6] wireless:libertas: ieee80211 powersave mode
This series makes IEEE 80211 powersave mode work again so that power usage is dramatically reduced when the device is connected. It does not include other power saving methods which are working when the device is not connected (like enabling deep sleep modus) Tested on GTA04 which includes a W2CBW003 chip (Marvel 8686) with sdio interface [PATCH 1/6] wireless:libertas: do not strip header for PS_MODE [PATCH 2/6] wireless:libertas: check whether bus can do more than [PATCH 3/6] wireless:libertas: add an cfg80211 interface for [PATCH 4/6] wireless:libertas: do not confirm sleep if commands are [PATCH 5/6] wireless:libertas: go back to ps mode without commands [PATCH 6/6] wireless:libertas: fix suspend problems -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/6] wireless:libertas: check whether bus can do more than polling
If a sdio host does not support sdio irqs, polling is used instead. That has an impact on performance. Some functionality should not be enabled then. This add a variable in libertas_priv to indicate that. Signed-off-by: Andreas Kemnade --- drivers/net/wireless/libertas/dev.h | 1 + drivers/net/wireless/libertas/if_sdio.c | 2 +- drivers/net/wireless/libertas/if_usb.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 6bd1608..edf710b 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -99,6 +99,7 @@ struct lbs_private { /* Hardware access */ void *card; bool iface_running; + u8 is_polling; /* host has to poll the card irq */ u8 fw_ready; u8 surpriseremoved; u8 setup_fw_on_resume; diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index f1f31a2..13db8b5 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -1271,7 +1271,7 @@ static int if_sdio_probe(struct sdio_func *func, priv->reset_card = if_sdio_reset_card; priv->power_save = if_sdio_power_save; priv->power_restore = if_sdio_power_restore; - + priv->is_polling = !(func->card->host->caps & MMC_CAP_SDIO_IRQ); ret = if_sdio_power_on(card); if (ret) goto err_activate_card; diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index dff08a2..aba0c99 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -267,6 +267,7 @@ static int if_usb_probe(struct usb_interface *intf, priv->enter_deep_sleep = NULL; priv->exit_deep_sleep = NULL; priv->reset_deep_sleep_wakeup = NULL; + priv->is_polling = false; #ifdef CONFIG_OLPC if (machine_is_olpc()) priv->reset_card = if_usb_reset_olpc_card; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/6] wireless:libertas: do not strip header for PS_MODE commands
struct cmd_ds_802_11_ps_mode contains the command header and a pointer to it was initialized with data points to the body which leads to mis-interpretation of the cmd_ds_802_11_ps_mode.action member. Signed-off-by: Andreas Kemnade --- drivers/net/wireless/libertas/cmd.c | 4 ++-- drivers/net/wireless/libertas/cmdresp.c | 5 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 0387a5b..40467d6 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -957,7 +957,7 @@ static void lbs_queue_cmd(struct lbs_private *priv, /* Exit_PS command needs to be queued in the header always. */ if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { - struct cmd_ds_802_11_ps_mode *psm = (void *) >cmdbuf; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmdnode->cmdbuf; if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { if (priv->psstate != PS_STATE_FULL_POWER) @@ -1387,7 +1387,7 @@ int lbs_execute_next_command(struct lbs_private *priv) * PS command. Ignore it if it is not Exit_PS. * otherwise send it down immediately. */ - struct cmd_ds_802_11_ps_mode *psm = (void *)[1]; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmd; lbs_deb_host( "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index e5442e8..701125f 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -123,7 +123,10 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) priv->cmd_timed_out = 0; if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { - struct cmd_ds_802_11_ps_mode *psmode = (void *) [1]; + /* struct cmd_ds_802_11_ps_mode also contains +* the header +*/ + struct cmd_ds_802_11_ps_mode *psmode = (void *)resp; u16 action = le16_to_cpu(psmode->action); lbs_deb_host( -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/6] wireless:libertas: do not strip header for PS_MODE commands
struct cmd_ds_802_11_ps_mode contains the command header and a pointer to it was initialized with data points to the body which leads to mis-interpretation of the cmd_ds_802_11_ps_mode.action member. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- drivers/net/wireless/libertas/cmd.c | 4 ++-- drivers/net/wireless/libertas/cmdresp.c | 5 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 0387a5b..40467d6 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -957,7 +957,7 @@ static void lbs_queue_cmd(struct lbs_private *priv, /* Exit_PS command needs to be queued in the header always. */ if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { - struct cmd_ds_802_11_ps_mode *psm = (void *) >cmdbuf; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmdnode->cmdbuf; if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { if (priv->psstate != PS_STATE_FULL_POWER) @@ -1387,7 +1387,7 @@ int lbs_execute_next_command(struct lbs_private *priv) * PS command. Ignore it if it is not Exit_PS. * otherwise send it down immediately. */ - struct cmd_ds_802_11_ps_mode *psm = (void *)[1]; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmd; lbs_deb_host( "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index e5442e8..701125f 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -123,7 +123,10 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) priv->cmd_timed_out = 0; if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { - struct cmd_ds_802_11_ps_mode *psmode = (void *) [1]; + /* struct cmd_ds_802_11_ps_mode also contains +* the header +*/ + struct cmd_ds_802_11_ps_mode *psmode = (void *)resp; u16 action = le16_to_cpu(psmode->action); lbs_deb_host( -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/6] wireless:libertas: check whether bus can do more than polling
If a sdio host does not support sdio irqs, polling is used instead. That has an impact on performance. Some functionality should not be enabled then. This add a variable in libertas_priv to indicate that. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- drivers/net/wireless/libertas/dev.h | 1 + drivers/net/wireless/libertas/if_sdio.c | 2 +- drivers/net/wireless/libertas/if_usb.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 6bd1608..edf710b 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -99,6 +99,7 @@ struct lbs_private { /* Hardware access */ void *card; bool iface_running; + u8 is_polling; /* host has to poll the card irq */ u8 fw_ready; u8 surpriseremoved; u8 setup_fw_on_resume; diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index f1f31a2..13db8b5 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -1271,7 +1271,7 @@ static int if_sdio_probe(struct sdio_func *func, priv->reset_card = if_sdio_reset_card; priv->power_save = if_sdio_power_save; priv->power_restore = if_sdio_power_restore; - + priv->is_polling = !(func->card->host->caps & MMC_CAP_SDIO_IRQ); ret = if_sdio_power_on(card); if (ret) goto err_activate_card; diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index dff08a2..aba0c99 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -267,6 +267,7 @@ static int if_usb_probe(struct usb_interface *intf, priv->enter_deep_sleep = NULL; priv->exit_deep_sleep = NULL; priv->reset_deep_sleep_wakeup = NULL; + priv->is_polling = false; #ifdef CONFIG_OLPC if (machine_is_olpc()) priv->reset_card = if_usb_reset_olpc_card; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/6] wireless:libertas: ieee80211 powersave mode
This series makes IEEE 80211 powersave mode work again so that power usage is dramatically reduced when the device is connected. It does not include other power saving methods which are working when the device is not connected (like enabling deep sleep modus) Tested on GTA04 which includes a W2CBW003 chip (Marvel 8686) with sdio interface [PATCH 1/6] wireless:libertas: do not strip header for PS_MODE [PATCH 2/6] wireless:libertas: check whether bus can do more than [PATCH 3/6] wireless:libertas: add an cfg80211 interface for [PATCH 4/6] wireless:libertas: do not confirm sleep if commands are [PATCH 5/6] wireless:libertas: go back to ps mode without commands [PATCH 6/6] wireless:libertas: fix suspend problems -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 4/6] wireless:libertas: do not confirm sleep if commands are pending
If the main thread gets one PS AWAKE event and one PS SLEEP event in one iteration over event_fifo there will never be checks for commands to be processed, since psstate will always be PS_STATE_SLEEP or PS_STATE_PRE_SLEEP Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- drivers/net/wireless/libertas/cmdresp.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 701125f..c95bf6d 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -257,6 +257,10 @@ int lbs_process_event(struct lbs_private *priv, u32 event) "EVENT: in FULL POWER mode, ignoring PS_SLEEP\n"); break; } + if (!list_empty(>cmdpendingq)) { + lbs_deb_cmd("EVENT: commands in queue, do not sleep\n"); + break; + } priv->psstate = PS_STATE_PRE_SLEEP; lbs_ps_confirm_sleep(priv); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/6] wireless:libertas: add an cfg80211 interface for powersaving
This patch adds an interface for handling commands like iwconfig wlanX power on/off. Such an interface formerly existed when the driver used wext. While performance with sdio in polling mode without using powersave mode is quite bad, powersaving mode is unusable, so do not enable it under such conditions. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- drivers/net/wireless/libertas/cfg.c | 38 + 1 file changed, 38 insertions(+) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 8317afd..fd18d03 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -2038,6 +2038,43 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) +int lbs_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, + bool enabled, int timeout) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + + if (!(priv->fwcapinfo & FW_CAPINFO_PS)) { + if (!enabled) + return 0; + else + return -EINVAL; + } + /* firmware does not work well with too long latency with power saving +* enabled, so do not enable it if there is only polling, no +* interrupts (like in some sdio hosts which can only +* poll for sdio irqs) +*/ + if (priv->is_polling) { + if (!enabled) + return 0; + else + return -EINVAL; + } + if (!enabled) { + priv->psmode = LBS802_11POWERMODECAM; + if (priv->psstate != PS_STATE_FULL_POWER) + lbs_set_ps_mode(priv, + PS_MODE_ACTION_EXIT_PS, + true); + return 0; + } + if (priv->psmode != LBS802_11POWERMODECAM) + return 0; + priv->psmode = LBS802_11POWERMODEMAX_PSP; + if (priv->connect_status == LBS_CONNECTED) + lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, true); + return 0; +} /* * Initialization @@ -2056,6 +2093,7 @@ static struct cfg80211_ops lbs_cfg80211_ops = { .change_virtual_intf = lbs_change_intf, .join_ibss = lbs_join_ibss, .leave_ibss = lbs_leave_ibss, + .set_power_mgmt = lbs_set_power_mgmt, }; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 6/6] wireless:libertas: fix suspend problems
When the device goes to suspend mode with powersaving enabled, lbs_remove_card tries to exit powersaving state even when already woken up. That command is not processed properly in that situation, so the system hangs at suspend, so disable it. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- drivers/net/wireless/libertas/main.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 8079560..b35b8bc 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -1060,7 +1060,12 @@ void lbs_remove_card(struct lbs_private *priv) if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { priv->psmode = LBS802_11POWERMODECAM; - lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); + /* no need to wakeup if already woken up, +* on suspend, this exit ps command is not processed +* the driver hangs +*/ + if (priv->psstate != PS_STATE_FULL_POWER) + lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); } if (priv->is_deep_sleep) { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 5/6] wireless:libertas: go back to ps mode without commands pending
Removes the old todo block and checks only whether ieee powersave mode is requested. We still have to check for being connected as this powersave mode includes logic for regularly waking up and checking for packets which only makes sense when connected. For not being connected, another mode is needed. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- drivers/net/wireless/libertas/cmd.c | 36 +--- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 40467d6..4ddd0e5 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1428,40 +1428,14 @@ int lbs_execute_next_command(struct lbs_private *priv) * check if in power save mode, if yes, put the device back * to PS mode */ -#ifdef TODO - /* -* This was the old code for libertas+wext. Someone that -* understands this beast should re-code it in a sane way. -* -* I actually don't understand why this is related to WPA -* and to connection status, shouldn't powering should be -* independ of such things? -*/ if ((priv->psmode != LBS802_11POWERMODECAM) && (priv->psstate == PS_STATE_FULL_POWER) && - ((priv->connect_status == LBS_CONNECTED) || - lbs_mesh_connected(priv))) { - if (priv->secinfo.WPAenabled || - priv->secinfo.WPA2enabled) { - /* check for valid WPA group keys */ - if (priv->wpa_mcast_key.len || - priv->wpa_unicast_key.len) { - lbs_deb_host( - "EXEC_NEXT_CMD: WPA enabled and GTK_SET" - " go back to PS_SLEEP"); - lbs_set_ps_mode(priv, - PS_MODE_ACTION_ENTER_PS, - false); - } - } else { - lbs_deb_host( - "EXEC_NEXT_CMD: cmdpendingq empty, " - "go back to PS_SLEEP"); - lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, - false); - } + (priv->connect_status == LBS_CONNECTED)) { + lbs_deb_host( + "EXEC_NEXT_CMD: cmdpendingq empty, go back to PS_SLEEP"); + lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, + false); } -#endif } ret = 0; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] omap_hdq: fix usecount handling
hdq_usecount was set to zero after a successful read, so omap_hdq_put could not properly free resources which leads e.g. to increasing usecounts in lsmod output Signed-off-by: Andreas Kemnade --- drivers/w1/masters/omap_hdq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 0e2f43b..a2eec97 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -618,7 +618,6 @@ static u8 omap_w1_read_byte(void *_hdq) hdq_disable_interrupt(hdq_data, OMAP_HDQ_CTRL_STATUS, ~OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK); - hdq_data->hdq_usecount = 0; /* Write followed by a read, release the module */ if (hdq_data->init_trans) { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] omap_hdq: fix usecount handling
hdq_usecount was set to zero after a successful read, so omap_hdq_put could not properly free resources which leads e.g. to increasing usecounts in lsmod output Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- drivers/w1/masters/omap_hdq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 0e2f43b..a2eec97 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -618,7 +618,6 @@ static u8 omap_w1_read_byte(void *_hdq) hdq_disable_interrupt(hdq_data, OMAP_HDQ_CTRL_STATUS, ~OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK); - hdq_data->hdq_usecount = 0; /* Write followed by a read, release the module */ if (hdq_data->init_trans) { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] net/wireless/libertas: do not strip header for PS_MODE commands
struct cmd_ds_802_11_ps_mode contains the command header and a pointer to it was initialized with data points to the body which leads to mis-interpretation of the cmd_ds_802_11_ps_mode.action member. Signed-off-by: Andreas Kemnade --- drivers/net/wireless/libertas/cmd.c |4 ++-- drivers/net/wireless/libertas/cmdresp.c |5 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 909a587..248722a 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -957,7 +957,7 @@ static void lbs_queue_cmd(struct lbs_private *priv, /* Exit_PS command needs to be queued in the header always. */ if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { - struct cmd_ds_802_11_ps_mode *psm = (void *) >cmdbuf; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmdnode->cmdbuf; if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { if (priv->psstate != PS_STATE_FULL_POWER) @@ -1387,7 +1387,7 @@ int lbs_execute_next_command(struct lbs_private *priv) * PS command. Ignore it if it is not Exit_PS. * otherwise send it down immediately. */ - struct cmd_ds_802_11_ps_mode *psm = (void *)[1]; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmd; lbs_deb_host( "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 316ac82..de99603 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -123,7 +123,10 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) priv->cmd_timed_out = 0; if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { - struct cmd_ds_802_11_ps_mode *psmode = (void *) [1]; + /* struct cmd_ds_802_11_ps_mode also contains +* the header +*/ + struct cmd_ds_802_11_ps_mode *psmode = (void *)resp; u16 action = le16_to_cpu(psmode->action); lbs_deb_host( -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] net/wireless/libertas: do not strip header for PS_MODE commands
struct cmd_ds_802_11_ps_mode contains the command header and a pointer to it was initialized with data points to the body which leads to mis-interpretation of the cmd_ds_802_11_ps_mode.action member. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> --- drivers/net/wireless/libertas/cmd.c |4 ++-- drivers/net/wireless/libertas/cmdresp.c |5 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 909a587..248722a 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -957,7 +957,7 @@ static void lbs_queue_cmd(struct lbs_private *priv, /* Exit_PS command needs to be queued in the header always. */ if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { - struct cmd_ds_802_11_ps_mode *psm = (void *) >cmdbuf; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmdnode->cmdbuf; if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { if (priv->psstate != PS_STATE_FULL_POWER) @@ -1387,7 +1387,7 @@ int lbs_execute_next_command(struct lbs_private *priv) * PS command. Ignore it if it is not Exit_PS. * otherwise send it down immediately. */ - struct cmd_ds_802_11_ps_mode *psm = (void *)[1]; + struct cmd_ds_802_11_ps_mode *psm = (void *)cmd; lbs_deb_host( "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 316ac82..de99603 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -123,7 +123,10 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) priv->cmd_timed_out = 0; if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { - struct cmd_ds_802_11_ps_mode *psmode = (void *) [1]; + /* struct cmd_ds_802_11_ps_mode also contains +* the header +*/ + struct cmd_ds_802_11_ps_mode *psmode = (void *)resp; u16 action = le16_to_cpu(psmode->action); lbs_deb_host( -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Gta04-owner] [PATCH 10/13] twl4030_charger: add software controlled linear charging mode.
On Sat, 14 Nov 2015 19:12:16 +0100 Pavel Machek wrote: > Hi! > > > > > Pavel Machek writes: > > > > > On Thu 2015-07-30 10:11:24, NeilBrown wrote: > > > > >> > > > > >> Add a 'continuous' option for usb charging which enables > > > > >> the "linear" charging mode of the twl4030. > > > > >> > > > > >> Linear charging does a good job with not-so-reliable power sources. > > > > >> Auto mode does not work well as it switches off when voltage drops > > > > >> momentarily. Care must be taken not to over-charge. > > > > > > > > > > Can you explain how the user can "care not to over-charge"? > > > > > > > > The following text reads: > > > > > > > > It was used with a bike hub dynamo since a year or so. In that case > > > > there are automatically charging stops when the cyclist needs a > > > > break. > > > > > > > > so: take a break from cycling occasionally. > > > > > > If the charger does not exceed 4.2V, I'd not call it overcharge. (Yes, > > > some clever > > > chargers actually let the battery drop below 4.2V when charge is done, > > > but...) > > > > > Yes, that is the case. Perhaps it is not to be called overcharge but > > it is said that lithium battery charging has to stop if in CV mode the > > current drops too low. In automatic mode the charger does exactly > > that. > > I would not let a battery for days at 4.2V CV.mode although a lot > > of cheap chargers > > Well, I agree that keeping battery at 4.2V constant voltage mode is > bad, but I'd not call it overcharge. If someone can fix the comment, > that would be nice. > here is my original comment ("on" was replaced by continuous "now"): twl4030_charger: add software controlled linear charging mode. adds a sysfs control node to achieve that. It can be set to auto: normal automatic charging is enabled (default) off: charging is off on: charing is on (software controlled) CC/CV mode is still automatically done, but end of charge due to low current not. Note: If linear charging mode is used there should be some method of stopping charging automatically. It is not a so time-critical, but it is the wrong setting for leaving a charger connected for several days since Lithium batteries should not be kept at 100% for longer periods. Linear charging does a good job with not so reliable power sources, since several voltage controlling is then often too intelligent. It was used with a bike hub dynamo since a year or so. In that case there are automatically charging stops when the cyclist needs a break. Signed-off-by: Andreas Kemnade > > > If the charger _does_ exceed 4.2V, then the battery will explode. Don't > > > do that. Don't > > > offer that to the user. > > > > > > On a related note... I've just killed USB charger by overloading it. They > > > are not protected. > > > > > > I believe your automatically-pull-max-power really should stick to the > > > well-known charging > > > currents (.5A, 1A, 1.7A), at the very minimum. > > > > > The main reason for the patch was to prevent switching off charging > > when Vbus drops low. The reason was not to get out extremely much > > current out of the charger. > > The electrical characteristics of a bicycle as a power source are. > > - the amount of current available changes > >- 500mA at around 17km/h > > - you cannot destroy it by electrically overloading > > > > If the current is set to e.g. 500mA and that linear charging mode is > > enabled, the battery gets the maximum current available (upto > > 500mA) regardless of the speed which is often changing. > > Yes... I guess that makes sense for you, but I wonder if we should be > doing this by default. It seems a lot of cheap chargers can be easily > destroyed if you overload them. > Hmm, I guess the twl4030_charger would not be the only one destroying such chargers. I have seen such hub dynamo-friendly behaviour on every device I had connected to it before (an ipaq h2200, openmoko gta02). I have checked all usb wall plug chargers I have seen and I found none which has a lower current then 500mA. Only one has 500mA. The rest has 1A or even 2A. But I think the non-ending cv stuff is a reason enough so that it is not the default charge method. I use it only at bootup when battery is low to have some time to fix charging issues manually and when cycling. Cycling is detected by acceleration values and I get some feedback if that charge mode is enabled or disabled. Regards. Andreas Kemnade signature.asc Description: PGP signature
Re: [Gta04-owner] [PATCH 10/13] twl4030_charger: add software controlled linear charging mode.
On Sat, 14 Nov 2015 19:12:16 +0100 Pavel Machek <pa...@ucw.cz> wrote: > Hi! > > > > > Pavel Machek <pa...@ucw.cz> writes: > > > > > On Thu 2015-07-30 10:11:24, NeilBrown wrote: > > > > >> > > > > >> Add a 'continuous' option for usb charging which enables > > > > >> the "linear" charging mode of the twl4030. > > > > >> > > > > >> Linear charging does a good job with not-so-reliable power sources. > > > > >> Auto mode does not work well as it switches off when voltage drops > > > > >> momentarily. Care must be taken not to over-charge. > > > > > > > > > > Can you explain how the user can "care not to over-charge"? > > > > > > > > The following text reads: > > > > > > > > It was used with a bike hub dynamo since a year or so. In that case > > > > there are automatically charging stops when the cyclist needs a > > > > break. > > > > > > > > so: take a break from cycling occasionally. > > > > > > If the charger does not exceed 4.2V, I'd not call it overcharge. (Yes, > > > some clever > > > chargers actually let the battery drop below 4.2V when charge is done, > > > but...) > > > > > Yes, that is the case. Perhaps it is not to be called overcharge but > > it is said that lithium battery charging has to stop if in CV mode the > > current drops too low. In automatic mode the charger does exactly > > that. > > I would not let a battery for days at 4.2V CV.mode although a lot > > of cheap chargers > > Well, I agree that keeping battery at 4.2V constant voltage mode is > bad, but I'd not call it overcharge. If someone can fix the comment, > that would be nice. > here is my original comment ("on" was replaced by continuous "now"): twl4030_charger: add software controlled linear charging mode. adds a sysfs control node to achieve that. It can be set to auto: normal automatic charging is enabled (default) off: charging is off on: charing is on (software controlled) CC/CV mode is still automatically done, but end of charge due to low current not. Note: If linear charging mode is used there should be some method of stopping charging automatically. It is not a so time-critical, but it is the wrong setting for leaving a charger connected for several days since Lithium batteries should not be kept at 100% for longer periods. Linear charging does a good job with not so reliable power sources, since several voltage controlling is then often too intelligent. It was used with a bike hub dynamo since a year or so. In that case there are automatically charging stops when the cyclist needs a break. Signed-off-by: Andreas Kemnade <andr...@kemnade.info> > > > If the charger _does_ exceed 4.2V, then the battery will explode. Don't > > > do that. Don't > > > offer that to the user. > > > > > > On a related note... I've just killed USB charger by overloading it. They > > > are not protected. > > > > > > I believe your automatically-pull-max-power really should stick to the > > > well-known charging > > > currents (.5A, 1A, 1.7A), at the very minimum. > > > > > The main reason for the patch was to prevent switching off charging > > when Vbus drops low. The reason was not to get out extremely much > > current out of the charger. > > The electrical characteristics of a bicycle as a power source are. > > - the amount of current available changes > >- 500mA at around 17km/h > > - you cannot destroy it by electrically overloading > > > > If the current is set to e.g. 500mA and that linear charging mode is > > enabled, the battery gets the maximum current available (upto > > 500mA) regardless of the speed which is often changing. > > Yes... I guess that makes sense for you, but I wonder if we should be > doing this by default. It seems a lot of cheap chargers can be easily > destroyed if you overload them. > Hmm, I guess the twl4030_charger would not be the only one destroying such chargers. I have seen such hub dynamo-friendly behaviour on every device I had connected to it before (an ipaq h2200, openmoko gta02). I have checked all usb wall plug chargers I have seen and I found none which has a lower current then 500mA. Only one has 500mA. The rest has 1A or even 2A. But I think the non-ending cv stuff is a reason enough so that it is not the default charge method. I use it only at bootup when battery is low to have some time to fix charging issues manually and when cycling. Cycling is detected by acceleration values and I get some feedback if that charge mode is enabled or disabled. Regards. Andreas Kemnade signature.asc Description: PGP signature
Re: [Gta04-owner] [PATCH 10/13] twl4030_charger: add software controlled linear charging mode.
On Tue, 6 Oct 2015 16:34:07 +0200 Pavel Machek wrote: > Hi! > > > Pavel Machek writes: > > > On Thu 2015-07-30 10:11:24, NeilBrown wrote: > > >> > > >> Add a 'continuous' option for usb charging which enables > > >> the "linear" charging mode of the twl4030. > > >> > > >> Linear charging does a good job with not-so-reliable power sources. > > >> Auto mode does not work well as it switches off when voltage drops > > >> momentarily. Care must be taken not to over-charge. > > > > > > Can you explain how the user can "care not to over-charge"? > > > > The following text reads: > > > > It was used with a bike hub dynamo since a year or so. In that case > > there are automatically charging stops when the cyclist needs a break. > > > > so: take a break from cycling occasionally. > > If the charger does not exceed 4.2V, I'd not call it overcharge. (Yes, some > clever > chargers actually let the battery drop below 4.2V when charge is done, but...) > Yes, that is the case. Perhaps it is not to be called overcharge but it is said that lithium battery charging has to stop if in CV mode the current drops too low. In automatic mode the charger does exactly that. I would not let a battery for days at 4.2V CV.mode although a lot of cheap chargers > If the charger _does_ exceed 4.2V, then the battery will explode. Don't do > that. Don't > offer that to the user. > > On a related note... I've just killed USB charger by overloading it. They are > not protected. > > I believe your automatically-pull-max-power really should stick to the > well-known charging > currents (.5A, 1A, 1.7A), at the very minimum. > The main reason for the patch was to prevent switching off charging when Vbus drops low. The reason was not to get out extremely much current out of the charger. The electrical characteristics of a bicycle as a power source are. - the amount of current available changes - 500mA at around 17km/h - you cannot destroy it by electrically overloading If the current is set to e.g. 500mA and that linear charging mode is enabled, the battery gets the maximum current available (upto 500mA) regardless of the speed which is often changing. Regards, Andreas Kemnade signature.asc Description: PGP signature
Re: [Gta04-owner] [PATCH 10/13] twl4030_charger: add software controlled linear charging mode.
On Tue, 6 Oct 2015 16:34:07 +0200 Pavel Machek <pa...@ucw.cz> wrote: > Hi! > > > Pavel Machek <pa...@ucw.cz> writes: > > > On Thu 2015-07-30 10:11:24, NeilBrown wrote: > > >> > > >> Add a 'continuous' option for usb charging which enables > > >> the "linear" charging mode of the twl4030. > > >> > > >> Linear charging does a good job with not-so-reliable power sources. > > >> Auto mode does not work well as it switches off when voltage drops > > >> momentarily. Care must be taken not to over-charge. > > > > > > Can you explain how the user can "care not to over-charge"? > > > > The following text reads: > > > > It was used with a bike hub dynamo since a year or so. In that case > > there are automatically charging stops when the cyclist needs a break. > > > > so: take a break from cycling occasionally. > > If the charger does not exceed 4.2V, I'd not call it overcharge. (Yes, some > clever > chargers actually let the battery drop below 4.2V when charge is done, but...) > Yes, that is the case. Perhaps it is not to be called overcharge but it is said that lithium battery charging has to stop if in CV mode the current drops too low. In automatic mode the charger does exactly that. I would not let a battery for days at 4.2V CV.mode although a lot of cheap chargers > If the charger _does_ exceed 4.2V, then the battery will explode. Don't do > that. Don't > offer that to the user. > > On a related note... I've just killed USB charger by overloading it. They are > not protected. > > I believe your automatically-pull-max-power really should stick to the > well-known charging > currents (.5A, 1A, 1.7A), at the very minimum. > The main reason for the patch was to prevent switching off charging when Vbus drops low. The reason was not to get out extremely much current out of the charger. The electrical characteristics of a bicycle as a power source are. - the amount of current available changes - 500mA at around 17km/h - you cannot destroy it by electrically overloading If the current is set to e.g. 500mA and that linear charging mode is enabled, the battery gets the maximum current available (upto 500mA) regardless of the speed which is often changing. Regards, Andreas Kemnade signature.asc Description: PGP signature