summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKejun ZHOU <kejun.zhou@linaro.org>2012-01-20 15:09:16 +0800
committerMathieu J. Poirier <mathieu.poirier@linaro.org>2012-01-20 12:25:41 -0700
commit7a9c9268c1f3e77a5eb6873b707c6d1482e30a58 (patch)
tree58fd0414ec2c477e9f5a661b5019193f8dd605e5
parentaf0a6e7d277ab4e10b92326d38af571018283261 (diff)
snowball: android: Fixing various issue with BT on Snowball
- Fixing kernel configs. - Adding wakelock management Signed-off-by: Kejun ZHOU <kejun.zhou@linaro.org> Committer: Mathieu Poirier <mathieu.poirier@linaro.org>
-rw-r--r--arch/arm/configs/u8500_android_defconfig6
-rw-r--r--drivers/staging/cg2900/bluetooth/cg2900_uart.c48
-rw-r--r--net/bluetooth/hci_core.c1
-rw-r--r--security/commoncap.c3
4 files changed, 47 insertions, 11 deletions
diff --git a/arch/arm/configs/u8500_android_defconfig b/arch/arm/configs/u8500_android_defconfig
index 7fe91e5e440..53f5d10cfc2 100644
--- a/arch/arm/configs/u8500_android_defconfig
+++ b/arch/arm/configs/u8500_android_defconfig
@@ -80,6 +80,7 @@ CONFIG_IPV6=y
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
# CONFIG_INET6_XFRM_MODE_BEET is not set
# CONFIG_IPV6_SIT is not set
+# CONFIG_ANDROID_PARANOID_NETWORK is not set
CONFIG_NETFILTER=y
CONFIG_NETFILTER_NETLINK_QUEUE=y
CONFIG_NETFILTER_NETLINK_LOG=y
@@ -103,11 +104,16 @@ CONFIG_BT_BNEP=y
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
CONFIG_CFG80211=y
CONFIG_NL80211_TESTMODE=y
CONFIG_CFG80211_REG_DEBUG=y
CONFIG_RFKILL=y
+CONFIG_RFKILL_PM=y
+CONFIG_RFKILL_LEDS=y
CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_REGULATOR=y
+CONFIG_RFKILL_GPIO=y
CONFIG_NET_9P=y
CONFIG_CAIF=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
diff --git a/drivers/staging/cg2900/bluetooth/cg2900_uart.c b/drivers/staging/cg2900/bluetooth/cg2900_uart.c
index 61194e0b25e..dfe94efdb28 100644
--- a/drivers/staging/cg2900/bluetooth/cg2900_uart.c
+++ b/drivers/staging/cg2900/bluetooth/cg2900_uart.c
@@ -33,6 +33,7 @@
#include <linux/tty.h>
#include <linux/tty_ldisc.h>
#include <linux/types.h>
+#include <linux/wakelock.h>
#include <linux/workqueue.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci.h>
@@ -299,6 +300,7 @@ struct uart_info {
unsigned long rx_count;
struct sk_buff *rx_skb;
struct sk_buff_head tx_queue;
+ spinlock_t rx_skb_lock;
struct hci_uart *hu;
@@ -320,6 +322,7 @@ struct uart_info {
struct cg2900_chip_dev chip_dev;
int cts_irq;
int cts_gpio;
+ struct wake_lock wake_lock;
bool suspend_blocked;
struct pm_qos_request_list pm_qos_latency;
};
@@ -446,6 +449,10 @@ static irqreturn_t cts_interrupt(int irq, void *dev_id)
disable_irq_wake(irq);
#endif
disable_irq_nosync(irq);
+ if (!uart_info->suspend_blocked) {
+ wake_lock(&uart_info->wake_lock);
+ uart_info->suspend_blocked = true;
+ }
/* Create work and leave IRQ context. */
(void)create_work_item(uart_info, handle_cts_irq);
@@ -606,6 +613,7 @@ static void wake_up_chip(struct uart_info *uart_info)
goto finished;
if (!uart_info->suspend_blocked) {
+ wake_lock(&uart_info->wake_lock);
uart_info->suspend_blocked = true;
pm_qos_update_request(&uart_info->pm_qos_latency,
CG2900_PM_QOS_LATENCY);
@@ -728,6 +736,7 @@ static void set_chip_sleep_mode(struct work_struct *work)
dev_dbg(MAIN_DEV, "New sleep_state: CHIP_ASLEEP\n");
uart_info->sleep_state = CHIP_ASLEEP;
if (uart_info->suspend_blocked) {
+ wake_unlock(&uart_info->wake_lock);
uart_info->suspend_blocked = false;
pm_qos_update_request(&uart_info->pm_qos_latency,
PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE);
@@ -1380,6 +1389,7 @@ static void uart_set_chip_power(struct cg2900_chip_dev *dev, bool chip_on)
if (chip_on) {
if (!uart_info->suspend_blocked) {
+ wake_lock(&uart_info->wake_lock);
uart_info->suspend_blocked = true;
pm_qos_update_request(&uart_info->pm_qos_latency,
CG2900_PM_QOS_LATENCY);
@@ -1421,6 +1431,7 @@ static void uart_set_chip_power(struct cg2900_chip_dev *dev, bool chip_on)
}
if (uart_info->suspend_blocked) {
+ wake_unlock(&uart_info->wake_lock);
uart_info->suspend_blocked = false;
pm_qos_update_request(&uart_info->pm_qos_latency,
PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE);
@@ -1433,21 +1444,28 @@ static void uart_set_chip_power(struct cg2900_chip_dev *dev, bool chip_on)
uart_info->sleep_state = CHIP_POWERED_DOWN;
}
- /*
- * Reset the uart_info state so that
- * next packet can be handled
- * correctly by driver.
- */
- uart_info->rx_state = W4_PACKET_TYPE;
- uart_info->rx_count = 0;
- kfree_skb(uart_info->rx_skb);
- uart_info->rx_skb = NULL;
cg2900_disable_regulator(uart_info);
/*
* Setting baud rate to 0 will tell UART driver to shut off its
* clocks.
*/
(void)hci_uart_set_baudrate(uart_info->hu, ZERO_BAUD_RATE);
+
+ spin_lock_bh(&uart_info->rx_skb_lock);
+ if (uart_info->rx_skb) {
+ /*
+ * Reset the uart_info state so that
+ * next packet can be handled
+ * correctly by driver.
+ */
+ dev_dbg(MAIN_DEV, "Power off in the middle of data receiving?"
+ "Reseting state machine.\n");
+ kfree_skb(uart_info->rx_skb);
+ uart_info->rx_skb = NULL;
+ uart_info->rx_state = W4_PACKET_TYPE;
+ uart_info->rx_count = 0;
+ }
+ spin_unlock_bh(&uart_info->rx_skb_lock);
}
unlock:
@@ -1687,6 +1705,8 @@ static int cg2900_hu_receive(struct hci_uart *hu,
print_hex_dump_bytes(NAME " RX:\t", DUMP_PREFIX_NONE,
data, count);
+ spin_lock_bh(&uart_info->rx_skb_lock);
+
/* Continue while there is data left to handle */
while (count) {
/*
@@ -1792,6 +1812,8 @@ check_h4_header:
spin_lock_bh(&(uart_info->transmission_lock));
uart_info->rx_in_progress = false;
spin_unlock_bh(&(uart_info->transmission_lock));
+
+ spin_unlock_bh(&uart_info->rx_skb_lock);
return 0;
}
@@ -1806,6 +1828,7 @@ check_h4_header:
(void)queue_work(uart_info->wq, &uart_info->restart_sleep_work.work);
+ spin_unlock_bh(&uart_info->rx_skb_lock);
return count;
}
@@ -1866,10 +1889,13 @@ static int cg2900_hu_close(struct hci_uart *hu)
/* Purge any stored sk_buffers */
skb_queue_purge(&uart_info->tx_queue);
+
+ spin_lock_bh(&uart_info->rx_skb_lock);
if (uart_info->rx_skb) {
kfree_skb(uart_info->rx_skb);
uart_info->rx_skb = NULL;
}
+ spin_unlock_bh(&uart_info->rx_skb_lock);
dev_info(MAIN_DEV, "UART closed\n");
err = create_work_item(uart_info, work_hw_deregistered);
@@ -1977,6 +2003,7 @@ static int __devinit cg2900_uart_probe(struct platform_device *pdev)
mutex_init(&(uart_info->sleep_state_lock));
spin_lock_init(&(uart_info->transmission_lock));
+ spin_lock_init(&(uart_info->rx_skb_lock));
uart_info->chip_dev.t_cb.open = uart_open;
uart_info->chip_dev.t_cb.close = uart_close;
@@ -1987,6 +2014,8 @@ static int __devinit cg2900_uart_probe(struct platform_device *pdev)
uart_info->chip_dev.pdev = pdev;
uart_info->chip_dev.dev = &pdev->dev;
uart_info->chip_dev.t_data = uart_info;
+ wake_lock_init(&uart_info->wake_lock, WAKE_LOCK_SUSPEND, NAME);
+ uart_info->suspend_blocked = false;
pm_qos_add_request(&uart_info->pm_qos_latency, PM_QOS_CPU_DMA_LATENCY,
PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE);
@@ -2087,6 +2116,7 @@ static int __devexit cg2900_uart_remove(struct platform_device *pdev)
hci_uart_unregister_proto(uart_info->hu->proto);
pm_qos_remove_request(&uart_info->pm_qos_latency);
+ wake_lock_destroy(&uart_info->wake_lock);
destroy_workqueue(uart_info->wq);
dev_info(MAIN_DEV, "CG2900 UART removed\n");
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 56943add45c..6b5a51f2b74 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -23,7 +23,6 @@
*/
/* Bluetooth HCI core. */
-
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/kmod.h>
diff --git a/security/commoncap.c b/security/commoncap.c
index 1322b6aa648..e508e2b170a 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -87,11 +87,12 @@ EXPORT_SYMBOL(cap_netlink_recv);
int cap_capable(struct task_struct *tsk, const struct cred *cred,
struct user_namespace *targ_ns, int cap, int audit)
{
+#ifdef CONFIG_ANDROID_PARANOID_NETWORK
if (cap == CAP_NET_RAW && in_egroup_p(AID_NET_RAW))
return 0;
if (cap == CAP_NET_ADMIN && in_egroup_p(AID_NET_ADMIN))
return 0;
-
+#endif
for (;;) {
/* The creator of the user namespace has all caps. */
if (targ_ns != &init_user_ns && targ_ns->creator == cred->user)