diff options
author | Kejun ZHOU <kejun.zhou@linaro.org> | 2012-02-29 11:34:17 +0800 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-02-29 11:00:42 +0100 |
commit | 789442c999644602d7ad441424eb894f64a7a753 (patch) | |
tree | 1290aaa841cfb81cfb13b5ba1dc7fc46fc7f76a9 | |
parent | d0b78cc166e7b7f8d5c1ed609f56e74523425a80 (diff) |
For #860588 Snowball: Bluetooth Turn ON Fails.stable-android-ux500-3.1
Signed-off-by: Kejun ZHOU <kejun.zhou@linaro.org>
-rw-r--r-- | arch/arm/configs/u8500_android_defconfig | 13 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-pins.c | 2 | ||||
-rw-r--r-- | drivers/staging/cg2900/bluetooth/cg2900_uart.c | 42 | ||||
-rw-r--r-- | drivers/staging/cg2900/board-ux500-cg2900.c | 6 | ||||
-rw-r--r-- | drivers/staging/cg2900/devices-cg2900-ux500.c | 18 | ||||
-rw-r--r-- | drivers/staging/cg2900/devices-cg2900.h | 4 | ||||
-rw-r--r-- | net/rfkill/core.c | 2 | ||||
-rw-r--r-- | security/commoncap.c | 2 |
8 files changed, 58 insertions, 31 deletions
diff --git a/arch/arm/configs/u8500_android_defconfig b/arch/arm/configs/u8500_android_defconfig index 9b7fd3d6660..cc75eb7f10b 100644 --- a/arch/arm/configs/u8500_android_defconfig +++ b/arch/arm/configs/u8500_android_defconfig @@ -79,6 +79,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 @@ -120,7 +121,7 @@ CONFIG_SENSORS_BH1780=y CONFIG_STE_TRACE_MODEM=y CONFIG_DISPDEV=y CONFIG_U8500_SIM_DETECT=y -CONFIG_STM_TRACE=y +# CONFIG_STM_TRACE is not set CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_MD=y @@ -143,14 +144,8 @@ CONFIG_PPP_MPPE=y # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=y -CONFIG_KEYBOARD_STMPE=y -CONFIG_KEYBOARD_TC3589X=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_BU21013=y -CONFIG_TOUCHSCREEN_CYTTSP_CORE=y -CONFIG_TOUCHSCREEN_CYTTSP_SPI=y CONFIG_INPUT_MISC=y CONFIG_INPUT_AB8500_ACCDET=y CONFIG_INPUT_AB8500_PONKEY=y @@ -178,11 +173,12 @@ CONFIG_SENSORS_L3G4200D=y CONFIG_WATCHDOG=y CONFIG_U8500_WATCHDOG_DEBUG=y CONFIG_TPS6105X=y -CONFIG_MFD_STMPE=y +# CONFIG_MFD_STMPE is not set CONFIG_MFD_TC3589X=y CONFIG_AB5500_CORE=y CONFIG_AB8500_CORE=y CONFIG_MFD_DB8500_PRCMU=y +CONFIG_REGULATOR=y CONFIG_REGULATOR_DEBUG=y CONFIG_REGULATOR_VIRTUAL_CONSUMER=y CONFIG_REGULATOR_AB8500=y @@ -191,6 +187,7 @@ CONFIG_REGULATOR_AB8500_DEBUG=y CONFIG_MEDIA_SUPPORT=y CONFIG_VIDEO_DEV=y # CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_RADIO_CG2900=y CONFIG_USB_VIDEO_CLASS=y CONFIG_RADIO_CG2900=y CONFIG_DRM=y diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c index 276305ebb33..dfdc9acb637 100644 --- a/arch/arm/mach-ux500/board-mop500-pins.c +++ b/arch/arm/mach-ux500/board-mop500-pins.c @@ -428,7 +428,7 @@ static struct ux500_pin_lookup mop500_pins[] = { PIN_LOOKUP("nmk-i2c.1", &mop500_pins_i2c1), PIN_LOOKUP("nmk-i2c.2", &mop500_pins_i2c2), PIN_LOOKUP("nmk-i2c.3", &mop500_pins_i2c3), - PIN_LOOKUP("ske", &mop500_pins_ske), +// PIN_LOOKUP("ske", &mop500_pins_ske), PIN_LOOKUP("sdi0", &mop500_pins_sdi0), PIN_LOOKUP("sdi1", &mop500_pins_sdi1), PIN_LOOKUP("sdi2", &mop500_pins_sdi2), diff --git a/drivers/staging/cg2900/bluetooth/cg2900_uart.c b/drivers/staging/cg2900/bluetooth/cg2900_uart.c index 61194e0b25e..07030c024c7 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> @@ -272,6 +273,7 @@ struct uart_delayed_work_struct { * @rx_count: Number of bytes left to receive. * @rx_skb: SK_buffer to store the received data into. * @tx_queue: TX queue for sending data to chip. + * @rx_skb_lock Spin lock to protect rx_skb. * @hu: Hci uart structure. * @wq: UART work queue. * @baud_rate_state: UART baud rate change state. @@ -291,6 +293,7 @@ struct uart_delayed_work_struct { * @chip_dev: Chip device for current UART transport. * @cts_irq: CTS interrupt for this UART. * @cts_gpio: CTS GPIO for this UART. + * @wake_lock: Wake lock for keeping user space awake (for Android). * @suspend_blocked: True if suspend operation is blocked in the framework. * @pm_qos_latency: PM QoS structure. */ @@ -299,6 +302,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 +324,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 +451,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 +615,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); @@ -690,7 +700,7 @@ static void set_chip_sleep_mode(struct work_struct *work) switch (uart_info->sleep_state) { case CHIP_FALLING_ASLEEP: if (!is_chip_flow_off(uart_info)) { - dev_dbg(MAIN_DEV, "Chip flow is on, it's not ready to" + dev_dbg(MAIN_DEV, "Chip flow is on, it's not ready to " "sleep yet\n"); goto schedule_sleep_work; } @@ -728,6 +738,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 +1391,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 +1433,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); @@ -1448,6 +1461,22 @@ static void uart_set_chip_power(struct cg2900_chip_dev *dev, bool chip_on) * 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 +1716,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 +1823,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 +1839,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 +1900,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 +2014,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 +2025,7 @@ 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); pm_qos_add_request(&uart_info->pm_qos_latency, PM_QOS_CPU_DMA_LATENCY, PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE); @@ -2087,6 +2126,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/drivers/staging/cg2900/board-ux500-cg2900.c b/drivers/staging/cg2900/board-ux500-cg2900.c index 2376c5dc078..dbc34cba582 100644 --- a/drivers/staging/cg2900/board-ux500-cg2900.c +++ b/drivers/staging/cg2900/board-ux500-cg2900.c @@ -175,6 +175,12 @@ static struct resource cg2900_uart_resources_snowball[] = { .name = "pmu_en", }, { + .start = CG2900_BT_ENABLE_GPIO, + .end = CG2900_BT_ENABLE_GPIO, + .flags = IORESOURCE_IO, + .name = "bt_enable", + }, + { .start = CG2900_UX500_BT_CTS_GPIO, .end = CG2900_UX500_BT_CTS_GPIO, .flags = IORESOURCE_IO, diff --git a/drivers/staging/cg2900/devices-cg2900-ux500.c b/drivers/staging/cg2900/devices-cg2900-ux500.c index 7e7c12ce4a0..5a5734671cb 100644 --- a/drivers/staging/cg2900/devices-cg2900-ux500.c +++ b/drivers/staging/cg2900/devices-cg2900-ux500.c @@ -37,16 +37,10 @@ void dcg2900_u8500_enable_chip(struct cg2900_chip_dev *dev) return; /* - * Due to a bug in CG2900 we cannot just set GPIO high to enable - * the chip. We must wait more than 100 msecs before enabling the - * chip. - * - Set PDB to low. - * - Wait for 100 msecs + * - SET PMU_EN to high + * - Wait for 300usec * - Set PDB to high. */ - gpio_set_value(info->gbf_gpio, 0); - schedule_timeout_uninterruptible(msecs_to_jiffies( - CHIP_ENABLE_PDB_LOW_TIMEOUT)); if (info->pmuen_gpio != -1) { /* @@ -186,16 +180,8 @@ void dcg2900_u5500_enable_chip(struct cg2900_chip_dev *dev) clk_enable(info->lpoclk); /* - * Due to a bug in CG2900 we cannot just set GPIO high to enable - * the chip. We must wait more than 100 msecs before enbling the - * chip. - * - Set PDB to low. - * - Wait for 100 msecs * - Set PDB to high. */ - prcmu_resetout(1, 0); - schedule_timeout_uninterruptible(msecs_to_jiffies( - CHIP_ENABLE_PDB_LOW_TIMEOUT)); prcmu_resetout(1, 1); } diff --git a/drivers/staging/cg2900/devices-cg2900.h b/drivers/staging/cg2900/devices-cg2900.h index 8781e00eaec..5ca95e1e0a1 100644 --- a/drivers/staging/cg2900/devices-cg2900.h +++ b/drivers/staging/cg2900/devices-cg2900.h @@ -37,10 +37,6 @@ extern void dcg2900_u5500_enable_chip(struct cg2900_chip_dev *dev); extern void dcg2900_u5500_disable_chip(struct cg2900_chip_dev *dev); extern int dcg2900_u5500_setup(struct cg2900_chip_dev *dev, struct dcg2900_info *info); -extern void dcg2900_u5500_enable_chip(struct cg2900_chip_dev *dev); -extern void dcg2900_u5500_disable_chip(struct cg2900_chip_dev *dev); -extern int dcg2900_u5500_setup(struct cg2900_chip_dev *dev, - struct dcg2900_info *info); /** * enum cg2900_gpio_pull_sleep - GPIO pull setting in sleep. diff --git a/net/rfkill/core.c b/net/rfkill/core.c index df2dae6b272..c953d96564d 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -722,7 +722,7 @@ static struct device_attribute rfkill_dev_attrs[] = { __ATTR(type, S_IRUGO, rfkill_type_show, NULL), __ATTR(index, S_IRUGO, rfkill_idx_show, NULL), __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL), - __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), + __ATTR(state, S_IRUGO|S_IWUGO/*S_IWUSR*/, rfkill_state_show, rfkill_state_store), __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), __ATTR(soft, S_IRUGO|S_IWUSR, rfkill_soft_show, rfkill_soft_store), __ATTR(hard, S_IRUGO, rfkill_hard_show, NULL), diff --git a/security/commoncap.c b/security/commoncap.c index 1322b6aa648..da21e7c93e4 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -87,10 +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. */ |