summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKejun ZHOU <kejun.zhou@linaro.org>2012-02-29 11:34:17 +0800
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-02-29 11:00:42 +0100
commit789442c999644602d7ad441424eb894f64a7a753 (patch)
tree1290aaa841cfb81cfb13b5ba1dc7fc46fc7f76a9
parentd0b78cc166e7b7f8d5c1ed609f56e74523425a80 (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_defconfig13
-rw-r--r--arch/arm/mach-ux500/board-mop500-pins.c2
-rw-r--r--drivers/staging/cg2900/bluetooth/cg2900_uart.c42
-rw-r--r--drivers/staging/cg2900/board-ux500-cg2900.c6
-rw-r--r--drivers/staging/cg2900/devices-cg2900-ux500.c18
-rw-r--r--drivers/staging/cg2900/devices-cg2900.h4
-rw-r--r--net/rfkill/core.c2
-rw-r--r--security/commoncap.c2
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. */