From 7a9c9268c1f3e77a5eb6873b707c6d1482e30a58 Mon Sep 17 00:00:00 2001 From: Kejun ZHOU Date: Fri, 20 Jan 2012 15:09:16 +0800 Subject: snowball: android: Fixing various issue with BT on Snowball - Fixing kernel configs. - Adding wakelock management Signed-off-by: Kejun ZHOU Committer: Mathieu Poirier --- arch/arm/configs/u8500_android_defconfig | 6 ++++ drivers/staging/cg2900/bluetooth/cg2900_uart.c | 48 +++++++++++++++++++++----- net/bluetooth/hci_core.c | 1 - security/commoncap.c | 3 +- 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 #include #include +#include #include #include #include @@ -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 #include #include 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) -- cgit v1.2.3