diff options
author | KalimochoAz <calimochoazucarado@gmail.com> | 2012-04-01 20:09:04 +0200 |
---|---|---|
committer | KalimochoAz <calimochoazucarado@gmail.com> | 2012-04-01 20:09:04 +0200 |
commit | 910d38a37b414ee4af1199071667b2ac19a4151e (patch) | |
tree | 91138a9a0239df0910a5581caf0926b1d2ccb81c | |
parent | 96b165e5470cb58e747c257dadc44e427274fa83 (diff) | |
parent | 665612374970f5dba43b65510b52b72130818541 (diff) | |
download | kernel_samsung_crespo-910d38a37b414ee4af1199071667b2ac19a4151e.zip kernel_samsung_crespo-910d38a37b414ee4af1199071667b2ac19a4151e.tar.gz kernel_samsung_crespo-910d38a37b414ee4af1199071667b2ac19a4151e.tar.bz2 |
Merge branch 'ics.googleupdate.4.0.4' into cm.ics
Conflicts:
fs/proc/base.c
35 files changed, 463 insertions, 201 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 81c137d..e5cfa6a 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -223,8 +223,8 @@ void cpu_idle(void) /* endless idle loop with no priority at all */ while (1) { - tick_nohz_stop_sched_tick(1); idle_notifier_call_chain(IDLE_START); + tick_nohz_stop_sched_tick(1); while (!need_resched()) { #ifdef CONFIG_HOTPLUG_CPU if (cpu_is_offline(smp_processor_id())) diff --git a/arch/arm/mach-s5pv210/dev-herring-phone.c b/arch/arm/mach-s5pv210/dev-herring-phone.c index f8798b3..b605e02 100755 --- a/arch/arm/mach-s5pv210/dev-herring-phone.c +++ b/arch/arm/mach-s5pv210/dev-herring-phone.c @@ -31,6 +31,7 @@ static struct modemctl_data mdmctl_data = { .gpio_cp_reset = GPIO_CP_RST, .gpio_phone_on = GPIO_PHONE_ON, .is_cdma_modem = 0, + .num_pdp_contexts = 3, }; static struct resource mdmctl_res[] = { @@ -67,8 +68,10 @@ static struct platform_device modemctl = { static int __init herring_init_phone_interface(void) { /* CDMA device */ - if (herring_is_cdma_wimax_dev()) + if (herring_is_cdma_wimax_dev()) { mdmctl_data.is_cdma_modem = 1; + mdmctl_data.num_pdp_contexts = 1; + } platform_device_register(&modemctl); return 0; diff --git a/arch/arm/mach-s5pv210/mach-herring.c b/arch/arm/mach-s5pv210/mach-herring.c index 88ef01a..7efb07c 100755 --- a/arch/arm/mach-s5pv210/mach-herring.c +++ b/arch/arm/mach-s5pv210/mach-herring.c @@ -4790,8 +4790,8 @@ static unsigned int herring_cdma_wimax_sleep_gpio_table[][3] = { { S5PV210_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /*WIMAX EEPROM I2C LINES*/ - { S5PV210_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, - { S5PV210_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, + { S5PV210_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, + { S5PV210_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /*WIMAX DBGEN*/ { S5PV210_GPD0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, @@ -4800,7 +4800,7 @@ static unsigned int herring_cdma_wimax_sleep_gpio_table[][3] = { { S5PV210_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /*WIMAX RESET_N*/ - { S5PV210_GPD0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, + { S5PV210_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, { S5PV210_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, { S5PV210_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, @@ -4862,20 +4862,20 @@ static unsigned int herring_cdma_wimax_sleep_gpio_table[][3] = { { S5PV210_GPG0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, - { S5PV210_GPG0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, + { S5PV210_GPG0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, { S5PV210_GPG0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, - { S5PV210_GPG0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, - { S5PV210_GPG0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, - { S5PV210_GPG0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, - { S5PV210_GPG0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, + { S5PV210_GPG0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, + { S5PV210_GPG0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, + { S5PV210_GPG0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, + { S5PV210_GPG0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, { S5PV210_GPG1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, { S5PV210_GPG1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, { S5PV210_GPG1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, - { S5PV210_GPG1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, - { S5PV210_GPG1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, - { S5PV210_GPG1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, - { S5PV210_GPG1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, + { S5PV210_GPG1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, + { S5PV210_GPG1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, + { S5PV210_GPG1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, + { S5PV210_GPG1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /*wimax SDIO pins*/ { S5PV210_GPG2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, @@ -4931,11 +4931,11 @@ static unsigned int herring_cdma_wimax_sleep_gpio_table[][3] = { { S5PV210_GPJ2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, { S5PV210_GPJ2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, { S5PV210_GPJ2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, - { S5PV210_GPJ2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN}, + { S5PV210_GPJ2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, { S5PV210_GPJ2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, { S5PV210_GPJ2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, - { S5PV210_GPJ2(7), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, + { S5PV210_GPJ2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, { S5PV210_GPJ3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, { S5PV210_GPJ3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, @@ -5363,11 +5363,82 @@ int __init herring_init_wifi_mem(void) return -ENOMEM; } + +/* Customized Locale table : OPTIONAL feature */ +#define WLC_CNTRY_BUF_SZ 4 +typedef struct cntry_locales_custom { + char iso_abbrev[WLC_CNTRY_BUF_SZ]; + char custom_locale[WLC_CNTRY_BUF_SZ]; + int custom_locale_rev; +} cntry_locales_custom_t; + +static cntry_locales_custom_t herring_wlan_translate_custom_table[] = { +/* Table should be filled out based on custom platform regulatory requirement */ + {"", "XY", 4}, /* universal */ + {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */ + {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */ + {"EU", "EU", 5}, /* European union countries */ + {"AT", "EU", 5}, + {"BE", "EU", 5}, + {"BG", "EU", 5}, + {"CY", "EU", 5}, + {"CZ", "EU", 5}, + {"DK", "EU", 5}, + {"EE", "EU", 5}, + {"FI", "EU", 5}, + {"FR", "EU", 5}, + {"DE", "EU", 5}, + {"GR", "EU", 5}, + {"HU", "EU", 5}, + {"IE", "EU", 5}, + {"IT", "EU", 5}, + {"LV", "EU", 5}, + {"LI", "EU", 5}, + {"LT", "EU", 5}, + {"LU", "EU", 5}, + {"MT", "EU", 5}, + {"NL", "EU", 5}, + {"PL", "EU", 5}, + {"PT", "EU", 5}, + {"RO", "EU", 5}, + {"SK", "EU", 5}, + {"SI", "EU", 5}, + {"ES", "EU", 5}, + {"SE", "EU", 5}, + {"GB", "EU", 5}, /* input ISO "GB" to : EU regrev 05 */ + {"IL", "IL", 0}, + {"CH", "CH", 0}, + {"TR", "TR", 0}, + {"NO", "NO", 0}, + {"KR", "XY", 3}, + {"AU", "XY", 3}, + {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */ + {"TW", "XY", 3}, + {"AR", "XY", 3}, + {"MX", "XY", 3} +}; + +static void *herring_wlan_get_country_code(char *ccode) +{ + int size = ARRAY_SIZE(herring_wlan_translate_custom_table); + int i; + + if (!ccode) + return NULL; + + for (i = 0; i < size; i++) + if (strcmp(ccode, herring_wlan_translate_custom_table[i].iso_abbrev) == 0) + return &herring_wlan_translate_custom_table[i]; + return &herring_wlan_translate_custom_table[0]; +} + + static struct wifi_platform_data wifi_pdata = { .set_power = wlan_power_en, .set_reset = wlan_reset_en, .set_carddetect = wlan_carddetect_en, .mem_prealloc = herring_mem_prealloc, + .get_country_code = herring_wlan_get_country_code, }; static struct platform_device sec_device_wifi = { @@ -5926,9 +5997,8 @@ void otg_phy_init(void) writel(readl(S3C_USBOTG_PHYTUNE) | (0x1<<20), S3C_USBOTG_PHYTUNE); - /* set DC level as 6 (6%) */ - writel((readl(S3C_USBOTG_PHYTUNE) & ~(0xf)) | (0x1<<2) | (0x1<<1), - S3C_USBOTG_PHYTUNE); + /* set DC level as 0xf (24%) */ + writel(readl(S3C_USBOTG_PHYTUNE) | 0xf, S3C_USBOTG_PHYTUNE); } EXPORT_SYMBOL(otg_phy_init); diff --git a/arch/arm/mach-s5pv210/power-domain.c b/arch/arm/mach-s5pv210/power-domain.c index 3383878..59a1a98 100644 --- a/arch/arm/mach-s5pv210/power-domain.c +++ b/arch/arm/mach-s5pv210/power-domain.c @@ -38,6 +38,7 @@ struct clk_should_be_running { const char *clk_name; struct device *dev; }; +static spinlock_t pd_lock; static struct regulator_consumer_supply s5pv210_pd_audio_supply[] = { REGULATOR_SUPPLY("pd", "samsung-i2s.0"), @@ -332,18 +333,25 @@ static int s5pv210_pd_pwr_off(int ctrl) static int s5pv210_pd_ctrl(int ctrlbit, int enable) { - u32 pd_reg = __raw_readl(S5P_NORMAL_CFG); + u32 pd_reg; + spin_lock(&pd_lock); + pd_reg = __raw_readl(S5P_NORMAL_CFG); if (enable) { __raw_writel((pd_reg | ctrlbit), S5P_NORMAL_CFG); if (s5pv210_pd_pwr_done(ctrlbit)) - return -ETIME; + goto out; } else { __raw_writel((pd_reg & ~(ctrlbit)), S5P_NORMAL_CFG); if (s5pv210_pd_pwr_off(ctrlbit)) - return -ETIME; + goto out; } + spin_unlock(&pd_lock); return 0; +out: + spin_unlock(&pd_lock); + return -ETIME; + } static int s5pv210_pd_clk_enable(struct clk_should_be_running *clk_run) @@ -497,6 +505,7 @@ static int __devinit reg_s5pv210_pd_probe(struct platform_device *pdev) drvdata->clk_run = config->clk_run; drvdata->ctrlbit = config->ctrlbit; + spin_lock_init(&pd_lock); drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, config->init_data, drvdata); diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index ca6b8e2..8098f82 100755 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c @@ -30,6 +30,7 @@ #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/delay.h> /* FSA9480 I2C registers */ #define FSA9480_REG_DEVID 0x01 @@ -397,18 +398,40 @@ static irqreturn_t fsa9480_irq_thread(int irq, void *data) struct fsa9480_usbsw *usbsw = data; struct i2c_client *client = usbsw->client; int intr; - - /* read and clear interrupt status bits */ - intr = i2c_smbus_read_word_data(client, FSA9480_REG_INT1); - if (intr < 0) { - dev_err(&client->dev, "%s: err %d\n", __func__, intr); - } else if (intr == 0) { - /* interrupt was fired, but no status bits were set, - so device was reset. In this case, the registers were - reset to defaults so they need to be reinitialised. */ + int max_events = 100; + int events_seen = 0; + + /* + * the fsa could have queued up a few events if we haven't processed + * them promptly + */ + while (max_events-- > 0) { + intr = i2c_smbus_read_word_data(client, FSA9480_REG_INT1); + if (intr < 0) + dev_err(&client->dev, "%s: err %d\n", __func__, intr); + else if (intr == 0) + break; + else if (intr > 0) + events_seen++; + } + if (!max_events) + dev_warn(&client->dev, "too many events. fsa hosed?\n"); + + if (!events_seen) { + /* + * interrupt was fired, but no status bits were set, + * so device was reset. In this case, the registers were + * reset to defaults so they need to be reinitialised. + */ fsa9480_reg_init(usbsw); } + /* + * fsa may take some time to update the dev_type reg after reading + * the int reg. + */ + usleep_range(200, 300); + /* device detection */ fsa9480_detect_dev(usbsw); @@ -422,7 +445,7 @@ static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw) if (client->irq) { ret = request_threaded_irq(client->irq, NULL, - fsa9480_irq_thread, IRQF_TRIGGER_FALLING, + fsa9480_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "fsa9480 micro USB", usbsw); if (ret) { dev_err(&client->dev, "failed to reqeust IRQ\n"); diff --git a/drivers/misc/samsung_modemctl/modem_ctl.c b/drivers/misc/samsung_modemctl/modem_ctl.c index e7504fd..f99f17c 100755 --- a/drivers/misc/samsung_modemctl/modem_ctl.c +++ b/drivers/misc/samsung_modemctl/modem_ctl.c @@ -1092,6 +1092,10 @@ static int __devinit modemctl_probe(struct platform_device *pdev) mc->gpio_cp_reset = pdata->gpio_cp_reset; mc->gpio_phone_on = pdata->gpio_phone_on; mc->is_cdma_modem = pdata->is_cdma_modem; + if (pdata->num_pdp_contexts) + mc->num_pdp_contexts = pdata->num_pdp_contexts; + else + mc->num_pdp_contexts = 1; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) diff --git a/drivers/misc/samsung_modemctl/modem_ctl.h b/drivers/misc/samsung_modemctl/modem_ctl.h index 7c23165..b4ad920 100644 --- a/drivers/misc/samsung_modemctl/modem_ctl.h +++ b/drivers/misc/samsung_modemctl/modem_ctl.h @@ -39,6 +39,7 @@ struct modemctl_data { unsigned gpio_cp_reset; unsigned gpio_phone_on; bool is_cdma_modem; /* 1:CDMA Modem */ + int num_pdp_contexts; }; #endif diff --git a/drivers/misc/samsung_modemctl/modem_ctl_p.h b/drivers/misc/samsung_modemctl/modem_ctl_p.h index 3de2231..6223b20 100644 --- a/drivers/misc/samsung_modemctl/modem_ctl_p.h +++ b/drivers/misc/samsung_modemctl/modem_ctl_p.h @@ -121,7 +121,7 @@ struct modemctl { struct wake_lock ip_tx_wakelock; struct wake_lock ip_rx_wakelock; - struct net_device *ndev; + struct net_device **ndev; int open_count; int status; @@ -137,6 +137,7 @@ struct modemctl { unsigned gpio_cp_reset; unsigned gpio_phone_on; bool is_cdma_modem; + int num_pdp_contexts; bool is_modem_delta_update; unsigned dpram_prev_phone_active; unsigned dpram_prev_status; diff --git a/drivers/misc/samsung_modemctl/modem_io.c b/drivers/misc/samsung_modemctl/modem_io.c index fe50da6..5c815ef 100644 --- a/drivers/misc/samsung_modemctl/modem_io.c +++ b/drivers/misc/samsung_modemctl/modem_io.c @@ -40,7 +40,8 @@ #include "modem_ctl_p.h" #define RAW_CH_VNET0 10 - +#define CHANNEL_TO_NETDEV_ID(id) (id - RAW_CH_VNET0) +#define NETDEV_TO_CHANNEL_ID(id) (id + RAW_CH_VNET0) /* general purpose fifo access routines */ @@ -309,6 +310,7 @@ struct raw_hdr { struct vnet { struct modemctl *mc; struct sk_buff_head txq; + int rmnet_ch_id; }; static void handle_raw_rx(struct modemctl *mc) @@ -319,17 +321,19 @@ static void handle_raw_rx(struct modemctl *mc) /* process inbound packets */ while (fifo_read(&mc->raw_rx, &raw, sizeof(raw)) == sizeof(raw)) { - struct net_device *dev = mc->ndev; + struct net_device *dev; unsigned sz = raw.len - (sizeof(raw) - 1); - if (unlikely(raw.channel != RAW_CH_VNET0)) { + if (unlikely(!(raw.channel >= RAW_CH_VNET0 && raw.channel < + NETDEV_TO_CHANNEL_ID(mc->num_pdp_contexts)))) { + MODEM_COUNT(mc, rx_unknown); pr_err("[VNET] unknown channel %d\n", raw.channel); if (fifo_skip(&mc->raw_rx, sz + 1) != (sz + 1)) goto purge_raw_fifo; continue; } - + dev = mc->ndev[CHANNEL_TO_NETDEV_ID(raw.channel)]; skb = dev_alloc_skb(sz + NET_IP_ALIGN); if (skb == NULL) { MODEM_COUNT(mc, rx_dropped); @@ -379,6 +383,9 @@ int handle_raw_tx(struct modemctl *mc, struct sk_buff *skb) struct raw_hdr raw; unsigned char ftr = 0x7e; unsigned sz; + int netdev_id; + struct vnet *vn = netdev_priv(skb->dev); + sz = skb->len + sizeof(raw) + 1; @@ -389,15 +396,16 @@ int handle_raw_tx(struct modemctl *mc, struct sk_buff *skb) raw.start = 0x7f; raw.len = 6 + skb->len; - raw.channel = RAW_CH_VNET0; + raw.channel = vn->rmnet_ch_id; raw.control = 0; fifo_write(&mc->raw_tx, &raw, sizeof(raw)); fifo_write(&mc->raw_tx, skb->data, skb->len); fifo_write(&mc->raw_tx, &ftr, 1); - mc->ndev->stats.tx_packets++; - mc->ndev->stats.tx_bytes += skb->len; + netdev_id = CHANNEL_TO_NETDEV_ID(vn->rmnet_ch_id); + mc->ndev[netdev_id]->stats.tx_packets++; + mc->ndev[netdev_id]->stats.tx_bytes += skb->len; mc->mmio_signal_bits |= MBD_SEND_RAW; @@ -408,17 +416,24 @@ int handle_raw_tx(struct modemctl *mc, struct sk_buff *skb) void modem_handle_io(struct modemctl *mc) { struct sk_buff *skb; - struct vnet *vn = netdev_priv(mc->ndev); + struct vnet *vn; + int i; + int cnt = 0; handle_raw_rx(mc); - while ((skb = skb_dequeue(&vn->txq))) - if (handle_raw_tx(mc, skb)) { - skb_queue_head(&vn->txq, skb); - break; - } - if (skb == NULL) - wake_unlock(&vn->mc->ip_tx_wakelock); + for (i = 0; i < mc->num_pdp_contexts; i++) { + vn = netdev_priv(mc->ndev[i]); + while ((skb = skb_dequeue(&vn->txq))) + if (handle_raw_tx(mc, skb)) { + skb_queue_head(&vn->txq, skb); + break; + } + if (skb == NULL) + cnt++; + } + if (cnt == mc->num_pdp_contexts) + wake_unlock(&mc->ip_tx_wakelock); } static int vnet_open(struct net_device *ndev) @@ -639,9 +654,10 @@ static int modem_pipe_register(struct m_pipe *pipe, const char *devname) int modem_io_init(struct modemctl *mc, void __iomem *mmio) { - struct net_device *ndev; struct vnet *vn; int r; + int i; + int ch_id; INIT_M_FIFO(mc->fmt_tx, FMT, TX, mmio); INIT_M_FIFO(mc->fmt_rx, FMT, RX, mmio); @@ -650,16 +666,30 @@ int modem_io_init(struct modemctl *mc, void __iomem *mmio) INIT_M_FIFO(mc->rfs_tx, RFS, TX, mmio); INIT_M_FIFO(mc->rfs_rx, RFS, RX, mmio); - ndev = alloc_netdev(0, "rmnet%d", vnet_setup); - if (ndev) { - vn = netdev_priv(ndev); - vn->mc = mc; - skb_queue_head_init(&vn->txq); - r = register_netdev(ndev); - if (r) - free_netdev(ndev); - else - mc->ndev = ndev; + mc->ndev = kmalloc(sizeof(struct net_device *) * mc->num_pdp_contexts, + GFP_KERNEL); + if (!mc->ndev) { + pr_err("memory allocation failed for netdev\n"); + return -ENOMEM; + } + for (i = 0, ch_id = RAW_CH_VNET0; i < mc->num_pdp_contexts; + i++, ch_id++) { + mc->ndev[i] = alloc_netdev(0, "rmnet%d", vnet_setup); + if (mc->ndev[i]) { + vn = netdev_priv(mc->ndev[i]); + vn->mc = mc; + vn->rmnet_ch_id = ch_id; + skb_queue_head_init(&vn->txq); + r = register_netdev(mc->ndev[i]); + if (r) { + free_netdev(mc->ndev[i]); + pr_err("failed to register rmnet%d\n", i); + goto free; + } + } else { + pr_err("failed to alloc rmnet%d\n", i); + goto free; + } } mc->cmd_pipe.tx = &mc->fmt_tx; @@ -683,4 +713,12 @@ int modem_io_init(struct modemctl *mc, void __iomem *mmio) pr_err("failed to register modem_rfs pipe\n"); return 0; + +free: + /* Unregister and free any alloced netdevs */ + while (--i >= 0) { + unregister_netdev(mc->ndev[i]); + free_netdev(mc->ndev[i]); + } + return -ENOMEM; } diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 393d817..e07d6c9 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -120,18 +120,19 @@ static int mmc_bus_remove(struct device *dev) return 0; } -static int mmc_bus_suspend(struct device *dev, pm_message_t state) +static int mmc_bus_pm_suspend(struct device *dev) { struct mmc_driver *drv = to_mmc_driver(dev->driver); struct mmc_card *card = mmc_dev_to_card(dev); int ret = 0; + pm_message_t state = { PM_EVENT_SUSPEND }; if (dev->driver && drv->suspend) ret = drv->suspend(card, state); return ret; } -static int mmc_bus_resume(struct device *dev) +static int mmc_bus_pm_resume(struct device *dev) { struct mmc_driver *drv = to_mmc_driver(dev->driver); struct mmc_card *card = mmc_dev_to_card(dev); @@ -143,7 +144,6 @@ static int mmc_bus_resume(struct device *dev) } #ifdef CONFIG_PM_RUNTIME - static int mmc_runtime_suspend(struct device *dev) { struct mmc_card *card = mmc_dev_to_card(dev); @@ -162,21 +162,13 @@ static int mmc_runtime_idle(struct device *dev) { return pm_runtime_suspend(dev); } +#endif /* CONFIG_PM_RUNTIME */ static const struct dev_pm_ops mmc_bus_pm_ops = { - .runtime_suspend = mmc_runtime_suspend, - .runtime_resume = mmc_runtime_resume, - .runtime_idle = mmc_runtime_idle, + SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_pm_suspend, mmc_bus_pm_resume) + SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, mmc_runtime_idle) }; -#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops) - -#else /* !CONFIG_PM_RUNTIME */ - -#define MMC_PM_OPS_PTR NULL - -#endif /* !CONFIG_PM_RUNTIME */ - static struct bus_type mmc_bus_type = { .name = "mmc", .dev_attrs = mmc_dev_attrs, @@ -184,9 +176,7 @@ static struct bus_type mmc_bus_type = { .uevent = mmc_bus_uevent, .probe = mmc_bus_probe, .remove = mmc_bus_remove, - .suspend = mmc_bus_suspend, - .resume = mmc_bus_resume, - .pm = MMC_PM_OPS_PTR, + .pm = &mmc_bus_pm_ops, }; int mmc_register_bus(void) diff --git a/drivers/net/wireless/bcm4329/dhd_common.c b/drivers/net/wireless/bcm4329/dhd_common.c index f7cd372..8b89e39 100644 --- a/drivers/net/wireless/bcm4329/dhd_common.c +++ b/drivers/net/wireless/bcm4329/dhd_common.c @@ -1896,6 +1896,41 @@ fail: #endif +/* + * returns = TRUE if associated, FALSE if not associated + */ +bool is_associated(dhd_pub_t *dhd, void *bss_buf) +{ + char bssid[ETHER_ADDR_LEN], zbuf[ETHER_ADDR_LEN]; + int ret = -1; + + bzero(bssid, ETHER_ADDR_LEN); + bzero(zbuf, ETHER_ADDR_LEN); + + ret = dhdcdc_set_ioctl(dhd, 0, WLC_GET_BSSID, (char *)bssid, ETHER_ADDR_LEN); + DHD_TRACE((" %s WLC_GET_BSSID ioctl res = %d\n", __FUNCTION__, ret)); + + if (ret == BCME_NOTASSOCIATED) { + DHD_TRACE(("%s: not associated! res:%d\n", __FUNCTION__, ret)); + } + + if (ret < 0) + return FALSE; + + if ((memcmp(bssid, zbuf, ETHER_ADDR_LEN) != 0)) { + /* STA is assocoated BSSID is non zero */ + + if (bss_buf) { + /* return bss if caller provided buf */ + memcpy(bss_buf, bssid, ETHER_ADDR_LEN); + } + return TRUE; + } else { + DHD_TRACE(("%s: WLC_GET_BSSID ioctl returned zero bssid\n", __FUNCTION__)); + return FALSE; + } +} + /* Function to estimate possible DTIM_SKIP value */ int dhd_get_dtim_skip(dhd_pub_t *dhd) { @@ -1979,7 +2014,6 @@ int dhd_pno_clean(dhd_pub_t *dhd) int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) { char iovbuf[128]; - uint8 bssid[6]; int ret = -1; if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) { @@ -1990,12 +2024,7 @@ int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) memset(iovbuf, 0, sizeof(iovbuf)); /* Check if disassoc to enable pno */ - if ((pfn_enabled) && \ - ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_GET_BSSID, \ - (char *)&bssid, ETHER_ADDR_LEN)) == BCME_NOTASSOCIATED)) { - DHD_TRACE(("%s pno enable called in disassoc mode\n", __FUNCTION__)); - } - else if (pfn_enabled) { + if (pfn_enabled && (is_associated(dhd, NULL) == TRUE)) { DHD_ERROR(("%s pno enable called in assoc mode ret=%d\n", \ __FUNCTION__, ret)); return ret; diff --git a/drivers/net/wireless/bcmdhd/Kconfig b/drivers/net/wireless/bcmdhd/Kconfig index db434ab..205c813 100644 --- a/drivers/net/wireless/bcmdhd/Kconfig +++ b/drivers/net/wireless/bcmdhd/Kconfig @@ -31,3 +31,10 @@ config BCMDHD_WEXT select WEXT_PRIV help Enables WEXT support + +config DHD_USE_STATIC_BUF + bool "Enable memory preallocation" + depends on BCMDHD + default n + ---help--- + Use memory preallocated in platform
\ No newline at end of file diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c index 70bacbd3..aedb508 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c @@ -1002,11 +1002,11 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u if (pkt == NULL) { sd_data(("%s: Creating new %s Packet, len=%d\n", __FUNCTION__, write ? "TX" : "RX", buflen_u)); -#ifdef DHD_USE_STATIC_BUF +#ifdef CONFIG_DHD_USE_STATIC_BUF if (!(mypkt = PKTGET_STATIC(sd->osh, buflen_u, write ? TRUE : FALSE))) { #else if (!(mypkt = PKTGET(sd->osh, buflen_u, write ? TRUE : FALSE))) { -#endif /* DHD_USE_STATIC_BUF */ +#endif /* CONFIG_DHD_USE_STATIC_BUF */ sd_err(("%s: PKTGET failed: len %d\n", __FUNCTION__, buflen_u)); return SDIOH_API_RC_FAIL; @@ -1023,11 +1023,11 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u if (!write) { bcopy(PKTDATA(sd->osh, mypkt), buffer, buflen_u); } -#ifdef DHD_USE_STATIC_BUF +#ifdef CONFIG_DHD_USE_STATIC_BUF PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); #else PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); -#endif /* DHD_USE_STATIC_BUF */ +#endif /* CONFIG_DHD_USE_STATIC_BUF */ } else if (((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) != 0) { /* Case 2: We have a packet, but it is unaligned. */ @@ -1036,11 +1036,11 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u sd_data(("%s: Creating aligned %s Packet, len=%d\n", __FUNCTION__, write ? "TX" : "RX", PKTLEN(sd->osh, pkt))); -#ifdef DHD_USE_STATIC_BUF +#ifdef CONFIG_DHD_USE_STATIC_BUF if (!(mypkt = PKTGET_STATIC(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) { #else if (!(mypkt = PKTGET(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) { -#endif /* DHD_USE_STATIC_BUF */ +#endif /* CONFIG_DHD_USE_STATIC_BUF */ sd_err(("%s: PKTGET failed: len %d\n", __FUNCTION__, PKTLEN(sd->osh, pkt))); return SDIOH_API_RC_FAIL; @@ -1061,11 +1061,11 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u PKTDATA(sd->osh, pkt), PKTLEN(sd->osh, mypkt)); } -#ifdef DHD_USE_STATIC_BUF +#ifdef CONFIG_DHD_USE_STATIC_BUF PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); #else PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); -#endif /* DHD_USE_STATIC_BUF */ +#endif /* CONFIG_DHD_USE_STATIC_BUF */ } else { /* case 3: We have a packet and it is aligned. */ sd_data(("%s: Aligned %s Packet, direct DMA\n", __FUNCTION__, write ? "Tx" : "Rx")); diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c index 726b639..0fa2329 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c @@ -181,11 +181,9 @@ static int bcmsdh_sdmmc_resume(struct device *pdev) { struct sdio_func *func = dev_to_sdio_func(pdev); - if (func->num != 2) - return 0; dhd_mmc_suspend = FALSE; #if defined(OOB_INTR_ONLY) - if (dhd_os_check_if_up(bcmsdh_get_drvdata())) + if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata())) bcmsdh_oob_intr_set(1); #endif smp_mb(); diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h index c87f6cf..84d1761 100644 --- a/drivers/net/wireless/bcmdhd/dhd.h +++ b/drivers/net/wireless/bcmdhd/dhd.h @@ -116,7 +116,7 @@ typedef enum { } dhd_if_state_t; -#if defined(DHD_USE_STATIC_BUF) +#if defined(CONFIG_DHD_USE_STATIC_BUF) uint8* dhd_os_prealloc(void *osh, int section, uint size); void dhd_os_prefree(void *osh, void *addr, uint size); @@ -128,7 +128,7 @@ void dhd_os_prefree(void *osh, void *addr, uint size); #define DHD_OS_PREALLOC(osh, section, size) MALLOC(osh, size) #define DHD_OS_PREFREE(osh, addr, size) MFREE(osh, addr, size) -#endif /* defined(DHD_USE_STATIC_BUF) */ +#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */ /* Packet alignment for most efficient SDIO (can change based on platform) */ #ifndef DHD_SDALIGN @@ -314,8 +314,8 @@ inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp) #define DHD_OS_WAKE_LOCK_TIMEOUT(pub) dhd_os_wake_lock_timeout(pub) #define DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(pub, val) dhd_os_wake_lock_timeout_enable(pub, val) -#define DHD_PACKET_TIMEOUT 1 -#define DHD_EVENT_TIMEOUT 2 +#define DHD_PACKET_TIMEOUT_MS 1000 +#define DHD_EVENT_TIMEOUT_MS 1500 /* interface operations (register, remove) should be atomic, use this lock to prevent race * condition among wifi on/off and interface operation functions diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c index 3a4de96..8460992 100644 --- a/drivers/net/wireless/bcmdhd/dhd_cdc.c +++ b/drivers/net/wireless/bcmdhd/dhd_cdc.c @@ -2460,7 +2460,7 @@ dhd_prot_attach(dhd_pub_t *dhd) return 0; fail: -#ifndef DHD_USE_STATIC_BUF +#ifndef CONFIG_DHD_USE_STATIC_BUF if (cdc != NULL) MFREE(dhd->osh, cdc, sizeof(dhd_prot_t)); #endif @@ -2474,7 +2474,7 @@ dhd_prot_detach(dhd_pub_t *dhd) #ifdef PROP_TXSTATUS dhd_wlfc_deinit(dhd); #endif -#ifndef DHD_USE_STATIC_BUF +#ifndef CONFIG_DHD_USE_STATIC_BUF MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t)); #endif dhd->prot = NULL; diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c index a29c2fa..9df70a0 100644 --- a/drivers/net/wireless/bcmdhd/dhd_common.c +++ b/drivers/net/wireless/bcmdhd/dhd_common.c @@ -1489,7 +1489,7 @@ dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen) return -1; iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen); - retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, TRUE, 0); + retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, FALSE, 0); if (retcode) { DHD_TRACE(("%s: ioctl WLC_GET_VAR error %d\n", @@ -1902,6 +1902,7 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr, if ((!dhd) && (!ssids_local)) { DHD_ERROR(("%s error exit\n", __FUNCTION__)); err = -1; + return err; } if (dhd_check_ap_wfd_mode_set(dhd) == TRUE) @@ -2155,14 +2156,14 @@ wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes_left) { - char* str = *list_str; + char* str; int idx = 0; if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) { DHD_ERROR(("%s error paramters\n", __FUNCTION__)); return -1; } - + str = *list_str; while (*bytes_left > 0) { if (str[0] != CSCAN_TLV_TYPE_SSID_IE) { diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c index 92cdc9b..d4cc56f 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux.c @@ -1032,6 +1032,9 @@ dhd_op_if(dhd_if_t *ifp) if (ret < 0) { ifp->set_multicast = FALSE; if (ifp->net) { +#ifdef WL_CFG80211 + wl_cfg80211_post_del((void*)(ifp->net)); +#endif free_netdev(ifp->net); } dhd->iflist[ifp->idx] = NULL; @@ -1397,7 +1400,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) int i; dhd_if_t *ifp; wl_event_msg_t event; - int tout = DHD_PACKET_TIMEOUT; + int tout = DHD_PACKET_TIMEOUT_MS; DHD_TRACE(("%s: Enter\n", __FUNCTION__)); @@ -1501,7 +1504,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) if (event.event_type == WLC_E_BTA_HCI_EVENT) { dhd_bta_doevt(dhdp, data, event.datalen); } - tout = DHD_EVENT_TIMEOUT; + tout = DHD_EVENT_TIMEOUT_MS; } ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]); @@ -2029,7 +2032,7 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) /* send to dongle only if we are not waiting for reload already */ if (dhd->pub.hang_was_sent) { DHD_ERROR(("%s: HANG was sent up earlier\n", __FUNCTION__)); - DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT); + DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS); DHD_OS_WAKE_UNLOCK(&dhd->pub); return OSL_ERROR(BCME_DONGLE_DOWN); } @@ -2296,7 +2299,6 @@ dhd_stop(struct net_device *net) if (ifidx == 0 && !dhd_download_fw_on_driverload) wl_android_wifi_off(net); #endif - dhd->pub.hang_was_sent = 0; dhd->pub.rxcnt_timeout = 0; dhd->pub.txcnt_timeout = 0; OLD_MOD_DEC_USE_COUNT; @@ -2325,6 +2327,8 @@ dhd_open(struct net_device *net) firmware_path[0] = '\0'; } + dhd->pub.hang_was_sent = 0; + #if !defined(WL_CFG80211) /* * Force start if ifconfig_up gets called before START command @@ -3915,7 +3919,7 @@ dhd_os_sdtxunlock(dhd_pub_t *pub) dhd_os_sdunlock(pub); } -#if defined(DHD_USE_STATIC_BUF) +#if defined(CONFIG_DHD_USE_STATIC_BUF) uint8* dhd_os_prealloc(void *osh, int section, uint size) { return (uint8*)wl_android_prealloc(section, size); @@ -3924,7 +3928,7 @@ uint8* dhd_os_prealloc(void *osh, int section, uint size) void dhd_os_prefree(void *osh, void *addr, uint size) { } -#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ +#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */ #if defined(CONFIG_WIRELESS_EXT) struct iw_statistics * @@ -4282,6 +4286,8 @@ int net_os_send_hang_message(struct net_device *dev) #endif #if defined(WL_CFG80211) ret = wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED); + dev_close(dev); + dev_open(dev); #endif } } @@ -4421,7 +4427,7 @@ int dhd_os_wake_lock_timeout(dhd_pub_t *pub) #ifdef CONFIG_HAS_WAKELOCK if (dhd->wakelock_timeout_enable) wake_lock_timeout(&dhd->wl_rxwake, - dhd->wakelock_timeout_enable * HZ); + msecs_to_jiffies(dhd->wakelock_timeout_enable)); #endif dhd->wakelock_timeout_enable = 0; spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_mon.c b/drivers/net/wireless/bcmdhd/dhd_linux_mon.c index dd9c71f..ce94ff9 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux_mon.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux_mon.c @@ -225,9 +225,10 @@ static void dhd_mon_if_set_multicast_list(struct net_device *ndev) mon_if = ndev_to_monif(ndev); if (mon_if == NULL || mon_if->real_ndev == NULL) { MON_PRINT(" cannot find matched net dev, skip the packet\n"); + } else { + MON_PRINT("enter, if name: %s, matched if name %s\n", + ndev->name, mon_if->real_ndev->name); } - - MON_PRINT("enter, if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name); } static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr) @@ -238,9 +239,10 @@ static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr) mon_if = ndev_to_monif(ndev); if (mon_if == NULL || mon_if->real_ndev == NULL) { MON_PRINT(" cannot find matched net dev, skip the packet\n"); + } else { + MON_PRINT("enter, if name: %s, matched if name %s\n", + ndev->name, mon_if->real_ndev->name); } - - MON_PRINT("enter, if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name); return ret; } diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c index 2930115..1bdc7d5 100644 --- a/drivers/net/wireless/bcmdhd/dhd_sdio.c +++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c @@ -382,7 +382,7 @@ static bool dhd_readahead; /* To check if there's window offered */ #define DATAOK(bus) \ - (((uint8)(bus->tx_max - bus->tx_seq) > 2) && \ + (((uint8)(bus->tx_max - bus->tx_seq) > 1) && \ (((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0)) /* To check if there's window offered for ctrl frame */ @@ -5736,7 +5736,7 @@ dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh) return; if (bus->rxbuf) { -#ifndef DHD_USE_STATIC_BUF +#ifndef CONFIG_DHD_USE_STATIC_BUF MFREE(osh, bus->rxbuf, bus->rxblen); #endif bus->rxctl = bus->rxbuf = NULL; @@ -5744,7 +5744,7 @@ dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh) } if (bus->databuf) { -#ifndef DHD_USE_STATIC_BUF +#ifndef CONFIG_DHD_USE_STATIC_BUF MFREE(osh, bus->databuf, MAX_DATA_BUF); #endif bus->databuf = NULL; diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h index ae1f975..fe71e16 100644 --- a/drivers/net/wireless/bcmdhd/include/epivers.h +++ b/drivers/net/wireless/bcmdhd/include/epivers.h @@ -44,6 +44,6 @@ #define EPI_VERSION_DEV 5.90.125 -#define EPI_VERSION_STR "5.90.125.94" +#define EPI_VERSION_STR "5.90.125.94.1" #endif diff --git a/drivers/net/wireless/bcmdhd/include/linux_osl.h b/drivers/net/wireless/bcmdhd/include/linux_osl.h index 1ec136e..38de298 100644 --- a/drivers/net/wireless/bcmdhd/include/linux_osl.h +++ b/drivers/net/wireless/bcmdhd/include/linux_osl.h @@ -268,7 +268,7 @@ extern int osl_error(int bcmerror); #define PKTLIST_DUMP(osh, buf) #define PKTDBG_TRACE(osh, pkt, bit) #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) -#ifdef DHD_USE_STATIC_BUF +#ifdef CONFIG_DHD_USE_STATIC_BUF #define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len)) #define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send)) #endif diff --git a/drivers/net/wireless/bcmdhd/linux_osl.c b/drivers/net/wireless/bcmdhd/linux_osl.c index 1a54437..b3fcdd2 100644 --- a/drivers/net/wireless/bcmdhd/linux_osl.c +++ b/drivers/net/wireless/bcmdhd/linux_osl.c @@ -47,7 +47,7 @@ #define OS_HANDLE_MAGIC 0x1234abcd #define BCM_MEM_FILENAME_LEN 24 -#ifdef DHD_USE_STATIC_BUF +#ifdef CONFIG_DHD_USE_STATIC_BUF #define STATIC_BUF_MAX_NUM 16 #define STATIC_BUF_SIZE (PAGE_SIZE * 2) #define STATIC_BUF_TOTAL_LEN (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE) @@ -70,7 +70,7 @@ typedef struct bcm_static_pkt { } bcm_static_pkt_t; static bcm_static_pkt_t *bcm_static_skb = 0; -#endif +#endif typedef struct bcm_mem_link { struct bcm_mem_link *prev; @@ -211,7 +211,7 @@ osl_attach(void *pdev, uint bustype, bool pkttag) break; } -#if defined(DHD_USE_STATIC_BUF) +#if defined(CONFIG_DHD_USE_STATIC_BUF) if (!bcm_static_buf) { if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+ STATIC_BUF_TOTAL_LEN))) { @@ -220,25 +220,25 @@ osl_attach(void *pdev, uint bustype, bool pkttag) else printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); - sema_init(&bcm_static_buf->static_sem, 1); bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; } if (!bcm_static_skb) { - int i; - void *skb_buff_ptr = 0; - bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); - skb_buff_ptr = dhd_os_prealloc(osh, 4, 0); - - bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *) * 16); - for (i = 0; i < STATIC_PKT_MAX_NUM * 2; i++) - bcm_static_skb->pkt_use[i] = 0; - - sema_init(&bcm_static_skb->osl_pkt_sem, 1); + void *skb_buff_ptr = dhd_os_prealloc(osh, 4, 0); + + if (skb_buff_ptr) { + bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); + bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *) * 16); + for (i = 0; i < STATIC_PKT_MAX_NUM * 2; i++) + bcm_static_skb->pkt_use[i] = 0; + sema_init(&bcm_static_skb->osl_pkt_sem, 1); + } else { + printk("can not alloc static skb buffers\n"); + } } -#endif +#endif return osh; } @@ -388,7 +388,7 @@ osl_ctfpool_stats(osl_t *osh, void *b) if ((osh == NULL) || (osh->ctfpool == NULL)) return; -#ifdef DHD_USE_STATIC_BUF +#ifdef CONFIG_DHD_USE_STATIC_BUF if (bcm_static_buf) { bcm_static_buf = 0; } @@ -548,14 +548,14 @@ osl_pktfree(osl_t *osh, void *p, bool send) } } -#ifdef DHD_USE_STATIC_BUF +#ifdef CONFIG_DHD_USE_STATIC_BUF void * osl_pktget_static(osl_t *osh, uint len) { int i; struct sk_buff *skb; - if (len > (PAGE_SIZE * 2)) { + if (!bcm_static_skb || (len > (PAGE_SIZE * 2))) { printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len); return osl_pktget(osh, len); } @@ -570,10 +570,10 @@ osl_pktget_static(osl_t *osh, uint len) if (i != STATIC_PKT_MAX_NUM) { bcm_static_skb->pkt_use[i] = 1; - up(&bcm_static_skb->osl_pkt_sem); skb = bcm_static_skb->skb_4k[i]; skb->tail = skb->data + len; skb->len = len; + up(&bcm_static_skb->osl_pkt_sem); return skb; } } @@ -586,10 +586,10 @@ osl_pktget_static(osl_t *osh, uint len) if (i != STATIC_PKT_MAX_NUM) { bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] = 1; - up(&bcm_static_skb->osl_pkt_sem); skb = bcm_static_skb->skb_8k[i]; skb->tail = skb->data + len; skb->len = len; + up(&bcm_static_skb->osl_pkt_sem); return skb; } @@ -603,9 +603,14 @@ osl_pktfree_static(osl_t *osh, void *p, bool send) { int i; + if (!bcm_static_skb) { + osl_pktfree(osh, p, send); + return; + } + + down(&bcm_static_skb->osl_pkt_sem); for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { if (p == bcm_static_skb->skb_4k[i]) { - down(&bcm_static_skb->osl_pkt_sem); bcm_static_skb->pkt_use[i] = 0; up(&bcm_static_skb->osl_pkt_sem); return; @@ -614,14 +619,15 @@ osl_pktfree_static(osl_t *osh, void *p, bool send) for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { if (p == bcm_static_skb->skb_8k[i]) { - down(&bcm_static_skb->osl_pkt_sem); bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0; up(&bcm_static_skb->osl_pkt_sem); return; } } + up(&bcm_static_skb->osl_pkt_sem); - return osl_pktfree(osh, p, send); + osl_pktfree(osh, p, send); + return; } #endif diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c index 9ca3d60..b680481 100644 --- a/drivers/net/wireless/bcmdhd/wl_android.c +++ b/drivers/net/wireless/bcmdhd/wl_android.c @@ -559,8 +559,10 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) bytes_written = strlen("OK"); } - if (bytes_written > 0) { - if (bytes_written > priv_cmd.total_len) { + if (bytes_written >= 0) { + if ((bytes_written == 0) && (priv_cmd.total_len > 0)) + command[0] = '\0'; + if (bytes_written >= priv_cmd.total_len) { DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written)); bytes_written = priv_cmd.total_len; } else { @@ -571,7 +573,8 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__)); ret = -EFAULT; } - } else { + } + else { ret = bytes_written; } @@ -675,20 +678,21 @@ void wl_android_wifictrl_func_del(void) } } -void* wl_android_prealloc(int section, unsigned long size) +void *wl_android_prealloc(int section, unsigned long size) { void *alloc_ptr = NULL; if (wifi_control_data && wifi_control_data->mem_prealloc) { alloc_ptr = wifi_control_data->mem_prealloc(section, size); if (alloc_ptr) { DHD_INFO(("success alloc section %d\n", section)); - bzero(alloc_ptr, size); + if (size != 0L) + bzero(alloc_ptr, size); return alloc_ptr; } } DHD_ERROR(("can't alloc section %d\n", section)); - return 0; + return NULL; } int wifi_get_irq_number(unsigned long *irq_flags_ptr) diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c index daa7d26..32241d5 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c @@ -16,7 +16,7 @@ * the license of that module. An independent module is a module which is not * derived from this software. The special exception does not apply to any * modifications of the software. - * + * * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. @@ -589,7 +589,7 @@ static const u32 __wl_cipher_suites[] = { WLAN_CIPHER_SUITE_WEP104, WLAN_CIPHER_SUITE_TKIP, WLAN_CIPHER_SUITE_CCMP, - WLAN_CIPHER_SUITE_AES_CMAC, + WLAN_CIPHER_SUITE_AES_CMAC }; /* There isn't a lot of sense in it, but you can transmit anything you like */ @@ -844,8 +844,10 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name, wl_set_p2p_status(wl, IF_ADD); err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec); - if (unlikely(err)) + if (unlikely(err)) { + WL_ERR((" virtual iface add failed (%d) \n", err)); return ERR_PTR(-ENOMEM); + } timeout = wait_event_interruptible_timeout(wl->dongle_event_wait, (wl_get_p2p_status(wl, IF_ADD) == false), @@ -860,7 +862,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name, } vwdev->wiphy = wl->wdev->wiphy; WL_INFO((" virtual interface(%s) is created memalloc done \n", - wl->p2p->vir_ifname)); + wl->p2p->vir_ifname)); index = alloc_idx_vwdev(wl); wl->vwdev[index] = vwdev; vwdev->iftype = @@ -873,6 +875,8 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name, wl_set_drv_status(wl, READY); wl->p2p->vif_created = true; set_mode_by_netdev(wl, _ndev, mode); + WL_DBG((" virtual interface(%s) wl->wdev %p wl->wdev->netdev %p vwdev %p vwdev->netdev %p\n", + wl->p2p->vir_ifname, wl->wdev, wl->wdev->netdev, vwdev, vwdev->netdev)); net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION); if (rtnl_is_locked()) { rtnl_unlock(); @@ -927,10 +931,14 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev) * ifconfig <inter> down and up sequnce, which will reload the fw * however we should cleanup the linux network virtual interfaces */ - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); - WL_ERR(("Firmware returned an error from p2p_ifdel\n")); - WL_ERR(("try to remove linux virtual interface %s\n", dev->name)); - dhd_del_if(dhd->info, dhd_net2idx(dhd->info, dev)); + /* Request framework to RESET and clean up */ + struct net_device *ndev = wl_to_prmry_ndev(wl); + WL_ERR(("Firmware returned an error (%d) from p2p_ifdel" + "HANG Notification sent to %s dev %p wdev %p ndev %p\n", ret, ndev->name, dev, wl->wdev, wl_to_prmry_ndev(wl))); + wl_cfg80211_hang(ndev, WLAN_REASON_UNSPECIFIED); + } + else { + WL_ERR(("Firmware success from p2p_ifdel dev %p wdev %p ndev %p", dev, wl->wdev, wl_to_prmry_ndev(wl))); } /* Wait for any pending scan req to get aborted from the sysioc context */ @@ -1035,7 +1043,7 @@ int (*_net_attach)(dhd_pub_t *dhdp, int ifidx)) WL_ERR(("net is NULL\n")); return 0; } - if (wl->p2p_supported) { + if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) { WL_DBG(("IF_ADD event called from dongle, old interface name: %s," "new name: %s\n", ndev->name, wl->p2p->vir_ifname)); /* Assign the net device to CONNECT BSSCFG */ @@ -1047,6 +1055,8 @@ int (*_net_attach)(dhd_pub_t *dhdp, int ifidx)) wl_clr_p2p_status(wl, IF_ADD); wake_up_interruptible(&wl->dongle_event_wait); + } else { + ret = BCME_NOTREADY; } return ret; } @@ -1063,7 +1073,8 @@ wl_cfg80211_notify_ifdel(struct net_device *ndev) return 0; } - if (p2p_is_on(wl) && wl->p2p->vif_created) { + if (p2p_is_on(wl) && wl->p2p->vif_created && + wl_get_p2p_status(wl, IF_DELETING)) { if (wl->scan_request) { /* Abort any pending scan requests */ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; @@ -1096,6 +1107,18 @@ wl_cfg80211_notify_ifdel(struct net_device *ndev) return 0; } +s32 wl_cfg80211_post_del(void* ndev) +{ + int index; + struct wl_priv *wl = wlcfg_drv_priv; + index = get_idx_vwdev_by_netdev(wl, (struct net_device *)ndev); + WL_DBG(("index : %d\n", index)); + if (index >= 0) { + free_vwdev_by_index(wl, index); + } + return 0; +} + s32 wl_cfg80211_is_progress_ifadd(void) { @@ -1130,8 +1153,8 @@ wl_cfg80211_notify_ifchange(void) static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request) { - u32 n_ssids = request->n_ssids; - u32 n_channels = request->n_channels; + u32 n_ssids; + u32 n_channels; u16 channel; chanspec_t chanspec; s32 i, offset; @@ -1160,6 +1183,12 @@ static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_req params->passive_time = htod32(params->passive_time); params->home_time = htod32(params->home_time); + if (!request) + return; + + n_ssids = request->n_ssids; + n_channels = request->n_channels; + /* Copy channel array if applicable */ WL_SCAN(("### List of channelspecs to scan ###\n")); if (n_channels > 0) { @@ -1248,8 +1277,7 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, return -ENOMEM; } - if (request != NULL) - wl_scan_prep(¶ms->params, request); + wl_scan_prep(¶ms->params, request); params->version = htod32(ISCAN_REQ_VERSION); params->action = htod16(action); @@ -1340,8 +1368,7 @@ wl_run_escan(struct wl_priv *wl, struct net_device *ndev, goto exit; } - if (request != NULL) - wl_scan_prep(¶ms->params, request); + wl_scan_prep(¶ms->params, request); params->version = htod32(ESCAN_REQ_VERSION); params->action = htod16(action); params->sync_id = htod16(0x1234); @@ -1461,7 +1488,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, (int)wl->status)); return -EAGAIN; } - if (request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) { + if (request && request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) { WL_ERR(("n_ssids > WL_SCAN_PARAMS_SSID_MAX\n")); return -EOPNOTSUPP; } @@ -4155,6 +4182,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) struct wl_cfg80211_bss_info *notif_bss_info; struct wl_scan_req *sr = wl_to_sr(wl); struct beacon_proberesp *beacon_proberesp; + struct cfg80211_bss *cbss = NULL; s32 mgmt_type; s32 signal; u32 freq; @@ -4213,13 +4241,15 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) signal = notif_bss_info->rssi * 100; - if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt, - le16_to_cpu(notif_bss_info->frame_len), - signal, GFP_KERNEL))) { + cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt, + le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL); + if (unlikely(!cbss)) { WL_ERR(("cfg80211_inform_bss_frame error\n")); kfree(notif_bss_info); return -EINVAL; } + + cfg80211_put_bss(cbss); kfree(notif_bss_info); return err; diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h index 262335e..232db1b 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h @@ -2,13 +2,13 @@ * Linux cfg80211 driver * * Copyright (C) 1999-2011, Broadcom Corporation - * + * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the * following added to such license: - * + * * As a special exception, the copyright holders of this software give you * permission to link this software with independent modules, and to copy and * distribute the resulting executable under terms of your choice, provided that @@ -16,7 +16,7 @@ * the license of that module. An independent module is a module which is not * derived from this software. The special exception does not apply to any * modifications of the software. - * + * * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. @@ -452,6 +452,7 @@ static inline s32 alloc_idx_vwdev(struct wl_priv *wl) if (wl->vwdev[i] == NULL) return i; } + WL_ERR((" *********alloc_idx_vwdev failed (%d) \n", -1)); return -1; } @@ -462,6 +463,7 @@ static inline s32 get_idx_vwdev_by_netdev(struct wl_priv *wl, struct net_device if ((wl->vwdev[i] != NULL) && (wl->vwdev[i]->netdev == ndev)) return i; } + WL_ERR((" *********get_idx_vwdev_by_netdev failed (%d) \n", -1)); return -1; } @@ -531,6 +533,7 @@ extern s32 wl_cfg80211_down(void); /* dongle down */ extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, s32 bssidx, int (*_net_attach)(dhd_pub_t *dhdp, int ifidx)); extern s32 wl_cfg80211_notify_ifdel(struct net_device *ndev); +extern s32 wl_cfg80211_post_del(void *ndev); extern s32 wl_cfg80211_is_progress_ifadd(void); extern s32 wl_cfg80211_is_progress_ifchange(void); extern s32 wl_cfg80211_is_progress_ifadd(void); diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c index ba3cc6c..32f7b57 100644 --- a/drivers/net/wireless/bcmdhd/wl_iw.c +++ b/drivers/net/wireless/bcmdhd/wl_iw.c @@ -1626,7 +1626,7 @@ wl_iw_send_priv_event( strcpy(extra, flag); wrqu.data.length = strlen(extra); wireless_send_event(dev, cmd, &wrqu, extra); - net_os_wake_lock_timeout_enable(dev, DHD_EVENT_TIMEOUT); + net_os_wake_lock_timeout_enable(dev, DHD_EVENT_TIMEOUT_MS); WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra)); return 0; diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c index d109bfb..00a446b 100644 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -100,6 +100,7 @@ struct android_dev { struct device *dev; bool enabled; + struct mutex mutex; bool connected; bool sw_connected; struct work_struct work; @@ -774,8 +775,13 @@ functions_show(struct device *pdev, struct device_attribute *attr, char *buf) struct android_usb_function *f; char *buff = buf; + mutex_lock(&dev->mutex); + list_for_each_entry(f, &dev->enabled_functions, enabled_list) buff += sprintf(buff, "%s,", f->name); + + mutex_unlock(&dev->mutex); + if (buff != buf) *(buff-1) = '\n'; return buff - buf; @@ -790,6 +796,13 @@ functions_store(struct device *pdev, struct device_attribute *attr, char buf[256], *b; int err; + mutex_lock(&dev->mutex); + + if (dev->enabled) { + mutex_unlock(&dev->mutex); + return -EBUSY; + } + INIT_LIST_HEAD(&dev->enabled_functions); strncpy(buf, buff, sizeof(buf)); @@ -804,6 +817,8 @@ functions_store(struct device *pdev, struct device_attribute *attr, } } + mutex_unlock(&dev->mutex); + return size; } @@ -821,8 +836,11 @@ static ssize_t enable_store(struct device *pdev, struct device_attribute *attr, struct usb_composite_dev *cdev = dev->cdev; int enabled = 0; + mutex_lock(&dev->mutex); + sscanf(buff, "%d", &enabled); if (enabled && !dev->enabled) { + cdev->next_string_id = 0; /* update values in composite driver's copy of device descriptor */ cdev->desc.idVendor = device_desc.idVendor; cdev->desc.idProduct = device_desc.idProduct; @@ -836,12 +854,16 @@ static ssize_t enable_store(struct device *pdev, struct device_attribute *attr, dev->enabled = true; } else if (!enabled && dev->enabled) { usb_gadget_disconnect(cdev->gadget); + /* Cancel pending control requests */ + usb_ep_dequeue(cdev->gadget->ep0, cdev->req); usb_remove_config(cdev, &android_config_driver); dev->enabled = false; } else { pr_err("android_usb: already %s\n", dev->enabled ? "enabled" : "disabled"); } + + mutex_unlock(&dev->mutex); return size; } @@ -875,9 +897,9 @@ field ## _show(struct device *dev, struct device_attribute *attr, \ } \ static ssize_t \ field ## _store(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t size) \ + const char *buf, size_t size) \ { \ - int value; \ + int value; \ if (sscanf(buf, format_string, &value) == 1) { \ device_desc.field = value; \ return size; \ @@ -895,10 +917,10 @@ field ## _show(struct device *dev, struct device_attribute *attr, \ } \ static ssize_t \ field ## _store(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t size) \ + const char *buf, size_t size) \ { \ if (size >= sizeof(buffer)) return -EINVAL; \ - if (sscanf(buf, "%s", buffer) == 1) { \ + if (sscanf(buf, "%s", buffer) == 1) { \ return size; \ } \ return -1; \ @@ -1133,6 +1155,7 @@ static int __init init(void) dev->functions = supported_functions; INIT_LIST_HEAD(&dev->enabled_functions); INIT_WORK(&dev->work, android_work); + mutex_init(&dev->mutex); err = android_create_device(dev); if (err) { diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 6cea2e1..d3cdffe 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -159,25 +159,6 @@ static const u32 oid_supported_list[] = #endif /* RNDIS_PM */ }; -/* HACK: copied from net/core/dev.c to replace dev_get_stats since - * dev_get_stats cannot be called from atomic context */ -static void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, - const struct net_device_stats *netdev_stats) -{ -#if BITS_PER_LONG == 64 - BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats)); - memcpy(stats64, netdev_stats, sizeof(*stats64)); -#else - size_t i, n = sizeof(*stats64) / sizeof(u64); - const unsigned long *src = (const unsigned long *)netdev_stats; - u64 *dst = (u64 *)stats64; - - BUILD_BUG_ON(sizeof(*netdev_stats) / sizeof(unsigned long) != - sizeof(*stats64) / sizeof(u64)); - for (i = 0; i < n; i++) - dst[i] = src[i]; -#endif -} /* NDIS Functions */ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, @@ -190,7 +171,7 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, rndis_query_cmplt_type *resp; struct net_device *net; struct rtnl_link_stats64 temp; - struct rtnl_link_stats64 *stats = &temp; + const struct rtnl_link_stats64 *stats; if (!r) return -ENOMEM; resp = (rndis_query_cmplt_type *)r->buf; @@ -213,7 +194,7 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, resp->InformationBufferOffset = cpu_to_le32(16); net = rndis_per_dev_params[configNr].dev; - netdev_stats_to_stats64(stats, &net->stats); + stats = dev_get_stats(net, &temp); switch (OID) { diff --git a/drivers/video/samsung/s3cfb_fimd6x.c b/drivers/video/samsung/s3cfb_fimd6x.c index 360f1f6..b5b73a1 100644 --- a/drivers/video/samsung/s3cfb_fimd6x.c +++ b/drivers/video/samsung/s3cfb_fimd6x.c @@ -152,6 +152,19 @@ int s3cfb_frame_off(struct s3cfb_global *ctrl) return 0; } +void s3cfb_readjust_pixclock(struct s3cfb_global *ctrl, u32 src_clk, u32 div) +{ + struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev); + int i; + u32 pixclock; + + pixclock = KHZ2PICOS(src_clk / 1000) * div; + dev_info(ctrl->dev, "pixclock adjusted from %d to %d\n", + ctrl->fb[0]->var.pixclock, pixclock); + for (i = 0; i < pdata->nr_wins; i++) + ctrl->fb[i]->var.pixclock = pixclock; +} + int s3cfb_set_clock(struct s3cfb_global *ctrl) { struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev); @@ -162,7 +175,8 @@ int s3cfb_set_clock(struct s3cfb_global *ctrl) /* fixed clock source: hclk */ cfg = readl(ctrl->regs + S3C_VIDCON0); cfg &= ~(S3C_VIDCON0_CLKSEL_MASK | S3C_VIDCON0_CLKVALUP_MASK | - S3C_VIDCON0_VCLKEN_MASK | S3C_VIDCON0_CLKDIR_MASK); + S3C_VIDCON0_VCLKEN_MASK | S3C_VIDCON0_CLKDIR_MASK | + S3C_VIDCON0_CLKVAL_F(-1)); cfg |= (S3C_VIDCON0_CLKVALUP_ALWAYS | S3C_VIDCON0_VCLKEN_NORMAL | S3C_VIDCON0_CLKDIR_DIVIDED); @@ -199,6 +213,7 @@ int s3cfb_set_clock(struct s3cfb_global *ctrl) dev_dbg(ctrl->dev, "parent clock: %d, vclk: %d, vclk div: %d\n", src_clk, vclk, div); + s3cfb_readjust_pixclock(ctrl, src_clk, div); return 0; } diff --git a/drivers/video/samsung/s3cfb_nt35580.c b/drivers/video/samsung/s3cfb_nt35580.c index 2779ce7..3a76083 100755 --- a/drivers/video/samsung/s3cfb_nt35580.c +++ b/drivers/video/samsung/s3cfb_nt35580.c @@ -214,6 +214,7 @@ static int __devinit nt35580_probe(struct spi_device *spi) } lcd->bl_dev->props.max_brightness = 255; + lcd->bl_dev->props.brightness = lcd->bl; spi_set_drvdata(spi, lcd); lcd->ldi_enable = 1; diff --git a/drivers/video/samsung/s3cfb_tl2796.c b/drivers/video/samsung/s3cfb_tl2796.c index b491bd7..e5c98e0 100755 --- a/drivers/video/samsung/s3cfb_tl2796.c +++ b/drivers/video/samsung/s3cfb_tl2796.c @@ -1139,7 +1139,7 @@ static int __devinit tl2796_probe(struct spi_device *spi) } lcd->bl_dev->props.max_brightness = 255; - lcd->bl_dev->props.brightness = 255; + lcd->bl_dev->props.brightness = lcd->bl; tl2796_ldi_enable(lcd); #ifdef CONFIG_HAS_EARLYSUSPEND diff --git a/fs/proc/base.c b/fs/proc/base.c index 0da2379..d2de026 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -796,6 +796,9 @@ static int mem_open(struct inode* inode, struct file* file) return 0; } +#define mem_write NULL + +#ifndef mem_write static ssize_t mem_rw(struct file *file, char __user *buf, size_t count, loff_t *ppos, int write) { @@ -847,6 +850,7 @@ free: free_page((unsigned long) page); return copied; } +#endif static ssize_t mem_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a32571a..5a7074a 100644..100755 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1462,6 +1462,15 @@ unlock: hci_conn_check_pending(hdev); } +static inline bool is_sco_active(struct hci_dev *hdev) +{ + if (hci_conn_hash_lookup_state(hdev, SCO_LINK, BT_CONNECTED) || + (hci_conn_hash_lookup_state(hdev, ESCO_LINK, + BT_CONNECTED))) + return true; + return false; +} + static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_conn_request *ev = (void *) skb->data; @@ -1505,7 +1514,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk bacpy(&cp.bdaddr, &ev->bdaddr); - if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) + if (lmp_rswitch_capable(hdev) && ((mask & HCI_LM_MASTER) + || is_sco_active(hdev))) cp.role = 0x00; /* Become master */ else cp.role = 0x01; /* Remain slave */ diff --git a/net/wireless/reg.c b/net/wireless/reg.c index ca76d8b..72f7fee 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1773,6 +1773,7 @@ static void restore_alpha2(char *alpha2, bool reset_user) static void restore_regulatory_settings(bool reset_user) { char alpha2[2]; + char world_alpha2[2]; struct reg_beacon *reg_beacon, *btmp; struct regulatory_request *reg_request, *tmp; LIST_HEAD(tmp_reg_req_list); @@ -1823,11 +1824,13 @@ static void restore_regulatory_settings(bool reset_user) /* First restore to the basic regulatory settings */ cfg80211_regdomain = cfg80211_world_regdom; + world_alpha2[0] = cfg80211_regdomain->alpha2[0]; + world_alpha2[1] = cfg80211_regdomain->alpha2[1]; mutex_unlock(®_mutex); mutex_unlock(&cfg80211_mutex); - regulatory_hint_core(cfg80211_regdomain->alpha2); + regulatory_hint_core(world_alpha2); /* * This restores the ieee80211_regdom module parameter |