From 2e5ad6b9c45d43cc4e7b8ac5ded1c55a7c4a3893 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 23 May 2012 12:53:11 -0400 Subject: xen/hvc: Collapse error logic. All of the error paths are doing the same logic. In which case we might as well collapse them in one path. CC: stable@kernel.org Acked-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- drivers/tty/hvc/hvc_xen.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index d3d91da..afc7fc2 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -216,22 +216,16 @@ static int xen_hvm_console_init(void) return 0; r = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v); - if (r < 0) { - kfree(info); - return -ENODEV; - } + if (r < 0) + goto err; info->evtchn = v; hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v); - if (r < 0) { - kfree(info); - return -ENODEV; - } + if (r < 0) + goto err; mfn = v; info->intf = ioremap(mfn << PAGE_SHIFT, PAGE_SIZE); - if (info->intf == NULL) { - kfree(info); - return -ENODEV; - } + if (info->intf == NULL) + goto err; info->vtermno = HVC_COOKIE; spin_lock(&xencons_lock); @@ -239,6 +233,9 @@ static int xen_hvm_console_init(void) spin_unlock(&xencons_lock); return 0; +err: + kfree(info); + return -ENODEV; } static int xen_pv_console_init(void) -- cgit v1.1 From a32c88b9386ce3df87f28dd46bdc3776cd6edf75 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 23 May 2012 12:55:38 -0400 Subject: xen/hvc: Fix error cases around HVM_PARAM_CONSOLE_PFN We weren't resetting the parameter to be passed in to a known default. Nor were we checking the return value of hvm_get_parameter. CC: stable@kernel.org Signed-off-by: Konrad Rzeszutek Wilk --- drivers/tty/hvc/hvc_xen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index afc7fc2..3277f0e 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -219,7 +219,8 @@ static int xen_hvm_console_init(void) if (r < 0) goto err; info->evtchn = v; - hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v); + v = 0; + r = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v); if (r < 0) goto err; mfn = v; -- cgit v1.1 From 5842f5768599094758931b74190cdf93641a8e35 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 23 May 2012 12:56:59 -0400 Subject: xen/hvc: Check HVM_PARAM_CONSOLE_[EVTCHN|PFN] for correctness. We need to make sure that those parameters are setup to be correct. As such the value of 0 is deemed invalid and we find that we bail out. The hypervisor sets by default all of them to be zero and when the hypercall is done does a simple: a.value = d->arch.hvm_domain.params[a.index]; Which means that if the Xen toolstack forgot to setup the proper HVM_PARAM_CONSOLE_EVTCHN (or the PFN one), we would get the default value of 0 and use that. CC: stable@kernel.org Fixes-Oracle-Bug: 14091238 Signed-off-by: Konrad Rzeszutek Wilk --- drivers/tty/hvc/hvc_xen.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 3277f0e..944eaeb 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -214,14 +214,19 @@ static int xen_hvm_console_init(void) /* already configured */ if (info->intf != NULL) return 0; - + /* + * If the toolstack (or the hypervisor) hasn't set these values, the + * default value is 0. Even though mfn = 0 and evtchn = 0 are + * theoretically correct values, in practice they never are and they + * mean that a legacy toolstack hasn't initialized the pv console correctly. + */ r = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v); - if (r < 0) + if (r < 0 || v == 0) goto err; info->evtchn = v; v = 0; r = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v); - if (r < 0) + if (r < 0 || v == 0) goto err; mfn = v; info->intf = ioremap(mfn << PAGE_SHIFT, PAGE_SIZE); -- cgit v1.1 From 5e152e6c4b0da84c66cad56597b42c4ecedb0448 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 23 May 2012 13:28:44 -0400 Subject: xen/events: Add WARN_ON when quick lookup found invalid type. All of the bind_XYZ_to_irq do a quick lookup to see if the event exists. And if it does, then the initialized IRQ number is returned instead of initializing a new IRQ number. This patch adds an extra logic to check that the type returned is proper one and that there is an IRQ handler setup for it. This patch has the benefit of being able to find drivers that are doing something naught. [v1: Enhanced based on Stefano's review] Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index faae2f9..af8b8fb 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -827,6 +827,9 @@ int bind_evtchn_to_irq(unsigned int evtchn) handle_edge_irq, "event"); xen_irq_info_evtchn_init(irq, evtchn); + } else { + struct irq_info *info = info_for_irq(irq); + WARN_ON(info == NULL || info->type != IRQT_EVTCHN); } out: @@ -862,6 +865,9 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) xen_irq_info_ipi_init(cpu, irq, evtchn, ipi); bind_evtchn_to_cpu(evtchn, cpu); + } else { + struct irq_info *info = info_for_irq(irq); + WARN_ON(info == NULL || info->type != IRQT_IPI); } out: @@ -939,6 +945,9 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu) xen_irq_info_virq_init(cpu, irq, evtchn, virq); bind_evtchn_to_cpu(evtchn, cpu); + } else { + struct irq_info *info = info_for_irq(irq); + WARN_ON(info == NULL || info->type != IRQT_VIRQ); } out: -- cgit v1.1 From 780dbcd0eedec6528d777b668019dabb36badf1a Mon Sep 17 00:00:00 2001 From: "Zhang, Yang Z" Date: Tue, 22 May 2012 08:40:16 +0000 Subject: xen/pci: Check for PCI bridge before using it. Some SR-IOV devices may use more than one bus number, but there is no real bridges because that have internal routing mechanism. So need to check whether the bridge is existing before using it. Signed-off-by: Yang Zhang Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c index b84bf0b..18fff88 100644 --- a/drivers/xen/pci.c +++ b/drivers/xen/pci.c @@ -59,7 +59,7 @@ static int xen_add_device(struct device *dev) #ifdef CONFIG_ACPI handle = DEVICE_ACPI_HANDLE(&pci_dev->dev); - if (!handle) + if (!handle && pci_dev->bus->bridge) handle = DEVICE_ACPI_HANDLE(pci_dev->bus->bridge); #ifdef CONFIG_PCI_IOV if (!handle && pci_dev->is_virtfn) -- cgit v1.1 From 121daad8fd1dce63076fa55aaedd5dc3f981b334 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Thu, 31 May 2012 20:53:08 +1000 Subject: hwrng: atmel-rng - fix race condition leading to repeated bits Data valid gets cleared by reading the ISR (status register) and NOT from reading ODATA (data register). A new data word can become available between checking ISR and reading ODATA, causing us to reuse the same data word next time atmel_trng_read() gets called, if that happens before the following data word is ready. With this fixed, rngtest no longer complains of 'Continous run' errors. Before: rngtest -c 1000 < /dev/hwrng rngtest 3 Copyright (c) 2004 by Henrique de Moraes Holschuh This is free software; see the source for copying conditions. There is NO warr. rngtest: starting FIPS tests... rngtest: bits received from input: 20000032 rngtest: FIPS 140-2 successes: 923 rngtest: FIPS 140-2 failures: 77 rngtest: FIPS 140-2(2001-10-10) Monobit: 0 rngtest: FIPS 140-2(2001-10-10) Poker: 0 rngtest: FIPS 140-2(2001-10-10) Runs: 1 rngtest: FIPS 140-2(2001-10-10) Long run: 0 rngtest: FIPS 140-2(2001-10-10) Continuous run: 76 rngtest: input channel speed: (min=721.402; avg=46003.510; max=49321.338)Kibitss rngtest: FIPS tests speed: (min=11.442; avg=12.714; max=12.801)Mibits/s rngtest: Program run time: 1931860 microseconds After: rngtest -c 1000 < /dev/hwrng rngtest 3 Copyright (c) 2004 by Henrique de Moraes Holschuh This is free software; see the source for copying conditions. There is NO warr. rngtest: starting FIPS tests... rngtest: bits received from input: 20000032 rngtest: FIPS 140-2 successes: 1000 rngtest: FIPS 140-2 failures: 0 rngtest: FIPS 140-2(2001-10-10) Monobit: 0 rngtest: FIPS 140-2(2001-10-10) Poker: 0 rngtest: FIPS 140-2(2001-10-10) Runs: 0 rngtest: FIPS 140-2(2001-10-10) Long run: 0 rngtest: FIPS 140-2(2001-10-10) Continuous run: 0 rngtest: input channel speed: (min=777.518; avg=36988.482; max=43115.342)Kibitss rngtest: FIPS tests speed: (min=11.951; avg=12.715; max=12.887)Mibits/s rngtest: Program run time: 2035543 microseconds Cc: stable@vger.kernel.org Signed-off-by: Peter Korsgaard Reported-by: George Pontis Acked-by: Nicolas Ferre Signed-off-by: Herbert Xu --- drivers/char/hw_random/atmel-rng.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index f518b99..6289f0e 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -36,6 +36,13 @@ static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max, /* data ready? */ if (readl(trng->base + TRNG_ODATA) & 1) { *data = readl(trng->base + TRNG_ODATA); + /* + ensure data ready is only set again AFTER the next data + word is ready in case it got set between checking ISR + and reading ODATA, so we don't risk re-reading the + same word + */ + readl(trng->base + TRNG_ISR); return 4; } else return 0; -- cgit v1.1 From bfaa25f33425db16a942b7c71e396a47581c646d Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 23 May 2012 16:30:53 -0600 Subject: regmap: clean up debugfs if regmap_init fails If debugfs isn't cleaned up, stale files will be left in the filesystem which will cause an OOPS when accessed the first time, and hang the accessing application when accessed again, presumably due to some lock being left held. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 0bcda48..2aa076e 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -368,7 +368,7 @@ struct regmap *regmap_init(struct device *dev, ret = regcache_init(map, config); if (ret < 0) - goto err_free_workbuf; + goto err_debugfs; /* Add a devres resource for dev_get_regmap() */ m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); @@ -383,7 +383,8 @@ struct regmap *regmap_init(struct device *dev, err_cache: regcache_exit(map); -err_free_workbuf: +err_debugfs: + regmap_debugfs_exit(map); kfree(map->work_buf); err_map: kfree(map); -- cgit v1.1 From 5494a98f451d59f6c05f3f688510e0832445f661 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 31 May 2012 21:10:30 -0300 Subject: regmap: Fix the size calculation for map->format.buf_size The word to be transmitted/received via regmap is composed by the following parts: config->reg_bits config->val_bits config->pad_bits ,so the total size should be calculated by summing up the number of bits of each element and using a DIV_ROUND_UP to return the number of bytes. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 2aa076e..04b4802 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -246,11 +246,11 @@ struct regmap *regmap_init(struct device *dev, map->lock = regmap_lock_mutex; map->unlock = regmap_unlock_mutex; } - map->format.buf_size = (config->reg_bits + config->val_bits) / 8; map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); map->format.pad_bytes = config->pad_bits / 8; map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); - map->format.buf_size += map->format.pad_bytes; + map->format.buf_size = DIV_ROUND_UP(config->reg_bits + + config->val_bits + config->pad_bits, 8); map->reg_shift = config->pad_bits % 8; if (config->reg_stride) map->reg_stride = config->reg_stride; -- cgit v1.1 From d8dc3494f77a5cc3b274bae36f7e74e85cf8a407 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Fri, 1 Jun 2012 18:12:14 -0400 Subject: HID: logitech: don't use stack based dj_report structures On a system with a logitech wireless keyboard/mouse and DMA-API debugging enabled, this warning appears at boot: kernel: WARNING: at lib/dma-debug.c:929 check_for_stack.part.12+0x70/0xa7() kernel: Hardware name: MS-7593 kernel: uhci_hcd 0000:00:1d.1: DMA-API: device driver maps memory fromstack [addr=ffff8801b0079c29] Make logi_dj_recv_query_paired_devices and logi_dj_recv_switch_to_dj_mode use a structure allocated with kzalloc rather than a stack based one. Signed-off-by: Marc Dionne Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 5e8a7ed..0f9c146 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -436,27 +436,37 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) { - struct dj_report dj_report; + struct dj_report *dj_report; + int retval; - memset(&dj_report, 0, sizeof(dj_report)); - dj_report.report_id = REPORT_ID_DJ_SHORT; - dj_report.device_index = 0xFF; - dj_report.report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES; - return logi_dj_recv_send_report(djrcv_dev, &dj_report); + dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); + if (!dj_report) + return -ENOMEM; + dj_report->report_id = REPORT_ID_DJ_SHORT; + dj_report->device_index = 0xFF; + dj_report->report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES; + retval = logi_dj_recv_send_report(djrcv_dev, dj_report); + kfree(dj_report); + return retval; } static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, unsigned timeout) { - struct dj_report dj_report; + struct dj_report *dj_report; + int retval; - memset(&dj_report, 0, sizeof(dj_report)); - dj_report.report_id = REPORT_ID_DJ_SHORT; - dj_report.device_index = 0xFF; - dj_report.report_type = REPORT_TYPE_CMD_SWITCH; - dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; - dj_report.report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; - return logi_dj_recv_send_report(djrcv_dev, &dj_report); + dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); + if (!dj_report) + return -ENOMEM; + dj_report->report_id = REPORT_ID_DJ_SHORT; + dj_report->device_index = 0xFF; + dj_report->report_type = REPORT_TYPE_CMD_SWITCH; + dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; + dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; + retval = logi_dj_recv_send_report(djrcv_dev, dj_report); + kfree(dj_report); + return retval; } -- cgit v1.1 From 617caccebe451716df21c069b079d5936ed7b0f3 Mon Sep 17 00:00:00 2001 From: AnilKumar Ch Date: Wed, 23 May 2012 17:45:09 +0530 Subject: can: c_can: fix "BUG! echo_skb is occupied!" during transmit This patch fixes an issue with transmit routine, which causes "can_put_echo_skb: BUG! echo_skb is occupied!" message when using "cansequence -p" on D_CAN controller. In c_can driver, while transmitting packets tx_echo flag holds the no of can frames put for transmission into the hardware. As the comment above c_can_do_tx() indicates, if we find any packet which is not transmitted then we should stop looking for more. In the current implementation this is not taken care of causing the said message. Also, fix the condition used to find if the packet is transmitted or not. Current code skips the first tx message object and ends up checking one extra invalid object. While at it, fix the comment on top of c_can_do_tx() to use the terminology "packet" instead of "package" since it is more standard. Cc: stable@kernel.org # 2.6.39+ Signed-off-by: AnilKumar Ch Acked-by: Wolfgang Grandegger Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 536bda0..9ac28df 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -686,7 +686,7 @@ static int c_can_get_berr_counter(const struct net_device *dev, * * We iterate from priv->tx_echo to priv->tx_next and check if the * packet has been transmitted, echo it back to the CAN framework. - * If we discover a not yet transmitted package, stop looking for more. + * If we discover a not yet transmitted packet, stop looking for more. */ static void c_can_do_tx(struct net_device *dev) { @@ -698,7 +698,7 @@ static void c_can_do_tx(struct net_device *dev) for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { msg_obj_no = get_tx_echo_msg_obj(priv); val = c_can_read_reg32(priv, &priv->regs->txrqst1); - if (!(val & (1 << msg_obj_no))) { + if (!(val & (1 << (msg_obj_no - 1)))) { can_get_echo_skb(dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); stats->tx_bytes += priv->read_reg(priv, @@ -706,6 +706,8 @@ static void c_can_do_tx(struct net_device *dev) & IF_MCONT_DLC_MASK; stats->tx_packets++; c_can_inval_msg_object(dev, 0, msg_obj_no); + } else { + break; } } -- cgit v1.1 From 148c87c89e1a8863d3d965179f3ab1a06490569e Mon Sep 17 00:00:00 2001 From: AnilKumar Ch Date: Wed, 23 May 2012 17:45:10 +0530 Subject: can: c_can: fix an interrupt thrash issue with c_can driver This patch fixes an interrupt thrash issue with c_can driver. In c_can_isr() function interrupts are disabled and enabled only in c_can_poll() function. c_can_isr() & c_can_poll() both read the irqstatus flag. However, irqstatus is always read as 0 in c_can_poll() because all C_CAN interrupts are disabled in c_can_isr(). This causes all interrupts to be re-enabled in c_can_poll() which in turn causes another interrupt since the event is not really handled. This keeps happening causing a flood of interrupts. To fix this, read the irqstatus register in isr and use the same cached value in the poll function. Cc: stable@kernel.org # 2.6.39+ Signed-off-by: AnilKumar Ch Acked-by: Wolfgang Grandegger Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can.c | 7 +++---- drivers/net/can/c_can/c_can.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 9ac28df..fa01621 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -952,7 +952,7 @@ static int c_can_poll(struct napi_struct *napi, int quota) struct net_device *dev = napi->dev; struct c_can_priv *priv = netdev_priv(dev); - irqstatus = priv->read_reg(priv, &priv->regs->interrupt); + irqstatus = priv->irqstatus; if (!irqstatus) goto end; @@ -1030,12 +1030,11 @@ end: static irqreturn_t c_can_isr(int irq, void *dev_id) { - u16 irqstatus; struct net_device *dev = (struct net_device *)dev_id; struct c_can_priv *priv = netdev_priv(dev); - irqstatus = priv->read_reg(priv, &priv->regs->interrupt); - if (!irqstatus) + priv->irqstatus = priv->read_reg(priv, &priv->regs->interrupt); + if (!priv->irqstatus) return IRQ_NONE; /* disable all interrupts and schedule the NAPI */ diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 9b7fbef..5f32d34 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -76,6 +76,7 @@ struct c_can_priv { unsigned int tx_next; unsigned int tx_echo; void *priv; /* for board-specific data */ + u16 irqstatus; }; struct net_device *alloc_c_can_dev(void); -- cgit v1.1 From f461f27a4436dbe691908fe08b867ef888848cc3 Mon Sep 17 00:00:00 2001 From: AnilKumar Ch Date: Wed, 23 May 2012 17:45:11 +0530 Subject: can: c_can: fix race condition in c_can_open() Fix the issue of C_CAN interrupts getting disabled forever when canconfig utility is used multiple times. According to NAPI usage we disable all the hardware interrupts in ISR and re-enable them in poll(). Current implementation calls napi_enable() after hardware interrupts are enabled. If we get any interrupts between these two steps then we do not process those interrupts because napi is not enabled. Mostly these interrupts come because of STATUS is not 0x7 or ERROR interrupts. If napi_enable() happens before HW interrupts enabled then c_can_poll() function will be called eventual re-enabling. This patch moves the napi_enable() call before interrupts enabled. Cc: stable@kernel.org # 2.6.39+ Signed-off-by: AnilKumar Ch Acked-by: Wolfgang Grandegger Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index fa01621..8dc84d6 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -1064,10 +1064,11 @@ static int c_can_open(struct net_device *dev) goto exit_irq_fail; } + napi_enable(&priv->napi); + /* start the c_can controller */ c_can_start(dev); - napi_enable(&priv->napi); netif_start_queue(dev); return 0; -- cgit v1.1 From dc605dbdb8dd152448ccb8d4c4d5bd9439965a20 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 30 May 2012 13:25:55 -0700 Subject: can: cc770: Fix likely misuse of | for & Using | with a constant is always true. Likely this should have be &. Signed-off-by: Joe Perches Signed-off-by: Marc Kleine-Budde --- drivers/net/can/cc770/cc770_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/cc770/cc770_platform.c b/drivers/net/can/cc770/cc770_platform.c index 53115ee..688371c 100644 --- a/drivers/net/can/cc770/cc770_platform.c +++ b/drivers/net/can/cc770/cc770_platform.c @@ -154,7 +154,7 @@ static int __devinit cc770_get_platform_data(struct platform_device *pdev, struct cc770_platform_data *pdata = pdev->dev.platform_data; priv->can.clock.freq = pdata->osc_freq; - if (priv->cpu_interface | CPUIF_DSC) + if (priv->cpu_interface & CPUIF_DSC) priv->can.clock.freq /= 2; priv->clkout = pdata->cor; priv->bus_config = pdata->bcr; -- cgit v1.1 From 1253585d7cb12a365e9effaf2f0c7991d2404996 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Mon, 21 May 2012 10:59:02 +0800 Subject: pinctrl: sirf: mark of_device_id match table as __devinitconst Signed-off-by: Barry Song Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-sirf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index ba15b1a..e9f8e7d 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c @@ -1184,7 +1184,7 @@ out_no_gpio_remap: return ret; } -static const struct of_device_id pinmux_ids[] = { +static const struct of_device_id pinmux_ids[] __devinitconst = { { .compatible = "sirf,prima2-gpio-pinmux" }, {} }; -- cgit v1.1 From bc66468cee4c23856b2e51d711e62e4ef773001a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 23 May 2012 00:20:17 +0200 Subject: pinctrl: fix a minor harmless typo The way the for_each_maps() macro is currently used, using "i" instead of "_i_" works and is harmless. Still, this is a bug, that can trigger any time, if the code around that macro changes. Better fix it now. Acked-by: Stephen Warren Signed-off-by: Guennadi Liakhovetski Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index c3b331b..0cc053a 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -61,7 +61,7 @@ static LIST_HEAD(pinctrl_maps); list_for_each_entry(_maps_node_, &pinctrl_maps, node) \ for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \ _i_ < _maps_node_->num_maps; \ - i++, _map_ = &_maps_node_->maps[_i_]) + _i_++, _map_ = &_maps_node_->maps[_i_]) /** * pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support -- cgit v1.1 From 0e9a126e95748e8283488818d98ae5bcb7b84515 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 23 May 2012 16:45:09 +0300 Subject: OMAPDSS: fix build when DEBUG_FS or DSS_DEBUG_SUPPORT disabled If CONFIG_DEBUG_FS or CONFIG_OMAP2_DSS_DEBUG_SUPPORT is disabled, the build fails: drivers/video/omap2/dss/core.c:197:50: error: static declaration of 'dss_debugfs_create_file' follows non-static declaration drivers/video/omap2/dss/dss.h:166:5: note: previous declaration of 'dss_debugfs_create_file' was here This patch fixes the dummy dss_debugfs_create_file() so that the driver builds. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 72ded9c..5066eee 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -194,8 +194,7 @@ static inline int dss_initialize_debugfs(void) static inline void dss_uninitialize_debugfs(void) { } -static inline int dss_debugfs_create_file(const char *name, - void (*write)(struct seq_file *)) +int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)) { return 0; } -- cgit v1.1 From d1700f9258552294300083eb62f83262f21ae1db Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 23 May 2012 16:56:09 +0300 Subject: OMAPDSS: Taal: fix compilation warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes a warning: drivers/video/omap2/displays/panel-taal.c: In function ‘taal_num_errors_show’: drivers/video/omap2/displays/panel-taal.c:529: warning: ‘errors’ may be used uninitialized in this function Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 2ce9992..901576e 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -526,7 +526,7 @@ static ssize_t taal_num_errors_show(struct device *dev, { struct omap_dss_device *dssdev = to_dss_device(dev); struct taal_data *td = dev_get_drvdata(&dssdev->dev); - u8 errors; + u8 errors = 0; int r; mutex_lock(&td->lock); -- cgit v1.1 From 5025ce070e2dff80bcf015a34a82edcf78229287 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 23 May 2012 17:02:26 +0300 Subject: OMAPDSS: fix bogus WARN_ON in dss_runtime_put() pm_runtime_put_sync() in dss_runtime_put() returns -EBUSY when any child of dss is still enabled. This happens, for example, when a display output is enabled and one dumps the clocks via debugfs. This causes dss_runtime_get & put to be called. While I couldn't find anything about this in the documentation and it wasn't immediately clear from runtime_pm code, it looks to me that pm_runtime_put_sync() returns -EBUSY to inform that things went fine, but the device could not be turned off as there are still child devices that are enabled. This is not a problem. This patch skips the WARN_ON if pm_runtime_put_sync() returns -EBUSY. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 6ea1ff1..7706323 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -731,7 +731,7 @@ static void dss_runtime_put(void) DSSDBG("dss_runtime_put\n"); r = pm_runtime_put_sync(&dss.pdev->dev); - WARN_ON(r < 0); + WARN_ON(r < 0 && r != -EBUSY); } /* DEBUGFS */ -- cgit v1.1 From c71c8fd4daa342ba714090586a55fc5db7eaa275 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 21 May 2012 20:55:40 +0800 Subject: regulator: palmas: Fix wrong kfree calls The devm_kzalloc function eliminates the need for manual resource releasing and simplify error handling. Resources allocated by devm_* are freed automatically on driver detach. Thus adding kfree calls here will introduce double free bug. The memory of desc array and the pointers to the rdev[] are allocated by devm_kzalloc call for struct palmas_pmic. struct palmas_pmic { struct palmas *palmas; struct device *dev; struct regulator_desc desc[PALMAS_NUM_REGS]; struct regulator_dev *rdev[PALMAS_NUM_REGS]; struct mutex mutex; int smps123; int smps457; int range[PALMAS_REG_SMPS10]; }; Which means we should not call kfree for pmic->rdev and pmic->desc. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index c4435f6..9b7ca90 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -775,9 +775,6 @@ static __devinit int palmas_probe(struct platform_device *pdev) err_unregister_regulator: while (--id >= 0) regulator_unregister(pmic->rdev[id]); - kfree(pmic->rdev); - kfree(pmic->desc); - kfree(pmic); return ret; } @@ -788,10 +785,6 @@ static int __devexit palmas_remove(struct platform_device *pdev) for (id = 0; id < PALMAS_NUM_REGS; id++) regulator_unregister(pmic->rdev[id]); - - kfree(pmic->rdev); - kfree(pmic->desc); - kfree(pmic); return 0; } -- cgit v1.1 From 0c09d3150902d8ca7e763d508ac1a93701b21321 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 23 May 2012 09:08:08 +0800 Subject: regulator: anatop: Use correct __devexit_p annotation __devexit functions are discarded when CONFIG_HOTPLUG is not set, so the symbol needs to be referenced carefully. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 3660bac..e82e7ea 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -224,7 +224,7 @@ static struct platform_driver anatop_regulator_driver = { .of_match_table = of_anatop_regulator_match_tbl, }, .probe = anatop_regulator_probe, - .remove = anatop_regulator_remove, + .remove = __devexit_p(anatop_regulator_remove), }; static int __init anatop_regulator_init(void) -- cgit v1.1 From 7d4be2f5ad223942577c2319153b86592f3da5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 3 Jun 2012 21:30:33 +0200 Subject: regulator: gpio-regulator: do not pass drvdata pointer as reference Commit c172708d38a4 (regulator: core: Use a struct to pass in regulator runtime configuration) added the drvdata pointer only per reference to the new config array in the gpio-regulator. Signed-off-by: Heiko Stuebner Acked-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/gpio-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 9997d7a..ebe2b5c 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -286,7 +286,7 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) cfg.dev = &pdev->dev; cfg.init_data = config->init_data; - cfg.driver_data = &drvdata; + cfg.driver_data = drvdata; drvdata->dev = regulator_register(&drvdata->desc, &cfg); if (IS_ERR(drvdata->dev)) { -- cgit v1.1 From 00926369b745fb0c1e5c27cec35f6adc9752f2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 3 Jun 2012 21:31:09 +0200 Subject: regulator: gpio-regulator: Fix finding of smallest value Commit 4dbd8f63f07a (regulator: gpio-regulator: Set the smallest voltage/current in the specified range) forgot to set the newly introduced best_val. Therefore it stayed always at INT_MAX thus breaking the setting of the voltage. Included is also an init value for target, as warnings about a possibly uninitialised target started appearing with this fix. Signed-off-by: Heiko Stuebner Acked-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/gpio-regulator.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index ebe2b5c..2c38bea 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -104,13 +104,15 @@ static int gpio_regulator_set_value(struct regulator_dev *dev, int min, int max) { struct gpio_regulator_data *data = rdev_get_drvdata(dev); - int ptr, target, state, best_val = INT_MAX; + int ptr, target = 0, state, best_val = INT_MAX; for (ptr = 0; ptr < data->nr_states; ptr++) if (data->states[ptr].value < best_val && data->states[ptr].value >= min && - data->states[ptr].value <= max) + data->states[ptr].value <= max) { target = data->states[ptr].gpios; + best_val = data->states[ptr].value; + } if (best_val == INT_MAX) return -EINVAL; -- cgit v1.1 From b0e4d7bf8b5704904a5d138d81a8ec8b7145767f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 3 Jun 2012 21:32:05 +0200 Subject: regulator: gpio-regulator: populate selector from set_voltage This was missing until now and the underlying _regulator_do_set_voltage is using this value when calling list_voltage. Signed-off-by: Heiko Stuebner Acked-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/gpio-regulator.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 2c38bea..242851a 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -101,7 +101,7 @@ static int gpio_regulator_get_value(struct regulator_dev *dev) } static int gpio_regulator_set_value(struct regulator_dev *dev, - int min, int max) + int min, int max, unsigned *selector) { struct gpio_regulator_data *data = rdev_get_drvdata(dev); int ptr, target = 0, state, best_val = INT_MAX; @@ -112,6 +112,8 @@ static int gpio_regulator_set_value(struct regulator_dev *dev, data->states[ptr].value <= max) { target = data->states[ptr].gpios; best_val = data->states[ptr].value; + if (selector) + *selector = ptr; } if (best_val == INT_MAX) @@ -130,7 +132,7 @@ static int gpio_regulator_set_voltage(struct regulator_dev *dev, int min_uV, int max_uV, unsigned *selector) { - return gpio_regulator_set_value(dev, min_uV, max_uV); + return gpio_regulator_set_value(dev, min_uV, max_uV, selector); } static int gpio_regulator_list_voltage(struct regulator_dev *dev, @@ -147,7 +149,7 @@ static int gpio_regulator_list_voltage(struct regulator_dev *dev, static int gpio_regulator_set_current_limit(struct regulator_dev *dev, int min_uA, int max_uA) { - return gpio_regulator_set_value(dev, min_uA, max_uA); + return gpio_regulator_set_value(dev, min_uA, max_uA, NULL); } static struct regulator_ops gpio_regulator_voltage_ops = { -- cgit v1.1 From 2e063c305a3da896ec3db99e66891411d0e38820 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 4 Jun 2012 13:36:34 +0530 Subject: OMAPDSS: DSI: Fix bug when calculating LP command interleaving parameters In function dsi_compute_interleave_lp(), the escape clock/LP clock time period is calculated incorrectly. The escape clock/LP clock is calculated as: LP Clock(Hz) = DSI_FCLK(Hz) / lp_clk_div Since we are calculating the time period of LP clock, the LP clock divider should be multiplied with the time period of DSI_FCLK. Calculating incorrect value of txclkesc results in incorrect calculation of LP interleaving parameters, it also creates a possibility of a divide by zero error. Reported-by: Sureshkumar Manimuthu Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index ec363d8..ca8382d 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3724,7 +3724,7 @@ static int dsi_compute_interleave_lp(int blank, int enter_hs, int exit_hs, /* CLKIN4DDR = 16 * TXBYTECLKHS */ tlp_avail = thsbyte_clk * (blank - trans_lp); - ttxclkesc = tdsi_fclk / lp_clk_div; + ttxclkesc = tdsi_fclk * lp_clk_div; lp_inter = ((tlp_avail - 8 * thsbyte_clk - 5 * tdsi_fclk) / ttxclkesc - 26) / 16; -- cgit v1.1 From 820234c86b982205aeeebde1ad71ccfe6bc4cc80 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:19 +0300 Subject: usb: gadget: atmel_usba_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/atmel_usba_udc.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index e23bf79..9a9bced 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -599,12 +599,6 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) spin_lock_irqsave(&ep->udc->lock, flags); - if (ep->ep.desc) { - spin_unlock_irqrestore(&ep->udc->lock, flags); - DBG(DBG_ERR, "ep%d already enabled\n", ep->index); - return -EBUSY; - } - ep->ep.desc = desc; ep->ep.maxpacket = maxpacket; -- cgit v1.1 From fc065a09524991a5138835c6499e895d6be14049 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:20 +0300 Subject: usb: gadget: fsl_qe_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_qe_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 51881f3..b09452d 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -1596,7 +1596,7 @@ static int qe_ep_enable(struct usb_ep *_ep, ep = container_of(_ep, struct qe_ep, ep); /* catch various bogus parameters */ - if (!_ep || !desc || ep->ep.desc || _ep->name == ep_name[0] || + if (!_ep || !desc || _ep->name == ep_name[0] || (desc->bDescriptorType != USB_DT_ENDPOINT)) return -EINVAL; -- cgit v1.1 From 1fa75972c7b9f165af102022aa0090fe0a3a6c16 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:21 +0300 Subject: usb: gadget: fsl_udc_core: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 2831685..7998418 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -567,7 +567,7 @@ static int fsl_ep_enable(struct usb_ep *_ep, ep = container_of(_ep, struct fsl_ep, ep); /* catch various bogus parameters */ - if (!_ep || !desc || ep->ep.desc + if (!_ep || !desc || (desc->bDescriptorType != USB_DT_ENDPOINT)) return -EINVAL; -- cgit v1.1 From aedaa44dd3214886d70fad92197b98a0ba286cb8 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:22 +0300 Subject: usb: gadget: goku_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/goku_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index b241e6c..3d28fb9 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -102,7 +102,7 @@ goku_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) unsigned long flags; ep = container_of(_ep, struct goku_ep, ep); - if (!_ep || !desc || ep->ep.desc + if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; dev = ep->dev; -- cgit v1.1 From e0f4f9d4c9138c40738104f80bd5008517fc712d Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:24 +0300 Subject: usb: gadget: mv_udc_core: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Acked-by: Yu Xu Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index dbcd132..117a4bb 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -464,7 +464,7 @@ static int mv_ep_enable(struct usb_ep *_ep, ep = container_of(_ep, struct mv_ep, ep); udc = ep->udc; - if (!_ep || !desc || ep->ep.desc + if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; -- cgit v1.1 From 77964b3ce862262e4a22d4e5093c158f72439a0b Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:25 +0300 Subject: usb: gadget: omap_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 7ba3246..a460e8c 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -153,7 +153,7 @@ static int omap_ep_enable(struct usb_ep *_ep, u16 maxp; /* catch various bogus parameters */ - if (!_ep || !desc || ep->ep.desc + if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT || ep->bEndpointAddress != desc->bEndpointAddress || ep->maxpacket < usb_endpoint_maxp(desc)) { -- cgit v1.1 From 3ba0b31aed94167998defadfbf17d2196db05814 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:26 +0300 Subject: usb: gadget: pxa25x_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa25x_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index d7c8cb3..f7ff9e8 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -218,7 +218,7 @@ static int pxa25x_ep_enable (struct usb_ep *_ep, struct pxa25x_udc *dev; ep = container_of (_ep, struct pxa25x_ep, ep); - if (!_ep || !desc || ep->ep.desc || _ep->name == ep0name + if (!_ep || !desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || ep->bEndpointAddress != desc->bEndpointAddress || ep->fifo_size < usb_endpoint_maxp (desc)) { -- cgit v1.1 From 0561ed440fbab943e1c881cab626bd7019647385 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:27 +0300 Subject: usb: gadget: s3c2410_udc: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 3de71d3..f2e51f5 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1062,7 +1062,7 @@ static int s3c2410_udc_ep_enable(struct usb_ep *_ep, ep = to_s3c2410_ep(_ep); - if (!_ep || !desc || ep->ep.desc + if (!_ep || !desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; -- cgit v1.1 From 109f0f718375e12bfdee53f025d85d94efed32a3 Mon Sep 17 00:00:00 2001 From: Ido Shayevitz Date: Mon, 4 Jun 2012 13:35:28 +0300 Subject: usb: gadget: s3c-hsudc.c: Remove unneeded condition The removed condition is always true, since the endpoint descriptor is set prior to calling the enable endpoint. Signed-off-by: Ido Shayevitz Acked-by: Heiko Stuebner Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 36c6836..236b271 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -760,7 +760,7 @@ static int s3c_hsudc_ep_enable(struct usb_ep *_ep, u32 ecr = 0; hsep = our_ep(_ep); - if (!_ep || !desc || hsep->ep.desc || _ep->name == ep0name + if (!_ep || !desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || hsep->bEndpointAddress != desc->bEndpointAddress || ep_maxpacket(hsep) < usb_endpoint_maxp(desc)) -- cgit v1.1 From 80e91fd59bc5291c6fe322551f644a58cf2c5e98 Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Mon, 4 Jun 2012 17:24:03 +0200 Subject: usb: gadget: regression fix - usage of usb_ep This patch removes redundant pointer to struct usb_endpoint_descriptor which were missed in commit 79149b8: usb: gadget: Update fsl_udc_core to use usb_endpoint_descriptor inside the struct usb_ep Due to clock framework regressions, this patch is only compile tested! Signed-off-by: Christoph Fritz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 2 +- drivers/usb/gadget/fsl_usb2_udc.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 7998418..bc6f9bb 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2575,7 +2575,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) /* for ep0: the desc defined here; * for other eps, gadget layer called ep_enable with defined desc */ - udc_controller->eps[0].desc = &fsl_ep0_desc; + udc_controller->eps[0].ep.desc = &fsl_ep0_desc; udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD; /* setup the udc->eps[] for non-control endpoints and link diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 5cd7b7e..f61a967 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h @@ -568,10 +568,10 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length) /* * ### internal used help routines. */ -#define ep_index(EP) ((EP)->desc->bEndpointAddress&0xF) +#define ep_index(EP) ((EP)->ep.desc->bEndpointAddress&0xF) #define ep_maxpacket(EP) ((EP)->ep.maxpacket) #define ep_is_in(EP) ( (ep_index(EP) == 0) ? (EP->udc->ep0_dir == \ - USB_DIR_IN ):((EP)->desc->bEndpointAddress \ + USB_DIR_IN) : ((EP)->ep.desc->bEndpointAddress \ & USB_DIR_IN)==USB_DIR_IN) #define get_ep_by_pipe(udc, pipe) ((pipe == 1)? &udc->eps[0]: \ &udc->eps[pipe]) -- cgit v1.1 From 6594b2d7b1ef8260e6e36ddc96bd37a40e39ba80 Mon Sep 17 00:00:00 2001 From: Jon Povey Date: Fri, 25 May 2012 10:50:18 +0900 Subject: usb: musb: davinci: Fix build breakage This appears to have been broken by commit 5cfb19ac604a68c030b245561f575c2d1bac1d49 (ARM: davinci: streamline sysmod access) For now, fix by hardcoding USB_PHY_CTRL and DM355_DEEPSLEEP Tested on DM365 with defconfig changes. Signed-off-by: Jon Povey Acked-by: Sekhar Nori CC: Felipe Balbi Cc: # v3.4.x Signed-off-by: Felipe Balbi --- drivers/usb/musb/davinci.c | 1 + drivers/usb/musb/davinci.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 768b4b5..9d63ba4 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -34,6 +34,7 @@ #include #include +#include #include diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h index 046c844..371baa0 100644 --- a/drivers/usb/musb/davinci.h +++ b/drivers/usb/musb/davinci.h @@ -15,7 +15,7 @@ */ /* Integrated highspeed/otg PHY */ -#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) +#define USBPHY_CTL_PADDR 0x01c40034 #define USBPHY_DATAPOL BIT(11) /* (dm355) switch D+/D- */ #define USBPHY_PHYCLKGD BIT(8) #define USBPHY_SESNDEN BIT(7) /* v(sess_end) comparator */ @@ -27,7 +27,7 @@ #define USBPHY_OTGPDWN BIT(1) #define USBPHY_PHYPDWN BIT(0) -#define DM355_DEEPSLEEP_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x48) +#define DM355_DEEPSLEEP_PADDR 0x01c40048 #define DRVVBUS_FORCE BIT(2) #define DRVVBUS_OVERRIDE BIT(1) -- cgit v1.1 From 08f75bf14fadaa81fe362d5acda9b77b113dd0a2 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 26 May 2012 00:21:33 +0300 Subject: usb: musb_gadget: fix crash caused by dangling pointer usb_ep_ops.disable must clear external copy of the endpoint descriptor, otherwise musb crashes after loading/unloading several gadget modules in a row: Unable to handle kernel paging request at virtual address bf013730 pgd = c0004000 [bf013730] *pgd=8f26d811, *pte=00000000, *ppte=00000000 Internal error: Oops: 7 [#1] Modules linked in: g_cdc [last unloaded: g_file_storage] CPU: 0 Not tainted (3.2.17 #647) PC is at musb_gadget_enable+0x4c/0x24c LR is at _raw_spin_lock_irqsave+0x4c/0x58 [] (musb_gadget_enable+0x4c/0x24c) from [] (gether_connect+0x3c/0x19c [g_cdc]) [] (gether_connect+0x3c/0x19c [g_cdc]) from [] (ecm_set_alt+0x15c/0x180 [g_cdc]) [] (ecm_set_alt+0x15c/0x180 [g_cdc]) from [] (composite_setup+0x85c/0xac4 [g_cdc]) [] (composite_setup+0x85c/0xac4 [g_cdc]) from [] (musb_g_ep0_irq+0x844/0x924) [] (musb_g_ep0_irq+0x844/0x924) from [] (musb_interrupt+0x79c/0x864) [] (musb_interrupt+0x79c/0x864) from [] (generic_interrupt+0x64/0x7c) [] (generic_interrupt+0x64/0x7c) from [] (handle_irq_event_percpu+0x28/0x178) ... Cc: stable@vger.kernel.org # v3.1+ Signed-off-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index f42c29b..95918da 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1232,6 +1232,7 @@ static int musb_gadget_disable(struct usb_ep *ep) } musb_ep->desc = NULL; + musb_ep->end_point.desc = NULL; /* abort all pending DMA and requests */ nuke(musb_ep, -ESHUTDOWN); -- cgit v1.1 From 9ec0db71af04f4560e27a3c2f5a0411ba3155198 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Mon, 4 Jun 2012 05:51:18 +0000 Subject: net: icplus: fix interrupt mask This patch fixes the interrupt mask for IC101 A/G devices and now enables the link/speed/duplex interrupts. This is done by setting the "INTR pin used" bit and cleaning all the other bits in the Register 17. Reported-by: Stuart Menefy Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/phy/icplus.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index 5ac46f5..47f8e89 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -41,6 +41,8 @@ MODULE_LICENSE("GPL"); #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ #define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ +#define IP101A_G_IRQ_PIN_USED (1<<15) /* INTR pin used */ +#define IP101A_G_IRQ_DEFAULT IP101A_G_IRQ_PIN_USED static int ip175c_config_init(struct phy_device *phydev) { @@ -136,6 +138,11 @@ static int ip1001_config_init(struct phy_device *phydev) if (c < 0) return c; + /* INTR pin used: speed/link/duplex will cause an interrupt */ + c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT); + if (c < 0) + return c; + if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { /* Additional delay (2ns) used to adjust RX clock phase * at RGMII interface */ -- cgit v1.1 From dc5cd894cace7bda4a743487a9f87d59a3f0a095 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 4 Jun 2012 06:42:38 +0000 Subject: net/hyperv: Use wait_event on outstanding sends during device removal Change the busy-waiting/udelay to wait_event on outstanding sends. Signed-off-by: Haiyang Zhang Reviewed-by: K. Y. Srinivasan Signed-off-by: David S. Miller --- drivers/net/hyperv/hyperv_net.h | 1 + drivers/net/hyperv/netvsc.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 4ffcd57..2857ab07 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -478,6 +478,7 @@ struct netvsc_device { u32 nvsp_version; atomic_t num_outstanding_sends; + wait_queue_head_t wait_drain; bool start_remove; bool destroy; /* diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 8b91947..0c56983 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -42,6 +42,7 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) if (!net_device) return NULL; + init_waitqueue_head(&net_device->wait_drain); net_device->start_remove = false; net_device->destroy = false; net_device->dev = device; @@ -387,12 +388,8 @@ int netvsc_device_remove(struct hv_device *device) spin_unlock_irqrestore(&device->channel->inbound_lock, flags); /* Wait for all send completions */ - while (atomic_read(&net_device->num_outstanding_sends)) { - dev_info(&device->device, - "waiting for %d requests to complete...\n", - atomic_read(&net_device->num_outstanding_sends)); - udelay(100); - } + wait_event(net_device->wait_drain, + atomic_read(&net_device->num_outstanding_sends) == 0); netvsc_disconnect_vsp(net_device); @@ -486,6 +483,9 @@ static void netvsc_send_completion(struct hv_device *device, num_outstanding_sends = atomic_dec_return(&net_device->num_outstanding_sends); + if (net_device->destroy && num_outstanding_sends == 0) + wake_up(&net_device->wait_drain); + if (netif_queue_stopped(ndev) && !net_device->start_remove && (hv_ringbuf_avail_percent(&device->channel->outbound) > RING_AVAIL_PERCENT_HIWATER || -- cgit v1.1 From f0e3bd23418e1ec1aeac5fc36b74bf2f645b1244 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Tue, 29 May 2012 15:39:04 -0700 Subject: mwifiex: invalidate bss config before setting channel for uAP Mark bss_config parameters as invalid before setting AP channel. This prevents from setting invalid parameters while setting AP channel to FW. Signed-off-by: Avinash Patil Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/uap_cmd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 76dfbc4..e9482c9 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -416,6 +416,7 @@ int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel) if (!bss_cfg) return -ENOMEM; + mwifiex_set_sys_config_invalid_data(bss_cfg); bss_cfg->band_cfg = BAND_CONFIG_MANUAL; bss_cfg->channel = channel; -- cgit v1.1 From 7a1c99343c5305c47b5e078d1af2144f9026df40 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Tue, 29 May 2012 15:39:05 -0700 Subject: mwifiex: support NL80211_HIDDEN_SSID_ZERO_LEN for uAP mwifiex uAP supports NL80211_HIDDEN_SSID_ZERO_LEN type of hidden SSID only. NL80211_HIDDEN_SSID_ZERO_CONTENTS is not supported. Signed-off-by: Avinash Patil Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 13 +++++++++++++ drivers/net/wireless/mwifiex/fw.h | 6 ++++++ drivers/net/wireless/mwifiex/uap_cmd.c | 9 +++++++++ 3 files changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 8767144..015fec3 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -948,6 +948,19 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, bss_cfg->ssid.ssid_len = params->ssid_len; } + switch (params->hidden_ssid) { + case NL80211_HIDDEN_SSID_NOT_IN_USE: + bss_cfg->bcast_ssid_ctl = 1; + break; + case NL80211_HIDDEN_SSID_ZERO_LEN: + bss_cfg->bcast_ssid_ctl = 0; + break; + case NL80211_HIDDEN_SSID_ZERO_CONTENTS: + /* firmware doesn't support this type of hidden SSID */ + default: + return -EINVAL; + } + if (mwifiex_set_secure_params(priv, bss_cfg, params)) { kfree(bss_cfg); wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 9f674bb..561452a 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -122,6 +122,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) #define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) +#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) #define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51) #define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60) #define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64) @@ -1209,6 +1210,11 @@ struct host_cmd_tlv_ssid { u8 ssid[0]; } __packed; +struct host_cmd_tlv_bcast_ssid { + struct host_cmd_tlv tlv; + u8 bcast_ctl; +} __packed; + struct host_cmd_tlv_beacon_period { struct host_cmd_tlv tlv; __le16 period; diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index e9482c9..8173ab6 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -132,6 +132,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) struct host_cmd_tlv_dtim_period *dtim_period; struct host_cmd_tlv_beacon_period *beacon_period; struct host_cmd_tlv_ssid *ssid; + struct host_cmd_tlv_bcast_ssid *bcast_ssid; struct host_cmd_tlv_channel_band *chan_band; struct host_cmd_tlv_frag_threshold *frag_threshold; struct host_cmd_tlv_rts_threshold *rts_threshold; @@ -153,6 +154,14 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) cmd_size += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len; tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len; + + bcast_ssid = (struct host_cmd_tlv_bcast_ssid *)tlv; + bcast_ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID); + bcast_ssid->tlv.len = + cpu_to_le16(sizeof(bcast_ssid->bcast_ctl)); + bcast_ssid->bcast_ctl = bss_cfg->bcast_ssid_ctl; + cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid); + tlv += sizeof(struct host_cmd_tlv_bcast_ssid); } if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) { chan_band = (struct host_cmd_tlv_channel_band *)tlv; -- cgit v1.1 From a5fdde28b4f5fb756032e7ad2c6fcdcffde20958 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 30 May 2012 10:36:12 +0200 Subject: iwlwifi: fix TX power antenna access Since my commit iwlwifi: use valid TX/RX antenna from hw_params the config values are pure overrides, not the real values for all hardware. Therefore, the EEPROM TX power reading code checks the wrong values, it should check the hw_params values. Cc: stable@kernel.org [3.4] Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 50c5891..b8e2b22 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -568,28 +568,28 @@ static int iwl_find_otp_image(struct iwl_trans *trans, * iwl_get_max_txpower_avg - get the highest tx power from all chains. * find the highest tx power from all chains for the channel */ -static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg, +static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, int element, s8 *max_txpower_in_half_dbm) { s8 max_txpower_avg = 0; /* (dBm) */ /* Take the highest tx power from any valid chains */ - if ((cfg->valid_tx_ant & ANT_A) && + if ((priv->hw_params.valid_tx_ant & ANT_A) && (enhanced_txpower[element].chain_a_max > max_txpower_avg)) max_txpower_avg = enhanced_txpower[element].chain_a_max; - if ((cfg->valid_tx_ant & ANT_B) && + if ((priv->hw_params.valid_tx_ant & ANT_B) && (enhanced_txpower[element].chain_b_max > max_txpower_avg)) max_txpower_avg = enhanced_txpower[element].chain_b_max; - if ((cfg->valid_tx_ant & ANT_C) && + if ((priv->hw_params.valid_tx_ant & ANT_C) && (enhanced_txpower[element].chain_c_max > max_txpower_avg)) max_txpower_avg = enhanced_txpower[element].chain_c_max; - if (((cfg->valid_tx_ant == ANT_AB) | - (cfg->valid_tx_ant == ANT_BC) | - (cfg->valid_tx_ant == ANT_AC)) && + if (((priv->hw_params.valid_tx_ant == ANT_AB) | + (priv->hw_params.valid_tx_ant == ANT_BC) | + (priv->hw_params.valid_tx_ant == ANT_AC)) && (enhanced_txpower[element].mimo2_max > max_txpower_avg)) max_txpower_avg = enhanced_txpower[element].mimo2_max; - if ((cfg->valid_tx_ant == ANT_ABC) && + if ((priv->hw_params.valid_tx_ant == ANT_ABC) && (enhanced_txpower[element].mimo3_max > max_txpower_avg)) max_txpower_avg = enhanced_txpower[element].mimo3_max; @@ -691,7 +691,7 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) ((txp->delta_20_in_40 & 0xf0) >> 4), (txp->delta_20_in_40 & 0x0f)); - max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx, + max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, &max_txp_avg_halfdbm); /* -- cgit v1.1 From 1ae2fc25a1289a84ca726541e3356ba5bcb7f7fe Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 30 May 2012 14:59:36 +0200 Subject: mac80211_hwsim: advertise interface combinations Enforcing interface combinations broke uses of hwsim with multiple virtual interfaces. Advertise that all combinations are possible to fix this. Reported-by: Nirav Shah Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index fb787df..4c9336c 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1721,6 +1721,24 @@ static void hwsim_exit_netlink(void) "unregister family %i\n", ret); } +static const struct ieee80211_iface_limit hwsim_if_limits[] = { + { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, + { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | +#ifdef CONFIG_MAC80211_MESH + BIT(NL80211_IFTYPE_MESH_POINT) | +#endif + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_GO) }, +}; + +static const struct ieee80211_iface_combination hwsim_if_comb = { + .limits = hwsim_if_limits, + .n_limits = ARRAY_SIZE(hwsim_if_limits), + .max_interfaces = 2048, + .num_different_channels = 1, +}; + static int __init init_mac80211_hwsim(void) { int i, err = 0; @@ -1782,6 +1800,9 @@ static int __init init_mac80211_hwsim(void) hw->wiphy->n_addresses = 2; hw->wiphy->addresses = data->addresses; + hw->wiphy->iface_combinations = &hwsim_if_comb; + hw->wiphy->n_iface_combinations = 1; + if (fake_hw_scan) { hw->wiphy->max_scan_ssids = 255; hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; -- cgit v1.1 From f304a993190965f48baa49792d5ab2849ae26bf9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 30 May 2012 13:25:56 -0700 Subject: brcmfmac: Fix likely misuse of | for & Using | with a constant is always true. Likely this should have be &. Signed-off-by: Joe Perches Acked-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index e2480d1..8e7e692 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -89,9 +89,9 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); - /* redirect, configure ane enable io for interrupt signal */ + /* redirect, configure and enable io for interrupt signal */ data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; - if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH) + if (sdiodev->irq_flags & IRQF_TRIGGER_HIGH) data |= SDIO_SEPINT_ACT_HI; brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); -- cgit v1.1 From e5851dac2c95af7159716832300b9f50c62c648e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 1 Jun 2012 11:29:40 +0200 Subject: rt2x00: use atomic variable for seqno Remove spinlock as atomic_t can be used instead. Note we use only 16 lower bits, upper bits are changed but we impilcilty cast to u16. This fix possible deadlock on IBSS mode reproted by lockdep: ================================= [ INFO: inconsistent lock state ] 3.4.0-wl+ #4 Not tainted --------------------------------- inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage. kworker/u:2/30374 [HC0[0]:SC0[0]:HE1:SE1] takes: (&(&intf->seqlock)->rlock){+.?...}, at: [] rt2x00queue_create_tx_descriptor+0x380/0x490 [rt2x00lib] {IN-SOFTIRQ-W} state was registered at: [] __lock_acquire+0x47b/0x1050 [] lock_acquire+0x84/0xf0 [] _raw_spin_lock+0x33/0x40 [] rt2x00queue_create_tx_descriptor+0x380/0x490 [rt2x00lib] [] rt2x00queue_write_tx_frame+0x1a/0x300 [rt2x00lib] [] rt2x00mac_tx+0x7f/0x380 [rt2x00lib] [] __ieee80211_tx+0x1b3/0x300 [mac80211] [] ieee80211_tx+0x105/0x130 [mac80211] [] ieee80211_xmit+0xad/0x100 [mac80211] [] ieee80211_subif_start_xmit+0x2d9/0x930 [mac80211] [] dev_hard_start_xmit+0x307/0x660 [] sch_direct_xmit+0xa1/0x1e0 [] dev_queue_xmit+0x183/0x730 [] neigh_resolve_output+0xfa/0x1e0 [] ip_finish_output+0x24a/0x460 [] ip_output+0xb7/0x100 [] ip_local_out+0x20/0x60 [] igmpv3_sendpack+0x4f/0x60 [] igmp_ifc_timer_expire+0x29f/0x330 [] run_timer_softirq+0x15c/0x2f0 [] __do_softirq+0xae/0x1e0 irq event stamp: 18380437 hardirqs last enabled at (18380437): [] __slab_alloc.clone.3+0x67/0x5f0 hardirqs last disabled at (18380436): [] __slab_alloc.clone.3+0x33/0x5f0 softirqs last enabled at (18377616): [] __do_softirq+0x123/0x1e0 softirqs last disabled at (18377611): [] do_softirq+0x9d/0xe0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&(&intf->seqlock)->rlock); lock(&(&intf->seqlock)->rlock); *** DEADLOCK *** 4 locks held by kworker/u:2/30374: #0: (wiphy_name(local->hw.wiphy)){++++.+}, at: [] process_one_work+0x109/0x3f0 #1: ((&sdata->work)){+.+.+.}, at: [] process_one_work+0x109/0x3f0 #2: (&ifibss->mtx){+.+.+.}, at: [] ieee80211_ibss_work+0x1b/0x470 [mac80211] #3: (&intf->beacon_skb_mutex){+.+...}, at: [] rt2x00queue_update_beacon+0x24/0x50 [rt2x00lib] stack backtrace: Pid: 30374, comm: kworker/u:2 Not tainted 3.4.0-wl+ #4 Call Trace: [] print_usage_bug+0x1f6/0x220 [] mark_lock+0x2c2/0x300 [] ? check_usage_forwards+0xc0/0xc0 [] __lock_acquire+0x4bc/0x1050 [] ? __kmalloc_track_caller+0x1c0/0x1d0 [] ? copy_skb_header+0x26/0x90 [] lock_acquire+0x84/0xf0 [] ? rt2x00queue_create_tx_descriptor+0x380/0x490 [rt2x00lib] [] _raw_spin_lock+0x33/0x40 [] ? rt2x00queue_create_tx_descriptor+0x380/0x490 [rt2x00lib] [] rt2x00queue_create_tx_descriptor+0x380/0x490 [rt2x00lib] [] rt2x00queue_update_beacon_locked+0x5f/0xb0 [rt2x00lib] [] rt2x00queue_update_beacon+0x2d/0x50 [rt2x00lib] [] rt2x00mac_bss_info_changed+0x1ca/0x200 [rt2x00lib] [] ? rt2x00mac_remove_interface+0x70/0x70 [rt2x00lib] [] ieee80211_bss_info_change_notify+0xe0/0x1d0 [mac80211] [] __ieee80211_sta_join_ibss+0x3b8/0x610 [mac80211] [] ? mark_held_locks+0x64/0xc0 [] ? virt_efi_query_capsule_caps+0x12/0x50 [] ieee80211_sta_join_ibss+0xf9/0x140 [mac80211] [] ieee80211_ibss_work+0x416/0x470 [mac80211] [] ? trace_hardirqs_on+0xb/0x10 [] ? skb_dequeue+0x4b/0x70 [] ieee80211_iface_work+0x13f/0x230 [mac80211] [] ? process_one_work+0x109/0x3f0 [] process_one_work+0x185/0x3f0 [] ? process_one_work+0x109/0x3f0 [] ? ieee80211_teardown_sdata+0xa0/0xa0 [mac80211] [] worker_thread+0x116/0x270 [] ? manage_workers+0x1e0/0x1e0 [] kthread+0x84/0x90 [] ? __init_kthread_worker+0x60/0x60 [] kernel_thread_helper+0x6/0x10 Cc: stable@vger.kernel.org Signed-off-by: Stanislaw Gruszka Acked-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 3 +-- drivers/net/wireless/rt2x00/rt2x00mac.c | 1 - drivers/net/wireless/rt2x00/rt2x00queue.c | 13 ++++++------- 3 files changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index ca36ccc..8f75402 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -396,8 +396,7 @@ struct rt2x00_intf { * for hardware which doesn't support hardware * sequence counting. */ - spinlock_t seqlock; - u16 seqno; + atomic_t seqno; }; static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index b49773e..dd24b26 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -277,7 +277,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, else rt2x00dev->intf_sta_count++; - spin_lock_init(&intf->seqlock); mutex_init(&intf->beacon_skb_mutex); intf->beacon = entry; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 4c662ec..2fd8301 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -207,6 +207,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); + u16 seqno; if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) return; @@ -238,15 +239,13 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, * sequence counting per-frame, since those will override the * sequence counter given by mac80211. */ - spin_lock(&intf->seqlock); - if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) - intf->seqno += 0x10; - hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); - hdr->seq_ctrl |= cpu_to_le16(intf->seqno); - - spin_unlock(&intf->seqlock); + seqno = atomic_add_return(0x10, &intf->seqno); + else + seqno = atomic_read(&intf->seqno); + hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); + hdr->seq_ctrl |= cpu_to_le16(seqno); } static void rt2x00queue_create_tx_descriptor_plcp(struct rt2x00_dev *rt2x00dev, -- cgit v1.1 From 69aaedd3cfd23b2c732e3cf1227370a35f5c89d4 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Fri, 1 Jun 2012 09:13:17 -0500 Subject: bcma: add ext PA workaround for BCM4331 and BCM43431 MacBook Pro models with BCM4331 wireless have been found to have the ext PA lines disabled after resuming from S3 without external power attach. This causes them to be unable to transmit. Add a workaround to ensure that the ext PA lines are enabled on BCM4331. Also extend all handling of ext PA line muxing to BCM43431 as is done in the Broadcom SDK. BugLink: http://bugs.launchpad.net/bugs/925577 Cc: Arend van Spriel Cc: Hauke Mehrtens Cc: stable@vger.kernel.org Signed-off-by: Seth Forshee Signed-off-by: John W. Linville --- drivers/bcma/driver_chipcommon_pmu.c | 4 +++- drivers/bcma/sprom.c | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index a058842..61ce405 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c @@ -139,7 +139,9 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc) bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7); break; case 0x4331: - /* BCM4331 workaround is SPROM-related, we put it in sprom.c */ + case 43431: + /* Ext PA lines must be enabled for tx on BCM4331 */ + bcma_chipco_bcm4331_ext_pa_lines_ctl(cc, true); break; case 43224: if (bus->chipinfo.rev == 0) { diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index c7f9335..f16f42d3 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -579,13 +579,13 @@ int bcma_sprom_get(struct bcma_bus *bus) if (!sprom) return -ENOMEM; - if (bus->chipinfo.id == 0x4331) + if (bus->chipinfo.id == 0x4331 || bus->chipinfo.id == 43431) bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); pr_debug("SPROM offset 0x%x\n", offset); bcma_sprom_read(bus, offset, sprom); - if (bus->chipinfo.id == 0x4331) + if (bus->chipinfo.id == 0x4331 || bus->chipinfo.id == 43431) bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); err = bcma_sprom_valid(sprom); -- cgit v1.1 From fcb6ff5e2cb83e1de10631f6621f45ca3401bf61 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 4 Jun 2012 13:43:11 +0200 Subject: iwlwifi: disable WoWLAN if !CONFIG_PM_SLEEP If CONFIG_PM_SLEEP is disabled, then iwlwifi doesn't support suspend/resume handlers and thus mac80211 (correctly) refuses advertising WoWLAN. Disable WoWLAN in the driver in this case. Cc: stable@kernel.org Reported-by: Sebastian Kemper Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index ab2f4d75..5d158ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -199,6 +199,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_IBSS_RSN; +#ifdef CONFIG_PM_SLEEP if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && priv->trans->ops->wowlan_suspend && device_can_wakeup(priv->trans->dev)) { @@ -217,6 +218,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, hw->wiphy->wowlan.pattern_max_len = IWLAGN_WOWLAN_MAX_PATTERN_LEN; } +#endif if (iwlwifi_mod_params.power_save) hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; -- cgit v1.1 From 9f132652d94c96476b0b0a8caf0c10e96ab10fa8 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 5 Jun 2012 00:02:05 -0400 Subject: ACPI sysfs.c strlen fix Current code is ignoring the last character of "enable" and "disable" in comparisons. https://bugzilla.kernel.org/show_bug.cgi?id=33732 Signed-off-by: Len Brown --- drivers/acpi/sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 9f66181..240a244 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) { int result = 0; - if (!strncmp(val, "enable", strlen("enable") - 1)) { + if (!strncmp(val, "enable", strlen("enable"))) { result = acpi_debug_trace(trace_method_name, trace_debug_level, trace_debug_layer, 0); if (result) @@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) goto exit; } - if (!strncmp(val, "disable", strlen("disable") - 1)) { + if (!strncmp(val, "disable", strlen("disable"))) { int name = 0; result = acpi_debug_trace((char *)&name, trace_debug_level, trace_debug_layer, 0); -- cgit v1.1 From 04723de09d034c1f1f871787ebbc6cc2e474dd2f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 May 2012 12:30:02 +0200 Subject: staging:iio: remove num_interrupt_lines from documentation Commit 5aa9618896e0ba49 ("staging:iio: remove broken support for multiple event interfaces.") removed the num_interrupt_lines field from struct iio_info but the documentation was never updated. Signed-off-by: Johan Hovold Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/device.txt | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt index 0338c7c..f03fbd3 100644 --- a/drivers/staging/iio/Documentation/device.txt +++ b/drivers/staging/iio/Documentation/device.txt @@ -29,8 +29,6 @@ Then fill in the following: * info->driver_module: Set to THIS_MODULE. Used to ensure correct ownership of various resources allocate by the core. - * info->num_interrupt_lines: - Number of event triggering hardware lines the device has. * info->event_attrs: Attributes used to enable / disable hardware events. * info->attrs: -- cgit v1.1 From e407fd655bf9b40c38cba29aa7d38149989798bb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Jun 2012 10:41:42 +0200 Subject: iio: Fix potential use after free There is no guarantee that the last reference to the iio device has already been dropped when iio_device_free is called. This means that we can up calling iio_dev_release after iio_device_free which will lead to a use after free. As the general rule the struct containing the device should always be freed in the release callback. This is what this patch does, it moves freeing the iio device struct as well as releasing the idr reference to the release callback. To ensure that the device is not freed before calling iio_device_free the device_unregister call in iio_device_unregister is broken apart. iio_device_unregister will now only call device_del to remove the device from the system and iio_device_free will call put_device to drop the reference we obtained in iio_devce_alloc. We also have to take care that calling iio_device_free without having called iio_device_register still works (i.e. this can happen if something failed during device initialization). For this to work properly two minor changes were necessary: channel_attr_list needs to be initialized in iio_device_alloc and we have to check whether the chrdev has been registered before releasing it in iio_device_release. This change also brings iio_device_unregister and iio_device_free more in sync with iio_device_register and iio_device_alloc which call device_add and device_initialize respectively. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-core.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 1ddd886..4f947e4 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -661,7 +661,6 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) * New channel registration method - relies on the fact a group does * not need to be initialized if it is name is NULL. */ - INIT_LIST_HEAD(&indio_dev->channel_attr_list); if (indio_dev->channels) for (i = 0; i < indio_dev->num_channels; i++) { ret = iio_device_add_channel_sysfs(indio_dev, @@ -725,12 +724,16 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) static void iio_dev_release(struct device *device) { struct iio_dev *indio_dev = dev_to_iio_dev(device); - cdev_del(&indio_dev->chrdev); + if (indio_dev->chrdev.dev) + cdev_del(&indio_dev->chrdev); if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) iio_device_unregister_trigger_consumer(indio_dev); iio_device_unregister_eventset(indio_dev); iio_device_unregister_sysfs(indio_dev); iio_device_unregister_debugfs(indio_dev); + + ida_simple_remove(&iio_ida, indio_dev->id); + kfree(indio_dev); } static struct device_type iio_dev_type = { @@ -761,6 +764,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) dev_set_drvdata(&dev->dev, (void *)dev); mutex_init(&dev->mlock); mutex_init(&dev->info_exist_lock); + INIT_LIST_HEAD(&dev->channel_attr_list); dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); if (dev->id < 0) { @@ -778,10 +782,8 @@ EXPORT_SYMBOL(iio_device_alloc); void iio_device_free(struct iio_dev *dev) { - if (dev) { - ida_simple_remove(&iio_ida, dev->id); - kfree(dev); - } + if (dev) + put_device(&dev->dev); } EXPORT_SYMBOL(iio_device_free); @@ -902,7 +904,7 @@ void iio_device_unregister(struct iio_dev *indio_dev) mutex_lock(&indio_dev->info_exist_lock); indio_dev->info = NULL; mutex_unlock(&indio_dev->info_exist_lock); - device_unregister(&indio_dev->dev); + device_del(&indio_dev->dev); } EXPORT_SYMBOL(iio_device_unregister); subsys_initcall(iio_init); -- cgit v1.1 From 61663171bea0ccb499f0818234c5be7ea6c4c791 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 5 Jun 2012 18:10:10 +0800 Subject: regulator: max8649: fix missing regmap in rdev In probe(), rdev->regmap must be assigned. Signed-off-by: Haojian Zhuang Signed-off-by: Mark Brown --- drivers/regulator/max8649.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 1f4bb80..9d540cd 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -259,6 +259,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, config.dev = &client->dev; config.init_data = pdata->regulator; config.driver_data = info; + config.regmap = info->regmap; info->regulator = regulator_register(&dcdc_desc, &config); if (IS_ERR(info->regulator)) { -- cgit v1.1 From f69a23b795d6ee3673583146ed7efcbaaa5add18 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Jun 2012 19:56:06 +0200 Subject: iwlwifi: fix double free/complete in firmware loading Linus reported that due to mac80211 failing to register the device (due to WoWLAN) his machine crashed etc. as we double-freed the vmalloc() firmware area. His patch to fix it was very similar to this one but I noticed that there's another bug in the area: we complete the completion before starting, so since we're running in a work struct context stop() could be called while in the middle of start() which will almost certainly lead to issues. Make a modification similar to his to avoid the double- free but also move the completion to another spot so it is only done after start() either finished or failed so that stop() can have a consistent state. Reported-by: Linus Torvalds Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-drv.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index d742900..fac67a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -861,13 +861,18 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) /* We have our copies now, allow OS release its copies */ release_firmware(ucode_raw); - complete(&drv->request_firmware_complete); drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); if (!drv->op_mode) - goto out_free_fw; + goto out_unbind; + /* + * Complete the firmware request last so that + * a driver unbind (stop) doesn't run while we + * are doing the start() above. + */ + complete(&drv->request_firmware_complete); return; try_again: -- cgit v1.1 From 0e1fa7ef25004b9c1a14147bce61c15c2f1c6744 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Jun 2012 09:38:35 +0200 Subject: iwlwifi: unregister LEDs if mac80211 registration fails Otherwise the LEDs stick around and cause issues the next time around since they're still there but not really hooked up. Cc: stable@kernel.org Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 5d158ca..3ee23134 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -251,6 +251,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ret = ieee80211_register_hw(priv->hw); if (ret) { IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); + iwl_leds_exit(priv); return ret; } priv->mac80211_registered = 1; -- cgit v1.1 From 5c888aa43ee9872efe2a09e8c9f03db84f60dd28 Mon Sep 17 00:00:00 2001 From: Emil Goode Date: Tue, 29 May 2012 18:57:00 +0200 Subject: video: bfin_adv7393fb: Convert to kstrtouint_from_user This patch removes a call to the deprecated simple_strtoul function and simplifies the code by replacing two function calls with one call to kstrtouint_from_user. -Simplify the adv7393_write_proc function by replacing the simple_strtoul and copy_from_user calls with one call to kstrtouint_from_user. -Change the count parameter from unsigned long to size_t as this is the type that the kstrtouint_from_user function expects. (size_t is what will be passed to the adv7393_write_proc function by the proc write handler function proc_file_write anyway) Signed-off-by: Emil Goode Signed-off-by: Florian Tobias Schandinat --- drivers/video/bfin_adv7393fb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/bfin_adv7393fb.c index 33ea874..9bdd4b0 100644 --- a/drivers/video/bfin_adv7393fb.c +++ b/drivers/video/bfin_adv7393fb.c @@ -353,18 +353,16 @@ adv7393_read_proc(char *page, char **start, off_t off, static int adv7393_write_proc(struct file *file, const char __user * buffer, - unsigned long count, void *data) + size_t count, void *data) { struct adv7393fb_device *fbdev = data; - char line[8]; unsigned int val; int ret; - ret = copy_from_user(line, buffer, count); + ret = kstrtouint_from_user(buffer, count, 0, &val); if (ret) return -EFAULT; - val = simple_strtoul(line, NULL, 0); adv7393_write(fbdev->client, val >> 8, val & 0xff); return count; -- cgit v1.1 From a2c658505bf5c75516ee0a79287223e86a2474af Mon Sep 17 00:00:00 2001 From: "nagalakshmi.nandigama@lsi.com" Date: Tue, 17 Apr 2012 11:25:04 +0530 Subject: [SCSI] mpt2sas: Fix unsafe using smp_processor_id() in preemptible When CONFIG_DEBUG_PREEMPT is enabled, bug is observed in the smp_processor_id(). This is because smp_processor_id() is not called in preempt safe condition. To fix this issue, use raw_smp_processor_id instead of smp_processor_id. Signed-off-by: Nagalakshmi Nandigama CC: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/mpt2sas/mpt2sas_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 6102ef2..9d46fcb 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -1792,7 +1792,7 @@ static inline void _base_writeq(__u64 b, volatile void __iomem *addr, static inline u8 _base_get_msix_index(struct MPT2SAS_ADAPTER *ioc) { - return ioc->cpu_msix_table[smp_processor_id()]; + return ioc->cpu_msix_table[raw_smp_processor_id()]; } /** -- cgit v1.1 From 470a54207ccf7045a59df727573bd9d148988582 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 26 May 2012 06:08:48 +0000 Subject: e1000e: test for valid check_reset_block function pointer commit 44abd5c12767a8c567dc4e45fd9aec3b13ca85e0 introduced NULL pointer dereferences when attempting to access the check_reset_block function pointer on 8257x and 80003es2lan non-copper devices. This fix should be applied back through 3.4. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ethtool.c | 6 ++++-- drivers/net/ethernet/intel/e1000e/mac.c | 2 +- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- drivers/net/ethernet/intel/e1000e/phy.c | 8 +++++--- 4 files changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index d863075..905e214 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -258,7 +258,8 @@ static int e1000_set_settings(struct net_device *netdev, * When SoL/IDER sessions are active, autoneg/speed/duplex * cannot be changed */ - if (hw->phy.ops.check_reset_block(hw)) { + if (hw->phy.ops.check_reset_block && + hw->phy.ops.check_reset_block(hw)) { e_err("Cannot change link characteristics when SoL/IDER is active.\n"); return -EINVAL; } @@ -1615,7 +1616,8 @@ static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data) * PHY loopback cannot be performed if SoL/IDER * sessions are active */ - if (hw->phy.ops.check_reset_block(hw)) { + if (hw->phy.ops.check_reset_block && + hw->phy.ops.check_reset_block(hw)) { e_err("Cannot do PHY loopback test when SoL/IDER is active.\n"); *data = 0; goto out; diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index 026e8b3..a134399 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -709,7 +709,7 @@ s32 e1000e_setup_link_generic(struct e1000_hw *hw) * In the case of the phy reset being blocked, we already have a link. * We do not need to set it up again. */ - if (hw->phy.ops.check_reset_block(hw)) + if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw)) return 0; /* diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index a4b0435..31d37a2 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -6237,7 +6237,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, adapter->hw.phy.ms_type = e1000_ms_hw_default; } - if (hw->phy.ops.check_reset_block(hw)) + if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw)) e_info("PHY reset is blocked due to SOL/IDER session.\n"); /* Set initial default active device features */ @@ -6404,7 +6404,7 @@ err_register: if (!(adapter->flags & FLAG_HAS_AMT)) e1000e_release_hw_control(adapter); err_eeprom: - if (!hw->phy.ops.check_reset_block(hw)) + if (hw->phy.ops.check_reset_block && !hw->phy.ops.check_reset_block(hw)) e1000_phy_hw_reset(&adapter->hw); err_hw_init: kfree(adapter->tx_ring); diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 0334d01..b860d4f 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -2155,9 +2155,11 @@ s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw) s32 ret_val; u32 ctrl; - ret_val = phy->ops.check_reset_block(hw); - if (ret_val) - return 0; + if (phy->ops.check_reset_block) { + ret_val = phy->ops.check_reset_block(hw); + if (ret_val) + return 0; + } ret_val = phy->ops.acquire(hw); if (ret_val) -- cgit v1.1 From 146d4cc98d660cbdeae52ae35a4d038d0dab6da5 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 15 May 2012 05:59:26 +0000 Subject: ixgbe: fix_features rxvlan is independent of DCB and needs to be set DCB can be used independent of if RX VLAN stripping is enabled or disabled so remove erroneous check. Also enable or disable VLAN stripping when features are applied so hardware and feature flags are in sync. CC: Alexander Duyck Signed-off-by: John Fastabend Tested-by: Marcus Dennis Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index bf20457..b8b2087 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3607,10 +3607,6 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) if (hw->mac.type == ixgbe_mac_82598EB) netif_set_gso_max_size(adapter->netdev, 32768); - - /* Enable VLAN tag insert/strip */ - adapter->netdev->features |= NETIF_F_HW_VLAN_RX; - hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); #ifdef IXGBE_FCOE @@ -6701,11 +6697,6 @@ static netdev_features_t ixgbe_fix_features(struct net_device *netdev, { struct ixgbe_adapter *adapter = netdev_priv(netdev); -#ifdef CONFIG_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) - features &= ~NETIF_F_HW_VLAN_RX; -#endif - /* return error if RXHASH is being enabled when RSS is not supported */ if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) features &= ~NETIF_F_RXHASH; @@ -6718,7 +6709,6 @@ static netdev_features_t ixgbe_fix_features(struct net_device *netdev, if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) features &= ~NETIF_F_LRO; - return features; } @@ -6766,6 +6756,11 @@ static int ixgbe_set_features(struct net_device *netdev, need_reset = true; } + if (features & NETIF_F_HW_VLAN_RX) + ixgbe_vlan_strip_enable(adapter); + else + ixgbe_vlan_strip_disable(adapter); + if (changed & NETIF_F_RXALL) need_reset = true; -- cgit v1.1 From 43e95f11ac0b06fec2c58431b092a60934d730e2 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 15 May 2012 06:12:17 +0000 Subject: ixgbe: IXGBE_RXD_STAT_VP set even with Rx stripping enabled The hardware bit IXGBE_RXD_STAT_VP appears to be set even when Rx stripping is disabled. This results in passing frames up the stack which do not have the 802.1Q tag stripped but have the tci bits set as if it was. Working around this with a check for the feature flag bit. I would welcome any better ideas or a pointer to exactly which bits in the hardware register need to be cleared to get the IXGBE_RXD_STAT_VP bit to be set per data sheet. Signed-off-by: John Fastabend Acked-by: Alexander Duyck Tested-by: Marcus Dennis Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index b8b2087..17ad6a3 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1390,6 +1390,8 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, union ixgbe_adv_rx_desc *rx_desc, struct sk_buff *skb) { + struct net_device *dev = rx_ring->netdev; + ixgbe_update_rsc_stats(rx_ring, skb); ixgbe_rx_hash(rx_ring, rx_desc, skb); @@ -1401,14 +1403,15 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb); #endif - if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { + if ((dev->features & NETIF_F_HW_VLAN_RX) && + ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); __vlan_hwaccel_put_tag(skb, vid); } skb_record_rx_queue(skb, rx_ring->queue_index); - skb->protocol = eth_type_trans(skb, rx_ring->netdev); + skb->protocol = eth_type_trans(skb, dev); } static void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector, -- cgit v1.1 From 09eeff52bf20d485bcafc441f01c142c59c3da16 Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Fri, 1 Jun 2012 10:39:45 -0400 Subject: mmc: sdhci: Use DBG() instead of pr_warning() on large timeout 3bdc9ba892d6 ("mmc: use really long write timeout to deal with crappy cards") in 3.4 increased the write timeout that the core sends to host drivers to 3 seconds. This makes sdhci's "requested timeout too large" warning trigger on every write; so, change this pr_warning() to a DBG(). Reported-by: Adrian Hunter Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index e626732..f4b8b4d 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -680,8 +680,8 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) } if (count >= 0xF) { - pr_warning("%s: Too large timeout 0x%x requested for CMD%d!\n", - mmc_hostname(host->mmc), count, cmd->opcode); + DBG("%s: Too large timeout 0x%x requested for CMD%d!\n", + mmc_hostname(host->mmc), count, cmd->opcode); count = 0xE; } -- cgit v1.1 From b87cc1b5d3a96ef9f1b3a4f8ce7aaff18e96c994 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Wed, 23 May 2012 15:52:15 +0200 Subject: mmc: atmel-mci: fix data timeout issue The data timeout timer was configured after mmc_add_host call. So, with bad timings, it was possible to have a mmc request causing mod_timer call on a non setup timer. Signed-off-by: Ludovic Desroches Signed-off-by: Chris Ball --- drivers/mmc/host/atmel-mci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 420aca6..456c077 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -2314,6 +2314,8 @@ static int __init atmci_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); + setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); + /* We need at least one slot to succeed */ nr_slots = 0; ret = -ENODEV; @@ -2352,8 +2354,6 @@ static int __init atmci_probe(struct platform_device *pdev) } } - setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); - dev_info(&pdev->dev, "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", host->mapbase, irq, nr_slots); -- cgit v1.1 From 693e5e2025278d90e1427f037e5ec8ea1ec7d5c4 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 6 Jun 2012 12:19:44 +0200 Subject: mmc: atmel-mci: fix burst/chunk size modification The use of DMA slave config operation requires that the burst size (aka chunk size) is specified through this interface. Modify atmel-mci slave driver to use this specification on its side. Signed-off-by: Nicolas Ferre Signed-off-by: Ludovic Desroches Signed-off-by: Chris Ball --- drivers/mmc/host/atmel-mci-regs.h | 14 ++++++++++++++ drivers/mmc/host/atmel-mci.c | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h index 787aba1..ab56f7d 100644 --- a/drivers/mmc/host/atmel-mci-regs.h +++ b/drivers/mmc/host/atmel-mci-regs.h @@ -140,4 +140,18 @@ #define atmci_writel(port,reg,value) \ __raw_writel((value), (port)->regs + reg) +/* + * Fix sconfig's burst size according to atmel MCI. We need to convert them as: + * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3. + * + * This can be done by finding most significant bit set. + */ +static inline unsigned int atmci_convert_chksize(unsigned int maxburst) +{ + if (maxburst > 1) + return fls(maxburst) - 2; + else + return 0; +} + #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */ diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 456c077..f2c115e 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -910,6 +910,7 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) enum dma_data_direction direction; enum dma_transfer_direction slave_dirn; unsigned int sglen; + u32 maxburst; u32 iflags; data->error = -EINPROGRESS; @@ -943,17 +944,18 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) if (!chan) return -ENODEV; - if (host->caps.has_dma) - atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(3) | ATMCI_DMAEN); - if (data->flags & MMC_DATA_READ) { direction = DMA_FROM_DEVICE; host->dma_conf.direction = slave_dirn = DMA_DEV_TO_MEM; + maxburst = atmci_convert_chksize(host->dma_conf.src_maxburst); } else { direction = DMA_TO_DEVICE; host->dma_conf.direction = slave_dirn = DMA_MEM_TO_DEV; + maxburst = atmci_convert_chksize(host->dma_conf.dst_maxburst); } + atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) | ATMCI_DMAEN); + sglen = dma_map_sg(chan->device->dev, data->sg, data->sg_len, direction); -- cgit v1.1 From 2a0fe914a38745f5b03534c4e4f4056cbd6978b8 Mon Sep 17 00:00:00 2001 From: Yong Ding Date: Tue, 15 May 2012 13:09:43 +0800 Subject: mmc: sdio: fix setting card data bus width as 4-bit SDIO_CCCR_IF[1:0] in SDIO card is used for card data bus width setting as below: 00b: 1-bit bus 01b: Reserved 10b: 4-bit bus 11b: 8-bit bus (only for embedded SDIO) And sdio_enable_wide is for setting data bus width as 4-bit. But currently, it first reads the register, second OR' 1b with SDIO_CCCR_IF[1], and then writes it back. As we can see, this is based on such assumption that the SDIO_CCCR_IF[0] is always 0. Apparently, this is not right. Signed-off-by: Yong Ding Acked-by: Philip Rakity Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 13d0e95..41c5fd8 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -218,6 +218,12 @@ static int sdio_enable_wide(struct mmc_card *card) if (ret) return ret; + if ((ctrl & SDIO_BUS_WIDTH_MASK) == SDIO_BUS_WIDTH_RESERVED) + pr_warning("%s: SDIO_CCCR_IF is invalid: 0x%02x\n", + mmc_hostname(card->host), ctrl); + + /* set as 4-bit bus width */ + ctrl &= ~SDIO_BUS_WIDTH_MASK; ctrl |= SDIO_BUS_WIDTH_4BIT; ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); -- cgit v1.1 From eed6c63cefaf935e6fb28c4dd9977a280ae544a8 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Sun, 20 May 2012 13:27:21 +0900 Subject: mmc: dw_mmc: fix the transmission handling in IDMAC DTO interrupt can be later than transmit interrupt(IDMAC) in case of write. Current handling of IDMAC interrupt sets EVENT_DATA_COMPLETE as well as EVENT_XFER_COMPLETE regardless of DTO rising. This makes the current request finish in tasklet and permits the next request even though current data transfer is still in progress. As a result, sequence is broken and lock-up happens. Setting EVENT_DATA_COMPLETE is not proper after IDMAC interrupt. It should be taken after DTO interrupt is generated. Reported-by: Dmitry Shmidt Signed-off-by: Seungwon Jeon Signed-off-by: Hyeonsu Kim Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 9bbf45f..b46faf0 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1623,7 +1623,6 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) { mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI); mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI); - set_bit(EVENT_DATA_COMPLETE, &host->pending_events); host->dma_ops->complete(host); } #endif -- cgit v1.1 From 141a712a4eb09639dd4973a7c5e6999e3b8ae04a Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Tue, 22 May 2012 13:01:03 +0900 Subject: mmc: dw_mmc: fix the IDMAC sw reset IDMAC may not be cleaned in driver probe if it has been already used in boot time. So IDMAC needs sw reset newly. And DMA interface reset precedes the internal DMAC reset. Additionally SDMMC_IDMAC_SWRESET is replaced with magic code. Signed-off-by: Seungwon Jeon Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index b46faf0..98fe023 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -418,6 +418,8 @@ static int dw_mci_idmac_init(struct dw_mci *host) p->des3 = host->sg_dma; p->des0 = IDMAC_DES0_ER; + mci_writel(host, BMOD, SDMMC_IDMAC_SWRESET); + /* Mask out interrupts - get Tx & Rx complete only */ mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); @@ -1724,7 +1726,8 @@ static void dw_mci_work_routine_card(struct work_struct *work) #ifdef CONFIG_MMC_DW_IDMAC ctrl = mci_readl(host, BMOD); - ctrl |= 0x01; /* Software reset of DMA */ + /* Software reset of DMA */ + ctrl |= SDMMC_IDMAC_SWRESET; mci_writel(host, BMOD, ctrl); #endif @@ -1949,10 +1952,6 @@ int dw_mci_probe(struct dw_mci *host) spin_lock_init(&host->lock); INIT_LIST_HEAD(&host->queue); - - host->dma_ops = host->pdata->dma_ops; - dw_mci_init_dma(host); - /* * Get the host data width - this assumes that HCON has been set with * the correct values. @@ -1980,10 +1979,11 @@ int dw_mci_probe(struct dw_mci *host) } /* Reset all blocks */ - if (!mci_wait_reset(&host->dev, host)) { - ret = -ENODEV; - goto err_dmaunmap; - } + if (!mci_wait_reset(&host->dev, host)) + return -ENODEV; + + host->dma_ops = host->pdata->dma_ops; + dw_mci_init_dma(host); /* Clear the interrupts for the host controller */ mci_writel(host, RINTSTS, 0xFFFFFFFF); @@ -2169,14 +2169,14 @@ int dw_mci_resume(struct dw_mci *host) if (host->vmmc) regulator_enable(host->vmmc); - if (host->dma_ops->init) - host->dma_ops->init(host); - if (!mci_wait_reset(&host->dev, host)) { ret = -ENODEV; return ret; } + if (host->dma_ops->init) + host->dma_ops->init(host); + /* Restore the old value at FIFOTH register */ mci_writel(host, FIFOTH, host->fifoth_val); -- cgit v1.1 From fda5f736864c46324dbc50246ef1ca0e84ebf4ae Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Tue, 22 May 2012 13:01:13 +0900 Subject: mmc: dw_mmc: fix incorrect setting of host->data of NULL Setting host->data to NULL is incorrect sequence in dw_mci_command_complete. This early setting makes the skip of dma_unmap_sg in dw_mci_dma_cleanup. Signed-off-by: Seungwon Jeon Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 98fe023..b070ee5 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -941,8 +941,8 @@ static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd mdelay(20); if (cmd->data) { - host->data = NULL; dw_mci_stop_dma(host); + host->data = NULL; } } } -- cgit v1.1 From e419990b5e811027b1552cbc5b76a6cc180f7f48 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Tue, 22 May 2012 13:01:21 +0900 Subject: mmc: dw_mmc: correct the calculation for CLKDIV In case of "host->bus_hz < slot->clock", divider value is miscalculated. And clock divider register value is multiple of 2. If calculated divider value is odd number, result can be over-clocking. Signed-off-by: Seungwon Jeon Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index b070ee5..1ca5e72 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -617,14 +617,15 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) u32 div; if (slot->clock != host->current_speed) { - if (host->bus_hz % slot->clock) + div = host->bus_hz / slot->clock; + if (host->bus_hz % slot->clock && host->bus_hz > slot->clock) /* * move the + 1 after the divide to prevent * over-clocking the card. */ - div = ((host->bus_hz / slot->clock) >> 1) + 1; - else - div = (host->bus_hz / slot->clock) >> 1; + div += 1; + + div = (host->bus_hz != slot->clock) ? DIV_ROUND_UP(div, 2) : 0; dev_info(&slot->mmc->class_dev, "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ" -- cgit v1.1 From 4f837791d90bca76384b665eb2649feab169cc13 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 09:44:09 -0400 Subject: mmc: omap: Fix a section warning regression Commit b6e0703b (mmc: omap: make it behave well as a module) made some __devinit changes but missed one function causing a section warning: WARNING: vmlinux.o(.devinit.text+0x8604): Section mismatch in reference from the function mmc_omap_probe) The function __devinit mmc_omap_probe() references a function __init mmc_omap_new_slot(). Signed-off-by: Tony Lindgren Acked-by: Felipe Balbi Signed-off-by: Chris Ball --- drivers/mmc/host/omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 552196c..feda306 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1300,7 +1300,7 @@ static const struct mmc_host_ops mmc_omap_ops = { .set_ios = mmc_omap_set_ios, }; -static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) +static int __devinit mmc_omap_new_slot(struct mmc_omap_host *host, int id) { struct mmc_omap_slot *slot = NULL; struct mmc_host *mmc; -- cgit v1.1 From 3caf41406dd67b412abae7df86cc2a09bef9621f Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 09:45:50 -0400 Subject: mmc: omap: Fix NULL pointer dereference if mmc_omap_new_slot() fails Commit b01a4f1c (mmc: omap: convert to per instance workqueue) initializes the workqueue too late causing the following: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: CPU: 0 Not tainted (3.4.0-08218-gb48b2c3 #158) PC is at __queue_work+0x8/0x46c LR is at queue_work_on+0x38/0x40 pc : [] lr : [] psr: 60000193 sp : c0691e1c ip : 00000000 fp : c07374ac r10: c7aae400 r9 : c0395700 r8 : 00000100 r7 : c0691e70 r6 : 00000000 r5 : 00000000 r4 : c7aae440 r3 : 00000001 r2 : c7aae440 r1 : 00000000 r0 : 00000000 Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 00c5387d Table: 80004000 DAC: 00000017 Process swapper/0 (pid: 0, stack limit = 0xc06902f8) Stack: (0xc0691e1c to 0xc0692000) Fix this by initializing the workqueue before mmc_omap_remove_slot() get called. Tested on n770, looks like n800 at least still has some other issue with MMC. Signed-off-by: Tony Lindgren Signed-off-by: Chris Ball --- drivers/mmc/host/omap.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index feda306..6b07730 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1485,24 +1485,27 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) } host->nr_slots = pdata->nr_slots; + + host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); + if (!host->mmc_omap_wq) + goto err_plat_cleanup; + for (i = 0; i < pdata->nr_slots; i++) { ret = mmc_omap_new_slot(host, i); if (ret < 0) { while (--i >= 0) mmc_omap_remove_slot(host->slots[i]); - goto err_plat_cleanup; + goto err_destroy_wq; } } host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); - host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); - if (!host->mmc_omap_wq) - goto err_plat_cleanup; - return 0; +err_destroy_wq: + destroy_workqueue(host->mmc_omap_wq); err_plat_cleanup: if (pdata->cleanup) pdata->cleanup(&pdev->dev); -- cgit v1.1 From ebbe6f889f36d35f4d1757ba2ecc0af6150bf12b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 6 Jun 2012 09:47:49 -0400 Subject: mmc: omap: Fix broken reg_shift initialization Commit fa550189 (mmc: core: Prevent eMMC VCC supply to be cut from late init) slightly affected timings for how things are done for the omap MMC driver causing the MMC cards not getting detected any longer. Turns out this was caused by buggy reg_shift initialization in the omap MMC driver that was happening after mmc_add_host() was being called. Fix this by initializing reg_shift before mmc_add_host() is called. Signed-off-by: Tony Lindgren Cc: Signed-off-by: Chris Ball --- drivers/mmc/host/omap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 6b07730..3e8dcf8 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1485,6 +1485,7 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) } host->nr_slots = pdata->nr_slots; + host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); if (!host->mmc_omap_wq) @@ -1500,8 +1501,6 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) } } - host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); - return 0; err_destroy_wq: -- cgit v1.1 From 85e727edb963459d13cdd9ce84c335d251a005a7 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 31 May 2012 20:31:47 +0900 Subject: mmc: core: return an error on suspend if mmc_deselect_cards fails When mmc_host is not spi mode, mmc/sd is doing mmc_deselect_cards(). mmc_deselect_cards could be returned error. If returned error, we can know something wrong when enter suspend. Signed-off-by: Jaehoon Chung Signed-off-by: Kyungmin Park Acked-by: Ulf Hansson Signed-off-by: Chris Ball --- drivers/mmc/core/mmc.c | 2 +- drivers/mmc/core/sd.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 2d4a4b7..258b203 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1326,7 +1326,7 @@ static int mmc_suspend(struct mmc_host *host) if (!err) mmc_card_set_sleep(host->card); } else if (!mmc_host_is_spi(host)) - mmc_deselect_cards(host); + err = mmc_deselect_cards(host); host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); mmc_release_host(host); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index c272c686..b2b43f6 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1075,16 +1075,18 @@ static void mmc_sd_detect(struct mmc_host *host) */ static int mmc_sd_suspend(struct mmc_host *host) { + int err = 0; + BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); if (!mmc_host_is_spi(host)) - mmc_deselect_cards(host); + err = mmc_deselect_cards(host); host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_release_host(host); - return 0; + return err; } /* -- cgit v1.1 From 81ec1daa118ec9a04c0a907883872ae2996372bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 3 Jun 2012 15:29:55 +0200 Subject: mmc: sdhci-s3c: pass IRQF ONESHOT to request threaded irq Fix a boot regression in existing kernels causing: genirq: Threaded irq requested with handler=NULL and !ONESHOT for irq XXX caused by 1c6c6952 (genirq: Reject bogus threaded irq requests). Signed-off-by: Heiko Stuebner Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-s3c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 55a164f..a50c205 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -404,7 +404,7 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc) if (sc->ext_cd_irq && request_threaded_irq(sc->ext_cd_irq, NULL, sdhci_s3c_gpio_card_detect_thread, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(dev), sc) == 0) { int status = gpio_get_value(sc->ext_cd_gpio); if (pdata->ext_cd_gpio_invert) -- cgit v1.1 From a3e545e9ab26892641ecac7cee30ea4b4e87977e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 21 May 2012 06:33:27 +0200 Subject: mmc: mxs-mmc: Move of_match_table out of CONFIG_PM Signed-off-by: Marek Vasut Acked-by: Shawn Guo Signed-off-by: Chris Ball --- drivers/mmc/host/mxs-mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 34a9026..277161d 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -894,8 +894,8 @@ static struct platform_driver mxs_mmc_driver = { .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &mxs_mmc_pm_ops, - .of_match_table = mxs_mmc_dt_ids, #endif + .of_match_table = mxs_mmc_dt_ids, }, }; -- cgit v1.1 From ff3dd78cb8055bcb3a10e526044d8b54a773c612 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Mon, 4 Jun 2012 19:22:55 +0000 Subject: stmmac: fix driver's doc when run kernel-doc script Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 7096633..ea33eae 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -833,8 +833,9 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) /** * stmmac_selec_desc_mode - * @dev : device pointer - * Description: select the Enhanced/Alternate or Normal descriptors */ + * @priv : private structure + * Description: select the Enhanced/Alternate or Normal descriptors + */ static void stmmac_selec_desc_mode(struct stmmac_priv *priv) { if (priv->plat->enh_desc) { @@ -1861,6 +1862,8 @@ static int stmmac_hw_init(struct stmmac_priv *priv) /** * stmmac_dvr_probe * @device: device pointer + * @plat_dat: platform data pointer + * @addr: iobase memory address * Description: this is the main probe function used to * call the alloc_etherdev, allocate the priv structure. */ -- cgit v1.1 From ba27ec66ffeb78cbf9f85e168b32551a9aaf2a34 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Mon, 4 Jun 2012 19:22:57 +0000 Subject: stmmac: fix driver Kconfig when built as module This patches fixes the driver when built as dynamic module. In fact, the platform part cannot be built and the probe fails (thanks to Bob Liu that reported this bug). v2: as D. Miller suggested, it is not necessary to make the pci and the platform code mutually exclusive. Having both could also help, at built time ,to verify that all the code is validated and compiles fine. v3: removed wrong Reviewed-by from the patch Reported-by: Bob Liu cc: Rayagond Kokatanur Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/Kconfig | 5 ++-- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 3 ++- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 25 +++++++++++++++++++ drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 29 +--------------------- .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 4 +-- 5 files changed, 31 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index 0364283..0076f77 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -13,9 +13,8 @@ config STMMAC_ETH if STMMAC_ETH config STMMAC_PLATFORM - tristate "STMMAC platform bus support" + bool "STMMAC Platform bus support" depends on STMMAC_ETH - default y ---help--- This selects the platform specific bus support for the stmmac device driver. This is the driver used @@ -26,7 +25,7 @@ config STMMAC_PLATFORM If unsure, say N. config STMMAC_PCI - tristate "STMMAC support on PCI bus (EXPERIMENTAL)" + bool "STMMAC PCI bus support (EXPERIMENTAL)" depends on STMMAC_ETH && PCI && EXPERIMENTAL ---help--- This is to select the Synopsys DWMAC available on PCI devices, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 6b5d060..6d07ba2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -95,7 +95,8 @@ extern int stmmac_mdio_register(struct net_device *ndev); extern void stmmac_set_ethtool_ops(struct net_device *netdev); extern const struct stmmac_desc_ops enh_desc_ops; extern const struct stmmac_desc_ops ndesc_ops; - +extern struct pci_driver stmmac_pci_driver; +extern struct platform_driver stmmac_pltfr_driver; int stmmac_freeze(struct net_device *ndev); int stmmac_restore(struct net_device *ndev); int stmmac_resume(struct net_device *ndev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index ea33eae..3638569 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef CONFIG_STMMAC_DEBUG_FS #include #include @@ -2093,6 +2094,30 @@ int stmmac_restore(struct net_device *ndev) } #endif /* CONFIG_PM */ +static int __init stmmac_init(void) +{ + int err = 0; + + err = platform_driver_register(&stmmac_pltfr_driver); + + if (!err) { + err = pci_register_driver(&stmmac_pci_driver); + if (err) + platform_driver_unregister(&stmmac_pltfr_driver); + } + + return err; +} + +static void __exit stmmac_exit(void) +{ + pci_unregister_driver(&stmmac_pci_driver); + platform_driver_unregister(&stmmac_pltfr_driver); +} + +module_init(stmmac_init); +module_exit(stmmac_exit); + #ifndef MODULE static int __init stmmac_cmdline_opt(char *str) { diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index 58fab53..cf826e6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -179,7 +179,7 @@ static DEFINE_PCI_DEVICE_TABLE(stmmac_id_table) = { MODULE_DEVICE_TABLE(pci, stmmac_id_table); -static struct pci_driver stmmac_driver = { +struct pci_driver stmmac_pci_driver = { .name = STMMAC_RESOURCE_NAME, .id_table = stmmac_id_table, .probe = stmmac_pci_probe, @@ -190,33 +190,6 @@ static struct pci_driver stmmac_driver = { #endif }; -/** - * stmmac_init_module - Entry point for the driver - * Description: This function is the entry point for the driver. - */ -static int __init stmmac_init_module(void) -{ - int ret; - - ret = pci_register_driver(&stmmac_driver); - if (ret < 0) - pr_err("%s: ERROR: driver registration failed\n", __func__); - - return ret; -} - -/** - * stmmac_cleanup_module - Cleanup routine for the driver - * Description: This function is the cleanup routine for the driver. - */ -static void __exit stmmac_cleanup_module(void) -{ - pci_unregister_driver(&stmmac_driver); -} - -module_init(stmmac_init_module); -module_exit(stmmac_cleanup_module); - MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PCI driver"); MODULE_AUTHOR("Rayagond Kokatanur "); MODULE_AUTHOR("Giuseppe Cavallaro "); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 3dd8f08..680d2b8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -255,7 +255,7 @@ static const struct of_device_id stmmac_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, stmmac_dt_ids); -static struct platform_driver stmmac_driver = { +struct platform_driver stmmac_pltfr_driver = { .probe = stmmac_pltfr_probe, .remove = stmmac_pltfr_remove, .driver = { @@ -266,8 +266,6 @@ static struct platform_driver stmmac_driver = { }, }; -module_platform_driver(stmmac_driver); - MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PLATFORM driver"); MODULE_AUTHOR("Giuseppe Cavallaro "); MODULE_LICENSE("GPL"); -- cgit v1.1 From 32a527add871a51b3c06177849d18bf71e33b320 Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Tue, 5 Jun 2012 02:23:20 +0000 Subject: ide: icside.c: Fix compile with CONFIG_BLK_DEV_IDEDMA_ICS=n The icside driver can be configured without DMA support, but it doesn't compile then, because DMA operations are referenced. drivers/ide/icside.c:523: error: 'icside_v6_port_ops' undeclared drivers/ide/icside.c:522: error: 'icside_dma_init' undeclared Signed-off-by: Christian Dietrich Signed-off-by: David S. Miller --- drivers/ide/icside.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 8716066..83e5100 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c @@ -375,8 +375,6 @@ static const struct ide_dma_ops icside_v6_dma_ops = { .dma_test_irq = icside_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, }; -#else -#define icside_v6_dma_ops NULL #endif static int icside_dma_off_init(ide_hwif_t *hwif, const struct ide_port_info *d) @@ -456,7 +454,6 @@ err_free: static const struct ide_port_info icside_v6_port_info __initdata = { .init_dma = icside_dma_off_init, .port_ops = &icside_v6_no_dma_port_ops, - .dma_ops = &icside_v6_dma_ops, .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO, .mwdma_mask = ATA_MWDMA2, .swdma_mask = ATA_SWDMA2, @@ -518,11 +515,13 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) ecard_set_drvdata(ec, state); +#ifdef CONFIG_BLK_DEV_IDEDMA_ICS if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) { d.init_dma = icside_dma_init; d.port_ops = &icside_v6_port_ops; - } else - d.dma_ops = NULL; + d.dma_ops = &icside_v6_dma_ops; + } +#endif ret = ide_host_register(host, &d, hws); if (ret) -- cgit v1.1 From 027253c138a12b075e724f94b6cc43fd7071c14f Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Tue, 5 Jun 2012 02:28:59 +0000 Subject: ide: icside.c: fix printk format string compile warning Use correct format string parameter for the peak datarate, and prevent uninitialized use of cycle_time. Signed-off-by: Christian Dietrich Signed-off-by: David S. Miller --- drivers/ide/icside.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 83e5100..bcb507b 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c @@ -236,7 +236,7 @@ static const struct ide_port_ops icside_v6_no_dma_port_ops = { */ static void icside_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - unsigned long cycle_time; + unsigned long cycle_time = 0; int use_dma_info = 0; const u8 xfer_mode = drive->dma_mode; @@ -271,9 +271,9 @@ static void icside_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) ide_set_drivedata(drive, (void *)cycle_time); - printk("%s: %s selected (peak %dMB/s)\n", drive->name, - ide_xfer_verbose(xfer_mode), - 2000 / (unsigned long)ide_get_drivedata(drive)); + printk(KERN_INFO "%s: %s selected (peak %luMB/s)\n", + drive->name, ide_xfer_verbose(xfer_mode), + 2000 / (cycle_time ? cycle_time : (unsigned long) -1)); } static const struct ide_port_ops icside_v6_port_ops = { -- cgit v1.1 From 9a43a02648e8414b2a757437820aa928208fc42f Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Wed, 6 Jun 2012 06:40:43 +0000 Subject: mv643xx_eth: Fix compile error for architectures without clk. Commit 452503ebc (ARM: Orion: Eth: Add clk/clkdev support.) broke the building of the driver on architectures which don't have clk support. In particular PPC32 Pegasos which uses this driver. Add #ifdef around the clk API usage. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mv643xx_eth.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 04d901d..f0f06b2 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -436,7 +436,9 @@ struct mv643xx_eth_private { /* * Hardware-specific parameters. */ +#if defined(CONFIG_HAVE_CLK) struct clk *clk; +#endif unsigned int t_clk; }; @@ -2895,17 +2897,17 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mp->dev = dev; /* - * Get the clk rate, if there is one, otherwise use the default. + * Start with a default rate, and if there is a clock, allow + * it to override the default. */ + mp->t_clk = 133000000; +#if defined(CONFIG_HAVE_CLK) mp->clk = clk_get(&pdev->dev, (pdev->id ? "1" : "0")); if (!IS_ERR(mp->clk)) { clk_prepare_enable(mp->clk); mp->t_clk = clk_get_rate(mp->clk); - } else { - mp->t_clk = 133000000; - printk(KERN_WARNING "Unable to get clock"); } - +#endif set_params(mp, pd); netif_set_real_num_tx_queues(dev, mp->txq_count); netif_set_real_num_rx_queues(dev, mp->rxq_count); @@ -2995,10 +2997,13 @@ static int mv643xx_eth_remove(struct platform_device *pdev) phy_detach(mp->phy); cancel_work_sync(&mp->tx_timeout_task); +#if defined(CONFIG_HAVE_CLK) if (!IS_ERR(mp->clk)) { clk_disable_unprepare(mp->clk); clk_put(mp->clk); } +#endif + free_netdev(mp->dev); platform_set_drvdata(pdev, NULL); -- cgit v1.1 From dd03cff23d694cfb0fdae80cb618e7ced05ea696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 5 Jun 2012 21:18:10 +0000 Subject: net: sierra_net: device IDs for Aircard 320U++ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding device IDs for Aircard 320U and two other devices found in the out-of-tree version of this driver. Cc: linux@sierrawireless.com Cc: Autif Khan Cc: Tom Cassidy Cc: stable@vger.kernel.org Signed-off-by: Bjørn Mork Acked-by: Greg Kroah-Hartman Signed-off-by: David S. Miller --- drivers/net/usb/sierra_net.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index 3faef56..d75d1f5 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -946,7 +946,7 @@ struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb, } static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 }; -static const struct sierra_net_info_data sierra_net_info_data_68A3 = { +static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { .rx_urb_size = 8 * 1024, .whitelist = { .infolen = ARRAY_SIZE(sierra_net_ifnum_list), @@ -954,7 +954,7 @@ static const struct sierra_net_info_data sierra_net_info_data_68A3 = { } }; -static const struct driver_info sierra_net_info_68A3 = { +static const struct driver_info sierra_net_info_direct_ip = { .description = "Sierra Wireless USB-to-WWAN Modem", .flags = FLAG_WWAN | FLAG_SEND_ZLP, .bind = sierra_net_bind, @@ -962,12 +962,18 @@ static const struct driver_info sierra_net_info_68A3 = { .status = sierra_net_status, .rx_fixup = sierra_net_rx_fixup, .tx_fixup = sierra_net_tx_fixup, - .data = (unsigned long)&sierra_net_info_data_68A3, + .data = (unsigned long)&sierra_net_info_data_direct_ip, }; static const struct usb_device_id products[] = { {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ - .driver_info = (unsigned long) &sierra_net_info_68A3}, + .driver_info = (unsigned long) &sierra_net_info_direct_ip}, + {USB_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */ + .driver_info = (unsigned long) &sierra_net_info_direct_ip}, + {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ + .driver_info = (unsigned long) &sierra_net_info_direct_ip}, + {USB_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */ + .driver_info = (unsigned long) &sierra_net_info_direct_ip}, {}, /* last item */ }; -- cgit v1.1 From ea80dadec7a06889562b478cf0b87afbe62b7ac8 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 6 Jun 2012 14:54:13 +0900 Subject: [SCSI] Fix sd_probe_domain config problem With CONFIG_BLK_DEV_SD = n and CONFIG_PM = n, you get this compile failure: (.text+0x4f6c77): undefined reference to `scsi_sd_probe_domain' This was introduced by commit a7a20d103994fd760766e6c9d494daa569cbfe06 Author: Dan Williams Date: Thu Mar 22 17:05:11 2012 -0700 [SCSI] sd: limit the scope of the async probe domain And happens because scsi_sd_probe_domain is conditionally defined but unconditionally used. Fix this by making the symbol unconditionally defined. Reported-by: Randy Dunlap Cc: Dan Williams Tested-by: Randy Dunlap Signed-off-by: James Bottomley --- drivers/scsi/scsi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 61c82a3..bbbc9c91 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -90,11 +90,9 @@ unsigned int scsi_logging_level; EXPORT_SYMBOL(scsi_logging_level); #endif -#if IS_ENABLED(CONFIG_PM) || IS_ENABLED(CONFIG_BLK_DEV_SD) -/* sd and scsi_pm need to coordinate flushing async actions */ +/* sd, scsi core and power management need to coordinate flushing async actions */ LIST_HEAD(scsi_sd_probe_domain); EXPORT_SYMBOL(scsi_sd_probe_domain); -#endif /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI. * You may not alter any existing entry (although adding new ones is -- cgit v1.1 From 279bf2e57c30c9a4482b2b6ede11b31c41e35e78 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 5 Jun 2012 18:16:31 +0200 Subject: staging:iio:ad7606: Re-add missing scale attribute Commit 50ac23be ("staging:iio:adc:ad7606 add local define for chan_spec structures.") accidentally removed the scale info_mask flag. This patch adds it back again. Signed-off-by: Lars-Peter Clausen Cc: stable [3.2+] Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7606_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index 10ab6dc..a13afff 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -235,7 +235,8 @@ static const struct attribute_group ad7606_attribute_group_range = { .indexed = 1, \ .channel = num, \ .address = num, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .scan_index = num, \ .scan_type = IIO_ST('s', 16, 16, 0), \ } -- cgit v1.1 From 30c1dc0ff30b5552e8af555265dbeac5637cbb48 Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Wed, 23 May 2012 16:47:31 +0530 Subject: dmaengine: pl330: dont complete descriptor for cyclic dma Commit eab215855803 ("dmaengine: pl330: dont complete descriptor for cyclic dma") wrongly completes descriptor for cyclic dma, hence following BUG_ON is still hit with cyclic DMA operations. kernel BUG at drivers/dma/dmaengine.h:53! Signed-off-by: Tushar Behera Acked-by: Jassi Brar Signed-off-by: Vinod Koul Cc: stable --- drivers/dma/pl330.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index cbcc28e..6d55042 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2321,7 +2321,7 @@ static void pl330_tasklet(unsigned long data) /* Pick up ripe tomatoes */ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) if (desc->status == DONE) { - if (pch->cyclic) + if (!pch->cyclic) dma_cookie_complete(&desc->txd); list_move_tail(&desc->node, &list); } -- cgit v1.1 From 8e2e27c7444ba7880aa0a4cb07a79de130d0ed93 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Mon, 4 Jun 2012 09:17:24 +0800 Subject: dma: imx-sdma: buf_tail should be initialize in prepare function This fix audio underrun issue. When SNDRV_PCM_TRIGGER_STOP and SNDRV_PCM_TRIGGER_START, it calls prepare again. buf_tail should be reset to zero. So move buf_tail initialization into prepare function. Signed-off-by: Richard Zhao Acked-by: Shawn Guo Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index fb4f499..1dc2a4a 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -815,8 +815,6 @@ static int sdma_request_channel(struct sdma_channel *sdmac) init_completion(&sdmac->done); - sdmac->buf_tail = 0; - return 0; out: @@ -927,6 +925,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( sdmac->flags = 0; + sdmac->buf_tail = 0; + dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n", sg_len, channel); @@ -1027,6 +1027,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( sdmac->status = DMA_IN_PROGRESS; + sdmac->buf_tail = 0; + sdmac->flags |= IMX_DMA_SG_LOOP; sdmac->direction = direction; ret = sdma_load_context(sdmac); -- cgit v1.1 From 5a67ac572e102f7d877b8a3a18a59315186e3e99 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Jun 2012 17:09:45 +0530 Subject: DMA: PL330: Add missing static storage class specifier Fixes the following sparse warning: drivers/dma/pl330.c:2542:5: warning: symbol 'add_desc' was not declared. Should it be static? Signed-off-by: Sachin Kamat Signed-off-by: Vinod Koul --- drivers/dma/pl330.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 6d55042..3ce7d55 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2539,7 +2539,7 @@ static inline void _init_desc(struct dma_pl330_desc *desc) } /* Returns the number of descriptors added to the DMAC pool */ -int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) +static int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) { struct dma_pl330_desc *desc; unsigned long flags; -- cgit v1.1 From 5ff0feac88ced864f44adb145142269196fa79d9 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 6 Jun 2012 10:01:30 +0000 Subject: sky2: fix checksum bit management on some chips The newer flavors of Yukon II use a different method for receive checksum offload. This is indicated in the driver by the SKY2_HW_NEW_LE flag. On these newer chips, the BMU_ENA_RX_CHKSUM should not be set. The driver would get incorrectly toggle the bit, enabling the old checksum logic on these chips and cause a BUG_ON() assertion. If receive checksum was toggled via ethtool. Reported-by: Kirill Smelkov Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/sky2.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index cace36f..28a5445 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -4381,10 +4381,12 @@ static int sky2_set_features(struct net_device *dev, netdev_features_t features) struct sky2_port *sky2 = netdev_priv(dev); netdev_features_t changed = dev->features ^ features; - if (changed & NETIF_F_RXCSUM) { - bool on = features & NETIF_F_RXCSUM; - sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), - on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); + if ((changed & NETIF_F_RXCSUM) && + !(sky2->hw->flags & SKY2_HW_NEW_LE)) { + sky2_write32(sky2->hw, + Q_ADDR(rxqaddr[sky2->port], Q_CSR), + (features & NETIF_F_RXCSUM) + ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); } if (changed & NETIF_F_RXHASH) -- cgit v1.1 From 752a6a5f84bfed18d0709383913d9d9d21b61c77 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 14 May 2012 10:00:12 +0100 Subject: regmap: Export regmap_reinit_cache() It's supposed to be there for drivers. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 04b4802..c89aa01 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -472,6 +472,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) return ret; } +EXPORT_SYMBOL_GPL(regmap_reinit_cache); /** * regmap_exit(): Free a previously allocated register map -- cgit v1.1 From 0bdc81e4e944781a2bcc971f9e3cf24ac7030939 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 7 Jun 2012 09:52:12 +0800 Subject: regulator: core: Properly handle the case min_uV < rdev->desc->min_uV in map_voltage_linear Properly handle the case if the specified min_uV is less than the voltage given by the lowest selector. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 7584a74..09a737c 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2050,6 +2050,9 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev, return -EINVAL; } + if (min_uV < rdev->desc->min_uV) + min_uV = rdev->desc->min_uV; + ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); if (ret < 0) return ret; -- cgit v1.1 From 33d5e332b9c5ce0bf3bfd44ca2127d1773b3f2ad Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Thu, 7 Jun 2012 19:25:07 +0000 Subject: stmmac: fix driver built w/ w/o both pci and platf modules The commit ba27ec66ffeb78cbf fixes the Kconfig of the driver when built as module allowing to select/unselect the PCI and Platform modules that are not anymore mutually exclusive. This patch fixes and guarantees that the driver builds on all the platforms w/ w/o PCI and when select/unselect the two stmmac supports. In case of there are some problems on both the configuration and the pci/pltf registration the module_init will fail. v2: set the CONFIG_STMMAC_PLATFORM enabled by default. I've just noticed that this can actually help on some configurations that don't enable any STMMAC options by default (e.g. SPEAr). v3: change printk level when do not register the driver. Reported-by: Fengguang Wu Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 + drivers/net/ethernet/stmicro/stmmac/stmmac.h | 60 ++++++++++++++++++++++- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 23 +++++---- 3 files changed, 72 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index 0076f77..9f44827 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -15,6 +15,7 @@ if STMMAC_ETH config STMMAC_PLATFORM bool "STMMAC Platform bus support" depends on STMMAC_ETH + default y ---help--- This selects the platform specific bus support for the stmmac device driver. This is the driver used diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 6d07ba2..94b21b4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "common.h" #ifdef CONFIG_STMMAC_TIMER #include "stmmac_timer.h" @@ -95,8 +96,6 @@ extern int stmmac_mdio_register(struct net_device *ndev); extern void stmmac_set_ethtool_ops(struct net_device *netdev); extern const struct stmmac_desc_ops enh_desc_ops; extern const struct stmmac_desc_ops ndesc_ops; -extern struct pci_driver stmmac_pci_driver; -extern struct platform_driver stmmac_pltfr_driver; int stmmac_freeze(struct net_device *ndev); int stmmac_restore(struct net_device *ndev); int stmmac_resume(struct net_device *ndev); @@ -144,3 +143,60 @@ static inline int stmmac_clk_get(struct stmmac_priv *priv) return 0; } #endif /* CONFIG_HAVE_CLK */ + + +#ifdef CONFIG_STMMAC_PLATFORM +extern struct platform_driver stmmac_pltfr_driver; +static inline int stmmac_register_platform(void) +{ + int err; + + err = platform_driver_register(&stmmac_pltfr_driver); + if (err) + pr_err("stmmac: failed to register the platform driver\n"); + + return err; +} +static inline void stmmac_unregister_platform(void) +{ + platform_driver_register(&stmmac_pltfr_driver); +} +#else +static inline int stmmac_register_platform(void) +{ + pr_debug("stmmac: do not register the platf driver\n"); + + return -EINVAL; +} +static inline void stmmac_unregister_platform(void) +{ +} +#endif /* CONFIG_STMMAC_PLATFORM */ + +#ifdef CONFIG_STMMAC_PCI +extern struct pci_driver stmmac_pci_driver; +static inline int stmmac_register_pci(void) +{ + int err; + + err = pci_register_driver(&stmmac_pci_driver); + if (err) + pr_err("stmmac: failed to register the PCI driver\n"); + + return err; +} +static inline void stmmac_unregister_pci(void) +{ + pci_unregister_driver(&stmmac_pci_driver); +} +#else +static inline int stmmac_register_pci(void) +{ + pr_debug("stmmac: do not register the PCI driver\n"); + + return -EINVAL; +} +static inline void stmmac_unregister_pci(void) +{ +} +#endif /* CONFIG_STMMAC_PCI */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 3638569..51b3b68 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -42,7 +42,6 @@ #include #include #include -#include #ifdef CONFIG_STMMAC_DEBUG_FS #include #include @@ -2094,25 +2093,29 @@ int stmmac_restore(struct net_device *ndev) } #endif /* CONFIG_PM */ +/* Driver can be configured w/ and w/ both PCI and Platf drivers + * depending on the configuration selected. + */ static int __init stmmac_init(void) { - int err = 0; + int err_plt = 0; + int err_pci = 0; - err = platform_driver_register(&stmmac_pltfr_driver); + err_plt = stmmac_register_platform(); + err_pci = stmmac_register_pci(); - if (!err) { - err = pci_register_driver(&stmmac_pci_driver); - if (err) - platform_driver_unregister(&stmmac_pltfr_driver); + if ((err_pci) && (err_plt)) { + pr_err("stmmac: driver registration failed\n"); + return -EINVAL; } - return err; + return 0; } static void __exit stmmac_exit(void) { - pci_unregister_driver(&stmmac_pci_driver); - platform_driver_unregister(&stmmac_pltfr_driver); + stmmac_unregister_platform(); + stmmac_unregister_pci(); } module_init(stmmac_init); -- cgit v1.1 From 6a2b28ef036ab5c66fdc606fe97d9e5cb34ea409 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 8 Jun 2012 00:28:16 -0700 Subject: Revert "niu: Add support for byte queue limits." This reverts commit efa230f2c68abab817f13473077f8d0cc74f43f3. BQL doesn't work with how this driver currently only takes TX interrupts every 1/4 of the TX ring. That behavior needs to be fixed, but that's a larger non-trivial task and for now we have to revert BQL support as this makes the device currently completely unusable. Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/niu.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 703c8cc..8c726b7 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -3598,7 +3598,6 @@ static int release_tx_packet(struct niu *np, struct tx_ring_info *rp, int idx) static void niu_tx_work(struct niu *np, struct tx_ring_info *rp) { struct netdev_queue *txq; - unsigned int tx_bytes; u16 pkt_cnt, tmp; int cons, index; u64 cs; @@ -3621,18 +3620,12 @@ static void niu_tx_work(struct niu *np, struct tx_ring_info *rp) netif_printk(np, tx_done, KERN_DEBUG, np->dev, "%s() pkt_cnt[%u] cons[%d]\n", __func__, pkt_cnt, cons); - tx_bytes = 0; - tmp = pkt_cnt; - while (tmp--) { - tx_bytes += rp->tx_buffs[cons].skb->len; + while (pkt_cnt--) cons = release_tx_packet(np, rp, cons); - } rp->cons = cons; smp_mb(); - netdev_tx_completed_queue(txq, pkt_cnt, tx_bytes); - out: if (unlikely(netif_tx_queue_stopped(txq) && (niu_tx_avail(rp) > NIU_TX_WAKEUP_THRESH(rp)))) { @@ -4333,7 +4326,6 @@ static void niu_free_channels(struct niu *np) struct tx_ring_info *rp = &np->tx_rings[i]; niu_free_tx_ring_info(np, rp); - netdev_tx_reset_queue(netdev_get_tx_queue(np->dev, i)); } kfree(np->tx_rings); np->tx_rings = NULL; @@ -6739,8 +6731,6 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb, prod = NEXT_TX(rp, prod); } - netdev_tx_sent_queue(txq, skb->len); - if (prod < rp->prod) rp->wrap_bit ^= TX_RING_KICK_WRAP; rp->prod = prod; -- cgit v1.1 From c8e9cf7bb240049117d2fa64d1540476c289396d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Jun 2012 12:15:15 +0200 Subject: vga_switcheroo: Add a helper function to get the client state Add vga_switcheroo_get_client_state() to get the current state of the client. This is necessary to determine the proper initial state of audio clients in HD-audio driver. Acked-by: Dave Airlie Signed-off-by: Takashi Iwai --- drivers/gpu/vga/vga_switcheroo.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 38f9534..eb4f64f 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -190,6 +190,19 @@ find_active_client(struct list_head *head) return NULL; } +int vga_switcheroo_get_client_state(struct pci_dev *pdev) +{ + struct vga_switcheroo_client *client; + + client = find_client_from_pci(&vgasr_priv.clients, pdev); + if (!client) + return VGA_SWITCHEROO_NOT_FOUND; + if (!vgasr_priv.active) + return VGA_SWITCHEROO_INIT; + return client->pwr_state; +} +EXPORT_SYMBOL(vga_switcheroo_get_client_state); + void vga_switcheroo_unregister_client(struct pci_dev *pdev) { struct vga_switcheroo_client *client; -- cgit v1.1 From aac495a8002bbf20e879572c6cf0789ab2ffb32b Mon Sep 17 00:00:00 2001 From: Stanislav Yakovlev Date: Mon, 14 May 2012 19:06:19 -0400 Subject: net/wireless: ipw2100: Fix WARN_ON occurring in wiphy_register called by ipw2100_pci_init_one The problem was found by Larry Finger: http://marc.info/?l=linux-wireless&m=133702401700614&w=2 The problem is identical to the one for ipw2200 which is already fixed: http://marc.info/?l=linux-wireless&m=133457257407196&w=2 [ 17.766431] ------------[ cut here ]------------ [ 17.766467] WARNING: at net/wireless/core.c:562 wiphy_register+0x34c/0x3c0 [cfg80211]() [ 17.766471] Hardware name: Latitude D600 [ 17.766474] Modules linked in: ipw2100(+) libipw pcmcia cfg80211 ppdev parport_pc yenta_socket sr_mod pcmcia_rsrc parport iTCO_wdt cdrom sg rfkill pcmcia_ core lib80211 tg3 video button battery ac iTCO_vendor_support joydev shpchp pcspkr pciehp pci_hotplug autofs4 radeon ttm drm_kms_helper uhci_hcd ehci_hcd rtc _cmos thermal drm hwmon i2c_algo_bit i2c_core processor usbcore usb_common ata_generic ata_piix ahci libahci libata [ 17.766525] Pid: 474, comm: modprobe Not tainted 3.4.0-rc7-wl+ #6 [ 17.766528] Call Trace: [ 17.766541] [] ? printk+0x28/0x2a [ 17.766552] [] warn_slowpath_common+0x6d/0xa0 [ 17.766563] [] ? wiphy_register+0x34c/0x3c0 [cfg80211] [ 17.766573] [] ? wiphy_register+0x34c/0x3c0 [cfg80211] [ 17.766578] [] warn_slowpath_null+0x1d/0x20 [ 17.766588] [] wiphy_register+0x34c/0x3c0 [cfg80211] [ 17.766605] [] ipw2100_wdev_init+0x196/0x1c0 [ipw2100] [ 17.766616] [] ipw2100_pci_init_one+0x2b2/0x694 [ipw2100] [ 17.766632] [] local_pci_probe+0x42/0xb0 [ 17.766637] [] pci_device_probe+0x60/0x90 [ 17.766645] [] ? sysfs_create_link+0x12/0x20 [ 17.766654] [] really_probe+0x56/0x2e0 [ 17.766659] [] ? create_dir+0x5d/0xa0 [ 17.766667] [] ? pm_runtime_barrier+0x3b/0xa0 [ 17.766672] [] driver_probe_device+0x44/0xa0 [ 17.766677] [] ? pci_match_device+0x97/0xa0 [ 17.766681] [] __driver_attach+0x89/0x90 [ 17.766686] [] ? driver_probe_device+0xa0/0xa0 [ 17.766691] [] bus_for_each_dev+0x3a/0x70 [ 17.766695] [] driver_attach+0x1c/0x30 [ 17.766699] [] ? driver_probe_device+0xa0/0xa0 [ 17.766704] [] bus_add_driver+0x187/0x280 [ 17.766710] [] ? kset_find_obj+0x2d/0x60 [ 17.766715] [] ? pci_device_probe+0x90/0x90 [ 17.766719] [] ? pci_device_probe+0x90/0x90 [ 17.766724] [] driver_register+0x65/0x110 [ 17.766729] [] __pci_register_driver+0x3d/0xa0 [ 17.766738] [] ipw2100_init+0x5c/0x1000 [ipw2100] [ 17.766743] [] do_one_initcall+0x2f/0x170 [ 17.766749] [] ? 0xe09f6fff [ 17.766757] [] sys_init_module+0xa8/0x210 [ 17.766766] [] syscall_call+0x7/0xb [ 17.766769] ---[ end trace 559898c6bb0d1c75 ]--- [ 17.767093] ipw2100: probe of 0000:02:03.0 failed with error -5 This warning appears only if we apply Ben Hutchings' fix http://marc.info/?l=linux-wireless&m=132720204412667&w=2 for the bug reported by Cesare Leonardi http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=656813 with cfg80211 warning during device registration ("cfg80211: failed to add phy80211 symlink to netdev!"). We separate device bring up and registration with network stack to avoid the problem. Signed-off-by: Stanislav Yakovlev Tested-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2100.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 9cfae0c..95aa8e1 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1903,14 +1903,6 @@ static void ipw2100_down(struct ipw2100_priv *priv) netif_stop_queue(priv->net_dev); } -/* Called by register_netdev() */ -static int ipw2100_net_init(struct net_device *dev) -{ - struct ipw2100_priv *priv = libipw_priv(dev); - - return ipw2100_up(priv, 1); -} - static int ipw2100_wdev_init(struct net_device *dev) { struct ipw2100_priv *priv = libipw_priv(dev); @@ -6087,7 +6079,6 @@ static const struct net_device_ops ipw2100_netdev_ops = { .ndo_stop = ipw2100_close, .ndo_start_xmit = libipw_xmit, .ndo_change_mtu = libipw_change_mtu, - .ndo_init = ipw2100_net_init, .ndo_tx_timeout = ipw2100_tx_timeout, .ndo_set_mac_address = ipw2100_set_address, .ndo_validate_addr = eth_validate_addr, @@ -6329,6 +6320,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, printk(KERN_INFO DRV_NAME ": Detected Intel PRO/Wireless 2100 Network Connection\n"); + err = ipw2100_up(priv, 1); + if (err) + goto fail; + err = ipw2100_wdev_init(dev); if (err) goto fail; @@ -6338,12 +6333,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, * network device we would call ipw2100_up. This introduced a race * condition with newer hotplug configurations (network was coming * up and making calls before the device was initialized). - * - * If we called ipw2100_up before we registered the device, then the - * device name wasn't registered. So, we instead use the net_dev->init - * member to call a function that then just turns and calls ipw2100_up. - * net_dev->init is called after name allocation but before the - * notifier chain is called */ + */ err = register_netdev(dev); if (err) { printk(KERN_WARNING DRV_NAME -- cgit v1.1 From 0fde0a8cfd0ede7f310d6a681c8e5a7cb3e32406 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 16 May 2012 11:06:21 +0200 Subject: rtl8187: ->brightness_set can not sleep Fix: BUG: sleeping function called from invalid context at kernel/workqueue.c:2547 in_atomic(): 1, irqs_disabled(): 0, pid: 629, name: wpa_supplicant 2 locks held by wpa_supplicant/629: #0: (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x14/0x20 #1: (&trigger->leddev_list_lock){.+.?..}, at: [] led_trigger_event+0x21/0x80 Pid: 629, comm: wpa_supplicant Not tainted 3.3.0-0.rc3.git5.1.fc17.i686 Call Trace: [] __might_sleep+0x126/0x1d0 [] wait_on_work+0x2c/0x1d0 [] __cancel_work_timer+0x6a/0x120 [] cancel_delayed_work_sync+0x10/0x20 [] rtl8187_led_brightness_set+0x82/0xf0 [rtl8187] [] led_trigger_event+0x5c/0x80 [] ieee80211_led_radio+0x1d/0x40 [mac80211] [] ieee80211_stop_device+0x13/0x230 [mac80211] Removing _sync is ok, because if led_on work is currently running it will be finished before led_off work start to perform, since they are always queued on the same mac80211 local->workqueue. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=795176 Signed-off-by: Stanislaw Gruszka Acked-by: Larry Finger Acked-by: Hin-Tak Leung Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187/leds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtl818x/rtl8187/leds.c b/drivers/net/wireless/rtl818x/rtl8187/leds.c index 2e0de2f..c2d5b49 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187/leds.c @@ -117,7 +117,7 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev, radio_on = true; } else if (radio_on) { radio_on = false; - cancel_delayed_work_sync(&priv->led_on); + cancel_delayed_work(&priv->led_on); ieee80211_queue_delayed_work(hw, &priv->led_off, 0); } } else if (radio_on) { -- cgit v1.1 From 06cf5c4c5bea549235da1aace86b90d4ad0084f8 Mon Sep 17 00:00:00 2001 From: Qasim Javed Date: Tue, 5 Jun 2012 01:25:44 -0500 Subject: mac80211_hwsim: Set IEEE80211_STAT_ACK flag when userspace indicates that the frame has been acknowledged. The station fail average is not updated correctly since the IEEE80211_STAT_ACK flag is not set when using wmediumd with mac80211_hwsim. Set this flag when wmediumd indicates that the frame was successfully transmitted (eventually). Signed-off-by: Qasim Javed Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 4c9336c..a0b7cfd 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1555,6 +1555,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, hdr = (struct ieee80211_hdr *) skb->data; mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2); } + txi->flags |= IEEE80211_TX_STAT_ACK; } ieee80211_tx_status_irqsafe(data2->hw, skb); return 0; -- cgit v1.1 From d2c8b15d0cb486f4938ba7f2af349d9d1220cb10 Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Tue, 5 Jun 2012 20:24:37 +0200 Subject: iwlwifi: use correct supported firmware for 6035 and 6000g2 My patch iwlwifi: use correct released ucode version did not correctly report supported firmware for the 6035 device. This patch fixes it. The minimum supported firmware version for 6035 is v6. Also correct the minimum supported firmware version for the 6000g2 series of devices. Cc: stable@kernel.org Signed-off-by: Meenakshi Venkataraman Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 19f7ee8..e5e8ada 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -35,17 +35,20 @@ #define IWL6000_UCODE_API_MAX 6 #define IWL6050_UCODE_API_MAX 5 #define IWL6000G2_UCODE_API_MAX 6 +#define IWL6035_UCODE_API_MAX 6 /* Oldest version we won't warn about */ #define IWL6000_UCODE_API_OK 4 #define IWL6000G2_UCODE_API_OK 5 #define IWL6050_UCODE_API_OK 5 #define IWL6000G2B_UCODE_API_OK 6 +#define IWL6035_UCODE_API_OK 6 /* Lowest firmware API version supported */ #define IWL6000_UCODE_API_MIN 4 #define IWL6050_UCODE_API_MIN 4 -#define IWL6000G2_UCODE_API_MIN 4 +#define IWL6000G2_UCODE_API_MIN 5 +#define IWL6035_UCODE_API_MIN 6 /* EEPROM versions */ #define EEPROM_6000_TX_POWER_VERSION (4) @@ -227,9 +230,25 @@ const struct iwl_cfg iwl6030_2bg_cfg = { IWL_DEVICE_6030, }; +#define IWL_DEVICE_6035 \ + .fw_name_pre = IWL6030_FW_PRE, \ + .ucode_api_max = IWL6035_UCODE_API_MAX, \ + .ucode_api_ok = IWL6035_UCODE_API_OK, \ + .ucode_api_min = IWL6035_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6030, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ + .base_params = &iwl6000_g2_base_params, \ + .bt_params = &iwl6000_bt_params, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true + const struct iwl_cfg iwl6035_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", - IWL_DEVICE_6030, + IWL_DEVICE_6035, .ht_params = &iwl6000_ht_params, }; -- cgit v1.1 From e64add27e1b4874f589e550b4e0ca6715070373f Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 5 Jun 2012 20:39:32 +0200 Subject: b43: do not call ieee80211_unregister_hw if we are not registred this patch fixes kernel Oops on "rmmod b43" if firmware was not loaded: BUG: unable to handle kernel NULL pointer dereference at 0000000000000088 IP: [] drain_workqueue+0x25/0x142 PGD 153ac6067 PUD 153b82067 PMD 0 Oops: 0000 [#1] SMP Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 4 ++++ drivers/net/wireless/b43/main.c | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 67c13af..c06b6cb 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -877,6 +877,10 @@ struct b43_wl { * from the mac80211 subsystem. */ u16 mac80211_initially_registered_queues; + /* Set this if we call ieee80211_register_hw() and check if we call + * ieee80211_unregister_hw(). */ + bool hw_registred; + /* We can only have one operating interface (802.11 core) * at a time. General information about this interface follows. */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5a39b22..acd03a4 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2437,6 +2437,7 @@ start_ieee80211: err = ieee80211_register_hw(wl->hw); if (err) goto err_one_core_detach; + wl->hw_registred = true; b43_leds_register(wl->current_dev); goto out; @@ -5299,6 +5300,7 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) hw->queues = modparam_qos ? B43_QOS_QUEUE_NUM : 1; wl->mac80211_initially_registered_queues = hw->queues; + wl->hw_registred = false; hw->max_rates = 2; SET_IEEE80211_DEV(hw, dev->dev); if (is_valid_ether_addr(sprom->et1mac)) @@ -5370,12 +5372,15 @@ static void b43_bcma_remove(struct bcma_device *core) * as the ieee80211 unreg will destroy the workqueue. */ cancel_work_sync(&wldev->restart_work); - /* Restore the queues count before unregistering, because firmware detect - * might have modified it. Restoring is important, so the networking - * stack can properly free resources. */ - wl->hw->queues = wl->mac80211_initially_registered_queues; - b43_leds_stop(wldev); - ieee80211_unregister_hw(wl->hw); + B43_WARN_ON(!wl); + if (wl->current_dev == wldev && wl->hw_registred) { + /* Restore the queues count before unregistering, because firmware detect + * might have modified it. Restoring is important, so the networking + * stack can properly free resources. */ + wl->hw->queues = wl->mac80211_initially_registered_queues; + b43_leds_stop(wldev); + ieee80211_unregister_hw(wl->hw); + } b43_one_core_detach(wldev->dev); @@ -5446,7 +5451,7 @@ static void b43_ssb_remove(struct ssb_device *sdev) cancel_work_sync(&wldev->restart_work); B43_WARN_ON(!wl); - if (wl->current_dev == wldev) { + if (wl->current_dev == wldev && wl->hw_registred) { /* Restore the queues count before unregistering, because firmware detect * might have modified it. Restoring is important, so the networking * stack can properly free resources. */ -- cgit v1.1 From e7027075d0d8fe2d1bf7b0db24623328d2601d3c Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 5 Jun 2012 20:58:20 +0200 Subject: bcma: fix null pointer in bcma_core_pci_irq_ctl pc could be null if hosttype != BCMA_HOSTTYPE_PCI. If we are on a device without a pci core this function is called with pc = null by b43 and brcmsmac. If the host type is PCI we have a pci core as well and pc can not be null. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/driver_pci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c index 9a96f14..c32ebd5 100644 --- a/drivers/bcma/driver_pci.c +++ b/drivers/bcma/driver_pci.c @@ -232,17 +232,19 @@ void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc) int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, bool enable) { - struct pci_dev *pdev = pc->core->bus->host_pci; + struct pci_dev *pdev; u32 coremask, tmp; int err = 0; - if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) { + if (!pc || core->bus->hosttype != BCMA_HOSTTYPE_PCI) { /* This bcma device is not on a PCI host-bus. So the IRQs are * not routed through the PCI core. * So we must not enable routing through the PCI core. */ goto out; } + pdev = pc->core->bus->host_pci; + err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp); if (err) goto out; -- cgit v1.1 From d6ee27eb13beab94056e0de52d81220058ca2297 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 6 Jun 2012 09:13:36 +0200 Subject: iwlwifi: don't mess up the SCD when removing a key When we remove a key, we put a key index which was supposed to tell the fw that we are actually removing the key. But instead the fw took that index as a valid index and messed up the SRAM of the device. This memory corruption on the device mangled the data of the SCD. The impact on the user is that SCD queue 2 got stuck after having removed keys. The message is the log that was printed is: Queue 2 stuck for 10000ms This doesn't seem to fix the higher queues that get stuck from time to time. Cc: stable@vger.kernel.org [2.6.27+] Reviewed-by: Meenakshi Venkataraman Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index aea07aa..eb6a8ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1267,7 +1267,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, key_flags |= STA_KEY_MULTICAST_MSK; sta_cmd.key.key_flags = key_flags; - sta_cmd.key.key_offset = WEP_INVALID_OFFSET; + sta_cmd.key.key_offset = keyconf->hw_key_idx; sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK; sta_cmd.mode = STA_CONTROL_MODIFY_MSK; -- cgit v1.1 From d012d04e4d6312ea157b6cf19e9689af934f5aa7 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 6 Jun 2012 13:55:02 +0200 Subject: iwlwifi: disable the buggy chain extension feature in HW This feature has been reported to be buggy and enabled by default. We therefore need to disable it manually. Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-prph.h | 1 + drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 3b106929..dfd5466 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -224,6 +224,7 @@ #define SCD_TXFACT (SCD_BASE + 0x10) #define SCD_ACTIVE (SCD_BASE + 0x14) #define SCD_QUEUECHAIN_SEL (SCD_BASE + 0xe8) +#define SCD_CHAINEXT_EN (SCD_BASE + 0x244) #define SCD_AGGR_SEL (SCD_BASE + 0x248) #define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ec6fb39..79c6b91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1058,6 +1058,11 @@ static void iwl_tx_start(struct iwl_trans *trans) iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10); + /* The chain extension of the SCD doesn't work well. This feature is + * enabled by default by the HW, so we need to disable it manually. + */ + iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); + /* Enable DMA channel */ for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), -- cgit v1.1 From cd8f76c0a0c6fce0b2cf23c9bd0123f91453f46d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 7 Jun 2012 22:59:59 +0000 Subject: be2net: fix a race in be_xmit() As soon as hardware is notified of a transmit, we no longer can assume skb can be dereferenced, as TX completion might have freed the packet. Signed-off-by: Eric Dumazet Cc: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 08efd30..fdb50ce 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -736,6 +736,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, copied = make_tx_wrbs(adapter, txq, skb, wrb_cnt, dummy_wrb); if (copied) { + int gso_segs = skb_shinfo(skb)->gso_segs; + /* record the sent skb in the sent_skb table */ BUG_ON(txo->sent_skb_list[start]); txo->sent_skb_list[start] = skb; @@ -753,8 +755,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, be_txq_notify(adapter, txq->id, wrb_cnt); - be_tx_stats_update(txo, wrb_cnt, copied, - skb_shinfo(skb)->gso_segs, stopped); + be_tx_stats_update(txo, wrb_cnt, copied, gso_segs, stopped); } else { txq->head = start; dev_kfree_skb_any(skb); -- cgit v1.1 From f41ef2e7dc4515777810016612316c38f84275e7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 8 Jun 2012 14:07:19 +0000 Subject: netdev: fix drivers/net/phy/ kernel-doc warnings Fix kernel-doc warnings in drivers/net/phy: Warning(drivers/net/phy/mdio_bus.c:109): No description found for parameter 'mdio_bus_np' Warning(drivers/net/phy/mdio_bus.c:109): Excess function parameter 'mdio_np' description in 'of_mdio_find_bus' Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/net/phy/mdio_bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 683ef1c..5061608 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -96,7 +96,7 @@ static int of_mdio_bus_match(struct device *dev, void *mdio_bus_np) } /** * of_mdio_find_bus - Given an mii_bus node, find the mii_bus. - * @mdio_np: Pointer to the mii_bus. + * @mdio_bus_np: Pointer to the mii_bus. * * Returns a pointer to the mii_bus, or NULL if none found. * -- cgit v1.1 From c91c3faea500da34d42a14735f1f67bb137b6413 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 9 Jun 2012 08:46:42 +0200 Subject: vga_switcheroo: Enable/disable audio clients at the right time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The audio clients have to be disabled before disabling the VGA and switching. Similarly, enabling the audio client should be done at last. Otherwise the audio-side operation stalls, eventually leading to Oops or lockups. Tested-by: Jörg-Volker Peetz Acked-by: Dave Airlie Signed-off-by: Takashi Iwai --- drivers/gpu/vga/vga_switcheroo.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index eb4f64f..5b3c7d1 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -304,8 +304,6 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client) vga_switchon(new_client); vga_set_default_device(new_client->pdev); - set_audio_state(new_client->id, VGA_SWITCHEROO_ON); - return 0; } @@ -321,6 +319,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) active->active = false; + set_audio_state(active->id, VGA_SWITCHEROO_OFF); + if (new_client->fb_info) { struct fb_event event; event.info = new_client->fb_info; @@ -334,11 +334,11 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) if (new_client->ops->reprobe) new_client->ops->reprobe(new_client->pdev); - set_audio_state(active->id, VGA_SWITCHEROO_OFF); - if (active->pwr_state == VGA_SWITCHEROO_ON) vga_switchoff(active); + set_audio_state(new_client->id, VGA_SWITCHEROO_ON); + new_client->active = true; return 0; } @@ -384,8 +384,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, /* pwr off the device not in use */ if (strncmp(usercmd, "OFF", 3) == 0) { list_for_each_entry(client, &vgasr_priv.clients, list) { - if (client->active) + if (client->active || client_is_audio(client)) continue; + set_audio_state(client->id, VGA_SWITCHEROO_OFF); if (client->pwr_state == VGA_SWITCHEROO_ON) vga_switchoff(client); } @@ -394,10 +395,11 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, /* pwr on the device not in use */ if (strncmp(usercmd, "ON", 2) == 0) { list_for_each_entry(client, &vgasr_priv.clients, list) { - if (client->active) + if (client->active || client_is_audio(client)) continue; if (client->pwr_state == VGA_SWITCHEROO_OFF) vga_switchon(client); + set_audio_state(client->id, VGA_SWITCHEROO_ON); } goto out; } -- cgit v1.1 From 6f32d03bc63ab27f5e21d40c4ec81e18d991f424 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 15 May 2012 15:02:57 -0600 Subject: drivers/video: use correct __devexit_p annotation __devexit functions are discarded when CONFIG_HOTPLUG is not set, so the symbol needs to be referenced carefully. Signed-off-by: Arnd Bergmann Signed-off-by: Mathieu Poirier Signed-off-by: Florian Tobias Schandinat --- drivers/video/broadsheetfb.c | 2 +- drivers/video/mbx/mbxfb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/broadsheetfb.c b/drivers/video/broadsheetfb.c index 377dde3..c95b417 100644 --- a/drivers/video/broadsheetfb.c +++ b/drivers/video/broadsheetfb.c @@ -1211,7 +1211,7 @@ static int __devexit broadsheetfb_remove(struct platform_device *dev) static struct platform_driver broadsheetfb_driver = { .probe = broadsheetfb_probe, - .remove = broadsheetfb_remove, + .remove = __devexit_p(broadsheetfb_remove), .driver = { .owner = THIS_MODULE, .name = "broadsheetfb", diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c index ab0a8e5..85e4f44 100644 --- a/drivers/video/mbx/mbxfb.c +++ b/drivers/video/mbx/mbxfb.c @@ -1045,7 +1045,7 @@ static int __devexit mbxfb_remove(struct platform_device *dev) static struct platform_driver mbxfb_driver = { .probe = mbxfb_probe, - .remove = mbxfb_remove, + .remove = __devexit_p(mbxfb_remove), .suspend = mbxfb_suspend, .resume = mbxfb_resume, .driver = { -- cgit v1.1 From ff9440465c82099ba3365930a97f90b3acfcc980 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 15 May 2012 15:02:58 -0600 Subject: video/ili9320: do not mark exported functions __devexit No symbol can be exported when the section is discarded - the only solution I could think of is not to mark symbols as __devexit when they are exported. Signed-off-by: Arnd Bergmann Signed-off-by: Mathieu Poirier Signed-off-by: Florian Tobias Schandinat --- drivers/video/backlight/ili9320.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c index 5118a9f..b67485a 100644 --- a/drivers/video/backlight/ili9320.c +++ b/drivers/video/backlight/ili9320.c @@ -267,7 +267,7 @@ int __devinit ili9320_probe_spi(struct spi_device *spi, EXPORT_SYMBOL_GPL(ili9320_probe_spi); -int __devexit ili9320_remove(struct ili9320 *ili) +int ili9320_remove(struct ili9320 *ili) { ili9320_power(ili, FB_BLANK_POWERDOWN); -- cgit v1.1 From d399099cbba92b247ac323a99ac4c5fa5b0ca68d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 15 May 2012 15:02:59 -0600 Subject: video/console: automatically select a font The frame buffer console needs at least one font to be built into the kernel, so add the necessary Kconfig magic to guarantee that one of the available font is always on. If a user accidentally disables all fonts manually, the 8x16 font will be selected anyway. Signed-off-by: Arnd Bergmann Signed-off-by: Mathieu Poirier Signed-off-by: Florian Tobias Schandinat --- drivers/video/console/Kconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index c2d11fe..e2c96d0 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -224,5 +224,19 @@ config FONT_10x18 big letters. It fits between the sun 12x22 and the normal 8x16 font. If other fonts are too big or too small for you, say Y, otherwise say N. +config FONT_AUTOSELECT + def_bool y + depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE || STI_CONSOLE || USB_SISUSBVGA_CON + depends on !FONT_8x8 + depends on !FONT_6x11 + depends on !FONT_7x14 + depends on !FONT_PEARL_8x8 + depends on !FONT_ACORN_8x8 + depends on !FONT_MINI_4x6 + depends on !FONT_SUN8x16 + depends on !FONT_SUN12x22 + depends on !FONT_10x18 + select FONT_8x16 + endmenu -- cgit v1.1 From f5c3ac242d05c07f646824aba25a541af7464c82 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 15 May 2012 15:03:00 -0600 Subject: drivers/savagefb: use mdelay instead of udelay Long delays need to use mdelay on architectures such as ARM that cannot compute long timeouts in udelay. Signed-off-by: Arnd Bergmann Signed-off-by: Mathieu Poirier Signed-off-by: Florian Tobias Schandinat --- drivers/video/savage/savagefb_driver.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index cee7803..f3d3b9c 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -1351,7 +1351,7 @@ static void savagefb_set_par_int(struct savagefb_par *par, struct savage_reg *r /* following part not present in X11 driver */ cr67 = vga_in8(0x3d5, par) & 0xf; vga_out8(0x3d5, 0x50 | cr67, par); - udelay(10000); + mdelay(10); vga_out8(0x3d4, 0x67, par); /* end of part */ vga_out8(0x3d5, reg->CR67 & ~0x0c, par); @@ -1904,11 +1904,11 @@ static int savage_init_hw(struct savagefb_par *par) vga_out8(0x3d4, 0x66, par); cr66 = vga_in8(0x3d5, par); vga_out8(0x3d5, cr66 | 0x02, par); - udelay(10000); + mdelay(10); vga_out8(0x3d4, 0x66, par); vga_out8(0x3d5, cr66 & ~0x02, par); /* clear reset flag */ - udelay(10000); + mdelay(10); /* @@ -1918,11 +1918,11 @@ static int savage_init_hw(struct savagefb_par *par) vga_out8(0x3d4, 0x3f, par); cr3f = vga_in8(0x3d5, par); vga_out8(0x3d5, cr3f | 0x08, par); - udelay(10000); + mdelay(10); vga_out8(0x3d4, 0x3f, par); vga_out8(0x3d5, cr3f & ~0x08, par); /* clear reset flags */ - udelay(10000); + mdelay(10); /* Savage ramdac speeds */ par->numClocks = 4; -- cgit v1.1 From 5fc05780b84d5227e6c15986f1bde488e52752bd Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 15 May 2012 15:03:01 -0600 Subject: drivers/tosa: driver needs I2C and SPI to compile This driver requires both SPI and I2C to build. Signed-off-by: Arnd Bergmann Signed-off-by: Mathieu Poirier Signed-off-by: Florian Tobias Schandinat --- drivers/video/backlight/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index af16884..d7487d2 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -88,7 +88,7 @@ config LCD_PLATFORM config LCD_TOSA tristate "Sharp SL-6000 LCD Driver" - depends on SPI && MACH_TOSA + depends on I2C && SPI && MACH_TOSA help If you have an Sharp SL-6000 Zaurus say Y to enable a driver for its LCD. -- cgit v1.1 From 6eda541d12116b4772baa09d3e8d7b0389df4289 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 8 Jun 2012 14:32:50 +0200 Subject: Bluetooth: Support AR3011 in Acer Iconia Tab W500 Acer used this chip connected via USB: Bus 005 Device 005: ID 0cf3:3005 Atheros Communications, Inc. AR3011 Bluetooth Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 224 Wireless bDeviceSubClass 1 Radio Frequency bDeviceProtocol 1 Bluetooth bMaxPacketSize0 64 idVendor 0x0cf3 Atheros Communications, Inc. idProduct 0x3005 AR3011 Bluetooth bcdDevice 0.01 iManufacturer 0 iProduct 0 iSerial 0 bNumConfigurations 1 Signed-off-by: Marek Vasut Cc: Gustavo Padovan Cc: Johan Hedberg Cc: Marcel Holtmann Signed-off-by: Gustavo Padovan --- drivers/bluetooth/ath3k.c | 1 + drivers/bluetooth/btusb.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index ad591bd..f0f6202 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, + { USB_DEVICE(0x0CF3, 0xE019) }, { USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0489, 0xE03D) }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c9463af..ff3eabc 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -125,6 +125,7 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, -- cgit v1.1 From e981f6d41acda2ae8c05e60feb2cb97772b4a6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Sun, 10 Jun 2012 14:37:07 +0300 Subject: remoteproc: fix print format warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix compile warnings from GCC 4.6.1 when printing values of type size_t. drivers/remoteproc/remoteproc_core.c:251:6: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 4 has type ‘size_t’ [-Wformat] drivers/remoteproc/remoteproc_core.c:938:9: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 4 has type ‘size_t’ [-Wformat] drivers/remoteproc/remoteproc_core.c:1023:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘size_t’ [-Wformat] Signed-off-by: Sjur Brændeland Signed-off-by: Ohad Ben-Cohen Cc: stable@vger.kernel.org --- drivers/remoteproc/remoteproc_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 8ea7bcc..cb13f1b 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -247,7 +247,7 @@ rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len) } if (offset + filesz > len) { - dev_err(dev, "truncated fw: need 0x%x avail 0x%x\n", + dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", offset + filesz, len); ret = -EINVAL; break; @@ -934,7 +934,7 @@ static void rproc_resource_cleanup(struct rproc *rproc) unmapped = iommu_unmap(rproc->domain, entry->da, entry->len); if (unmapped != entry->len) { /* nothing much to do besides complaining */ - dev_err(dev, "failed to unmap %u/%u\n", entry->len, + dev_err(dev, "failed to unmap %u/%zu\n", entry->len, unmapped); } @@ -1020,7 +1020,7 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) ehdr = (struct elf32_hdr *)fw->data; - dev_info(dev, "Booting fw image %s, size %d\n", name, fw->size); + dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size); /* * if enabling an IOMMU isn't relevant for this rproc, this is -- cgit v1.1 From 30338cf09f82523d8747670f7363cc8af347c79f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Sun, 10 Jun 2012 14:37:51 +0300 Subject: remoteproc: fix missing fault indication in error-path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If rproc_find_rsc_table() fails, rproc_fw_boot() must set return-value before jumping to clean_up label. Otherwise no error value is returned. Signed-off-by: Sjur Brændeland Signed-off-by: Ohad Ben-Cohen Cc: stable@vger.kernel.org --- drivers/remoteproc/remoteproc_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index cb13f1b..66324ee 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1041,8 +1041,10 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) /* look for the resource table */ table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz); - if (!table) + if (!table) { + ret = -EINVAL; goto clean_up; + } /* handle fw resources which are required to boot rproc */ ret = rproc_handle_boot_rsc(rproc, table, tablesz); -- cgit v1.1 From d26098759cf6d32148649c165f87a7590bc25b89 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sat, 9 Jun 2012 10:57:41 -0400 Subject: drm/radeon: fix tiling and command stream checking on evergreen v3 Fix regresson since the introduction of command stream checking on evergreen (thread referenced below). Issue is cause by ddx allocating bo with formula width*height*bpp while programming the GPU command stream with ALIGN(height, 8). In some case (where page alignment does not hide the extra size bo should be according to height alignment) the kernel will reject the command stream. This patch reprogram the command stream to slice - 1 (slice is a derivative value from height) which avoid rejecting the command stream while keeping the value of command stream checking from a security point of view. This patch also fix wrong computation of layer size for 2D tiled surface. Which should fix issue when 2D color tiling is enabled. This dump the radeon KMS_DRIVER_MINOR so userspace can know if they are on a fixed kernel or not. https://lkml.org/lkml/2012/6/3/80 https://bugs.freedesktop.org/show_bug.cgi?id=50892 https://bugs.freedesktop.org/show_bug.cgi?id=50857 !!! STABLE need a custom version of this patch for 3.4 !!! v2: actually bump the minor version and add comment about stable v3: do compute the height the ddx was trying to use [airlied: drop left over debug] Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen_cs.c | 49 ++++++++++++++++++++++++++++++++--- drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- 2 files changed, 47 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 4e7dd2b..c1655412 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -52,6 +52,7 @@ struct evergreen_cs_track { u32 cb_color_view[12]; u32 cb_color_pitch[12]; u32 cb_color_slice[12]; + u32 cb_color_slice_idx[12]; u32 cb_color_attrib[12]; u32 cb_color_cmask_slice[8];/* unused */ u32 cb_color_fmask_slice[8];/* unused */ @@ -127,12 +128,14 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track) track->cb_color_info[i] = 0; track->cb_color_view[i] = 0xFFFFFFFF; track->cb_color_pitch[i] = 0; - track->cb_color_slice[i] = 0; + track->cb_color_slice[i] = 0xfffffff; + track->cb_color_slice_idx[i] = 0; } track->cb_target_mask = 0xFFFFFFFF; track->cb_shader_mask = 0xFFFFFFFF; track->cb_dirty = true; + track->db_depth_slice = 0xffffffff; track->db_depth_view = 0xFFFFC000; track->db_depth_size = 0xFFFFFFFF; track->db_depth_control = 0xFFFFFFFF; @@ -250,10 +253,9 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, { struct evergreen_cs_track *track = p->track; unsigned palign, halign, tileb, slice_pt; + unsigned mtile_pr, mtile_ps, mtileb; tileb = 64 * surf->bpe * surf->nsamples; - palign = track->group_size / (8 * surf->bpe * surf->nsamples); - palign = MAX(8, palign); slice_pt = 1; if (tileb > surf->tsplit) { slice_pt = tileb / surf->tsplit; @@ -262,7 +264,10 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, /* macro tile width & height */ palign = (8 * surf->bankw * track->npipes) * surf->mtilea; halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; - surf->layer_size = surf->nbx * surf->nby * surf->bpe * slice_pt; + mtileb = (palign / 8) * (halign / 8) * tileb;; + mtile_pr = surf->nbx / palign; + mtile_ps = (mtile_pr * surf->nby) / halign; + surf->layer_size = mtile_ps * mtileb * slice_pt; surf->base_align = (palign / 8) * (halign / 8) * tileb; surf->palign = palign; surf->halign = halign; @@ -434,6 +439,39 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i offset += surf.layer_size * mslice; if (offset > radeon_bo_size(track->cb_color_bo[id])) { + /* old ddx are broken they allocate bo with w*h*bpp but + * program slice with ALIGN(h, 8), catch this and patch + * command stream. + */ + if (!surf.mode) { + volatile u32 *ib = p->ib.ptr; + unsigned long tmp, nby, bsize, size, min = 0; + + /* find the height the ddx wants */ + if (surf.nby > 8) { + min = surf.nby - 8; + } + bsize = radeon_bo_size(track->cb_color_bo[id]); + tmp = track->cb_color_bo_offset[id] << 8; + for (nby = surf.nby; nby > min; nby--) { + size = nby * surf.nbx * surf.bpe * surf.nsamples; + if ((tmp + size * mslice) <= bsize) { + break; + } + } + if (nby > min) { + surf.nby = nby; + slice = ((nby * surf.nbx) / 64) - 1; + if (!evergreen_surface_check(p, &surf, "cb")) { + /* check if this one works */ + tmp += surf.layer_size * mslice; + if (tmp <= bsize) { + ib[track->cb_color_slice_idx[id]] = slice; + goto old_ddx_ok; + } + } + } + } dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, " "offset %d, max layer %d, bo size %ld, slice %d)\n", __func__, __LINE__, id, surf.layer_size, @@ -446,6 +484,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i surf.tsplit, surf.mtilea); return -EINVAL; } +old_ddx_ok: return 0; } @@ -1532,6 +1571,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR7_SLICE: tmp = (reg - CB_COLOR0_SLICE) / 0x3c; track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx); + track->cb_color_slice_idx[tmp] = idx; track->cb_dirty = true; break; case CB_COLOR8_SLICE: @@ -1540,6 +1580,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR11_SLICE: tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8; track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx); + track->cb_color_slice_idx[tmp] = idx; track->cb_dirty = true; break; case CB_COLOR0_ATTRIB: diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index f0bb2b5..03e5f5d 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -57,9 +57,10 @@ * 2.13.0 - virtual memory support, streamout * 2.14.0 - add evergreen tiling informations * 2.15.0 - add max_pipes query + * 2.16.0 - fix evergreen 2D tiled surface calculation */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 15 +#define KMS_DRIVER_MINOR 16 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); -- cgit v1.1 From 7dbb491878a2c51d372a8890fa45a8ff80358af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fran=C3=A7ois=20romieu?= Date: Sat, 9 Jun 2012 10:53:16 +0000 Subject: r8169: avoid NAPI scheduling delay. While reworking the r8169 driver a few months ago to perform the smallest amount of work in the irq handler, I took care of avoiding any irq mask register operation in the slow work dedicated user context thread. The slow work thread scheduled an extra round of NAPI work which would ultimately set the irq mask register as required, thus keeping such irq mask operations in the NAPI handler. It would eventually race with the irq handler and delay NAPI execution for - assuming no further irq - a whole ksoftirqd period. Mildly a problem for rare link changes or corner case PCI events. The race was always lost after the last bh disabling lock had been removed from the work thread and people started wondering where those pesky "NOHZ: local_softirq_pending 08" messages came from. Actually the irq mask register _can_ be set up directly in the slow work thread. Signed-off-by: Francois Romieu Reported-by: Dave Jones Tested-by: Marc Dionne Cc: Thomas Gleixner Cc: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 9757ce3..7260aa7 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5889,11 +5889,7 @@ static void rtl_slow_event_work(struct rtl8169_private *tp) if (status & LinkChg) __rtl8169_check_link_status(dev, tp, tp->mmio_addr, true); - napi_disable(&tp->napi); - rtl_irq_disable(tp); - - napi_enable(&tp->napi); - napi_schedule(&tp->napi); + rtl_irq_enable_all(tp); } static void rtl_task(struct work_struct *work) -- cgit v1.1 From 83a27052c3376793bc879e00e6e6805d6fb7aab9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Jun 2012 22:35:24 +0000 Subject: virtio-net: fix a race on 32bit arches commit 3fa2a1df909 (virtio-net: per cpu 64 bit stats (v2)) added a race on 32bit arches. We must use separate syncp for rx and tx path as they can be run at the same time on different cpus. Thus one sequence increment can be lost and readers spin forever. Signed-off-by: Eric Dumazet Cc: Stephen Hemminger Cc: Michael S. Tsirkin Cc: Jason Wang Acked-by: Rusty Russell Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 5214b1e..f18149a 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -42,7 +42,8 @@ module_param(gso, bool, 0444); #define VIRTNET_DRIVER_VERSION "1.0.0" struct virtnet_stats { - struct u64_stats_sync syncp; + struct u64_stats_sync tx_syncp; + struct u64_stats_sync rx_syncp; u64 tx_bytes; u64 tx_packets; @@ -300,10 +301,10 @@ static void receive_buf(struct net_device *dev, void *buf, unsigned int len) hdr = skb_vnet_hdr(skb); - u64_stats_update_begin(&stats->syncp); + u64_stats_update_begin(&stats->rx_syncp); stats->rx_bytes += skb->len; stats->rx_packets++; - u64_stats_update_end(&stats->syncp); + u64_stats_update_end(&stats->rx_syncp); if (hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { pr_debug("Needs csum!\n"); @@ -565,10 +566,10 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi) while ((skb = virtqueue_get_buf(vi->svq, &len)) != NULL) { pr_debug("Sent skb %p\n", skb); - u64_stats_update_begin(&stats->syncp); + u64_stats_update_begin(&stats->tx_syncp); stats->tx_bytes += skb->len; stats->tx_packets++; - u64_stats_update_end(&stats->syncp); + u64_stats_update_end(&stats->tx_syncp); tot_sgs += skb_vnet_hdr(skb)->num_sg; dev_kfree_skb_any(skb); @@ -703,12 +704,16 @@ static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev, u64 tpackets, tbytes, rpackets, rbytes; do { - start = u64_stats_fetch_begin(&stats->syncp); + start = u64_stats_fetch_begin(&stats->tx_syncp); tpackets = stats->tx_packets; tbytes = stats->tx_bytes; + } while (u64_stats_fetch_retry(&stats->tx_syncp, start)); + + do { + start = u64_stats_fetch_begin(&stats->rx_syncp); rpackets = stats->rx_packets; rbytes = stats->rx_bytes; - } while (u64_stats_fetch_retry(&stats->syncp, start)); + } while (u64_stats_fetch_retry(&stats->rx_syncp, start)); tot->rx_packets += rpackets; tot->tx_packets += tpackets; -- cgit v1.1 From 7d0c399fe94d4fe572eadc7405654a282e5df63d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 May 2012 13:36:43 +0900 Subject: clocksource: sh_cmt: Convert timer lock to raw spinlock. Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 32fe9ef..98b06ba 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -48,13 +48,13 @@ struct sh_cmt_priv { unsigned long next_match_value; unsigned long max_match_value; unsigned long rate; - spinlock_t lock; + raw_spinlock_t lock; struct clock_event_device ced; struct clocksource cs; unsigned long total_cycles; }; -static DEFINE_SPINLOCK(sh_cmt_lock); +static DEFINE_RAW_SPINLOCK(sh_cmt_lock); #define CMSTR -1 /* shared register */ #define CMCSR 0 /* channel register */ @@ -139,7 +139,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) unsigned long flags, value; /* start stop register shared by multiple timer channels */ - spin_lock_irqsave(&sh_cmt_lock, flags); + raw_spin_lock_irqsave(&sh_cmt_lock, flags); value = sh_cmt_read(p, CMSTR); if (start) @@ -148,7 +148,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) value &= ~(1 << cfg->timer_bit); sh_cmt_write(p, CMSTR, value); - spin_unlock_irqrestore(&sh_cmt_lock, flags); + raw_spin_unlock_irqrestore(&sh_cmt_lock, flags); } static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) @@ -328,9 +328,9 @@ static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) { unsigned long flags; - spin_lock_irqsave(&p->lock, flags); + raw_spin_lock_irqsave(&p->lock, flags); __sh_cmt_set_next(p, delta); - spin_unlock_irqrestore(&p->lock, flags); + raw_spin_unlock_irqrestore(&p->lock, flags); } static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) @@ -385,7 +385,7 @@ static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag) int ret = 0; unsigned long flags; - spin_lock_irqsave(&p->lock, flags); + raw_spin_lock_irqsave(&p->lock, flags); if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) ret = sh_cmt_enable(p, &p->rate); @@ -398,7 +398,7 @@ static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag) if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT))) __sh_cmt_set_next(p, p->max_match_value); out: - spin_unlock_irqrestore(&p->lock, flags); + raw_spin_unlock_irqrestore(&p->lock, flags); return ret; } @@ -408,7 +408,7 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag) unsigned long flags; unsigned long f; - spin_lock_irqsave(&p->lock, flags); + raw_spin_lock_irqsave(&p->lock, flags); f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE); p->flags &= ~flag; @@ -420,7 +420,7 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag) if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE)) __sh_cmt_set_next(p, p->max_match_value); - spin_unlock_irqrestore(&p->lock, flags); + raw_spin_unlock_irqrestore(&p->lock, flags); } static struct sh_cmt_priv *cs_to_sh_cmt(struct clocksource *cs) @@ -435,13 +435,13 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs) unsigned long value; int has_wrapped; - spin_lock_irqsave(&p->lock, flags); + raw_spin_lock_irqsave(&p->lock, flags); value = p->total_cycles; raw = sh_cmt_get_counter(p, &has_wrapped); if (unlikely(has_wrapped)) raw += p->match_value + 1; - spin_unlock_irqrestore(&p->lock, flags); + raw_spin_unlock_irqrestore(&p->lock, flags); return value + raw; } @@ -591,7 +591,7 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name, p->max_match_value = (1 << p->width) - 1; p->match_value = p->max_match_value; - spin_lock_init(&p->lock); + raw_spin_lock_init(&p->lock); if (clockevent_rating) sh_cmt_register_clockevent(p, name, clockevent_rating); -- cgit v1.1 From 50393a92c89c603e2d043c9f0212d3bd66701c86 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 May 2012 13:38:54 +0900 Subject: clocksource: sh_mtu2: Convert timer lock to raw spinlock. Signed-off-by: Paul Mundt --- drivers/clocksource/sh_mtu2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index a2172f6..d9b76ca 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -43,7 +43,7 @@ struct sh_mtu2_priv { struct clock_event_device ced; }; -static DEFINE_SPINLOCK(sh_mtu2_lock); +static DEFINE_RAW_SPINLOCK(sh_mtu2_lock); #define TSTR -1 /* shared register */ #define TCR 0 /* channel register */ @@ -107,7 +107,7 @@ static void sh_mtu2_start_stop_ch(struct sh_mtu2_priv *p, int start) unsigned long flags, value; /* start stop register shared by multiple timer channels */ - spin_lock_irqsave(&sh_mtu2_lock, flags); + raw_spin_lock_irqsave(&sh_mtu2_lock, flags); value = sh_mtu2_read(p, TSTR); if (start) @@ -116,7 +116,7 @@ static void sh_mtu2_start_stop_ch(struct sh_mtu2_priv *p, int start) value &= ~(1 << cfg->timer_bit); sh_mtu2_write(p, TSTR, value); - spin_unlock_irqrestore(&sh_mtu2_lock, flags); + raw_spin_unlock_irqrestore(&sh_mtu2_lock, flags); } static int sh_mtu2_enable(struct sh_mtu2_priv *p) -- cgit v1.1 From c2225a57e596a308424e59abc7e864f866fe4493 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 May 2012 13:39:09 +0900 Subject: clocksource: sh_tmu: Convert timer lock to raw spinlock. Signed-off-by: Paul Mundt --- drivers/clocksource/sh_tmu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 97f54b6..852b3f1 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -45,7 +45,7 @@ struct sh_tmu_priv { struct clocksource cs; }; -static DEFINE_SPINLOCK(sh_tmu_lock); +static DEFINE_RAW_SPINLOCK(sh_tmu_lock); #define TSTR -1 /* shared register */ #define TCOR 0 /* channel register */ @@ -95,7 +95,7 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start) unsigned long flags, value; /* start stop register shared by multiple timer channels */ - spin_lock_irqsave(&sh_tmu_lock, flags); + raw_spin_lock_irqsave(&sh_tmu_lock, flags); value = sh_tmu_read(p, TSTR); if (start) @@ -104,7 +104,7 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start) value &= ~(1 << cfg->timer_bit); sh_tmu_write(p, TSTR, value); - spin_unlock_irqrestore(&sh_tmu_lock, flags); + raw_spin_unlock_irqrestore(&sh_tmu_lock, flags); } static int sh_tmu_enable(struct sh_tmu_priv *p) -- cgit v1.1 From 3977407e83129f53e43d3ac44be8702f59fa3f77 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 11 Jun 2012 17:10:16 +0900 Subject: clocksource: sh_tmu: Use clockevents_config_and_register(). This switches over to the now exported clockevents_config() and clockevents_config_and_register() helpers. This knocks off a long-standing TMU TODO item. Signed-off-by: Paul Mundt --- drivers/clocksource/sh_tmu.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 852b3f1..c1b51d4 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -245,12 +245,7 @@ static void sh_tmu_clock_event_start(struct sh_tmu_priv *p, int periodic) sh_tmu_enable(p); - /* TODO: calculate good shift from rate and counter bit width */ - - ced->shift = 32; - ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift); - ced->max_delta_ns = clockevent_delta2ns(0xffffffff, ced); - ced->min_delta_ns = 5000; + clockevents_config(ced, p->rate); if (periodic) { p->periodic = (p->rate + HZ/2) / HZ; @@ -323,7 +318,8 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p, ced->set_mode = sh_tmu_clock_event_mode; dev_info(&p->pdev->dev, "used for clock events\n"); - clockevents_register_device(ced); + + clockevents_config_and_register(ced, 1, 0x300, 0xffffffff); ret = setup_irq(p->irqaction.irq, &p->irqaction); if (ret) { -- cgit v1.1 From 16b0dc29c1af9df341428f4c49ada4f626258082 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 10 Jun 2012 21:11:57 +0000 Subject: dummy: fix rcu_sched self-detected stalls Trying to "modprobe dummy numdummies=30000" triggers : INFO: rcu_sched self-detected stall on CPU { 8} (t=60000 jiffies) After this splat, RTNL is locked and reboot is needed. We must call cond_resched() to avoid this, even holding RTNL. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/dummy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 442d91a..bab0158 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -187,8 +187,10 @@ static int __init dummy_init_module(void) rtnl_lock(); err = __rtnl_link_register(&dummy_link_ops); - for (i = 0; i < numdummies && !err; i++) + for (i = 0; i < numdummies && !err; i++) { err = dummy_init_one(); + cond_resched(); + } if (err < 0) __rtnl_link_unregister(&dummy_link_ops); rtnl_unlock(); -- cgit v1.1 From e35fca4791fcdd43dc1fd769797df40c562ab491 Mon Sep 17 00:00:00 2001 From: Chen Gong Date: Tue, 8 May 2012 20:40:12 -0300 Subject: edac: avoid mce decoding crash after edac driver unloaded Some edac drivers register themselves as mce decoders via notifier_chain. But in current notifier_chain implementation logic, it doesn't accept same notifier registered twice. If so, it will be wrong when adding/removing the element from the list. For example, on one SandyBridge platform, remove module sb_edac and then trigger one error, it will hit oops because it has no mce decoder registered but related notifier_chain still points to an invalid callback function. Here is an example: Call Trace: [] atomic_notifier_call_chain+0x1a/0x20 [] mce_log+0x46/0x180 [] apei_mce_report_mem_error+0x4a/0x60 [] ghes_do_proc+0x192/0x210 [] ghes_proc+0x46/0x70 [] ghes_notify_sci+0x48/0x80 [] notifier_call_chain+0x55/0x80 [] __blocking_notifier_call_chain+0x5a/0x80 [] ? acpi_os_wait_events_complete+0x23/0x23 [] blocking_notifier_call_chain+0x16/0x20 [] acpi_hed_notify+0x19/0x1b [] acpi_device_notify+0x19/0x1b [] acpi_ev_notify_dispatch+0x67/0x7f [] acpi_os_execute_deferred+0x29/0x36 [] process_one_work+0x132/0x450 [] worker_thread+0x17b/0x3c0 [] ? manage_workers+0x120/0x120 [] kthread+0x9e/0xb0 [] kernel_thread_helper+0x4/0x10 [] ? kthread_freezable_should_stop+0x70/0x70 [] ? gs_change+0x13/0x13 Code: f3 49 89 d4 45 85 ed 4d 89 c6 48 8b 0f 74 48 48 85 c9 75 17 eb 41 0f 1f 80 00 00 00 00 41 83 ed 01 4c 89 f9 74 22 4d 85 ff 74 1d <4c> 8b 79 08 4c 89 e2 48 89 de 48 89 cf ff 11 4d 85 f6 74 04 41 RIP [] notifier_call_chain+0x46/0x80 RSP CR2: ffffffffa01af838 ---[ end trace 0100930068e73e6f ]--- BUG: unable to handle kernel paging request at fffffffffffffff8 IP: [] kthread_data+0x10/0x20 PGD 1a0d067 PUD 1a0e067 PMD 0 Oops: 0000 [#2] SMP Only i7core_edac and sb_edac have such issues because they have more than one memory controller which means they have to register mce decoder many times. Cc: # 3.2 and upper Signed-off-by: Chen Gong Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 15 ++++----------- drivers/edac/sb_edac.c | 8 ++++---- 2 files changed, 8 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index d27778f..a499c7e 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1814,12 +1814,6 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val, if (mce->bank != 8) return NOTIFY_DONE; -#ifdef CONFIG_SMP - /* Only handle if it is the right mc controller */ - if (mce->socketid != pvt->i7core_dev->socket) - return NOTIFY_DONE; -#endif - smp_rmb(); if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { smp_wmb(); @@ -2116,8 +2110,6 @@ static void i7core_unregister_mci(struct i7core_dev *i7core_dev) if (pvt->enable_scrub) disable_sdram_scrub_setting(mci); - mce_unregister_decode_chain(&i7_mce_dec); - /* Disable EDAC polling */ i7core_pci_ctl_release(pvt); @@ -2222,8 +2214,6 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev) /* DCLK for scrub rate setting */ pvt->dclk_freq = get_dclk_freq(); - mce_register_decode_chain(&i7_mce_dec); - return 0; fail0: @@ -2367,8 +2357,10 @@ static int __init i7core_init(void) pci_rc = pci_register_driver(&i7core_driver); - if (pci_rc >= 0) + if (pci_rc >= 0) { + mce_register_decode_chain(&i7_mce_dec); return 0; + } i7core_printk(KERN_ERR, "Failed to register device with error %d.\n", pci_rc); @@ -2384,6 +2376,7 @@ static void __exit i7core_exit(void) { debugf2("MC: " __FILE__ ": %s()\n", __func__); pci_unregister_driver(&i7core_driver); + mce_unregister_decode_chain(&i7_mce_dec); } module_init(i7core_init); diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 4adaf4b..a21ace0 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -1604,8 +1604,6 @@ static void sbridge_unregister_mci(struct sbridge_dev *sbridge_dev) debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n", __func__, mci, &sbridge_dev->pdev[0]->dev); - mce_unregister_decode_chain(&sbridge_mce_dec); - /* Remove MC sysfs nodes */ edac_mc_del_mc(mci->dev); @@ -1682,7 +1680,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev) goto fail0; } - mce_register_decode_chain(&sbridge_mce_dec); return 0; fail0: @@ -1811,8 +1808,10 @@ static int __init sbridge_init(void) pci_rc = pci_register_driver(&sbridge_driver); - if (pci_rc >= 0) + if (pci_rc >= 0) { + mce_register_decode_chain(&sbridge_mce_dec); return 0; + } sbridge_printk(KERN_ERR, "Failed to register device with error %d.\n", pci_rc); @@ -1828,6 +1827,7 @@ static void __exit sbridge_exit(void) { debugf2("MC: " __FILE__ ": %s()\n", __func__); pci_unregister_driver(&sbridge_driver); + mce_unregister_decode_chain(&sbridge_mce_dec); } module_init(sbridge_init); -- cgit v1.1 From 2cbb587d3bc41a305168e91b4f3c5b6944a12566 Mon Sep 17 00:00:00 2001 From: Chen Gong Date: Mon, 14 May 2012 05:51:26 -0300 Subject: edac: fix the error about memory type detection on SandyBridge On SandyBridge, DDRIOA(Dev: 17 Func: 0 Offset: 328) is used to detect whether DIMM is RDIMM/LRDIMM, not TA(Dev: 15 Func: 0). Signed-off-by: Chen Gong Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/sb_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index a21ace0..36ad17e 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -555,7 +555,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) pvt->is_close_pg = false; } - pci_read_config_dword(pvt->pci_ta, RANK_CFG_A, ®); + pci_read_config_dword(pvt->pci_ddrio, RANK_CFG_A, ®); if (IS_RDIMM_ENABLED(reg)) { /* FIXME: Can also be LRDIMM */ debugf0("Memory is registered\n"); -- cgit v1.1 From b9bc5ddb1b76d3f7ee14c533300aa95907c6969e Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Wed, 6 Jun 2012 19:49:42 -0500 Subject: mpc85xx_edac: fix error: too few arguments to function 'edac_mc_alloc' commit ca0907b "edac: Remove the legacy EDAC ABI" broke mpc85xx_edac in the following manner: mpc85xx_edac.c:983:35: error: too few arguments to function 'edac_mc_alloc' this patch puts back the missing 'layers' argument. [mchehab@redhat.com: As Ben sent a similar fix, I added his SOB on this patch] Signed-off-by: Kim Phillips Signed-off-by: Ben Collins Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/mpc85xx_edac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 4c40235..0e37462 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -980,7 +980,8 @@ static int __devinit mpc85xx_mc_err_probe(struct platform_device *op) layers[1].type = EDAC_MC_LAYER_CHANNEL; layers[1].size = 1; layers[1].is_virt_csrow = false; - mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), sizeof(*pdata)); + mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers, + sizeof(*pdata)); if (!mci) { devres_release_group(&op->dev, mpc85xx_mc_err_probe); return -ENOMEM; -- cgit v1.1 From afb6a6a01b51b6712485ea045e2b882061d250d9 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Thu, 24 May 2012 11:44:22 -0500 Subject: staging: omapdrm: fix crash when freeing bad fb During unload, don't cleanup the framebuffer if it is not valid. Signed-off-by: Andy Gross Reviewed-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_fbdev.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/staging/omapdrm/omap_fbdev.c index 11acd4c..8c6ed3b 100644 --- a/drivers/staging/omapdrm/omap_fbdev.c +++ b/drivers/staging/omapdrm/omap_fbdev.c @@ -208,7 +208,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, */ ret = omap_gem_get_paddr(fbdev->bo, &paddr, true); if (ret) { - dev_err(dev->dev, "could not map (paddr)!\n"); + dev_err(dev->dev, + "could not map (paddr)! Skipping framebuffer alloc\n"); ret = -ENOMEM; goto fail; } @@ -388,8 +389,11 @@ void omap_fbdev_free(struct drm_device *dev) fbi = helper->fbdev; - unregister_framebuffer(fbi); - framebuffer_release(fbi); + /* only cleanup framebuffer if it is present */ + if (fbi) { + unregister_framebuffer(fbi); + framebuffer_release(fbi); + } drm_fb_helper_fini(helper); -- cgit v1.1 From 8447c4d15e357a458c9051ddc84aa6c8b9c27000 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Wed, 6 Jun 2012 13:11:05 -0400 Subject: edac: Do alignment logic properly in edac_align_ptr() The logic was checking the sizeof the structure being allocated to determine whether an alignment fixup was required. This isn't right; what we actually care about is the alignment of the actual pointer that's about to be returned. This became an issue recently because struct edac_mc_layer has a size that is not zero modulo eight, so we were taking the correctly-aligned pointer and forcing it to be misaligned. On Tile this caused an alignment exception. Signed-off-by: Chris Metcalf Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/edac_mc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 10f3750..de5ba86e 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -164,7 +164,7 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems) else return (char *)ptr; - r = size % align; + r = (unsigned long)p % align; if (r == 0) return (char *)ptr; -- cgit v1.1 From 6ab6827ee99937834cc268298ee4eab1a651569e Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Fri, 8 Jun 2012 21:25:25 +0530 Subject: RDMA/ocrdma: Fixed GID table for vlan and events 1. Fix reporting GID table addition events. 2. Enable vlan based GID entries only when VLAN is enabled at compile time (test CONFIG_VLAN_8021Q / CONFIG_VLAN_8021Q_MODULE). Signed-off-by: Parav Pandit Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma_main.c | 63 ++++++++++++++++-------------- 1 file changed, 34 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 04fef3d..b050e62 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c @@ -97,13 +97,11 @@ static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr, sgid->raw[15] = mac_addr[5]; } -static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, +static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, bool is_vlan, u16 vlan_id) { int i; - bool found = false; union ib_gid new_sgid; - int free_idx = OCRDMA_MAX_SGID; unsigned long flags; memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); @@ -115,23 +113,19 @@ static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, sizeof(union ib_gid))) { /* found free entry */ - if (!found) { - free_idx = i; - found = true; - break; - } + memcpy(&dev->sgid_tbl[i], &new_sgid, + sizeof(union ib_gid)); + spin_unlock_irqrestore(&dev->sgid_lock, flags); + return true; } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, sizeof(union ib_gid))) { /* entry already present, no addition is required. */ spin_unlock_irqrestore(&dev->sgid_lock, flags); - return; + return false; } } - /* if entry doesn't exist and if table has some space, add entry */ - if (found) - memcpy(&dev->sgid_tbl[free_idx], &new_sgid, - sizeof(union ib_gid)); spin_unlock_irqrestore(&dev->sgid_lock, flags); + return false; } static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, @@ -167,7 +161,8 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) ocrdma_get_guid(dev, &sgid->raw[8]); } -static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) { struct net_device *netdev, *tmp; u16 vlan_id; @@ -175,8 +170,6 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) netdev = dev->nic_info.netdev; - ocrdma_add_default_sgid(dev); - rcu_read_lock(); for_each_netdev_rcu(&init_net, tmp) { if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { @@ -194,10 +187,23 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) } } rcu_read_unlock(); +} +#else +static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) +{ + +} +#endif /* VLAN */ + +static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) +{ + ocrdma_add_default_sgid(dev); + ocrdma_add_vlan_sgids(dev); return 0; } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \ +defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) static int ocrdma_inet6addr_event(struct notifier_block *notifier, unsigned long event, void *ptr) @@ -208,6 +214,7 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, struct ib_event gid_event; struct ocrdma_dev *dev; bool found = false; + bool updated = false; bool is_vlan = false; u16 vid = 0; @@ -233,23 +240,21 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, mutex_lock(&dev->dev_lock); switch (event) { case NETDEV_UP: - ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); + updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); break; case NETDEV_DOWN: - found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); - if (found) { - /* found the matching entry, notify - * the consumers about it - */ - gid_event.device = &dev->ibdev; - gid_event.element.port_num = 1; - gid_event.event = IB_EVENT_GID_CHANGE; - ib_dispatch_event(&gid_event); - } + updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); break; default: break; } + if (updated) { + /* GID table updated, notify the consumers about it */ + gid_event.device = &dev->ibdev; + gid_event.element.port_num = 1; + gid_event.event = IB_EVENT_GID_CHANGE; + ib_dispatch_event(&gid_event); + } mutex_unlock(&dev->dev_lock); return NOTIFY_OK; } @@ -258,7 +263,7 @@ static struct notifier_block ocrdma_inet6addr_notifier = { .notifier_call = ocrdma_inet6addr_event }; -#endif /* IPV6 */ +#endif /* IPV6 and VLAN */ static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, u8 port_num) -- cgit v1.1 From 07bb54244e466f1517357f47a498574f97c31e08 Mon Sep 17 00:00:00 2001 From: Mahesh Vardhamanaiah Date: Fri, 8 Jun 2012 21:25:52 +0530 Subject: RDMA/ocrdma: Correct reported max queue sizes Fix code to read the max wqe and max rqe values from mailbox response. Signed-off-by: Mahesh Vardhamanaiah Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma_hw.c | 15 +++++---------- drivers/infiniband/hw/ocrdma/ocrdma_sli.h | 2 +- 2 files changed, 6 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 9343a15..7507968 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c @@ -990,8 +990,6 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, struct ocrdma_dev_attr *attr, struct ocrdma_mbx_query_config *rsp) { - int max_q_mem; - attr->max_pd = (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT; @@ -1037,18 +1035,15 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, attr->max_inline_data = attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) + sizeof(struct ocrdma_sge)); - max_q_mem = OCRDMA_Q_PAGE_BASE_SIZE << (OCRDMA_MAX_Q_PAGE_SIZE_CNT - 1); - /* hw can queue one less then the configured size, - * so publish less by one to stack. - */ if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - dev->attr.max_wqe = max_q_mem / dev->attr.wqe_size; attr->ird = 1; attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE; attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES; - } else - dev->attr.max_wqe = (max_q_mem / dev->attr.wqe_size) - 1; - dev->attr.max_rqe = (max_q_mem / dev->attr.rqe_size) - 1; + } + dev->attr.max_wqe = rsp->max_wqes_rqes_per_q >> + OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET; + dev->attr.max_rqe = rsp->max_wqes_rqes_per_q & + OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK; } static int ocrdma_check_fw_config(struct ocrdma_dev *dev, diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index 7fd80cc..8411441 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h @@ -458,7 +458,7 @@ enum { OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET = 0, OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, + OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET, OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET = 16, OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK = 0xFFFF << -- cgit v1.1 From 634c5796a5c60964faf9d51892571ffe36ad24d5 Mon Sep 17 00:00:00 2001 From: Mahesh Vardhamanaiah Date: Fri, 8 Jun 2012 21:26:11 +0530 Subject: RDMA/ocrdma: Correct queue SGE calculation Fix max sge calculation for sq, rq, srq for all hardware types. Signed-off-by: Mahesh Vardhamanaiah Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma.h | 1 + drivers/infiniband/hw/ocrdma/ocrdma_hw.c | 3 +++ drivers/infiniband/hw/ocrdma/ocrdma_sli.h | 3 +++ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 6 +++--- 4 files changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h index 037f5ce..48970af 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma.h @@ -61,6 +61,7 @@ struct ocrdma_dev_attr { u32 max_inline_data; int max_send_sge; int max_recv_sge; + int max_srq_sge; int max_mr; u64 max_mr_size; u32 max_num_mr_pbl; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 7507968..71942af 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c @@ -1002,6 +1002,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, attr->max_recv_sge = (rsp->max_write_send_sge & OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; + attr->max_srq_sge = (rsp->max_srq_rqe_sge & + OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >> + OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET; attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index 8411441..c75cbdf 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h @@ -418,6 +418,9 @@ enum { OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT = 16, + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK = 0xFFFF << + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT, OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index d16d172..0e88088 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -83,8 +83,8 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) IB_DEVICE_SHUTDOWN_PORT | IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_LOCAL_DMA_LKEY; - attr->max_sge = dev->attr.max_send_sge; - attr->max_sge_rd = dev->attr.max_send_sge; + attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_srq_sge); + attr->max_sge_rd = 0; attr->max_cq = dev->attr.max_cq; attr->max_cqe = dev->attr.max_cqe; attr->max_mr = dev->attr.max_mr; @@ -97,7 +97,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp); attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp; attr->max_srq = (dev->attr.max_qp - 1); - attr->max_srq_sge = attr->max_sge; + attr->max_srq_sge = attr->max_srq_sge; attr->max_srq_wr = dev->attr.max_rqe; attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; attr->max_fast_reg_page_list_len = 0; -- cgit v1.1 From a3698a9b919d2a54e3348be48ab65d102b2f105d Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Mon, 11 Jun 2012 16:39:20 +0530 Subject: RDMA/ocrdma: Fixed RQ error CQE polling Fix RQ/SRQ error CQE polling. Return error CQE to consumer for error case which was not returned previously. Signed-off-by: Parav Pandit Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index 0e88088..d55d459 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -2301,8 +2301,10 @@ static bool ocrdma_poll_err_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe, *stop = true; expand = false; } - } else + } else { + *polled = true; expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status); + } return expand; } -- cgit v1.1 From d9762df4a9d0e412b6676a96135323d6924406b8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Jun 2012 02:17:16 -0300 Subject: [media] Fix vivi regression This patch fixes a regression introduced by commit 5126f2590bee412e3053de851cb07f531e4be36a: [media] v4l2-dev: add flag to have the core lock all file operations I forgot to add the locks to the vivi read operation. Regards, Hans Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vivi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 0960d7f..08c1024 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1149,10 +1149,14 @@ static ssize_t vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { struct vivi_dev *dev = video_drvdata(file); + int err; dprintk(dev, 1, "read called\n"); - return vb2_read(&dev->vb_vidq, data, count, ppos, + mutex_lock(&dev->mutex); + err = vb2_read(&dev->vb_vidq, data, count, ppos, file->f_flags & O_NONBLOCK); + mutex_unlock(&dev->mutex); + return err; } static unsigned int -- cgit v1.1 From 2031b4c2b4904f7448ab9e4bc6b9bf16e32709f5 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 6 Jun 2012 10:33:10 +0530 Subject: ath9k: Fix a WARNING on suspend/resume with IBSS this patch is dependent on the patch "cfg80211: fix interface combinations" In ath9k currently we have ADHOC interface as a single incompatible interface. when drv_add_interface is called during resume we got to consider number of vifs already present in addition to checking the drivers 'opmode' information about ADHOC. we incorrectly assume an ADHOC interface is already present. Then we may miss some driver specific data for the ADHOC interface after resume. The above mentioned checks can be removed from the driver, as the patch 'cfg80211: fix interface combinations' ensures that if an interface type is not advertised by the driver in any of the interface combinations(via ieee80211_iface_combination) then it shall be treated as a single incompatible interface. Fixes the following warning on suspend/resume with ibss interface. ath: phy0: Cannot create ADHOC interface when other interfaces already exist. WARNING: at net/mac80211/driver-ops.h:12 ieee80211_reconfig+0x1882/0x1ca0 [mac80211]() Hardware name: 2842RK1 wlan2: Failed check-sdata-in-driver check, flags: 0x0 Call Trace: [] warn_slowpath_common+0x72/0xa0 [] ? ieee80211_reconfig+0x1882/0x1ca0 [mac80211] [] ? ieee80211_reconfig+0x1882/0x1ca0 [mac80211] [] warn_slowpath_fmt+0x33/0x40 [] ieee80211_reconfig+0x1882/0x1ca0 [mac80211] [] ? mutex_lock_nested+0x23a/0x2f0 [] ieee80211_resume+0x27/0x70 [mac80211] [] wiphy_resume+0x8f/0xa0 [cfg80211] Cc: stable@vger.kernel.org Cc: Rajkumar Manoharan Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4de4473..08506f1 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1443,15 +1443,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, } } - if ((ah->opmode == NL80211_IFTYPE_ADHOC) || - ((vif->type == NL80211_IFTYPE_ADHOC) && - sc->nvifs > 0)) { - ath_err(common, "Cannot create ADHOC interface when other" - " interfaces already exist.\n"); - ret = -EINVAL; - goto out; - } - ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); sc->nvifs++; -- cgit v1.1 From a23415fd7ed4bfa8e203ecf141d43da7180193af Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 6 Jun 2012 10:33:42 +0530 Subject: ath9k: remove incompatible IBSS interface check in change_iface 'cfg80211: fix interface combinations' ensures that if an interface type is not advertised by the driver in any of the interface combinations (via ieee80211_iface_combination) then it shall be treated as a single incompatible interface. if there are more than one interfaces present and changing them to incompatible interface type is not possible. These checks will be properly handled by cfg80211_change_iface -> cfg80211_can_change_interface. this patch is dependent on 'cfg80211: fix interface combinations' Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 08506f1..ac41f1e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1467,15 +1467,6 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); - /* See if new interface type is valid. */ - if ((new_type == NL80211_IFTYPE_ADHOC) && - (sc->nvifs > 1)) { - ath_err(common, "When using ADHOC, it must be the only" - " interface.\n"); - ret = -EINVAL; - goto out; - } - if (ath9k_uses_beacons(new_type) && !ath9k_uses_beacons(vif->type)) { if (sc->nbcnvifs >= ATH_BCBUF) { -- cgit v1.1 From b0fd49b7d7599dc87402df13ab6e571e2222601f Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 9 Jun 2012 18:45:20 +0300 Subject: rndis_wlan: fix matching bssid check in rndis_check_bssid_list() rndis_check_bssid_list() originally tried to check if bssid->mac and match_bssid are equal using compare_ether_addr() when it should use !compare_ether_addr(). This check was added by commit b5257c952dda24df7078c74b7b811b44c6e49206 as part of workaround for hardware issue. Commit 2e42e4747ea72943c21551d8a206b51a9893b1e0 that replaced compare_ether_addr with ether_addr_equal relieved that this compare to be inverse of what it should be. Compare was added as response to hardware bug, where bssid-list does not contain BSSID and other information of currently connected AP (spec insists that device must provide this information in the list when connected). Lack bssid-data on current connection then causes WARN_ON somewhere in cfg80211. Workaround was to check if bssid-list returns current bssid and if it does not, manually construct bssid information in other ways. And this workaround worked, with inverse check. Which must mean that when hardware is experiencing the problem, it's actually returning empty bssid-list and this check didn't make any difference for workaround. However inverse check causes workaround be activated when bssid-list returns only entry, currently connected BSSID. That does not cause problems in itself, just slightly more inaccurate information in scan-list. Cc: Joe Perches Cc: David S. Miller Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 2e9e6af..dfcd02a 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2110,7 +2110,7 @@ resize_buf: while (check_bssid_list_item(bssid, bssid_len, buf, len)) { if (rndis_bss_info_update(usbdev, bssid) && match_bssid && matched) { - if (!ether_addr_equal(bssid->mac, match_bssid)) + if (ether_addr_equal(bssid->mac, match_bssid)) *matched = true; } -- cgit v1.1 From 0b5dabedcc9498013d7de2998f0828340657c8a3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 Jun 2012 12:32:07 -0300 Subject: [media] Fix query/enum_dv_timings regression Now query/enum_dv_timings finally work again. The timings API patches and the core ioctl changes clearly sailed right past each other without realizing that both needed to adapt to the other. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 5ccbd46..1500208 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -679,6 +679,8 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset); SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings); SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); + SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings); + SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings); /* yes, really vidioc_subscribe_event */ SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event); SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event); -- cgit v1.1 From bffaecc75cc6cbbf1e46571256d7b137df61bff6 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 21 May 2012 12:28:14 -0300 Subject: [media] lg2160: fix off-by-one error in lg216x_write_regs Fix an off-by-one error in lg216x_write_regs, causing the last element of the lg216x init block to be ignored. Spotted by Dan Carpenter. Reported-by: Dan Carpenter Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lg2160.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/lg2160.c b/drivers/media/dvb/frontends/lg2160.c index a3ab1a5..cc11260 100644 --- a/drivers/media/dvb/frontends/lg2160.c +++ b/drivers/media/dvb/frontends/lg2160.c @@ -126,7 +126,7 @@ static int lg216x_write_regs(struct lg216x_state *state, lg_reg("writing %d registers...\n", len); - for (i = 0; i < len - 1; i++) { + for (i = 0; i < len; i++) { ret = lg216x_write_reg(state, regs[i].reg, regs[i].val); if (lg_fail(ret)) return ret; -- cgit v1.1 From 110301833d6f6c74e4da3a31fc3d327eb3436812 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 15 May 2012 05:12:44 -0300 Subject: [media] radio/si470x: Add support for the Axentia ALERT FM USB Receiver Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 3 +++ drivers/media/radio/si470x/radio-si470x-usb.c | 2 ++ 3 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 4da66b4..20fecb8 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1800,6 +1800,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, + { HID_USB_DEVICE(USB_VENDOR_ID_AXENTIA, USB_DEVICE_ID_AXENTIA_FM_RADIO) }, { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e39aecb..70298d1 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -157,6 +157,9 @@ #define USB_VENDOR_ID_AVERMEDIA 0x07ca #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 +#define USB_VENDOR_ID_AXENTIA 0x12cf +#define USB_DEVICE_ID_AXENTIA_FM_RADIO 0x7111 + #define USB_VENDOR_ID_BELKIN 0x050d #define USB_DEVICE_ID_FLIP_KVM 0x3201 diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index e9f6387..f412f7a 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -51,6 +51,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */ { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) }, + /* Axentia ALERT FM USB Receiver */ + { USB_DEVICE_AND_INTERFACE_INFO(0x12cf, 0x7111, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } }; -- cgit v1.1 From 5daf53a6eb5c54c618c9def388d81c2769fd11a0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 19 May 2012 07:57:03 -0300 Subject: [media] snd_tea575x: Make the module using snd_tea575x the fops owner Before this patch the owner field of the /dev/radio# device fops was set to the snd-tea575x-tuner module itself. Meaning that the module which was using it could be rmmod-ed while the device is open, and then BAD things happen. I know, as I found out the hard way :) Note that there is no need to also somehow increase the refcount of the snd-tea575x-tuner module itself, since any drivers using it will have symbolic references to it. Signed-off-by: Hans de Goede CC: Ondrej Zary Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-maxiradio.c | 2 +- drivers/media/radio/radio-sf16fmr2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 740a3d5..b415211 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -157,7 +157,7 @@ static int __devinit maxiradio_probe(struct pci_dev *pdev, const struct pci_devi goto err_out_free_region; dev->io = pci_resource_start(pdev, 0); - if (snd_tea575x_init(&dev->tea)) { + if (snd_tea575x_init(&dev->tea, THIS_MODULE)) { printk(KERN_ERR "radio-maxiradio: Unable to detect TEA575x tuner\n"); goto err_out_free_region; } diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 52b8011..4efcbec 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -238,7 +238,7 @@ static int __devinit fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io) snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "%s:%s", fmr2->is_fmd2 ? "PnP" : "ISA", dev_name(pdev)); - if (snd_tea575x_init(&fmr2->tea)) { + if (snd_tea575x_init(&fmr2->tea, THIS_MODULE)) { printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n"); release_region(fmr2->io, 2); return -ENODEV; -- cgit v1.1 From 5c164646e25a5a073875c6ca346efa0d5afb6934 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 20 May 2012 08:11:04 -0300 Subject: [media] bttv: Use btv->has_radio rather then the card info when registering the tuner bttv_init_card2() sets btv->has_audio to a *default* value from the tvcards array and then may update it by reading a card specific eeprom or gpio detection. After bttv_init_card2(), bttv_init_tuner() gets called, and it should clearly use the updated, dynamic has_radio value from btv->has_radio, rather then the const value in the tvcards array. This fixes the radio not working on my Hauppauge WinTV. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-cards.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index ff2933a..1c030fe 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -3649,7 +3649,7 @@ void __devinit bttv_init_tuner(struct bttv *btv) struct tuner_setup tun_setup; /* Load tuner module before issuing tuner config call! */ - if (bttv_tvcards[btv->c.type].has_radio) + if (btv->has_radio) v4l2_i2c_new_subdev(&btv->c.v4l2_dev, &btv->c.i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); @@ -3664,7 +3664,7 @@ void __devinit bttv_init_tuner(struct bttv *btv) tun_setup.type = btv->tuner_type; tun_setup.addr = addr; - if (bttv_tvcards[btv->c.type].has_radio) + if (btv->has_radio) tun_setup.mode_mask |= T_RADIO; bttv_call_all(btv, tuner, s_type_addr, &tun_setup); -- cgit v1.1 From 792a21b0def241e73345e366a456ae7e516ba2f5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 20 May 2012 12:05:30 -0300 Subject: [media] bttv: Remove unused needs_tvaudio card variable Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-cards.c | 76 ---------------------------------- drivers/media/video/bt8xx/bttv.h | 1 - 2 files changed, 77 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 1c030fe..959d4e1 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -371,7 +371,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -384,7 +383,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -398,7 +396,6 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -414,7 +411,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -427,7 +423,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0, 1, 0, 1 }, .gpiomute = 3, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -440,7 +435,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x0f, .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, /* 0x04 for some cards ?? */ - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= avermedia_tvphone_audio, @@ -454,7 +448,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, - .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -469,7 +462,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0xc00, 0x800, 0x400 }, .gpiomute = 0xc00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -482,7 +474,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 2, 3 }, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -496,7 +487,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -510,7 +500,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -524,7 +513,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 14, 11, 7 }, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -536,7 +524,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 14, 11, 7 }, - .needs_tvaudio = 1, .msp34xx_alt = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -553,7 +540,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */ .gpiomute = 4, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -567,7 +553,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 1, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -583,7 +568,6 @@ struct tvcard bttv_tvcards[] = { /* 2003-10-20 by "Anton A. Arapov" */ .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -597,7 +581,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1, 0), .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, .gpiomute = 0xcfa007, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .volume_gpio = winview_volume, @@ -611,7 +594,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 0, 0, 0 }, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -660,7 +642,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 0x800, 0x400 }, .gpiomute = 0xc00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -691,7 +672,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = {0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0xc00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -706,7 +686,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, @@ -720,7 +699,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -748,7 +726,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 }, .gpiomute = 0x40000, - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, @@ -793,7 +770,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, - .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .muxsel_hook = PXC200_muxsel, @@ -834,7 +810,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -847,7 +822,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x500, 0, 0x300, 0x900 }, .gpiomute = 0x900, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -874,7 +848,6 @@ struct tvcard bttv_tvcards[] = { Note: There exists another variant "Winfast 2000" with tv stereo !? Note: eeprom only contains FF and pci subsystem id 107d:6606 */ - .needs_tvaudio = 0, .pll = PLL_28, .has_radio = 1, .tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */ @@ -934,7 +907,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0x551400, 0x551200, 0, 0 }, .gpiomute = 0x551c00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -949,7 +921,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0xd0001, 0, 0 }, .gpiomute = 1, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -966,7 +937,6 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -980,7 +950,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 4, 11, 7 }, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -995,7 +964,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0, 0}, - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1066,7 +1034,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_35, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1084,7 +1051,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = {2,0,0,0 }, .gpiomute = 1, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1163,7 +1129,6 @@ struct tvcard bttv_tvcards[] = { MUX2 (mask 0x30000): 0,2,3= from MSP34xx 1= FM stereo Radio from Tuner */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1179,7 +1144,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0x10, 8 }, .gpiomute = 4, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1218,7 +1182,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -1250,7 +1213,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(3, 1), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_35, .tuner_type = TUNER_ABSENT, @@ -1266,7 +1228,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0x800, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4036FY5_NTSC, .tuner_addr = ADDR_UNSET, @@ -1312,7 +1273,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2), .gpiomux = { }, .no_msp34xx = 1, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1329,7 +1289,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 1, 0, 4, 4 }, .gpiomute = 9, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1379,7 +1338,6 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0x1800, .audio_mode_gpio= fv2000s_audio, .no_msp34xx = 1, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1393,7 +1351,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x500, 0x500, 0x300, 0x900 }, .gpiomute = 0x900, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1477,7 +1434,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */ .gpiomute = 13, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_LG_PAL_I_FM, .tuner_addr = ADDR_UNSET, @@ -1514,7 +1470,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x01, 0x00, 0x03, 0x03 }, .gpiomute = 0x09, - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1540,7 +1495,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -1567,7 +1521,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 4, - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1597,7 +1550,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -1619,7 +1571,6 @@ struct tvcard bttv_tvcards[] = { * btwincap uses 0x80000/0x80003 */ .gpiomute = 4, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1655,7 +1606,6 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .muxsel = MUXSEL(2, 0, 1, 1), - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1875,7 +1825,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3}, .gpiomute = 4, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1902,7 +1851,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -1920,7 +1868,6 @@ struct tvcard bttv_tvcards[] = { /* Tuner, Radio, external, internal, off, on */ .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 }, .gpiomute = 0x0f, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, @@ -1936,7 +1883,6 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 1), - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -2034,7 +1980,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -2049,7 +1994,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2062,7 +2006,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2079,7 +2022,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0), .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2094,7 +2036,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1), .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2118,7 +2059,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .svhs = NO_SVHS, /* card has no svhs */ - .needs_tvaudio = 0, .no_msp34xx = 1, .no_tda7432 = 1, .gpiomask = 0x00, @@ -2168,7 +2108,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 1, 1 }, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_35, @@ -2210,7 +2149,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .no_msp34xx = 1, .no_tda7432 = 1, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -2222,7 +2160,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .svhs = 2, - .needs_tvaudio = 0, .gpiomask = 0x68, .muxsel = MUXSEL(2, 3, 1), .gpiomux = { 0x68, 0x68, 0x61, 0x61 }, @@ -2241,7 +2178,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2265,7 +2201,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .pll = PLL_28, - .needs_tvaudio = 0, .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2358,7 +2293,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2405,7 +2339,6 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .gpiomask = 0x008007, .gpiomux = { 0, 0x000001,0,0 }, - .needs_tvaudio = 1, .has_radio = 1, }, [BTTV_BOARD_TIBET_CS16] = { @@ -2518,7 +2451,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, .tuner_addr = 0xc1 >>1, @@ -2534,7 +2466,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TENA_9533_DI, .tuner_addr = ADDR_UNSET, @@ -2615,7 +2546,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 1, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, @@ -2714,7 +2644,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -2746,7 +2675,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */ .gpiomute = 3, /* CONTVFMi */ - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */ .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -2785,7 +2713,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(0, 2, 3, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2799,7 +2726,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2813,7 +2739,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(3, 2, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2877,7 +2802,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index c517161..acfe2f3 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h @@ -236,7 +236,6 @@ struct tvcard { /* i2c audio flags */ unsigned int no_msp34xx:1; unsigned int no_tda7432:1; - unsigned int needs_tvaudio:1; unsigned int msp34xx_alt:1; /* Note: currently no card definition needs to mark the presence of a RDS saa6588 chip. If this is ever needed, then add a new -- cgit v1.1 From 7025e521b1b068af8a47a7625335a605bbd4d7ea Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 21 May 2012 07:46:22 -0300 Subject: [media] bttv: The Hauppauge 61334 needs the msp3410 to do radio demodulation The (radio) audio out from the tuner (which can also demod FM radio) does not seem to be hooked up to the msp3410 on this board in any way, so the only way to get sound from the radio part is to make the msp3410 do the FM radio demod. The msp3410 can handle this fine, but it is a bit weird compared to how it is handled on other boards. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-cards.c | 4 ++++ drivers/media/video/bt8xx/bttv-driver.c | 5 +++++ drivers/media/video/bt8xx/bttvp.h | 1 + 3 files changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 959d4e1..856ab96 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -3648,6 +3648,10 @@ static void __devinit hauppauge_eeprom(struct bttv *btv) bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name); btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB; } + + /* The 61334 needs the msp3410 to do the radio demod to get sound */ + if (tv.model == 61334) + btv->radio_uses_msp_demodulator = 1; } static int terratec_active_radio_upgrade(struct bttv *btv) diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a9cfb0f..ff7a589 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -1218,6 +1218,11 @@ audio_mux(struct bttv *btv, int input, int mute) For now this is sufficient. */ switch (input) { case TVAUDIO_INPUT_RADIO: + /* Some boards need the msp do to the radio demod */ + if (btv->radio_uses_msp_demodulator) { + in = MSP_INPUT_DEFAULT; + break; + } in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index db943a8d..70fd4f23 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h @@ -440,6 +440,7 @@ struct bttv { /* radio data/state */ int has_radio; int radio_user; + int radio_uses_msp_demodulator; /* miro/pinnacle + Aimslab VHX philips matchbox (tea5757 radio tuner) support */ -- cgit v1.1 From b6fc2eb965726bf31bbbca6e7a833f98c03a6ce2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 14 May 2012 14:51:22 -0300 Subject: [media] gspca_pac7311: Correct number of controls This avoids the need for a re-alloc during init. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac7311.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 2cb7d95..115da16 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -418,7 +418,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); + v4l2_ctrl_handler_init(hdl, 5); sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_CONTRAST, 0, 15, 1, 7); -- cgit v1.1 From bc378feeda46633cfa92dac7a7ef5df66047b0ef Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 14 May 2012 14:55:15 -0300 Subject: [media] gscpa_sn9c20x: Move clustering of controls to after error checking Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sn9c20x.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index ad09820..6c31e46 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -1761,7 +1761,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_SATURATION, 0, 255, 1, 127); sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_HUE, -180, 180, 1, 0); - v4l2_ctrl_cluster(4, &sd->brightness); sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAMMA, 0, 255, 1, 0x10); @@ -1770,7 +1769,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28); sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28); - v4l2_ctrl_cluster(2, &sd->blue); if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 && @@ -1779,7 +1777,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_HFLIP, 0, 1, 1, 0); sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); - v4l2_ctrl_cluster(2, &sd->hflip); } if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB && @@ -1794,6 +1791,20 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_GAIN, 0, 28, 1, 0); sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + } + + sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } + + v4l2_ctrl_cluster(4, &sd->brightness); + v4l2_ctrl_cluster(2, &sd->blue); + if (sd->hflip) + v4l2_ctrl_cluster(2, &sd->hflip); + if (sd->autogain) { if (sd->sensor == SENSOR_SOI968) /* this sensor doesn't have the exposure control and autogain is clustered with gain instead. This works @@ -1803,13 +1814,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) /* Otherwise autogain is clustered with exposure. */ v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); } - - sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } return 0; } -- cgit v1.1 From cf3c1c319500e879daa1487f41bb094bd377566f Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 16 May 2012 18:42:45 -0300 Subject: [media] gspca_ov534: make AGC and AWB controls independent Even if the best results are indeed achieved with both AGC and AWB enabled, the webcam is capable of setting these independently, and the user can see the difference of any of the 4 combinations of these two boolean controls. Removing the dependency from one another simplifies the code and gives more control to the user. Signed-off-by: Antonio Ospite Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index b5acb1e..c16bd1b 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -96,7 +96,7 @@ static void setbrightness(struct gspca_dev *gspca_dev); static void setcontrast(struct gspca_dev *gspca_dev); static void setgain(struct gspca_dev *gspca_dev); static void setexposure(struct gspca_dev *gspca_dev); -static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val); +static void setagc(struct gspca_dev *gspca_dev); static void setawb(struct gspca_dev *gspca_dev); static void setaec(struct gspca_dev *gspca_dev); static void setsharpness(struct gspca_dev *gspca_dev); @@ -189,7 +189,7 @@ static const struct ctrl sd_ctrls[] = { .step = 1, .default_value = 1, }, - .set = sd_setagc + .set_control = setagc }, [AWB] = { { @@ -1242,10 +1242,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->ctrls = sd->ctrls; - /* the auto white balance control works only when auto gain is set */ - if (sd_ctrls[AGC].qctrl.default_value == 0) - gspca_dev->ctrl_inac |= (1 << AWB); - cam->cam_mode = ov772x_mode; cam->nmodes = ARRAY_SIZE(ov772x_mode); @@ -1486,29 +1482,6 @@ scan_next: } while (remaining_len > 0); } -static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->ctrls[AGC].val = val; - - /* the auto white balance control works only - * when auto gain is set */ - if (val) { - gspca_dev->ctrl_inac &= ~(1 << AWB); - } else { - gspca_dev->ctrl_inac |= (1 << AWB); - if (sd->ctrls[AWB].val) { - sd->ctrls[AWB].val = 0; - if (gspca_dev->streaming) - setawb(gspca_dev); - } - } - if (gspca_dev->streaming) - setagc(gspca_dev); - return gspca_dev->usb_err; -} - static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { -- cgit v1.1 From af05ef01e9cde84620c6855a8d8ab9c8a1db9009 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 22 May 2012 11:24:05 -0300 Subject: [media] gspca-core: Fix buffers staying in queued state after a stream_off This fixes a regression introduced by commit f7059ea and should be backported to all supported stable kernels which have this commit. Signed-off-by: Hans de Goede Tested-by: Antonio Ospite CC: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 137166d..31721ea 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1653,7 +1653,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type buf_type) { struct gspca_dev *gspca_dev = video_drvdata(file); - int ret; + int i, ret; if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1678,6 +1678,8 @@ static int vidioc_streamoff(struct file *file, void *priv, wake_up_interruptible(&gspca_dev->wq); /* empty the transfer queues */ + for (i = 0; i < gspca_dev->nframes; i++) + gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS; atomic_set(&gspca_dev->fr_q, 0); atomic_set(&gspca_dev->fr_i, 0); gspca_dev->fr_o = 0; -- cgit v1.1 From f19ed98111d508bafc1aa31478f2c612cbdc26b5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 28 May 2012 14:04:07 -0300 Subject: [media] gspca - ov534/ov534_9: Fix sccd_read/write errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ov534 bridge is too slow to handle the sensor accesses requested by fast hosts giving 'sccb_reg_write failed'. A small delay fixes the problem. Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 1 + drivers/media/video/gspca/ov534_9.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index c16bd1b..80c81dd 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -851,6 +851,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) int i; for (i = 0; i < 5; i++) { + msleep(10); data = ov534_reg_read(gspca_dev, OV534_REG_STATUS); switch (data) { diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c index e6601b8..0120f94 100644 --- a/drivers/media/video/gspca/ov534_9.c +++ b/drivers/media/video/gspca/ov534_9.c @@ -1008,6 +1008,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) int i; for (i = 0; i < 5; i++) { + msleep(10); data = reg_r(gspca_dev, OV534_REG_STATUS); switch (data) { -- cgit v1.1 From f9798ef6342e6dad3fc3d7aa2ce2147469acf507 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 28 May 2012 14:05:25 -0300 Subject: [media] gspca - sonixj: Fix bad values of webcam 0458:7025 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The webcam 0458:7025 (Eye911Q) has: - an inverted power pin, - a sensor mi0360b which cannot be probed. Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 4d1696d..f38faa9 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -3120,7 +3120,7 @@ static const struct sd_desc sd_desc = { | (SENSOR_ ## sensor << 8) \ | (flags) static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)}, + {USB_DEVICE(0x0458, 0x7025), BSF(SN9C120, MI0360B, F_PDN_INV)}, {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)}, {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)}, -- cgit v1.1 From 5cd0b50fddb6649bfd73648912464e1cc90bd0c1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 23 May 2012 02:41:39 -0300 Subject: [media] saa7146_fops: remove unused variable Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_fops.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 7d42c11..0cdbd74 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -198,7 +198,6 @@ static int fops_open(struct file *file) struct saa7146_dev *dev = video_drvdata(file); struct saa7146_fh *fh = NULL; int result = 0; - enum v4l2_buf_type type; DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); @@ -207,10 +206,6 @@ static int fops_open(struct file *file) DEB_D("using: %p\n", dev); - type = vdev->vfl_type == VFL_TYPE_GRABBER - ? V4L2_BUF_TYPE_VIDEO_CAPTURE - : V4L2_BUF_TYPE_VBI_CAPTURE; - /* check if an extension is registered */ if( NULL == dev->ext ) { DEB_S("no extension registered for this device\n"); -- cgit v1.1 From 91e0cd499fe8482d5104c1f8f49b478f76617b40 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 23 May 2012 02:48:37 -0300 Subject: [media] cx24110: fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v4l-dvb-git/drivers/media/dvb/frontends/cx24110.c: In function ‘cx24110_read_ucblocks’: v4l-dvb-git/drivers/media/dvb/frontends/cx24110.c:520:40: warning: value computed is not used [-Wunused-value] Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/cx24110.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 98ecaf0..3180f5b 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c @@ -516,9 +516,9 @@ static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) if(cx24110_readreg(state,0x10)&0x40) { /* the RS error counter has finished one counting window */ cx24110_writereg(state,0x10,0x60); /* select the byer reg */ - cx24110_readreg(state, 0x12) | + (void)(cx24110_readreg(state, 0x12) | (cx24110_readreg(state, 0x13) << 8) | - (cx24110_readreg(state, 0x14) << 16); + (cx24110_readreg(state, 0x14) << 16)); cx24110_writereg(state,0x10,0x70); /* select the bler reg */ state->lastbler=cx24110_readreg(state,0x12)| (cx24110_readreg(state,0x13)<<8)| -- cgit v1.1 From f9ac50c244f9030b300d6f390e838239612d7efa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 23 May 2012 06:32:52 -0300 Subject: [media] vino: fix compiler warnings v4l-dvb-git/drivers/media/video/vino.c: In function 'vino_acquire_input': v4l-dvb-git/drivers/media/video/vino.c:2602:18: warning: 'data_norm' may be used uninitialized in this function [-Wuninitialized] v4l-dvb-git/drivers/media/video/vino.c: In function 'vino_set_input': v4l-dvb-git/drivers/media/video/vino.c:2690:19: warning: 'data_norm' may be used uninitialized in this function [-Wuninitialized] Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vino.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 4d7391e..aae1720 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -2561,7 +2561,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) } else if (vino_drvdata->decoder && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) { int input; - int data_norm; + int data_norm = 0; v4l2_std_id norm; input = VINO_INPUT_COMPOSITE; @@ -2651,7 +2651,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) } if (vino_drvdata->decoder_owner == vcs->channel) { - int data_norm; + int data_norm = 0; v4l2_std_id norm; ret = decoder_call(video, s_routing, -- cgit v1.1 From 3e1141e2ce5667301a74ca2ef396d9bd5e995f7f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 25 May 2012 09:29:12 -0300 Subject: [media] smsusb: add autodetection support for USB ID 2040:f5a0 Signed-off-by: Michael Krufky Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 63c004a..664e460 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -544,6 +544,8 @@ static const struct usb_device_id smsusb_id_table[] __devinitconst = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0xc0a0), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0xf5a0), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { } /* Terminating entry */ }; -- cgit v1.1 From e30478598a8476d02e3b00caa89ce1a3b1dad54b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 10 Jun 2012 23:24:00 +0000 Subject: lpc_eth: add missing ndo_change_mtu() lpc_eth does a copy of transmitted skbs to DMA area, without checking skb lengths, so can trigger buffer overflows : memcpy(pldat->tx_buff_v + txidx * ENET_MAXF_SIZE, skb->data, len); One way to get bigger skbs is to allow MTU changes above the 1500 limit. Calling eth_change_mtu() in ndo_change_mtu() makes sure this cannot happen. Signed-off-by: Eric Dumazet Cc: Roland Stigge Cc: Kevin Wells Acked-by: Roland Stigge Signed-off-by: David S. Miller --- drivers/net/ethernet/nxp/lpc_eth.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 8d2666f..10febdc 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c @@ -1320,6 +1320,7 @@ static const struct net_device_ops lpc_netdev_ops = { .ndo_set_rx_mode = lpc_eth_set_multicast_list, .ndo_do_ioctl = lpc_eth_ioctl, .ndo_set_mac_address = lpc_set_mac_address, + .ndo_change_mtu = eth_change_mtu, }; static int lpc_eth_drv_probe(struct platform_device *pdev) -- cgit v1.1 From 3f16da51b0e533871d22a29682f3c3969d4f7e22 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 11 Jun 2012 07:21:36 +0000 Subject: lpc_eth: fix tx completion __lpc_handle_xmit() has two bugs : 1) It can leak skbs in case TXSTATUS_ERROR is set 2) It can wake up txqueue while no slot was freed. Signed-off-by: Eric Dumazet Reported-by: Roland Stigge Tested-by: Roland Stigge Cc: Kevin Wells Signed-off-by: David S. Miller --- drivers/net/ethernet/nxp/lpc_eth.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 10febdc..083d671 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c @@ -946,16 +946,16 @@ static void __lpc_handle_xmit(struct net_device *ndev) /* Update stats */ ndev->stats.tx_packets++; ndev->stats.tx_bytes += skb->len; - - /* Free buffer */ - dev_kfree_skb_irq(skb); } + dev_kfree_skb_irq(skb); txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); } - if (netif_queue_stopped(ndev)) - netif_wake_queue(ndev); + if (pldat->num_used_tx_buffs <= ENET_TX_DESC/2) { + if (netif_queue_stopped(ndev)) + netif_wake_queue(ndev); + } } static int __lpc_handle_recv(struct net_device *ndev, int budget) -- cgit v1.1 From 0c142c86991551b8b9675ab72609f7a29ee2e1e3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 May 2012 11:51:31 -0300 Subject: [media] v4l2-ioctl: set readbuffers to 2 in g_parm If g_parm is handled automatically, then set readbuffers to 2, which is the minimum number of buffers videobuf uses. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-ioctl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 91be4e8..d7fa896 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -1680,6 +1680,7 @@ static long __video_do_ioctl(struct file *file, break; ret = 0; + p->parm.capture.readbuffers = 2; if (ops->vidioc_g_std) ret = ops->vidioc_g_std(file, fh, &std); if (ret == 0) -- cgit v1.1 From a5ee6e41b2dee2aae2930278ba070ea8385db040 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 May 2012 11:58:06 -0300 Subject: [media] v4l2-dev.c: fix g_parm regression in determine_valid_ioctls() The field current_norm does not have to be set for g_parm to be a valid ioctl. Remove that check, but add a check whether this is a video node instead as g_parm only makes sense for those nodes. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 1500208..83dbb2d 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -656,7 +656,7 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); - if (ops->vidioc_g_parm || vdev->current_norm) + if (ops->vidioc_g_parm || vdev->vfl_type == VFL_TYPE_GRABBER) set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm); SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); -- cgit v1.1 From c44ff8fa026ab34d95ce0805a56ca507c313a91d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 May 2012 12:01:40 -0300 Subject: [media] tuner-core: return the frequency range of the correct tuner The frequency range of the current tuner (radio or TV) was returned instead of the frequency range of the requested tuner (which depends on the device node). This bug caused the frequency range of the radio tuner to be returned when G_TUNER was called on a video node. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tuner-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 3e050e1..1ad5ab6 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -1178,7 +1178,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; if (vt->type == t->mode && analog_ops->get_afc) vt->afc = analog_ops->get_afc(&t->fe); - if (t->mode != V4L2_TUNER_RADIO) { + if (vt->type != V4L2_TUNER_RADIO) { vt->capability |= V4L2_TUNER_CAP_NORM; vt->rangelow = tv_range[0] * 16; vt->rangehigh = tv_range[1] * 16; -- cgit v1.1 From 1c36dfc5c51b1406c2454fde922491ca6dab8513 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 May 2012 08:04:26 -0300 Subject: [media] ivtv: fix support for big-endian systems base_addr has type resource_size_t, which may be 64 bits on a 32-bit ppc. Tested on my ppc board. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.c | 18 +++++++++--------- drivers/media/video/ivtv/ivtv-driver.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 057929e..5462ce2 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -866,10 +866,10 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, pci_write_config_dword(pdev, 0x40, 0xffff); IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%lx\n", + "irq: %d, latency: %d, memory: 0x%llx\n", pdev->device, pdev->revision, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - pdev->irq, pci_latency, (unsigned long)itv->base_addr); + pdev->irq, pci_latency, (u64)itv->base_addr); return 0; } @@ -1007,7 +1007,7 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, itv->cxhdl.priv = itv; itv->cxhdl.func = ivtv_api_func; - IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); + IVTV_DEBUG_INFO("base addr: 0x%llx\n", (u64)itv->base_addr); /* PCI Device Setup */ retval = ivtv_setup_pci(itv, pdev, pci_id); @@ -1017,8 +1017,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, goto free_mem; /* map io memory */ - IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); if (!itv->enc_mem) { @@ -1034,8 +1034,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, } if (itv->has_cx23415) { - IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); if (!itv->dec_mem) { @@ -1056,8 +1056,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, } /* map registers memory */ - IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); itv->reg_mem = ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); if (!itv->reg_mem) { diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 2e22002..a7e00f8 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -622,7 +622,7 @@ struct ivtv { struct v4l2_subdev *sd_video; /* controlling video decoder subdev */ struct v4l2_subdev *sd_audio; /* controlling audio subdev */ struct v4l2_subdev *sd_muxer; /* controlling audio muxer subdev */ - u32 base_addr; /* PCI resource base address */ + resource_size_t base_addr; /* PCI resource base address */ volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */ volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */ volatile void __iomem *reg_mem; /* pointer to mapped registers */ -- cgit v1.1 From 42d0c3ad28837a4a475c18b69160053fdb562976 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 May 2012 08:07:03 -0300 Subject: [media] cx18: support big-endian systems base_addr has type resource_size_t, which may be 64 bits. Also fix a few endian issues related to mailboxes and firmware loading. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.c | 10 +++++----- drivers/media/video/cx18/cx18-driver.h | 2 +- drivers/media/video/cx18/cx18-firmware.c | 9 +++++++-- drivers/media/video/cx18/cx18-mailbox.c | 15 ++++++++++----- 4 files changed, 23 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index b55d57c..7e5ffd6 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -838,10 +838,10 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, } CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%lx\n", + "irq: %d, latency: %d, memory: 0x%llx\n", cx->pci_dev->device, cx->card_rev, pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn), - cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr); + cx->pci_dev->irq, pci_latency, (u64)cx->base_addr); return 0; } @@ -938,7 +938,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, if (retval) goto err; - CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); + CX18_DEBUG_INFO("base addr: 0x%llx\n", (u64)cx->base_addr); /* PCI Device Setup */ retval = cx18_setup_pci(cx, pci_dev, pci_id); @@ -946,8 +946,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, goto free_workqueues; /* map io memory */ - CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); + CX18_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); if (!cx->enc_mem) { diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 7a37e0e..2767c64 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -622,7 +622,7 @@ struct cx18 { unique ID. Starts at 1, so 0 can be used as uninitialized value in the stream->id. */ - u32 base_addr; + resource_size_t base_addr; u8 card_rev; void __iomem *enc_mem, *reg_mem; diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c index 1b3fb50..b85c292 100644 --- a/drivers/media/video/cx18/cx18-firmware.c +++ b/drivers/media/video/cx18/cx18-firmware.c @@ -164,8 +164,13 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32]; while (offset + sizeof(seghdr) < fw->size) { - /* TODO: byteswapping */ - memcpy(&seghdr, src + offset / 4, sizeof(seghdr)); + const u32 *shptr = src + offset / 4; + + seghdr.sync1 = le32_to_cpu(shptr[0]); + seghdr.sync2 = le32_to_cpu(shptr[1]); + seghdr.addr = le32_to_cpu(shptr[2]); + seghdr.size = le32_to_cpu(shptr[3]); + offset += sizeof(seghdr); if (seghdr.sync1 != APU_ROM_SYNC1 || seghdr.sync2 != APU_ROM_SYNC2) { diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index ed81183..eabf00c 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c @@ -434,6 +434,7 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order) { u32 handle, mdl_ack_offset, mdl_ack_count; struct cx18_mailbox *mb; + int i; mb = &order->mb; handle = mb->args[0]; @@ -447,8 +448,9 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order) return -1; } - cx18_memcpy_fromio(cx, order->mdl_ack, cx->enc_mem + mdl_ack_offset, - sizeof(struct cx18_mdl_ack) * mdl_ack_count); + for (i = 0; i < sizeof(struct cx18_mdl_ack) * mdl_ack_count; i += sizeof(u32)) + ((u32 *)order->mdl_ack)[i / sizeof(u32)] = + cx18_readl(cx, cx->enc_mem + mdl_ack_offset + i); if ((order->flags & CX18_F_EWO_MB_STALE) == 0) mb_ack_irq(cx, order); @@ -538,6 +540,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) struct cx18_mailbox *order_mb; struct cx18_in_work_order *order; int submit; + int i; switch (rpu) { case CPU: @@ -562,10 +565,12 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) order_mb = &order->mb; /* mb->cmd and mb->args[0] through mb->args[2] */ - cx18_memcpy_fromio(cx, &order_mb->cmd, &mb->cmd, 4 * sizeof(u32)); + for (i = 0; i < 4; i++) + (&order_mb->cmd)[i] = cx18_readl(cx, &mb->cmd + i); + /* mb->request and mb->ack. N.B. we want to read mb->ack last */ - cx18_memcpy_fromio(cx, &order_mb->request, &mb->request, - 2 * sizeof(u32)); + for (i = 0; i < 2; i++) + (&order_mb->request)[i] = cx18_readl(cx, &mb->request + i); if (order_mb->request == order_mb->ack) { CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our " -- cgit v1.1 From 6ba4c432dcc8686b8493de5733ce7c986364730e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 May 2012 09:28:02 -0300 Subject: [media] cx88: fix firmware load on big-endian systems Tested with a HVR-1300. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-blackbird.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index e46446a..ed7b2aa 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -471,7 +471,7 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) dprintk(1,"Loading firmware ...\n"); dataptr = (u32*)firmware->data; for (i = 0; i < (firmware->size >> 2); i++) { - value = *dataptr; + value = le32_to_cpu(*dataptr); checksum += ~value; memory_write(dev->core, i, value); dataptr++; -- cgit v1.1 From de87897af08081aecb0c0bbc5fa01a8640e2d74c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Jun 2012 01:46:50 -0300 Subject: [media] bw-qcam: driver and pixfmt documentation fixes Fix the documentation of the Y4 and Y6 formats. Fix a poll() issue, add support for enum_frmsizes, set the proper parent device and fix a few compliance issues. Tested with an actual Connectix B&W parallel port webcam, both on a little-endian and a big-endian platform. This driver has never been so good, doing 320x240 at 1 frame per second :-) I know, nobody cares, but still it is cool that linux can still support this old webcam. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bw-qcam.c | 47 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 2520219..5b75a64 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -607,8 +607,9 @@ static long qc_capture(struct qcam *q, char __user *buf, unsigned long len) } o = i * pixels_per_line + pixels_read + k; if (o < len) { + u8 ch = invert - buffer[k]; got++; - put_user((invert - buffer[k]) << shift, buf + o); + put_user(ch << shift, buf + o); } } pixels_read += bytes; @@ -648,8 +649,8 @@ static int qcam_querycap(struct file *file, void *priv, struct qcam *qcam = video_drvdata(file); strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); - strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card)); - strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); + strlcpy(vcap->card, "Connectix B&W Quickcam", sizeof(vcap->card)); + strlcpy(vcap->bus_info, qcam->pport->name, sizeof(vcap->bus_info)); vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; @@ -688,8 +689,8 @@ static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f pix->height = qcam->height / qcam->transfer_scale; pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6; pix->field = V4L2_FIELD_NONE; - pix->bytesperline = qcam->width; - pix->sizeimage = qcam->width * qcam->height; + pix->bytesperline = pix->width; + pix->sizeimage = pix->width * pix->height; /* Just a guess */ pix->colorspace = V4L2_COLORSPACE_SRGB; return 0; @@ -757,7 +758,7 @@ static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes "4-Bit Monochrome", V4L2_PIX_FMT_Y4, { 0, 0, 0, 0 } }, - { 0, 0, 0, + { 1, 0, 0, "6-Bit Monochrome", V4L2_PIX_FMT_Y6, { 0, 0, 0, 0 } }, @@ -772,6 +773,25 @@ static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes return 0; } +static int qcam_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + static const struct v4l2_frmsize_discrete sizes[] = { + { 80, 60 }, + { 160, 120 }, + { 320, 240 }, + }; + + if (fsize->index > 2) + return -EINVAL; + if (fsize->pixel_format != V4L2_PIX_FMT_Y4 && + fsize->pixel_format != V4L2_PIX_FMT_Y6) + return -EINVAL; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete = sizes[fsize->index]; + return 0; +} + static ssize_t qcam_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -795,6 +815,11 @@ static ssize_t qcam_read(struct file *file, char __user *buf, return len; } +static unsigned int qcam_poll(struct file *filp, poll_table *wait) +{ + return v4l2_ctrl_poll(filp, wait) | POLLIN | POLLRDNORM; +} + static int qcam_s_ctrl(struct v4l2_ctrl *ctrl) { struct qcam *qcam = @@ -828,7 +853,7 @@ static const struct v4l2_file_operations qcam_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, .release = v4l2_fh_release, - .poll = v4l2_ctrl_poll, + .poll = qcam_poll, .unlocked_ioctl = video_ioctl2, .read = qcam_read, }; @@ -839,6 +864,7 @@ static const struct v4l2_ioctl_ops qcam_ioctl_ops = { .vidioc_s_input = qcam_s_input, .vidioc_enum_input = qcam_enum_input, .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, + .vidioc_enum_framesizes = qcam_enum_framesizes, .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, @@ -864,9 +890,9 @@ static struct qcam *qcam_init(struct parport *port) return NULL; v4l2_dev = &qcam->v4l2_dev; - strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name)); + snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams); - if (v4l2_device_register(NULL, v4l2_dev) < 0) { + if (v4l2_device_register(port->dev, v4l2_dev) < 0) { v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); kfree(qcam); return NULL; @@ -886,7 +912,7 @@ static struct qcam *qcam_init(struct parport *port) return NULL; } qcam->pport = port; - qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, + qcam->pdev = parport_register_device(port, v4l2_dev->name, NULL, NULL, NULL, 0, NULL); if (qcam->pdev == NULL) { v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); @@ -975,6 +1001,7 @@ static int init_bwqcam(struct parport *port) return -ENODEV; } qc_calibrate(qcam); + v4l2_ctrl_handler_setup(&qcam->hdl); parport_release(qcam->pdev); -- cgit v1.1 From 883ffd6e64114495f68652721065149a2bbd9de6 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 7 Jun 2012 23:21:05 +0000 Subject: net: stmmac: Fix clock en-/disable calls clk_{un}prepare is mandatory for platforms using common clock framework. Since these drivers are used by SPEAr platform, which supports common clock framework, add clk_{un}prepare() support for them. Otherwise the clocks are not correctly en-/disabled and ethernet support doesn't work. Signed-off-by: Stefan Roese Cc: Viresh Kumar Cc: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 94b21b4..dc20c56 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -109,7 +109,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, static inline int stmmac_clk_enable(struct stmmac_priv *priv) { if (!IS_ERR(priv->stmmac_clk)) - return clk_enable(priv->stmmac_clk); + return clk_prepare_enable(priv->stmmac_clk); return 0; } @@ -119,7 +119,7 @@ static inline void stmmac_clk_disable(struct stmmac_priv *priv) if (IS_ERR(priv->stmmac_clk)) return; - clk_disable(priv->stmmac_clk); + clk_disable_unprepare(priv->stmmac_clk); } static inline int stmmac_clk_get(struct stmmac_priv *priv) { -- cgit v1.1 From 78b10615ad295393a7d66ea57218171c0a07c059 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 11 Jun 2012 16:35:50 -0700 Subject: staging/comedi: fix build for USB not enabled Calls to optional subsystems cannot be made indiscriminately. Enclose all of the usb helper functions inside #if IS_ENABLED(CONFIG_USB) to fix these build errors. (The pci helper functions are OK since there are stubs in linux/pci.h for the called functions when PCI is not enabled. Possibly the same could be done for the called USB functions.) ERROR: "usb_deregister" [drivers/staging/comedi/comedi.ko] undefined! ERROR: "usb_register_driver" [drivers/staging/comedi/comedi.ko] undefined! Signed-off-by: Randy Dunlap Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 1c3d638..aeac1ca 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -981,6 +982,8 @@ void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, } EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); +#if IS_ENABLED(CONFIG_USB) + static int comedi_old_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { @@ -1043,3 +1046,5 @@ void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); + +#endif -- cgit v1.1 From b7abee6ef888117f92db370620ebf116a38e3f4d Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 7 Jun 2012 12:56:54 +0000 Subject: tg3: Apply short DMA frag workaround to 5906 5906 devices also need the short DMA fragment workaround. This patch makes the necessary change. Signed-off-by: Matt Carlson Tested-by: Christian Kujau Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index edeeb51..e47ff8b 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -14275,7 +14275,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } } - if (tg3_flag(tp, 5755_PLUS)) + if (tg3_flag(tp, 5755_PLUS) || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tg3_flag_set(tp, SHORT_DMA_BUG); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) -- cgit v1.1 From e3d62d7e8e05a6a4b08f4672385ae58fc0f132c4 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Thu, 7 Jun 2012 10:45:02 +0000 Subject: tilegx network driver: initial support This change adds support for the tilegx network driver based on the GXIO IORPC support in the tilegx software stack, using the on-chip mPIPE packet processing engine. Signed-off-by: Chris Metcalf Signed-off-by: David S. Miller --- drivers/net/ethernet/tile/Kconfig | 2 + drivers/net/ethernet/tile/Makefile | 4 +- drivers/net/ethernet/tile/tilegx.c | 1898 ++++++++++++++++++++++++++++++++++++ 3 files changed, 1902 insertions(+), 2 deletions(-) create mode 100644 drivers/net/ethernet/tile/tilegx.c (limited to 'drivers') diff --git a/drivers/net/ethernet/tile/Kconfig b/drivers/net/ethernet/tile/Kconfig index 2d9218f..098b1c4 100644 --- a/drivers/net/ethernet/tile/Kconfig +++ b/drivers/net/ethernet/tile/Kconfig @@ -7,6 +7,8 @@ config TILE_NET depends on TILE default y select CRC32 + select TILE_GXIO_MPIPE if TILEGX + select HIGH_RES_TIMERS if TILEGX ---help--- This is a standard Linux network device driver for the on-chip Tilera Gigabit Ethernet and XAUI interfaces. diff --git a/drivers/net/ethernet/tile/Makefile b/drivers/net/ethernet/tile/Makefile index f634f14..0ef9eef 100644 --- a/drivers/net/ethernet/tile/Makefile +++ b/drivers/net/ethernet/tile/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_TILE_NET) += tile_net.o ifdef CONFIG_TILEGX -tile_net-objs := tilegx.o mpipe.o iorpc_mpipe.o dma_queue.o +tile_net-y := tilegx.o else -tile_net-objs := tilepro.o +tile_net-y := tilepro.o endif diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c new file mode 100644 index 0000000..83b4b38 --- /dev/null +++ b/drivers/net/ethernet/tile/tilegx.c @@ -0,0 +1,1898 @@ +/* + * Copyright 2012 Tilera Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include +#include /* printk() */ +#include /* kmalloc() */ +#include /* error codes */ +#include /* size_t */ +#include +#include +#include +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Default transmit lockup timeout period, in jiffies. */ +#define TILE_NET_TIMEOUT (5 * HZ) + +/* The maximum number of distinct channels (idesc.channel is 5 bits). */ +#define TILE_NET_CHANNELS 32 + +/* Maximum number of idescs to handle per "poll". */ +#define TILE_NET_BATCH 128 + +/* Maximum number of packets to handle per "poll". */ +#define TILE_NET_WEIGHT 64 + +/* Number of entries in each iqueue. */ +#define IQUEUE_ENTRIES 512 + +/* Number of entries in each equeue. */ +#define EQUEUE_ENTRIES 2048 + +/* Total header bytes per equeue slot. Must be big enough for 2 bytes + * of NET_IP_ALIGN alignment, plus 14 bytes (?) of L2 header, plus up to + * 60 bytes of actual TCP header. We round up to align to cache lines. + */ +#define HEADER_BYTES 128 + +/* Maximum completions per cpu per device (must be a power of two). + * ISSUE: What is the right number here? If this is too small, then + * egress might block waiting for free space in a completions array. + * ISSUE: At the least, allocate these only for initialized echannels. + */ +#define TILE_NET_MAX_COMPS 64 + +#define MAX_FRAGS (MAX_SKB_FRAGS + 1) + +/* Size of completions data to allocate. + * ISSUE: Probably more than needed since we don't use all the channels. + */ +#define COMPS_SIZE (TILE_NET_CHANNELS * sizeof(struct tile_net_comps)) + +/* Size of NotifRing data to allocate. */ +#define NOTIF_RING_SIZE (IQUEUE_ENTRIES * sizeof(gxio_mpipe_idesc_t)) + +/* Timeout to wake the per-device TX timer after we stop the queue. + * We don't want the timeout too short (adds overhead, and might end + * up causing stop/wake/stop/wake cycles) or too long (affects performance). + * For the 10 Gb NIC, 30 usec means roughly 30+ 1500-byte packets. + */ +#define TX_TIMER_DELAY_USEC 30 + +/* Timeout to wake the per-cpu egress timer to free completions. */ +#define EGRESS_TIMER_DELAY_USEC 1000 + +MODULE_AUTHOR("Tilera Corporation"); +MODULE_LICENSE("GPL"); + +/* A "packet fragment" (a chunk of memory). */ +struct frag { + void *buf; + size_t length; +}; + +/* A single completion. */ +struct tile_net_comp { + /* The "complete_count" when the completion will be complete. */ + s64 when; + /* The buffer to be freed when the completion is complete. */ + struct sk_buff *skb; +}; + +/* The completions for a given cpu and echannel. */ +struct tile_net_comps { + /* The completions. */ + struct tile_net_comp comp_queue[TILE_NET_MAX_COMPS]; + /* The number of completions used. */ + unsigned long comp_next; + /* The number of completions freed. */ + unsigned long comp_last; +}; + +/* The transmit wake timer for a given cpu and echannel. */ +struct tile_net_tx_wake { + struct hrtimer timer; + struct net_device *dev; +}; + +/* Info for a specific cpu. */ +struct tile_net_info { + /* The NAPI struct. */ + struct napi_struct napi; + /* Packet queue. */ + gxio_mpipe_iqueue_t iqueue; + /* Our cpu. */ + int my_cpu; + /* True if iqueue is valid. */ + bool has_iqueue; + /* NAPI flags. */ + bool napi_added; + bool napi_enabled; + /* Number of small sk_buffs which must still be provided. */ + unsigned int num_needed_small_buffers; + /* Number of large sk_buffs which must still be provided. */ + unsigned int num_needed_large_buffers; + /* A timer for handling egress completions. */ + struct hrtimer egress_timer; + /* True if "egress_timer" is scheduled. */ + bool egress_timer_scheduled; + /* Comps for each egress channel. */ + struct tile_net_comps *comps_for_echannel[TILE_NET_CHANNELS]; + /* Transmit wake timer for each egress channel. */ + struct tile_net_tx_wake tx_wake[TILE_NET_CHANNELS]; +}; + +/* Info for egress on a particular egress channel. */ +struct tile_net_egress { + /* The "equeue". */ + gxio_mpipe_equeue_t *equeue; + /* The headers for TSO. */ + unsigned char *headers; +}; + +/* Info for a specific device. */ +struct tile_net_priv { + /* Our network device. */ + struct net_device *dev; + /* The primary link. */ + gxio_mpipe_link_t link; + /* The primary channel, if open, else -1. */ + int channel; + /* The "loopify" egress link, if needed. */ + gxio_mpipe_link_t loopify_link; + /* The "loopify" egress channel, if open, else -1. */ + int loopify_channel; + /* The egress channel (channel or loopify_channel). */ + int echannel; + /* Total stats. */ + struct net_device_stats stats; +}; + +/* Egress info, indexed by "priv->echannel" (lazily created as needed). */ +static struct tile_net_egress egress_for_echannel[TILE_NET_CHANNELS]; + +/* Devices currently associated with each channel. + * NOTE: The array entry can become NULL after ifconfig down, but + * we do not free the underlying net_device structures, so it is + * safe to use a pointer after reading it from this array. + */ +static struct net_device *tile_net_devs_for_channel[TILE_NET_CHANNELS]; + +/* A mutex for "tile_net_devs_for_channel". */ +static DEFINE_MUTEX(tile_net_devs_for_channel_mutex); + +/* The per-cpu info. */ +static DEFINE_PER_CPU(struct tile_net_info, per_cpu_info); + +/* The "context" for all devices. */ +static gxio_mpipe_context_t context; + +/* Buffer sizes and mpipe enum codes for buffer stacks. + * See arch/tile/include/gxio/mpipe.h for the set of possible values. + */ +#define BUFFER_SIZE_SMALL_ENUM GXIO_MPIPE_BUFFER_SIZE_128 +#define BUFFER_SIZE_SMALL 128 +#define BUFFER_SIZE_LARGE_ENUM GXIO_MPIPE_BUFFER_SIZE_1664 +#define BUFFER_SIZE_LARGE 1664 + +/* The small/large "buffer stacks". */ +static int small_buffer_stack = -1; +static int large_buffer_stack = -1; + +/* Amount of memory allocated for each buffer stack. */ +static size_t buffer_stack_size; + +/* The actual memory allocated for the buffer stacks. */ +static void *small_buffer_stack_va; +static void *large_buffer_stack_va; + +/* The buckets. */ +static int first_bucket = -1; +static int num_buckets = 1; + +/* The ingress irq. */ +static int ingress_irq = -1; + +/* Text value of tile_net.cpus if passed as a module parameter. */ +static char *network_cpus_string; + +/* The actual cpus in "network_cpus". */ +static struct cpumask network_cpus_map; + +/* If "loopify=LINK" was specified, this is "LINK". */ +static char *loopify_link_name; + +/* If "tile_net.custom" was specified, this is non-NULL. */ +static char *custom_str; + +/* The "tile_net.cpus" argument specifies the cpus that are dedicated + * to handle ingress packets. + * + * The parameter should be in the form "tile_net.cpus=m-n[,x-y]", where + * m, n, x, y are integer numbers that represent the cpus that can be + * neither a dedicated cpu nor a dataplane cpu. + */ +static bool network_cpus_init(void) +{ + char buf[1024]; + int rc; + + if (network_cpus_string == NULL) + return false; + + rc = cpulist_parse_crop(network_cpus_string, &network_cpus_map); + if (rc != 0) { + pr_warn("tile_net.cpus=%s: malformed cpu list\n", + network_cpus_string); + return false; + } + + /* Remove dedicated cpus. */ + cpumask_and(&network_cpus_map, &network_cpus_map, cpu_possible_mask); + + if (cpumask_empty(&network_cpus_map)) { + pr_warn("Ignoring empty tile_net.cpus='%s'.\n", + network_cpus_string); + return false; + } + + cpulist_scnprintf(buf, sizeof(buf), &network_cpus_map); + pr_info("Linux network CPUs: %s\n", buf); + return true; +} + +module_param_named(cpus, network_cpus_string, charp, 0444); +MODULE_PARM_DESC(cpus, "cpulist of cores that handle network interrupts"); + +/* The "tile_net.loopify=LINK" argument causes the named device to + * actually use "loop0" for ingress, and "loop1" for egress. This + * allows an app to sit between the actual link and linux, passing + * (some) packets along to linux, and forwarding (some) packets sent + * out by linux. + */ +module_param_named(loopify, loopify_link_name, charp, 0444); +MODULE_PARM_DESC(loopify, "name the device to use loop0/1 for ingress/egress"); + +/* The "tile_net.custom" argument causes us to ignore the "conventional" + * classifier metadata, in particular, the "l2_offset". + */ +module_param_named(custom, custom_str, charp, 0444); +MODULE_PARM_DESC(custom, "indicates a (heavily) customized classifier"); + +/* Atomically update a statistics field. + * Note that on TILE-Gx, this operation is fire-and-forget on the + * issuing core (single-cycle dispatch) and takes only a few cycles + * longer than a regular store when the request reaches the home cache. + * No expensive bus management overhead is required. + */ +static void tile_net_stats_add(unsigned long value, unsigned long *field) +{ + BUILD_BUG_ON(sizeof(atomic_long_t) != sizeof(unsigned long)); + atomic_long_add(value, (atomic_long_t *)field); +} + +/* Allocate and push a buffer. */ +static bool tile_net_provide_buffer(bool small) +{ + int stack = small ? small_buffer_stack : large_buffer_stack; + const unsigned long buffer_alignment = 128; + struct sk_buff *skb; + int len; + + len = sizeof(struct sk_buff **) + buffer_alignment; + len += (small ? BUFFER_SIZE_SMALL : BUFFER_SIZE_LARGE); + skb = dev_alloc_skb(len); + if (skb == NULL) + return false; + + /* Make room for a back-pointer to 'skb' and guarantee alignment. */ + skb_reserve(skb, sizeof(struct sk_buff **)); + skb_reserve(skb, -(long)skb->data & (buffer_alignment - 1)); + + /* Save a back-pointer to 'skb'. */ + *(struct sk_buff **)(skb->data - sizeof(struct sk_buff **)) = skb; + + /* Make sure "skb" and the back-pointer have been flushed. */ + wmb(); + + gxio_mpipe_push_buffer(&context, stack, + (void *)va_to_tile_io_addr(skb->data)); + + return true; +} + +/* Convert a raw mpipe buffer to its matching skb pointer. */ +static struct sk_buff *mpipe_buf_to_skb(void *va) +{ + /* Acquire the associated "skb". */ + struct sk_buff **skb_ptr = va - sizeof(*skb_ptr); + struct sk_buff *skb = *skb_ptr; + + /* Paranoia. */ + if (skb->data != va) { + /* Panic here since there's a reasonable chance + * that corrupt buffers means generic memory + * corruption, with unpredictable system effects. + */ + panic("Corrupt linux buffer! va=%p, skb=%p, skb->data=%p", + va, skb, skb->data); + } + + return skb; +} + +static void tile_net_pop_all_buffers(int stack) +{ + for (;;) { + tile_io_addr_t addr = + (tile_io_addr_t)gxio_mpipe_pop_buffer(&context, stack); + if (addr == 0) + break; + dev_kfree_skb_irq(mpipe_buf_to_skb(tile_io_addr_to_va(addr))); + } +} + +/* Provide linux buffers to mPIPE. */ +static void tile_net_provide_needed_buffers(void) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + + while (info->num_needed_small_buffers != 0) { + if (!tile_net_provide_buffer(true)) + goto oops; + info->num_needed_small_buffers--; + } + + while (info->num_needed_large_buffers != 0) { + if (!tile_net_provide_buffer(false)) + goto oops; + info->num_needed_large_buffers--; + } + + return; + +oops: + /* Add a description to the page allocation failure dump. */ + pr_notice("Tile %d still needs some buffers\n", info->my_cpu); +} + +static inline bool filter_packet(struct net_device *dev, void *buf) +{ + /* Filter packets received before we're up. */ + if (dev == NULL || !(dev->flags & IFF_UP)) + return true; + + /* Filter out packets that aren't for us. */ + if (!(dev->flags & IFF_PROMISC) && + !is_multicast_ether_addr(buf) && + compare_ether_addr(dev->dev_addr, buf) != 0) + return true; + + return false; +} + +static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb, + gxio_mpipe_idesc_t *idesc, unsigned long len) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + struct tile_net_priv *priv = netdev_priv(dev); + + /* Encode the actual packet length. */ + skb_put(skb, len); + + skb->protocol = eth_type_trans(skb, dev); + + /* Acknowledge "good" hardware checksums. */ + if (idesc->cs && idesc->csum_seed_val == 0xFFFF) + skb->ip_summed = CHECKSUM_UNNECESSARY; + + netif_receive_skb(skb); + + /* Update stats. */ + tile_net_stats_add(1, &priv->stats.rx_packets); + tile_net_stats_add(len, &priv->stats.rx_bytes); + + /* Need a new buffer. */ + if (idesc->size == BUFFER_SIZE_SMALL_ENUM) + info->num_needed_small_buffers++; + else + info->num_needed_large_buffers++; +} + +/* Handle a packet. Return true if "processed", false if "filtered". */ +static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + struct net_device *dev = tile_net_devs_for_channel[idesc->channel]; + uint8_t l2_offset; + void *va; + void *buf; + unsigned long len; + bool filter; + + /* Drop packets for which no buffer was available. + * NOTE: This happens under heavy load. + */ + if (idesc->be) { + struct tile_net_priv *priv = netdev_priv(dev); + tile_net_stats_add(1, &priv->stats.rx_dropped); + gxio_mpipe_iqueue_consume(&info->iqueue, idesc); + if (net_ratelimit()) + pr_info("Dropping packet (insufficient buffers).\n"); + return false; + } + + /* Get the "l2_offset", if allowed. */ + l2_offset = custom_str ? 0 : gxio_mpipe_idesc_get_l2_offset(idesc); + + /* Get the raw buffer VA (includes "headroom"). */ + va = tile_io_addr_to_va((unsigned long)(long)idesc->va); + + /* Get the actual packet start/length. */ + buf = va + l2_offset; + len = idesc->l2_size - l2_offset; + + /* Point "va" at the raw buffer. */ + va -= NET_IP_ALIGN; + + filter = filter_packet(dev, buf); + if (filter) { + gxio_mpipe_iqueue_drop(&info->iqueue, idesc); + } else { + struct sk_buff *skb = mpipe_buf_to_skb(va); + + /* Skip headroom, and any custom header. */ + skb_reserve(skb, NET_IP_ALIGN + l2_offset); + + tile_net_receive_skb(dev, skb, idesc, len); + } + + gxio_mpipe_iqueue_consume(&info->iqueue, idesc); + return !filter; +} + +/* Handle some packets for the current CPU. + * + * This function handles up to TILE_NET_BATCH idescs per call. + * + * ISSUE: Since we do not provide new buffers until this function is + * complete, we must initially provide enough buffers for each network + * cpu to fill its iqueue and also its batched idescs. + * + * ISSUE: The "rotting packet" race condition occurs if a packet + * arrives after the queue appears to be empty, and before the + * hypervisor interrupt is re-enabled. + */ +static int tile_net_poll(struct napi_struct *napi, int budget) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + unsigned int work = 0; + gxio_mpipe_idesc_t *idesc; + int i, n; + + /* Process packets. */ + while ((n = gxio_mpipe_iqueue_try_peek(&info->iqueue, &idesc)) > 0) { + for (i = 0; i < n; i++) { + if (i == TILE_NET_BATCH) + goto done; + if (tile_net_handle_packet(idesc + i)) { + if (++work >= budget) + goto done; + } + } + } + + /* There are no packets left. */ + napi_complete(&info->napi); + + /* Re-enable hypervisor interrupts. */ + gxio_mpipe_enable_notif_ring_interrupt(&context, info->iqueue.ring); + + /* HACK: Avoid the "rotting packet" problem. */ + if (gxio_mpipe_iqueue_try_peek(&info->iqueue, &idesc) > 0) + napi_schedule(&info->napi); + + /* ISSUE: Handle completions? */ + +done: + tile_net_provide_needed_buffers(); + + return work; +} + +/* Handle an ingress interrupt on the current cpu. */ +static irqreturn_t tile_net_handle_ingress_irq(int irq, void *unused) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + napi_schedule(&info->napi); + return IRQ_HANDLED; +} + +/* Free some completions. This must be called with interrupts blocked. */ +static int tile_net_free_comps(gxio_mpipe_equeue_t *equeue, + struct tile_net_comps *comps, + int limit, bool force_update) +{ + int n = 0; + while (comps->comp_last < comps->comp_next) { + unsigned int cid = comps->comp_last % TILE_NET_MAX_COMPS; + struct tile_net_comp *comp = &comps->comp_queue[cid]; + if (!gxio_mpipe_equeue_is_complete(equeue, comp->when, + force_update || n == 0)) + break; + dev_kfree_skb_irq(comp->skb); + comps->comp_last++; + if (++n == limit) + break; + } + return n; +} + +/* Add a completion. This must be called with interrupts blocked. + * tile_net_equeue_try_reserve() will have ensured a free completion entry. + */ +static void add_comp(gxio_mpipe_equeue_t *equeue, + struct tile_net_comps *comps, + uint64_t when, struct sk_buff *skb) +{ + int cid = comps->comp_next % TILE_NET_MAX_COMPS; + comps->comp_queue[cid].when = when; + comps->comp_queue[cid].skb = skb; + comps->comp_next++; +} + +static void tile_net_schedule_tx_wake_timer(struct net_device *dev) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + struct tile_net_priv *priv = netdev_priv(dev); + + hrtimer_start(&info->tx_wake[priv->echannel].timer, + ktime_set(0, TX_TIMER_DELAY_USEC * 1000UL), + HRTIMER_MODE_REL_PINNED); +} + +static enum hrtimer_restart tile_net_handle_tx_wake_timer(struct hrtimer *t) +{ + struct tile_net_tx_wake *tx_wake = + container_of(t, struct tile_net_tx_wake, timer); + netif_wake_subqueue(tx_wake->dev, smp_processor_id()); + return HRTIMER_NORESTART; +} + +/* Make sure the egress timer is scheduled. */ +static void tile_net_schedule_egress_timer(void) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + + if (!info->egress_timer_scheduled) { + hrtimer_start(&info->egress_timer, + ktime_set(0, EGRESS_TIMER_DELAY_USEC * 1000UL), + HRTIMER_MODE_REL_PINNED); + info->egress_timer_scheduled = true; + } +} + +/* The "function" for "info->egress_timer". + * + * This timer will reschedule itself as long as there are any pending + * completions expected for this tile. + */ +static enum hrtimer_restart tile_net_handle_egress_timer(struct hrtimer *t) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + unsigned long irqflags; + bool pending = false; + int i; + + local_irq_save(irqflags); + + /* The timer is no longer scheduled. */ + info->egress_timer_scheduled = false; + + /* Free all possible comps for this tile. */ + for (i = 0; i < TILE_NET_CHANNELS; i++) { + struct tile_net_egress *egress = &egress_for_echannel[i]; + struct tile_net_comps *comps = info->comps_for_echannel[i]; + if (comps->comp_last >= comps->comp_next) + continue; + tile_net_free_comps(egress->equeue, comps, -1, true); + pending = pending || (comps->comp_last < comps->comp_next); + } + + /* Reschedule timer if needed. */ + if (pending) + tile_net_schedule_egress_timer(); + + local_irq_restore(irqflags); + + return HRTIMER_NORESTART; +} + +/* Helper function for "tile_net_update()". + * "dev" (i.e. arg) is the device being brought up or down, + * or NULL if all devices are now down. + */ +static void tile_net_update_cpu(void *arg) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + struct net_device *dev = arg; + + if (!info->has_iqueue) + return; + + if (dev != NULL) { + if (!info->napi_added) { + netif_napi_add(dev, &info->napi, + tile_net_poll, TILE_NET_WEIGHT); + info->napi_added = true; + } + if (!info->napi_enabled) { + napi_enable(&info->napi); + info->napi_enabled = true; + } + enable_percpu_irq(ingress_irq, 0); + } else { + disable_percpu_irq(ingress_irq); + if (info->napi_enabled) { + napi_disable(&info->napi); + info->napi_enabled = false; + } + /* FIXME: Drain the iqueue. */ + } +} + +/* Helper function for tile_net_open() and tile_net_stop(). + * Always called under tile_net_devs_for_channel_mutex. + */ +static int tile_net_update(struct net_device *dev) +{ + static gxio_mpipe_rules_t rules; /* too big to fit on the stack */ + bool saw_channel = false; + int channel; + int rc; + int cpu; + + gxio_mpipe_rules_init(&rules, &context); + + for (channel = 0; channel < TILE_NET_CHANNELS; channel++) { + if (tile_net_devs_for_channel[channel] == NULL) + continue; + if (!saw_channel) { + saw_channel = true; + gxio_mpipe_rules_begin(&rules, first_bucket, + num_buckets, NULL); + gxio_mpipe_rules_set_headroom(&rules, NET_IP_ALIGN); + } + gxio_mpipe_rules_add_channel(&rules, channel); + } + + /* NOTE: This can fail if there is no classifier. + * ISSUE: Can anything else cause it to fail? + */ + rc = gxio_mpipe_rules_commit(&rules); + if (rc != 0) { + netdev_warn(dev, "gxio_mpipe_rules_commit failed: %d\n", rc); + return -EIO; + } + + /* Update all cpus, sequentially (to protect "netif_napi_add()"). */ + for_each_online_cpu(cpu) + smp_call_function_single(cpu, tile_net_update_cpu, + (saw_channel ? dev : NULL), 1); + + /* HACK: Allow packets to flow in the simulator. */ + if (saw_channel) + sim_enable_mpipe_links(0, -1); + + return 0; +} + +/* Allocate and initialize mpipe buffer stacks, and register them in + * the mPIPE TLBs, for both small and large packet sizes. + * This routine supports tile_net_init_mpipe(), below. + */ +static int init_buffer_stacks(struct net_device *dev, int num_buffers) +{ + pte_t hash_pte = pte_set_home((pte_t) { 0 }, PAGE_HOME_HASH); + int rc; + + /* Compute stack bytes; we round up to 64KB and then use + * alloc_pages() so we get the required 64KB alignment as well. + */ + buffer_stack_size = + ALIGN(gxio_mpipe_calc_buffer_stack_bytes(num_buffers), + 64 * 1024); + + /* Allocate two buffer stack indices. */ + rc = gxio_mpipe_alloc_buffer_stacks(&context, 2, 0, 0); + if (rc < 0) { + netdev_err(dev, "gxio_mpipe_alloc_buffer_stacks failed: %d\n", + rc); + return rc; + } + small_buffer_stack = rc; + large_buffer_stack = rc + 1; + + /* Allocate the small memory stack. */ + small_buffer_stack_va = + alloc_pages_exact(buffer_stack_size, GFP_KERNEL); + if (small_buffer_stack_va == NULL) { + netdev_err(dev, + "Could not alloc %zd bytes for buffer stacks\n", + buffer_stack_size); + return -ENOMEM; + } + rc = gxio_mpipe_init_buffer_stack(&context, small_buffer_stack, + BUFFER_SIZE_SMALL_ENUM, + small_buffer_stack_va, + buffer_stack_size, 0); + if (rc != 0) { + netdev_err(dev, "gxio_mpipe_init_buffer_stack: %d\n", rc); + return rc; + } + rc = gxio_mpipe_register_client_memory(&context, small_buffer_stack, + hash_pte, 0); + if (rc != 0) { + netdev_err(dev, + "gxio_mpipe_register_buffer_memory failed: %d\n", + rc); + return rc; + } + + /* Allocate the large buffer stack. */ + large_buffer_stack_va = + alloc_pages_exact(buffer_stack_size, GFP_KERNEL); + if (large_buffer_stack_va == NULL) { + netdev_err(dev, + "Could not alloc %zd bytes for buffer stacks\n", + buffer_stack_size); + return -ENOMEM; + } + rc = gxio_mpipe_init_buffer_stack(&context, large_buffer_stack, + BUFFER_SIZE_LARGE_ENUM, + large_buffer_stack_va, + buffer_stack_size, 0); + if (rc != 0) { + netdev_err(dev, "gxio_mpipe_init_buffer_stack failed: %d\n", + rc); + return rc; + } + rc = gxio_mpipe_register_client_memory(&context, large_buffer_stack, + hash_pte, 0); + if (rc != 0) { + netdev_err(dev, + "gxio_mpipe_register_buffer_memory failed: %d\n", + rc); + return rc; + } + + return 0; +} + +/* Allocate per-cpu resources (memory for completions and idescs). + * This routine supports tile_net_init_mpipe(), below. + */ +static int alloc_percpu_mpipe_resources(struct net_device *dev, + int cpu, int ring) +{ + struct tile_net_info *info = &per_cpu(per_cpu_info, cpu); + int order, i, rc; + struct page *page; + void *addr; + + /* Allocate the "comps". */ + order = get_order(COMPS_SIZE); + page = homecache_alloc_pages(GFP_KERNEL, order, cpu); + if (page == NULL) { + netdev_err(dev, "Failed to alloc %zd bytes comps memory\n", + COMPS_SIZE); + return -ENOMEM; + } + addr = pfn_to_kaddr(page_to_pfn(page)); + memset(addr, 0, COMPS_SIZE); + for (i = 0; i < TILE_NET_CHANNELS; i++) + info->comps_for_echannel[i] = + addr + i * sizeof(struct tile_net_comps); + + /* If this is a network cpu, create an iqueue. */ + if (cpu_isset(cpu, network_cpus_map)) { + order = get_order(NOTIF_RING_SIZE); + page = homecache_alloc_pages(GFP_KERNEL, order, cpu); + if (page == NULL) { + netdev_err(dev, + "Failed to alloc %zd bytes iqueue memory\n", + NOTIF_RING_SIZE); + return -ENOMEM; + } + addr = pfn_to_kaddr(page_to_pfn(page)); + rc = gxio_mpipe_iqueue_init(&info->iqueue, &context, ring++, + addr, NOTIF_RING_SIZE, 0); + if (rc < 0) { + netdev_err(dev, + "gxio_mpipe_iqueue_init failed: %d\n", rc); + return rc; + } + info->has_iqueue = true; + } + + return ring; +} + +/* Initialize NotifGroup and buckets. + * This routine supports tile_net_init_mpipe(), below. + */ +static int init_notif_group_and_buckets(struct net_device *dev, + int ring, int network_cpus_count) +{ + int group, rc; + + /* Allocate one NotifGroup. */ + rc = gxio_mpipe_alloc_notif_groups(&context, 1, 0, 0); + if (rc < 0) { + netdev_err(dev, "gxio_mpipe_alloc_notif_groups failed: %d\n", + rc); + return rc; + } + group = rc; + + /* Initialize global num_buckets value. */ + if (network_cpus_count > 4) + num_buckets = 256; + else if (network_cpus_count > 1) + num_buckets = 16; + + /* Allocate some buckets, and set global first_bucket value. */ + rc = gxio_mpipe_alloc_buckets(&context, num_buckets, 0, 0); + if (rc < 0) { + netdev_err(dev, "gxio_mpipe_alloc_buckets failed: %d\n", rc); + return rc; + } + first_bucket = rc; + + /* Init group and buckets. */ + rc = gxio_mpipe_init_notif_group_and_buckets( + &context, group, ring, network_cpus_count, + first_bucket, num_buckets, + GXIO_MPIPE_BUCKET_STICKY_FLOW_LOCALITY); + if (rc != 0) { + netdev_err( + dev, + "gxio_mpipe_init_notif_group_and_buckets failed: %d\n", + rc); + return rc; + } + + return 0; +} + +/* Create an irq and register it, then activate the irq and request + * interrupts on all cores. Note that "ingress_irq" being initialized + * is how we know not to call tile_net_init_mpipe() again. + * This routine supports tile_net_init_mpipe(), below. + */ +static int tile_net_setup_interrupts(struct net_device *dev) +{ + int cpu, rc; + + rc = create_irq(); + if (rc < 0) { + netdev_err(dev, "create_irq failed: %d\n", rc); + return rc; + } + ingress_irq = rc; + tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU); + rc = request_irq(ingress_irq, tile_net_handle_ingress_irq, + 0, NULL, NULL); + if (rc != 0) { + netdev_err(dev, "request_irq failed: %d\n", rc); + destroy_irq(ingress_irq); + ingress_irq = -1; + return rc; + } + + for_each_online_cpu(cpu) { + struct tile_net_info *info = &per_cpu(per_cpu_info, cpu); + if (info->has_iqueue) { + gxio_mpipe_request_notif_ring_interrupt( + &context, cpu_x(cpu), cpu_y(cpu), + 1, ingress_irq, info->iqueue.ring); + } + } + + return 0; +} + +/* Undo any state set up partially by a failed call to tile_net_init_mpipe. */ +static void tile_net_init_mpipe_fail(void) +{ + int cpu; + + /* Do cleanups that require the mpipe context first. */ + if (small_buffer_stack >= 0) + tile_net_pop_all_buffers(small_buffer_stack); + if (large_buffer_stack >= 0) + tile_net_pop_all_buffers(large_buffer_stack); + + /* Destroy mpipe context so the hardware no longer owns any memory. */ + gxio_mpipe_destroy(&context); + + for_each_online_cpu(cpu) { + struct tile_net_info *info = &per_cpu(per_cpu_info, cpu); + free_pages((unsigned long)(info->comps_for_echannel[0]), + get_order(COMPS_SIZE)); + info->comps_for_echannel[0] = NULL; + free_pages((unsigned long)(info->iqueue.idescs), + get_order(NOTIF_RING_SIZE)); + info->iqueue.idescs = NULL; + } + + if (small_buffer_stack_va) + free_pages_exact(small_buffer_stack_va, buffer_stack_size); + if (large_buffer_stack_va) + free_pages_exact(large_buffer_stack_va, buffer_stack_size); + + small_buffer_stack_va = NULL; + large_buffer_stack_va = NULL; + large_buffer_stack = -1; + small_buffer_stack = -1; + first_bucket = -1; +} + +/* The first time any tilegx network device is opened, we initialize + * the global mpipe state. If this step fails, we fail to open the + * device, but if it succeeds, we never need to do it again, and since + * tile_net can't be unloaded, we never undo it. + * + * Note that some resources in this path (buffer stack indices, + * bindings from init_buffer_stack, etc.) are hypervisor resources + * that are freed implicitly by gxio_mpipe_destroy(). + */ +static int tile_net_init_mpipe(struct net_device *dev) +{ + int i, num_buffers, rc; + int cpu; + int first_ring, ring; + int network_cpus_count = cpus_weight(network_cpus_map); + + if (!hash_default) { + netdev_err(dev, "Networking requires hash_default!\n"); + return -EIO; + } + + rc = gxio_mpipe_init(&context, 0); + if (rc != 0) { + netdev_err(dev, "gxio_mpipe_init failed: %d\n", rc); + return -EIO; + } + + /* Set up the buffer stacks. */ + num_buffers = + network_cpus_count * (IQUEUE_ENTRIES + TILE_NET_BATCH); + rc = init_buffer_stacks(dev, num_buffers); + if (rc != 0) + goto fail; + + /* Provide initial buffers. */ + rc = -ENOMEM; + for (i = 0; i < num_buffers; i++) { + if (!tile_net_provide_buffer(true)) { + netdev_err(dev, "Cannot allocate initial sk_bufs!\n"); + goto fail; + } + } + for (i = 0; i < num_buffers; i++) { + if (!tile_net_provide_buffer(false)) { + netdev_err(dev, "Cannot allocate initial sk_bufs!\n"); + goto fail; + } + } + + /* Allocate one NotifRing for each network cpu. */ + rc = gxio_mpipe_alloc_notif_rings(&context, network_cpus_count, 0, 0); + if (rc < 0) { + netdev_err(dev, "gxio_mpipe_alloc_notif_rings failed %d\n", + rc); + goto fail; + } + + /* Init NotifRings per-cpu. */ + first_ring = rc; + ring = first_ring; + for_each_online_cpu(cpu) { + rc = alloc_percpu_mpipe_resources(dev, cpu, ring); + if (rc < 0) + goto fail; + ring = rc; + } + + /* Initialize NotifGroup and buckets. */ + rc = init_notif_group_and_buckets(dev, first_ring, network_cpus_count); + if (rc != 0) + goto fail; + + /* Create and enable interrupts. */ + rc = tile_net_setup_interrupts(dev); + if (rc != 0) + goto fail; + + return 0; + +fail: + tile_net_init_mpipe_fail(); + return rc; +} + +/* Create persistent egress info for a given egress channel. + * Note that this may be shared between, say, "gbe0" and "xgbe0". + * ISSUE: Defer header allocation until TSO is actually needed? + */ +static int tile_net_init_egress(struct net_device *dev, int echannel) +{ + struct page *headers_page, *edescs_page, *equeue_page; + gxio_mpipe_edesc_t *edescs; + gxio_mpipe_equeue_t *equeue; + unsigned char *headers; + int headers_order, edescs_order, equeue_order; + size_t edescs_size; + int edma; + int rc = -ENOMEM; + + /* Only initialize once. */ + if (egress_for_echannel[echannel].equeue != NULL) + return 0; + + /* Allocate memory for the "headers". */ + headers_order = get_order(EQUEUE_ENTRIES * HEADER_BYTES); + headers_page = alloc_pages(GFP_KERNEL, headers_order); + if (headers_page == NULL) { + netdev_warn(dev, + "Could not alloc %zd bytes for TSO headers.\n", + PAGE_SIZE << headers_order); + goto fail; + } + headers = pfn_to_kaddr(page_to_pfn(headers_page)); + + /* Allocate memory for the "edescs". */ + edescs_size = EQUEUE_ENTRIES * sizeof(*edescs); + edescs_order = get_order(edescs_size); + edescs_page = alloc_pages(GFP_KERNEL, edescs_order); + if (edescs_page == NULL) { + netdev_warn(dev, + "Could not alloc %zd bytes for eDMA ring.\n", + edescs_size); + goto fail_headers; + } + edescs = pfn_to_kaddr(page_to_pfn(edescs_page)); + + /* Allocate memory for the "equeue". */ + equeue_order = get_order(sizeof(*equeue)); + equeue_page = alloc_pages(GFP_KERNEL, equeue_order); + if (equeue_page == NULL) { + netdev_warn(dev, + "Could not alloc %zd bytes for equeue info.\n", + PAGE_SIZE << equeue_order); + goto fail_edescs; + } + equeue = pfn_to_kaddr(page_to_pfn(equeue_page)); + + /* Allocate an edma ring. Note that in practice this can't + * fail, which is good, because we will leak an edma ring if so. + */ + rc = gxio_mpipe_alloc_edma_rings(&context, 1, 0, 0); + if (rc < 0) { + netdev_warn(dev, "gxio_mpipe_alloc_edma_rings failed: %d\n", + rc); + goto fail_equeue; + } + edma = rc; + + /* Initialize the equeue. */ + rc = gxio_mpipe_equeue_init(equeue, &context, edma, echannel, + edescs, edescs_size, 0); + if (rc != 0) { + netdev_err(dev, "gxio_mpipe_equeue_init failed: %d\n", rc); + goto fail_equeue; + } + + /* Done. */ + egress_for_echannel[echannel].equeue = equeue; + egress_for_echannel[echannel].headers = headers; + return 0; + +fail_equeue: + __free_pages(equeue_page, equeue_order); + +fail_edescs: + __free_pages(edescs_page, edescs_order); + +fail_headers: + __free_pages(headers_page, headers_order); + +fail: + return rc; +} + +/* Return channel number for a newly-opened link. */ +static int tile_net_link_open(struct net_device *dev, gxio_mpipe_link_t *link, + const char *link_name) +{ + int rc = gxio_mpipe_link_open(link, &context, link_name, 0); + if (rc < 0) { + netdev_err(dev, "Failed to open '%s'\n", link_name); + return rc; + } + rc = gxio_mpipe_link_channel(link); + if (rc < 0 || rc >= TILE_NET_CHANNELS) { + netdev_err(dev, "gxio_mpipe_link_channel bad value: %d\n", rc); + gxio_mpipe_link_close(link); + return -EINVAL; + } + return rc; +} + +/* Help the kernel activate the given network interface. */ +static int tile_net_open(struct net_device *dev) +{ + struct tile_net_priv *priv = netdev_priv(dev); + int cpu, rc; + + mutex_lock(&tile_net_devs_for_channel_mutex); + + /* Do one-time initialization the first time any device is opened. */ + if (ingress_irq < 0) { + rc = tile_net_init_mpipe(dev); + if (rc != 0) + goto fail; + } + + /* Determine if this is the "loopify" device. */ + if (unlikely((loopify_link_name != NULL) && + !strcmp(dev->name, loopify_link_name))) { + rc = tile_net_link_open(dev, &priv->link, "loop0"); + if (rc < 0) + goto fail; + priv->channel = rc; + rc = tile_net_link_open(dev, &priv->loopify_link, "loop1"); + if (rc < 0) + goto fail; + priv->loopify_channel = rc; + priv->echannel = rc; + } else { + rc = tile_net_link_open(dev, &priv->link, dev->name); + if (rc < 0) + goto fail; + priv->channel = rc; + priv->echannel = rc; + } + + /* Initialize egress info (if needed). Once ever, per echannel. */ + rc = tile_net_init_egress(dev, priv->echannel); + if (rc != 0) + goto fail; + + tile_net_devs_for_channel[priv->channel] = dev; + + rc = tile_net_update(dev); + if (rc != 0) + goto fail; + + mutex_unlock(&tile_net_devs_for_channel_mutex); + + /* Initialize the transmit wake timer for this device for each cpu. */ + for_each_online_cpu(cpu) { + struct tile_net_info *info = &per_cpu(per_cpu_info, cpu); + struct tile_net_tx_wake *tx_wake = + &info->tx_wake[priv->echannel]; + + hrtimer_init(&tx_wake->timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + tx_wake->timer.function = tile_net_handle_tx_wake_timer; + tx_wake->dev = dev; + } + + for_each_online_cpu(cpu) + netif_start_subqueue(dev, cpu); + netif_carrier_on(dev); + return 0; + +fail: + if (priv->loopify_channel >= 0) { + if (gxio_mpipe_link_close(&priv->loopify_link) != 0) + netdev_warn(dev, "Failed to close loopify link!\n"); + priv->loopify_channel = -1; + } + if (priv->channel >= 0) { + if (gxio_mpipe_link_close(&priv->link) != 0) + netdev_warn(dev, "Failed to close link!\n"); + priv->channel = -1; + } + priv->echannel = -1; + tile_net_devs_for_channel[priv->channel] = NULL; + mutex_unlock(&tile_net_devs_for_channel_mutex); + + /* Don't return raw gxio error codes to generic Linux. */ + return (rc > -512) ? rc : -EIO; +} + +/* Help the kernel deactivate the given network interface. */ +static int tile_net_stop(struct net_device *dev) +{ + struct tile_net_priv *priv = netdev_priv(dev); + int cpu; + + for_each_online_cpu(cpu) { + struct tile_net_info *info = &per_cpu(per_cpu_info, cpu); + struct tile_net_tx_wake *tx_wake = + &info->tx_wake[priv->echannel]; + + hrtimer_cancel(&tx_wake->timer); + netif_stop_subqueue(dev, cpu); + } + + mutex_lock(&tile_net_devs_for_channel_mutex); + tile_net_devs_for_channel[priv->channel] = NULL; + (void)tile_net_update(dev); + if (priv->loopify_channel >= 0) { + if (gxio_mpipe_link_close(&priv->loopify_link) != 0) + netdev_warn(dev, "Failed to close loopify link!\n"); + priv->loopify_channel = -1; + } + if (priv->channel >= 0) { + if (gxio_mpipe_link_close(&priv->link) != 0) + netdev_warn(dev, "Failed to close link!\n"); + priv->channel = -1; + } + priv->echannel = -1; + mutex_unlock(&tile_net_devs_for_channel_mutex); + + return 0; +} + +/* Determine the VA for a fragment. */ +static inline void *tile_net_frag_buf(skb_frag_t *f) +{ + unsigned long pfn = page_to_pfn(skb_frag_page(f)); + return pfn_to_kaddr(pfn) + f->page_offset; +} + +/* Acquire a completion entry and an egress slot, or if we can't, + * stop the queue and schedule the tx_wake timer. + */ +static s64 tile_net_equeue_try_reserve(struct net_device *dev, + struct tile_net_comps *comps, + gxio_mpipe_equeue_t *equeue, + int num_edescs) +{ + /* Try to acquire a completion entry. */ + if (comps->comp_next - comps->comp_last < TILE_NET_MAX_COMPS - 1 || + tile_net_free_comps(equeue, comps, 32, false) != 0) { + + /* Try to acquire an egress slot. */ + s64 slot = gxio_mpipe_equeue_try_reserve(equeue, num_edescs); + if (slot >= 0) + return slot; + + /* Freeing some completions gives the equeue time to drain. */ + tile_net_free_comps(equeue, comps, TILE_NET_MAX_COMPS, false); + + slot = gxio_mpipe_equeue_try_reserve(equeue, num_edescs); + if (slot >= 0) + return slot; + } + + /* Still nothing; give up and stop the queue for a short while. */ + netif_stop_subqueue(dev, smp_processor_id()); + tile_net_schedule_tx_wake_timer(dev); + return -1; +} + +/* Determine how many edesc's are needed for TSO. + * + * Sometimes, if "sendfile()" requires copying, we will be called with + * "data" containing the header and payload, with "frags" being empty. + * Sometimes, for example when using NFS over TCP, a single segment can + * span 3 fragments. This requires special care. + */ +static int tso_count_edescs(struct sk_buff *skb) +{ + struct skb_shared_info *sh = skb_shinfo(skb); + unsigned int data_len = skb->data_len; + unsigned int p_len = sh->gso_size; + long f_id = -1; /* id of the current fragment */ + long f_size = -1; /* size of the current fragment */ + long f_used = -1; /* bytes used from the current fragment */ + long n; /* size of the current piece of payload */ + int num_edescs = 0; + int segment; + + for (segment = 0; segment < sh->gso_segs; segment++) { + + unsigned int p_used = 0; + + /* One edesc for header and for each piece of the payload. */ + for (num_edescs++; p_used < p_len; num_edescs++) { + + /* Advance as needed. */ + while (f_used >= f_size) { + f_id++; + f_size = sh->frags[f_id].size; + f_used = 0; + } + + /* Use bytes from the current fragment. */ + n = p_len - p_used; + if (n > f_size - f_used) + n = f_size - f_used; + f_used += n; + p_used += n; + } + + /* The last segment may be less than gso_size. */ + data_len -= p_len; + if (data_len < p_len) + p_len = data_len; + } + + return num_edescs; +} + +/* Prepare modified copies of the skbuff headers. + * FIXME: add support for IPv6. + */ +static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, + s64 slot) +{ + struct skb_shared_info *sh = skb_shinfo(skb); + struct iphdr *ih; + struct tcphdr *th; + unsigned int data_len = skb->data_len; + unsigned char *data = skb->data; + unsigned int ih_off, th_off, sh_len, p_len; + unsigned int isum_seed, tsum_seed, id, seq; + long f_id = -1; /* id of the current fragment */ + long f_size = -1; /* size of the current fragment */ + long f_used = -1; /* bytes used from the current fragment */ + long n; /* size of the current piece of payload */ + int segment; + + /* Locate original headers and compute various lengths. */ + ih = ip_hdr(skb); + th = tcp_hdr(skb); + ih_off = skb_network_offset(skb); + th_off = skb_transport_offset(skb); + sh_len = th_off + tcp_hdrlen(skb); + p_len = sh->gso_size; + + /* Set up seed values for IP and TCP csum and initialize id and seq. */ + isum_seed = ((0xFFFF - ih->check) + + (0xFFFF - ih->tot_len) + + (0xFFFF - ih->id)); + tsum_seed = th->check + (0xFFFF ^ htons(skb->len)); + id = ntohs(ih->id); + seq = ntohl(th->seq); + + /* Prepare all the headers. */ + for (segment = 0; segment < sh->gso_segs; segment++) { + unsigned char *buf; + unsigned int p_used = 0; + + /* Copy to the header memory for this segment. */ + buf = headers + (slot % EQUEUE_ENTRIES) * HEADER_BYTES + + NET_IP_ALIGN; + memcpy(buf, data, sh_len); + + /* Update copied ip header. */ + ih = (struct iphdr *)(buf + ih_off); + ih->tot_len = htons(sh_len + p_len - ih_off); + ih->id = htons(id); + ih->check = csum_long(isum_seed + ih->tot_len + + ih->id) ^ 0xffff; + + /* Update copied tcp header. */ + th = (struct tcphdr *)(buf + th_off); + th->seq = htonl(seq); + th->check = csum_long(tsum_seed + htons(sh_len + p_len)); + if (segment != sh->gso_segs - 1) { + th->fin = 0; + th->psh = 0; + } + + /* Skip past the header. */ + slot++; + + /* Skip past the payload. */ + while (p_used < p_len) { + + /* Advance as needed. */ + while (f_used >= f_size) { + f_id++; + f_size = sh->frags[f_id].size; + f_used = 0; + } + + /* Use bytes from the current fragment. */ + n = p_len - p_used; + if (n > f_size - f_used) + n = f_size - f_used; + f_used += n; + p_used += n; + + slot++; + } + + id++; + seq += p_len; + + /* The last segment may be less than gso_size. */ + data_len -= p_len; + if (data_len < p_len) + p_len = data_len; + } + + /* Flush the headers so they are ready for hardware DMA. */ + wmb(); +} + +/* Pass all the data to mpipe for egress. */ +static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, + struct sk_buff *skb, unsigned char *headers, s64 slot) +{ + struct tile_net_priv *priv = netdev_priv(dev); + struct skb_shared_info *sh = skb_shinfo(skb); + unsigned int data_len = skb->data_len; + unsigned int p_len = sh->gso_size; + gxio_mpipe_edesc_t edesc_head = { { 0 } }; + gxio_mpipe_edesc_t edesc_body = { { 0 } }; + long f_id = -1; /* id of the current fragment */ + long f_size = -1; /* size of the current fragment */ + long f_used = -1; /* bytes used from the current fragment */ + long n; /* size of the current piece of payload */ + unsigned long tx_packets = 0, tx_bytes = 0; + unsigned int csum_start, sh_len; + int segment; + + /* Prepare to egress the headers: set up header edesc. */ + csum_start = skb_checksum_start_offset(skb); + sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); + edesc_head.csum = 1; + edesc_head.csum_start = csum_start; + edesc_head.csum_dest = csum_start + skb->csum_offset; + edesc_head.xfer_size = sh_len; + + /* This is only used to specify the TLB. */ + edesc_head.stack_idx = large_buffer_stack; + edesc_body.stack_idx = large_buffer_stack; + + /* Egress all the edescs. */ + for (segment = 0; segment < sh->gso_segs; segment++) { + void *va; + unsigned char *buf; + unsigned int p_used = 0; + + /* Egress the header. */ + buf = headers + (slot % EQUEUE_ENTRIES) * HEADER_BYTES + + NET_IP_ALIGN; + edesc_head.va = va_to_tile_io_addr(buf); + gxio_mpipe_equeue_put_at(equeue, edesc_head, slot); + slot++; + + /* Egress the payload. */ + while (p_used < p_len) { + + /* Advance as needed. */ + while (f_used >= f_size) { + f_id++; + f_size = sh->frags[f_id].size; + f_used = 0; + } + + va = tile_net_frag_buf(&sh->frags[f_id]) + f_used; + + /* Use bytes from the current fragment. */ + n = p_len - p_used; + if (n > f_size - f_used) + n = f_size - f_used; + f_used += n; + p_used += n; + + /* Egress a piece of the payload. */ + edesc_body.va = va_to_tile_io_addr(va); + edesc_body.xfer_size = n; + edesc_body.bound = !(p_used < p_len); + gxio_mpipe_equeue_put_at(equeue, edesc_body, slot); + slot++; + } + + tx_packets++; + tx_bytes += sh_len + p_len; + + /* The last segment may be less than gso_size. */ + data_len -= p_len; + if (data_len < p_len) + p_len = data_len; + } + + /* Update stats. */ + tile_net_stats_add(tx_packets, &priv->stats.tx_packets); + tile_net_stats_add(tx_bytes, &priv->stats.tx_bytes); +} + +/* Do "TSO" handling for egress. + * + * Normally drivers set NETIF_F_TSO only to support hardware TSO; + * otherwise the stack uses scatter-gather to implement GSO in software. + * On our testing, enabling GSO support (via NETIF_F_SG) drops network + * performance down to around 7.5 Gbps on the 10G interfaces, although + * also dropping cpu utilization way down, to under 8%. But + * implementing "TSO" in the driver brings performance back up to line + * rate, while dropping cpu usage even further, to less than 4%. In + * practice, profiling of GSO shows that skb_segment() is what causes + * the performance overheads; we benefit in the driver from using + * preallocated memory to duplicate the TCP/IP headers. + */ +static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + struct tile_net_priv *priv = netdev_priv(dev); + int channel = priv->echannel; + struct tile_net_egress *egress = &egress_for_echannel[channel]; + struct tile_net_comps *comps = info->comps_for_echannel[channel]; + gxio_mpipe_equeue_t *equeue = egress->equeue; + unsigned long irqflags; + int num_edescs; + s64 slot; + + /* Determine how many mpipe edesc's are needed. */ + num_edescs = tso_count_edescs(skb); + + local_irq_save(irqflags); + + /* Try to acquire a completion entry and an egress slot. */ + slot = tile_net_equeue_try_reserve(dev, comps, equeue, num_edescs); + if (slot < 0) { + local_irq_restore(irqflags); + return NETDEV_TX_BUSY; + } + + /* Set up copies of header data properly. */ + tso_headers_prepare(skb, egress->headers, slot); + + /* Actually pass the data to the network hardware. */ + tso_egress(dev, equeue, skb, egress->headers, slot); + + /* Add a completion record. */ + add_comp(equeue, comps, slot + num_edescs - 1, skb); + + local_irq_restore(irqflags); + + /* Make sure the egress timer is scheduled. */ + tile_net_schedule_egress_timer(); + + return NETDEV_TX_OK; +} + +/* Analyze the body and frags for a transmit request. */ +static unsigned int tile_net_tx_frags(struct frag *frags, + struct sk_buff *skb, + void *b_data, unsigned int b_len) +{ + unsigned int i, n = 0; + + struct skb_shared_info *sh = skb_shinfo(skb); + + if (b_len != 0) { + frags[n].buf = b_data; + frags[n++].length = b_len; + } + + for (i = 0; i < sh->nr_frags; i++) { + skb_frag_t *f = &sh->frags[i]; + frags[n].buf = tile_net_frag_buf(f); + frags[n++].length = skb_frag_size(f); + } + + return n; +} + +/* Help the kernel transmit a packet. */ +static int tile_net_tx(struct sk_buff *skb, struct net_device *dev) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + struct tile_net_priv *priv = netdev_priv(dev); + struct tile_net_egress *egress = &egress_for_echannel[priv->echannel]; + gxio_mpipe_equeue_t *equeue = egress->equeue; + struct tile_net_comps *comps = + info->comps_for_echannel[priv->echannel]; + unsigned int len = skb->len; + unsigned char *data = skb->data; + unsigned int num_edescs; + struct frag frags[MAX_FRAGS]; + gxio_mpipe_edesc_t edescs[MAX_FRAGS]; + unsigned long irqflags; + gxio_mpipe_edesc_t edesc = { { 0 } }; + unsigned int i; + s64 slot; + + if (skb_is_gso(skb)) + return tile_net_tx_tso(skb, dev); + + num_edescs = tile_net_tx_frags(frags, skb, data, skb_headlen(skb)); + + /* This is only used to specify the TLB. */ + edesc.stack_idx = large_buffer_stack; + + /* Prepare the edescs. */ + for (i = 0; i < num_edescs; i++) { + edesc.xfer_size = frags[i].length; + edesc.va = va_to_tile_io_addr(frags[i].buf); + edescs[i] = edesc; + } + + /* Mark the final edesc. */ + edescs[num_edescs - 1].bound = 1; + + /* Add checksum info to the initial edesc, if needed. */ + if (skb->ip_summed == CHECKSUM_PARTIAL) { + unsigned int csum_start = skb_checksum_start_offset(skb); + edescs[0].csum = 1; + edescs[0].csum_start = csum_start; + edescs[0].csum_dest = csum_start + skb->csum_offset; + } + + local_irq_save(irqflags); + + /* Try to acquire a completion entry and an egress slot. */ + slot = tile_net_equeue_try_reserve(dev, comps, equeue, num_edescs); + if (slot < 0) { + local_irq_restore(irqflags); + return NETDEV_TX_BUSY; + } + + for (i = 0; i < num_edescs; i++) + gxio_mpipe_equeue_put_at(equeue, edescs[i], slot++); + + /* Add a completion record. */ + add_comp(equeue, comps, slot - 1, skb); + + /* NOTE: Use ETH_ZLEN for short packets (e.g. 42 < 60). */ + tile_net_stats_add(1, &priv->stats.tx_packets); + tile_net_stats_add(max_t(unsigned int, len, ETH_ZLEN), + &priv->stats.tx_bytes); + + local_irq_restore(irqflags); + + /* Make sure the egress timer is scheduled. */ + tile_net_schedule_egress_timer(); + + return NETDEV_TX_OK; +} + +/* Return subqueue id on this core (one per core). */ +static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb) +{ + return smp_processor_id(); +} + +/* Deal with a transmit timeout. */ +static void tile_net_tx_timeout(struct net_device *dev) +{ + int cpu; + + for_each_online_cpu(cpu) + netif_wake_subqueue(dev, cpu); +} + +/* Ioctl commands. */ +static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + return -EOPNOTSUPP; +} + +/* Get system network statistics for device. */ +static struct net_device_stats *tile_net_get_stats(struct net_device *dev) +{ + struct tile_net_priv *priv = netdev_priv(dev); + return &priv->stats; +} + +/* Change the MTU. */ +static int tile_net_change_mtu(struct net_device *dev, int new_mtu) +{ + if ((new_mtu < 68) || (new_mtu > 1500)) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + +/* Change the Ethernet address of the NIC. + * + * The hypervisor driver does not support changing MAC address. However, + * the hardware does not do anything with the MAC address, so the address + * which gets used on outgoing packets, and which is accepted on incoming + * packets, is completely up to us. + * + * Returns 0 on success, negative on failure. + */ +static int tile_net_set_mac_address(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EINVAL; + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + return 0; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +/* Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ +static void tile_net_netpoll(struct net_device *dev) +{ + disable_percpu_irq(ingress_irq); + tile_net_handle_ingress_irq(ingress_irq, NULL); + enable_percpu_irq(ingress_irq, 0); +} +#endif + +static const struct net_device_ops tile_net_ops = { + .ndo_open = tile_net_open, + .ndo_stop = tile_net_stop, + .ndo_start_xmit = tile_net_tx, + .ndo_select_queue = tile_net_select_queue, + .ndo_do_ioctl = tile_net_ioctl, + .ndo_get_stats = tile_net_get_stats, + .ndo_change_mtu = tile_net_change_mtu, + .ndo_tx_timeout = tile_net_tx_timeout, + .ndo_set_mac_address = tile_net_set_mac_address, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = tile_net_netpoll, +#endif +}; + +/* The setup function. + * + * This uses ether_setup() to assign various fields in dev, including + * setting IFF_BROADCAST and IFF_MULTICAST, then sets some extra fields. + */ +static void tile_net_setup(struct net_device *dev) +{ + ether_setup(dev); + dev->netdev_ops = &tile_net_ops; + dev->watchdog_timeo = TILE_NET_TIMEOUT; + dev->features |= NETIF_F_LLTX; + dev->features |= NETIF_F_HW_CSUM; + dev->features |= NETIF_F_SG; + dev->features |= NETIF_F_TSO; + dev->mtu = 1500; +} + +/* Allocate the device structure, register the device, and obtain the + * MAC address from the hypervisor. + */ +static void tile_net_dev_init(const char *name, const uint8_t *mac) +{ + int ret; + int i; + int nz_addr = 0; + struct net_device *dev; + struct tile_net_priv *priv; + + /* HACK: Ignore "loop" links. */ + if (strncmp(name, "loop", 4) == 0) + return; + + /* Allocate the device structure. Normally, "name" is a + * template, instantiated by register_netdev(), but not for us. + */ + dev = alloc_netdev_mqs(sizeof(*priv), name, tile_net_setup, + NR_CPUS, 1); + if (!dev) { + pr_err("alloc_netdev_mqs(%s) failed\n", name); + return; + } + + /* Initialize "priv". */ + priv = netdev_priv(dev); + memset(priv, 0, sizeof(*priv)); + priv->dev = dev; + priv->channel = -1; + priv->loopify_channel = -1; + priv->echannel = -1; + + /* Get the MAC address and set it in the device struct; this must + * be done before the device is opened. If the MAC is all zeroes, + * we use a random address, since we're probably on the simulator. + */ + for (i = 0; i < 6; i++) + nz_addr |= mac[i]; + + if (nz_addr) { + memcpy(dev->dev_addr, mac, 6); + dev->addr_len = 6; + } else { + random_ether_addr(dev->dev_addr); + } + + /* Register the network device. */ + ret = register_netdev(dev); + if (ret) { + netdev_err(dev, "register_netdev failed %d\n", ret); + free_netdev(dev); + return; + } +} + +/* Per-cpu module initialization. */ +static void tile_net_init_module_percpu(void *unused) +{ + struct tile_net_info *info = &__get_cpu_var(per_cpu_info); + int my_cpu = smp_processor_id(); + + info->has_iqueue = false; + + info->my_cpu = my_cpu; + + /* Initialize the egress timer. */ + hrtimer_init(&info->egress_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + info->egress_timer.function = tile_net_handle_egress_timer; +} + +/* Module initialization. */ +static int __init tile_net_init_module(void) +{ + int i; + char name[GXIO_MPIPE_LINK_NAME_LEN]; + uint8_t mac[6]; + + pr_info("Tilera Network Driver\n"); + + mutex_init(&tile_net_devs_for_channel_mutex); + + /* Initialize each CPU. */ + on_each_cpu(tile_net_init_module_percpu, NULL, 1); + + /* Find out what devices we have, and initialize them. */ + for (i = 0; gxio_mpipe_link_enumerate_mac(i, name, mac) >= 0; i++) + tile_net_dev_init(name, mac); + + if (!network_cpus_init()) + network_cpus_map = *cpu_online_mask; + + return 0; +} + +module_init(tile_net_init_module); -- cgit v1.1 From 08224262adefb5e6460888b2490a96e1bc28aef5 Mon Sep 17 00:00:00 2001 From: Bart Westgeest Date: Mon, 11 Jun 2012 12:13:08 -0400 Subject: staging: usbip: bugfix for stack corruption on 64-bit architectures Previously a 6 byte array (buf) was erroneously cast to a 8 byte long (event_bits) on 64-bit architectures which caused a stack corruption. Signed-off-by: Bart Westgeest Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index f708cba..117a7ad 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -205,7 +205,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) int retval = 0; /* the enough buffer is allocated according to USB_MAXCHILDREN */ - unsigned long *event_bits = (unsigned long *) buf; + u32 *event_bits = (unsigned long *) buf; int rhport; int changed = 0; -- cgit v1.1 From c475c06f4bb689d6ad87d7512e036d6dface3160 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Tue, 12 Jun 2012 08:27:04 +0800 Subject: hwrng: atmel-rng - fix data valid check Brown paper bag: Data valid is LSB of the ISR (status register), and NOT of ODATA (current random data word)! With this, rngtest is a lot happier. Before: rngtest 3 Copyright (c) 2004 by Henrique de Moraes Holschuh This is free software; see the source for copying conditions. There is NO warr. rngtest: starting FIPS tests... rngtest: bits received from input: 20000032 rngtest: FIPS 140-2 successes: 3 rngtest: FIPS 140-2 failures: 997 rngtest: FIPS 140-2(2001-10-10) Monobit: 604 rngtest: FIPS 140-2(2001-10-10) Poker: 996 rngtest: FIPS 140-2(2001-10-10) Runs: 36 rngtest: FIPS 140-2(2001-10-10) Long run: 0 rngtest: FIPS 140-2(2001-10-10) Continuous run: 117 rngtest: input channel speed: (min=622.371; avg=23682.481; max=28224.350)Kibitss rngtest: FIPS tests speed: (min=12.361; avg=12.718; max=12.861)Mibits/s rngtest: Program run time: 2331696 microsecondsx After: rngtest 3 Copyright (c) 2004 by Henrique de Moraes Holschuh This is free software; see the source for copying conditions. There is NO warr. rngtest: starting FIPS tests... rngtest: bits received from input: 20000032 rngtest: FIPS 140-2 successes: 999 rngtest: FIPS 140-2 failures: 1 rngtest: FIPS 140-2(2001-10-10) Monobit: 0 rngtest: FIPS 140-2(2001-10-10) Poker: 0 rngtest: FIPS 140-2(2001-10-10) Runs: 1 rngtest: FIPS 140-2(2001-10-10) Long run: 0 rngtest: FIPS 140-2(2001-10-10) Continuous run: 0 rngtest: input channel speed: (min=777.363; avg=43588.270; max=47870.711)Kibitss rngtest: FIPS tests speed: (min=11.943; avg=12.716; max=12.844)Mibits/s rngtest: Program run time: 1955282 microseconds Cc: stable@vger.kernel.org Signed-off-by: Peter Korsgaard Reported-by: George Pontis Acked-by: Nicolas Ferre Signed-off-by: Herbert Xu --- drivers/char/hw_random/atmel-rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 6289f0e..731c904 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -34,7 +34,7 @@ static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max, u32 *data = buf; /* data ready? */ - if (readl(trng->base + TRNG_ODATA) & 1) { + if (readl(trng->base + TRNG_ISR) & 1) { *data = readl(trng->base + TRNG_ODATA); /* ensure data ready is only set again AFTER the next data -- cgit v1.1 From 6c4ae5c2e7bfbb7d10d73611f69ac8a8609d84fd Mon Sep 17 00:00:00 2001 From: Giancarlo Formicuccia Date: Sun, 10 Jun 2012 08:33:11 +0200 Subject: Bluetooth: add support for atheros 0930:0219 Add support for the AR3012 chip found on the Toshiba Sallite M840-1000-XQ. usb-devices shows: T: Bus=01 Lev=02 Prnt=02 Port=02 Cnt=01 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0930 ProdID=0219 Rev=00.02 S: Manufacturer=Atheros Communications S: Product=Bluetooth USB Host Controller S: SerialNumber=Alaska Day 2006 C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb Signed-off-by: Giancarlo Formicuccia Signed-off-by: Gustavo Padovan --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index f0f6202..10308cd 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -78,6 +78,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x0CF3, 0xE004) }, + { USB_DEVICE(0x0930, 0x0219) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -102,6 +103,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ff3eabc..83ebb24 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -140,6 +140,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, -- cgit v1.1 From 3fbd8716da4c69ddbb76c022f3f4a0d50723c68f Mon Sep 17 00:00:00 2001 From: Rafal Prylowski Date: Mon, 28 May 2012 23:35:54 +0800 Subject: leds: don't disable blinking when writing the same value to delay_on or delay_off Function led_set_software_blink() assumes that blink timer is still running, but commit 488bc35bf40df89d37486c1826b178a2fba36ce7 introduced disabling of blink timer before each call to led_set_software_blink(). Correct led_software_blink(): 1) remove protection against reprogramming blink timer to the same values, because it only disables blinking now, 2) remove unnecessary call to led_stop_software_blink(). Signed-off-by: Rafal Prylowski Cc: Richard Purdie Signed-off-by: Bryan Wu --- drivers/leds/led-core.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index d686004..d65353d 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -44,13 +44,6 @@ static void led_set_software_blink(struct led_classdev *led_cdev, if (!led_cdev->blink_brightness) led_cdev->blink_brightness = led_cdev->max_brightness; - if (led_get_trigger_data(led_cdev) && - delay_on == led_cdev->blink_delay_on && - delay_off == led_cdev->blink_delay_off) - return; - - led_stop_software_blink(led_cdev); - led_cdev->blink_delay_on = delay_on; led_cdev->blink_delay_off = delay_off; -- cgit v1.1 From 9cd5ec5e5447f99ffb33ce39c1fcd0e3306e11d1 Mon Sep 17 00:00:00 2001 From: Jeffrin Jose Date: Sun, 3 Jun 2012 20:11:52 +0800 Subject: leds: fixed a coding style issue. Fixed a coding style issue relating to trailing white space error found by checkpatch.pl tool in drivers/leds/led-class.c Signed-off-by: Jeffrin Jose Signed-off-by: Bryan Wu --- drivers/leds/led-class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 8ee92c8..e663e6f 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -29,7 +29,7 @@ static void led_update_brightness(struct led_classdev *led_cdev) led_cdev->brightness = led_cdev->brightness_get(led_cdev); } -static ssize_t led_brightness_show(struct device *dev, +static ssize_t led_brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); -- cgit v1.1 From 9473c4c16700ec965904f23234fd0f8677ce6231 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 9 Jun 2012 07:41:42 +0800 Subject: leds: Make LEDS_ASIC3 and LEDS_RENESAS_TPU depend on LEDS_CLASS=y Otherwise, I got below build error when CONFIG_LEDS_CLASS=m. LD init/built-in.o drivers/built-in.o: In function `asic3_led_probe': clkdev.c:(.devinit.text+0x4680): undefined reference to `led_classdev_register' drivers/built-in.o: In function `r_tpu_probe': clkdev.c:(.devinit.text+0x4838): undefined reference to `led_classdev_register' drivers/built-in.o: In function `asic3_led_remove': clkdev.c:(.devexit.text+0x564): undefined reference to `led_classdev_unregister' drivers/built-in.o: In function `r_tpu_remove': clkdev.c:(.devexit.text+0x5a0): undefined reference to `led_classdev_unregister' make: *** [vmlinux] Error 1 Signed-off-by: Axel Lin Signed-off-by: Bryan Wu --- drivers/leds/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 04cb8c8..12b2b55 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -379,7 +379,7 @@ config LEDS_NETXBIG config LEDS_ASIC3 bool "LED support for the HTC ASIC3" - depends on LEDS_CLASS + depends on LEDS_CLASS=y depends on MFD_ASIC3 default y help @@ -390,7 +390,7 @@ config LEDS_ASIC3 config LEDS_RENESAS_TPU bool "LED support for Renesas TPU" - depends on LEDS_CLASS && HAVE_CLK && GENERIC_GPIO + depends on LEDS_CLASS=y && HAVE_CLK && GENERIC_GPIO help This option enables build of the LED TPU platform driver, suitable to drive any TPU channel on newer Renesas SoCs. -- cgit v1.1 From 34ddeb035d704eafdcdb3cbc781894300136c3c4 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 12 Jun 2012 11:20:19 +0800 Subject: ACPI, APEI, Avoid too much error reporting in runtime This patch fixed the following bug. https://bugzilla.kernel.org/show_bug.cgi?id=43282 This is caused by a firmware bug checking (checking generic address register provided by firmware) in runtime. The checking should be done in address mapping time instead of runtime to avoid too much error reporting in runtime. Reported-by: Pawel Sikora Signed-off-by: Huang Ying Tested-by: Jean Delvare Cc: stable@vger.kernel.org Signed-off-by: Len Brown --- drivers/acpi/apei/apei-base.c | 17 +++++++++++++++-- drivers/acpi/apei/apei-internal.h | 9 +++++++++ drivers/acpi/apei/ghes.c | 6 +++--- 3 files changed, 27 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 5577762..6686b1e 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -243,7 +243,7 @@ static int pre_map_gar_callback(struct apei_exec_context *ctx, u8 ins = entry->instruction; if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) - return acpi_os_map_generic_address(&entry->register_region); + return apei_map_generic_address(&entry->register_region); return 0; } @@ -276,7 +276,7 @@ static int post_unmap_gar_callback(struct apei_exec_context *ctx, u8 ins = entry->instruction; if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) - acpi_os_unmap_generic_address(&entry->register_region); + apei_unmap_generic_address(&entry->register_region); return 0; } @@ -606,6 +606,19 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, return 0; } +int apei_map_generic_address(struct acpi_generic_address *reg) +{ + int rc; + u32 access_bit_width; + u64 address; + + rc = apei_check_gar(reg, &address, &access_bit_width); + if (rc) + return rc; + return acpi_os_map_generic_address(reg); +} +EXPORT_SYMBOL_GPL(apei_map_generic_address); + /* read GAR in interrupt (including NMI) or process context */ int apei_read(u64 *val, struct acpi_generic_address *reg) { diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index cca240a..f220d64 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h @@ -7,6 +7,8 @@ #define APEI_INTERNAL_H #include +#include +#include struct apei_exec_context; @@ -68,6 +70,13 @@ static inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 actio /* IP has been set in instruction function */ #define APEI_EXEC_SET_IP 1 +int apei_map_generic_address(struct acpi_generic_address *reg); + +static inline void apei_unmap_generic_address(struct acpi_generic_address *reg) +{ + acpi_os_unmap_generic_address(reg); +} + int apei_read(u64 *val, struct acpi_generic_address *reg); int apei_write(u64 val, struct acpi_generic_address *reg); diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 9b3cac0..1599566 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -301,7 +301,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) if (!ghes) return ERR_PTR(-ENOMEM); ghes->generic = generic; - rc = acpi_os_map_generic_address(&generic->error_status_address); + rc = apei_map_generic_address(&generic->error_status_address); if (rc) goto err_free; error_block_length = generic->error_block_length; @@ -321,7 +321,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) return ghes; err_unmap: - acpi_os_unmap_generic_address(&generic->error_status_address); + apei_unmap_generic_address(&generic->error_status_address); err_free: kfree(ghes); return ERR_PTR(rc); @@ -330,7 +330,7 @@ err_free: static void ghes_fini(struct ghes *ghes) { kfree(ghes->estatus); - acpi_os_unmap_generic_address(&ghes->generic->error_status_address); + apei_unmap_generic_address(&ghes->generic->error_status_address); } enum { -- cgit v1.1 From 2347fc440558993013e8132791c409239da4fc0d Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Sun, 10 Jun 2012 16:15:17 -0400 Subject: usb: gadget: Complete fsl qe/udc driver conversion commit ec39e2ae (usb: gadget: Update fsl_qe_udc to use usb_endpoint_descriptor inside the struct usb_ep) did not completely convert the fsl gadget drivers to use the desc in usb_ep as described in commit messages. Fix the macros that were still referencing the old pointer. Signed-off-by: Ben Collins Cc: Ido Shayevitz [ balbi@ti.com : brush up commit log a bit ] Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_qe_udc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/fsl_qe_udc.h index 4c07ca9..7026919 100644 --- a/drivers/usb/gadget/fsl_qe_udc.h +++ b/drivers/usb/gadget/fsl_qe_udc.h @@ -153,10 +153,10 @@ struct usb_ep_para{ #define USB_BUSMODE_DTB 0x02 /* Endpoint basic handle */ -#define ep_index(EP) ((EP)->desc->bEndpointAddress & 0xF) +#define ep_index(EP) ((EP)->ep.desc->bEndpointAddress & 0xF) #define ep_maxpacket(EP) ((EP)->ep.maxpacket) #define ep_is_in(EP) ((ep_index(EP) == 0) ? (EP->udc->ep0_dir == \ - USB_DIR_IN) : ((EP)->desc->bEndpointAddress \ + USB_DIR_IN) : ((EP)->ep.desc->bEndpointAddress \ & USB_DIR_IN) == USB_DIR_IN) /* ep0 transfer state */ -- cgit v1.1 From efec381ced2c0416c3765abce076896cf464dc0c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 6 Jun 2012 22:50:41 +0200 Subject: pinctrl: nomadik: add clk_prepare() call We now strictly require clk_prepare() calls to be issued before any clk_enable() calls. Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index b26395d..ba7122f 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1246,6 +1246,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) ret = PTR_ERR(clk); goto out_unmap; } + clk_prepare(clk); nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); if (!nmk_chip) { -- cgit v1.1 From e85bbc19d5a9ad2b48bf8f2fd3277d6fe58f23ce Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 12 Jun 2012 12:43:06 +0200 Subject: pinctrl: nomadik: fix up typo Commit a60b57eddaa8af6c02cf7bbeb58ebf82881f08ac "drivers/gpio: gpio-nomadik: Add support for irqdomains" changed GPIO offset calculations to have this form: (gpio % NMK_GPIO_PER_CHIP) except in this one place for setting sleep mode, where the conversion was all wrong, and instead mod:ing the GPIO with the IRQ base which does not make any sense. So fix this up so we can use sleepmode. Reviewed-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index ba7122f..e8937e7 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -673,7 +673,7 @@ static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, * wakeup is anyhow controlled by the RIMSC and FIMSC registers. */ if (nmk_chip->sleepmode && on) { - __nmk_gpio_set_slpm(nmk_chip, gpio % nmk_chip->chip.base, + __nmk_gpio_set_slpm(nmk_chip, gpio % NMK_GPIO_PER_CHIP, NMK_GPIO_SLPM_WAKEUP_ENABLE); } -- cgit v1.1 From 3a86a5f8abb33956446ae31b1e9c149d7b2d1d21 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 9 Jun 2012 00:52:11 +0530 Subject: pinctrl: pinctrl-imx: free allocated pinctrl_map structure only once and use kernel facilities for IMX_PMX_DUMP a) as we allocate the pinctrl_map structure at imx_dt_node_to_map at line 167, anyway if its an element, or a num_elements * (sizeof(type)) elements allocated to one single pointer must be freed only once. CASE. A) as new_map is not moved and allocated like, for (i = 0; i < MAX_ELEMS; i++) { new_map[i] = kmalloc(numelems * size, GFP_KERNEL); } its freed as for (i = 0; i < MAX_ELEMS; i++) { kfree(new_map[i]); } CASE. B) and its allocated like new_map = kmalloc(numelems * size, GFP_KERNEL); it just needs kfree not as case A's. b) use KERN_DEBUG facility for the IMX_PMX_DUMP macro. Signed-off-by: Devendra Naga Acked-by: Dong Aisheng Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-imx.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c index f6e7c67..09f3a30 100644 --- a/drivers/pinctrl/pinctrl-imx.c +++ b/drivers/pinctrl/pinctrl-imx.c @@ -27,16 +27,16 @@ #include "core.h" #include "pinctrl-imx.h" -#define IMX_PMX_DUMP(info, p, m, c, n) \ -{ \ - int i, j; \ - printk("Format: Pin Mux Config\n"); \ - for (i = 0; i < n; i++) { \ - j = p[i]; \ - printk("%s %d 0x%lx\n", \ - info->pins[j].name, \ - m[i], c[i]); \ - } \ +#define IMX_PMX_DUMP(info, p, m, c, n) \ +{ \ + int i, j; \ + printk(KERN_DEBUG "Format: Pin Mux Config\n"); \ + for (i = 0; i < n; i++) { \ + j = p[i]; \ + printk(KERN_DEBUG "%s %d 0x%lx\n", \ + info->pins[j].name, \ + m[i], c[i]); \ + } \ } /* The bits in CONFIG cell defined in binding doc*/ @@ -201,10 +201,7 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, static void imx_dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map, unsigned num_maps) { - int i; - - for (i = 0; i < num_maps; i++) - kfree(map); + kfree(map); } static struct pinctrl_ops imx_pctrl_ops = { @@ -475,9 +472,8 @@ static int __devinit imx_pinctrl_parse_groups(struct device_node *np, grp->configs[j] = config & ~IMX_PAD_SION; } -#ifdef DEBUG IMX_PMX_DUMP(info, grp->pins, grp->mux_mode, grp->configs, grp->npins); -#endif + return 0; } -- cgit v1.1 From c71157c54a4f86e4f355dc6952268e8536013502 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 7 Jun 2012 22:19:26 +0530 Subject: pinctrl: pinctrl-imx: free if of_get_parent fails to get the parent node of_get_parent can return null if no parent node found, so the allocated new_map should be freed. Signed-off-by: Devendra Naga Acked-by: Dong Aisheng Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-imx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c index 09f3a30..542b01b 100644 --- a/drivers/pinctrl/pinctrl-imx.c +++ b/drivers/pinctrl/pinctrl-imx.c @@ -173,8 +173,10 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, /* create mux map */ parent = of_get_parent(np); - if (!parent) + if (!parent) { + kfree(new_map); return -EINVAL; + } new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; new_map[0].data.mux.function = parent->name; new_map[0].data.mux.group = np->name; -- cgit v1.1 From 67695f2eae210b0631fb92cf5649d0454953e230 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Fri, 8 Jun 2012 21:33:12 +0800 Subject: pinctrl: pinctrl-imx: fix incorrect debug message of maps After create config map, the new_map pointer becomes point to PIN_MAP_TYPE_CONFIGS_PIN map rather than PIN_MAP_TYPE_MUX_GROUP map any more. Thus using new_map pointer to display the MUX_GROUP info is not correct. Using map pointer instead to show the correct MUX_GROUP map info. Original the debug message is: imx6q-pinctrl 20e0000.iomuxc: maps: function Yp group MX6Q_PAD_SD3_CMD num 12 After fix it is: imx6q-pinctrl 20e0000.iomuxc: maps: function usdhc3 group usdhc3grp-1 num 11 Reported-by: Richard Zhao Signed-off-by: Dong Aisheng Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c index 542b01b..dd6d93a 100644 --- a/drivers/pinctrl/pinctrl-imx.c +++ b/drivers/pinctrl/pinctrl-imx.c @@ -195,7 +195,7 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, } dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", - new_map->data.mux.function, new_map->data.mux.group, map_num); + (*map)->data.mux.function, (*map)->data.mux.group, map_num); return 0; } -- cgit v1.1 From 0bf7481852c8ece4888c299ba0259b789c3dbde3 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 9 Jun 2012 17:31:23 +0530 Subject: pinctrl: pinctrl-mxs: Take care of frees if the kzalloc fails if there is no purecfg , the group pointer is allocated using kzalloc and if it fails to allocate, we wont free the new_map, if config is true, we call kmemdup and if it fails to do so we wont free the allocated group if there is no purecfg. fix this by doing the frees of new_map pointer and group pointers. Acked-by: Dong Aisheng Signed-off-by: Devendra Naga Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-mxs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index 556e45a..9d46303 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -107,8 +107,10 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, /* Compose group name */ group = kzalloc(length, GFP_KERNEL); - if (!group) - return -ENOMEM; + if (!group) { + ret = -ENOMEM; + goto free; + } snprintf(group, length, "%s.%d", np->name, reg); new_map[i].data.mux.group = group; i++; @@ -118,7 +120,7 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, pconfig = kmemdup(&config, sizeof(config), GFP_KERNEL); if (!pconfig) { ret = -ENOMEM; - goto free; + goto free_group; } new_map[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; @@ -133,6 +135,9 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; +free_group: + if (!purecfg) + free(group); free: kfree(new_map); return ret; -- cgit v1.1 From 149ff9e1f240e7b57a02e0be5f74f21d0307d1d3 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 9 Jun 2012 17:32:31 +0530 Subject: pinctrl: pinctrl-mxs: set platform driver data to NULL at errpath and at unregister clear the platform data pointer when mxs_pinctrl_probe_dt fails, and also before the unregistering with pinctrl subsystem. Signed-off-by: Devendra Naga Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-mxs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index 9d46303..afb50ee 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -516,6 +516,7 @@ int __devinit mxs_pinctrl_probe(struct platform_device *pdev, return 0; err: + platform_set_drvdata(pdev, NULL); iounmap(d->base); return ret; } @@ -525,6 +526,7 @@ int __devexit mxs_pinctrl_remove(struct platform_device *pdev) { struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); + platform_set_drvdata(pdev, NULL); pinctrl_unregister(d->pctl); iounmap(d->base); -- cgit v1.1 From a393c730ab69617c3291a3b0b2a228c9be2fc28c Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 12 Jun 2012 13:28:42 +0200 Subject: drm/ttm: Fix buffer object metadata accounting regression v2 A regression was introduced in the 3.3 rc series, commit "drm/ttm: simplify memory accounting for ttm user v2", causing the metadata of buffer objects created using the ttm_bo_create() function to be accounted twice. That causes massive leaks with the vmwgfx driver running for example SpecViewperf Catia-03 test 2, eventually killing the app. Furthermore, the same commit introduces a regression where metadata accounting is leaked if a buffer object is initialized with an illegal size. This is also fixed with this commit. v2: Fixed an error path and removed an unused variable. Signed-off-by: Thomas Hellstrom Reviewed-by: Konrad Rzeszutek Wilk Cc: Jerome Glisse Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index b67cfca..36f4b28 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1204,6 +1204,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, (*destroy)(bo); else kfree(bo); + ttm_mem_global_free(mem_glob, acc_size); return -EINVAL; } bo->destroy = destroy; @@ -1307,22 +1308,14 @@ int ttm_bo_create(struct ttm_bo_device *bdev, struct ttm_buffer_object **p_bo) { struct ttm_buffer_object *bo; - struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; size_t acc_size; int ret; - acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct ttm_buffer_object)); - ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); - if (unlikely(ret != 0)) - return ret; - bo = kzalloc(sizeof(*bo), GFP_KERNEL); - - if (unlikely(bo == NULL)) { - ttm_mem_global_free(mem_glob, acc_size); + if (unlikely(bo == NULL)) return -ENOMEM; - } + acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct ttm_buffer_object)); ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment, buffer_start, interruptible, persistent_swap_storage, acc_size, NULL, NULL); -- cgit v1.1 From 1b8487368bb0acedf23e226974b63aaaf2bfddbd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 12 Jun 2012 11:10:50 -0700 Subject: Revert "staging: usbip: bugfix for stack corruption on 64-bit architectures" This reverts commit 08224262adefb5e6460888b2490a96e1bc28aef5 as it's just not right. Reported-by: Ben Hutchings Cc: stable Cc: Bart Westgeest Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 117a7ad..f708cba 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -205,7 +205,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) int retval = 0; /* the enough buffer is allocated according to USB_MAXCHILDREN */ - u32 *event_bits = (unsigned long *) buf; + unsigned long *event_bits = (unsigned long *) buf; int rhport; int changed = 0; -- cgit v1.1 From 33735a94afdfb39c550b952a40f77c60afdddfa5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Jun 2012 15:09:21 +0200 Subject: staging:iio:ad7298: Fix linker error due to missing IIO kfifo buffer The ad7298 drivers buffer implementation uses the IIO kfifo buffer, so it needs to select IIO_KFIFO_BUF. Otherwise (if no other driver selects the symbol) the following linker error will occur: drivers/built-in.o: In function `ad7298_register_ring_funcs_and_init': (.text+0x245cf2): undefined reference to `iio_kfifo_allocate' drivers/built-in.o: In function `ad7298_register_ring_funcs_and_init': (.text+0x245d7d): undefined reference to `iio_kfifo_free' drivers/built-in.o: In function `ad7298_ring_cleanup': (.text+0x245dcd): undefined reference to `iio_kfifo_free' Signed-off-by: Lars-Peter Clausen Reported-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 2490dd2..8f1b3af 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -13,6 +13,7 @@ config AD7291 config AD7298 tristate "Analog Devices AD7298 ADC driver" depends on SPI + select IIO_KFIFO_BUF if IIO_BUFFER help Say yes here to build support for Analog Devices AD7298 8 Channel ADC with temperature sensor. -- cgit v1.1 From 6ddcd46463aa66855f1f8e74de454740a5f4aef4 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Mon, 11 Jun 2012 18:13:57 -0700 Subject: mwifiex: fix incorrect privacy setting in beacon and probe response Test procedure: 1. Start AP with security setting (e.g. WPA2) 2. Stop AP 3. Start AP with open security Here it's observed that privacy is enabled in beacons and probe responses. This patch fixes it by checking the privacy parameter from cfg80211_ap_settings. If privacy is not set in cfg80211_ap_settings, set open authentication and no encryption in FW. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/uap_cmd.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 8173ab6..89f9a2a 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -27,6 +27,17 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, struct cfg80211_ap_settings *params) { int i; + if (!params->privacy) { + bss_config->protocol = PROTOCOL_NO_SECURITY; + bss_config->key_mgmt = KEY_MGMT_NONE; + bss_config->wpa_cfg.length = 0; + priv->sec_info.wep_enabled = 0; + priv->sec_info.wpa_enabled = 0; + priv->sec_info.wpa2_enabled = 0; + + return 0; + } + switch (params->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: bss_config->auth_mode = WLAN_AUTH_OPEN; -- cgit v1.1 From 8a93664df90db983cfede122f9b4ddb3a8284e52 Mon Sep 17 00:00:00 2001 From: Weiping Pan Date: Sun, 10 Jun 2012 23:00:20 +0000 Subject: bonding:record primary when modify it via sysfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we modify primary via sysfs and it is not a valid slave, we should record it for future use, and this behavior is the same with bond_check_params(). Signed-off-by: Weiping Pan Acked-by: Nicolas de Pesloüan Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_sysfs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index aef42f0..485bedb 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1082,8 +1082,12 @@ static ssize_t bonding_store_primary(struct device *d, } } - pr_info("%s: Unable to set %.*s as primary slave.\n", - bond->dev->name, (int)strlen(buf) - 1, buf); + strncpy(bond->params.primary, ifname, IFNAMSIZ); + bond->params.primary[IFNAMSIZ - 1] = 0; + + pr_info("%s: Recording %s as primary, " + "but it has not been enslaved to %s yet.\n", + bond->dev->name, ifname, bond->dev->name); out: write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); -- cgit v1.1 From 5ee31c6898ea5537fcea160999d60dc63bc0c305 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 12 Jun 2012 06:03:51 +0000 Subject: bonding: Fix corrupted queue_mapping In the transmit path of the bonding driver, skb->cb is used to stash the skb->queue_mapping so that the bonding device can set its own queue mapping. This value becomes corrupted since the skb->cb is also used in __dev_xmit_skb. When transmitting through bonding driver, bond_select_queue is called from dev_queue_xmit. In bond_select_queue the original skb->queue_mapping is copied into skb->cb (via bond_queue_mapping) and skb->queue_mapping is overwritten with the bond driver queue. Subsequently in dev_queue_xmit, __dev_xmit_skb is called which writes the packet length into skb->cb, thereby overwriting the stashed queue mappping. In bond_dev_queue_xmit (called from hard_start_xmit), the queue mapping for the skb is set to the stashed value which is now the skb length and hence is an invalid queue for the slave device. If we want to save skb->queue_mapping into skb->cb[], best place is to add a field in struct qdisc_skb_cb, to make sure it wont conflict with other layers (eg : Qdiscc, Infiniband...) This patchs also makes sure (struct qdisc_skb_cb)->data is aligned on 8 bytes : netem qdisc for example assumes it can store an u64 in it, without misalignment penalty. Note : we only have 20 bytes left in (struct qdisc_skb_cb)->data[]. The largest user is CHOKe and it fills it. Based on a previous patch from Tom Herbert. Signed-off-by: Eric Dumazet Reported-by: Tom Herbert Cc: John Fastabend Cc: Roland Dreier Acked-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2ee8cf9..b9c2ae6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -76,6 +76,7 @@ #include #include #include +#include #include "bonding.h" #include "bond_3ad.h" #include "bond_alb.h" @@ -381,8 +382,6 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr) return next; } -#define bond_queue_mapping(skb) (*(u16 *)((skb)->cb)) - /** * bond_dev_queue_xmit - Prepare skb for xmit. * @@ -395,7 +394,9 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, { skb->dev = slave_dev; - skb->queue_mapping = bond_queue_mapping(skb); + BUILD_BUG_ON(sizeof(skb->queue_mapping) != + sizeof(qdisc_skb_cb(skb)->bond_queue_mapping)); + skb->queue_mapping = qdisc_skb_cb(skb)->bond_queue_mapping; if (unlikely(netpoll_tx_running(slave_dev))) bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); @@ -4171,7 +4172,7 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb) /* * Save the original txq to restore before passing to the driver */ - bond_queue_mapping(skb) = skb->queue_mapping; + qdisc_skb_cb(skb)->bond_queue_mapping = skb->queue_mapping; if (unlikely(txq >= dev->real_num_tx_queues)) { do { -- cgit v1.1 From 58bcd3322944f31c9a8b02694e221c645cf4ffd9 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 8 Jun 2012 18:51:23 -0700 Subject: serial: fix kernel-doc warnings in 8250.c Fix kernel-doc warnings in drivers/tty/serial/8250/8250.c: Warning(drivers/tty/serial/8250/8250.c:3128): No description found for parameter 'up' Warning(drivers/tty/serial/8250/8250.c:3128): Excess function parameter 'port' description in 'serial8250_register_8250_port' Signed-off-by: Randy Dunlap Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 47d061b..6e1958a 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -3113,7 +3113,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * /** * serial8250_register_8250_port - register a serial port - * @port: serial port template + * @up: serial port template * * Configure the serial port specified by the request. If the * port exists and is in use, it is hung up and unregistered -- cgit v1.1 From f109293f5889dd30477564a3ce2c901f4024a53e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 5 Jun 2012 09:46:07 -0700 Subject: serial: fix serial_txx9.c build warning/typo Fix kconfig symbol test to use "defined": drivers/tty/serial/serial_txx9.c: warning: "CONFIG_CONSOLE_POLL" is not defined [-Wundef] Reported-by: Geert Uytterhoeven Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_txx9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index 34bd345..6ae2a58 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -466,7 +466,7 @@ static void serial_txx9_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&up->port.lock, flags); } -#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || (CONFIG_CONSOLE_POLL) +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || defined(CONFIG_CONSOLE_POLL) /* * Wait for transmitter & holding register to empty */ -- cgit v1.1 From 78d80c5a720ea370defa3e3124c0f7f7179bdfe5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 23 May 2012 21:18:46 +0200 Subject: serial/amba-pl011: move custom pin control to driver We had a boot regression in Ux500 in the merge window because two orthogonal pin control schemes for the PL011 were merged at the same time: - One using the .init() and .exit() hooks into the platform for Ux500 putting the pins into default vs sleep state respectively as the port was started/stopped. commit a09806607fd20bed2f8c41fe22793386790a14aa "ARM: ux500: switch to using pinctrl for uart0" - One hogging the default setting at PL011 probe() commit 258e055111d3cde2607e0d04eb91da2f7a59b591 "serial: amba-pl011: adopt pinctrl support" To get a solution that works for both let's scrap the stuff in the platform callbacks, instead have the driver itself select default and sleep states when the port is started/stopped. Hopefully this works for all clients. Platform callbacks are bad for device tree migration anyway, so this rids us of another problem in Ux500. Cc: Shawn Guo Cc: Russell King Reported-by: Lee Jones Signed-off-by: Linus Walleij Tested-by: Shawn Guo Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 45 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 4ad721f..c17923e 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -133,6 +133,10 @@ struct pl011_dmatx_data { struct uart_amba_port { struct uart_port port; struct clk *clk; + /* Two optional pin states - default & sleep */ + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + struct pinctrl_state *pins_sleep; const struct vendor_data *vendor; unsigned int dmacr; /* dma control reg */ unsigned int im; /* interrupt mask */ @@ -1312,6 +1316,14 @@ static int pl011_startup(struct uart_port *port) unsigned int cr; int retval; + /* Optionaly enable pins to be muxed in and configured */ + if (!IS_ERR(uap->pins_default)) { + retval = pinctrl_select_state(uap->pinctrl, uap->pins_default); + if (retval) + dev_err(port->dev, + "could not set default pins\n"); + } + retval = clk_prepare(uap->clk); if (retval) goto out; @@ -1420,6 +1432,7 @@ static void pl011_shutdown(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; + int retval; /* * disable all interrupts @@ -1462,6 +1475,14 @@ static void pl011_shutdown(struct uart_port *port) */ clk_disable(uap->clk); clk_unprepare(uap->clk); + /* Optionally let pins go into sleep states */ + if (!IS_ERR(uap->pins_sleep)) { + retval = pinctrl_select_state(uap->pinctrl, uap->pins_sleep); + if (retval) + dev_err(port->dev, + "could not set pins to sleep state\n"); + } + if (uap->port.dev->platform_data) { struct amba_pl011_data *plat; @@ -1792,6 +1813,14 @@ static int __init pl011_console_setup(struct console *co, char *options) if (!uap) return -ENODEV; + /* Allow pins to be muxed in and configured */ + if (!IS_ERR(uap->pins_default)) { + ret = pinctrl_select_state(uap->pinctrl, uap->pins_default); + if (ret) + dev_err(uap->port.dev, + "could not set default pins\n"); + } + ret = clk_prepare(uap->clk); if (ret) return ret; @@ -1844,7 +1873,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) { struct uart_amba_port *uap; struct vendor_data *vendor = id->data; - struct pinctrl *pinctrl; void __iomem *base; int i, ret; @@ -1869,11 +1897,20 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) goto free; } - pinctrl = devm_pinctrl_get_select_default(&dev->dev); - if (IS_ERR(pinctrl)) { - ret = PTR_ERR(pinctrl); + uap->pinctrl = devm_pinctrl_get(&dev->dev); + if (IS_ERR(uap->pinctrl)) { + ret = PTR_ERR(uap->pinctrl); goto unmap; } + uap->pins_default = pinctrl_lookup_state(uap->pinctrl, + PINCTRL_STATE_DEFAULT); + if (IS_ERR(uap->pins_default)) + dev_err(&dev->dev, "could not get default pinstate\n"); + + uap->pins_sleep = pinctrl_lookup_state(uap->pinctrl, + PINCTRL_STATE_SLEEP); + if (IS_ERR(uap->pins_sleep)) + dev_dbg(&dev->dev, "could not get sleep pinstate\n"); uap->clk = clk_get(&dev->dev, NULL); if (IS_ERR(uap->clk)) { -- cgit v1.1 From e58c5de8f59d124907c993ea3126c69493b7eec7 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 12 Jun 2012 10:17:25 -0400 Subject: drivers/ide/ide-cs.c: adjust suspicious bit operation IO_DATA_PATH_WIDTH_8 is 0, so a bit-and with it is always false. The value IO_DATA_PATH_WIDTH covers the bits of the IO_DATA_PATH constants, so first pick those bits and then make the test using !=. This problem was found using Coccinelle (http://coccinelle.lip6.fr/). Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/ide/ide-cs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index 28e344e..f1e922e 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c @@ -167,7 +167,8 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data) { int *is_kme = priv_data; - if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) { + if ((pdev->resource[0]->flags & IO_DATA_PATH_WIDTH) + != IO_DATA_PATH_WIDTH_8) { pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; } -- cgit v1.1 From de102ef41f24a4c251c4a3838796bb27557d4d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Sat, 19 May 2012 19:19:48 +0200 Subject: USB: cdc-wdm: Add Vodafone/Huawei K5005 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested-by: Thomas Schäfer Signed-off-by: Bjørn Mork Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index ea8b304..8fd398d 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -55,6 +55,15 @@ static const struct usb_device_id wdm_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */ }, + { + /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | + USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 57, /* NOTE: CDC ECM control interface! */ + }, { } }; -- cgit v1.1 From 4cbbb039a9719fb3bba73d255c6a95bc6dc6428b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Sat, 19 May 2012 19:20:50 +0200 Subject: USB: option: Add Vodafone/Huawei K5005 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested-by: Thomas Schäfer Signed-off-by: Bjørn Mork Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 1aae902..f3e4a47 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -150,6 +150,7 @@ static void option_instat_callback(struct urb *urb); #define HUAWEI_PRODUCT_E14AC 0x14AC #define HUAWEI_PRODUCT_K3806 0x14AE #define HUAWEI_PRODUCT_K4605 0x14C6 +#define HUAWEI_PRODUCT_K5005 0x14C8 #define HUAWEI_PRODUCT_K3770 0x14C9 #define HUAWEI_PRODUCT_K3771 0x14CA #define HUAWEI_PRODUCT_K4510 0x14CB @@ -666,6 +667,9 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, -- cgit v1.1 From c41444ccfa33a1c20efa319e554cb531576e64a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Thu, 24 May 2012 11:19:04 +0200 Subject: USB: qcserial: Add Sierra Wireless device IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some additional IDs found in the BSD/GPL licensed out-of-tree GobiSerial driver from Sierra Wireless. Signed-off-by: Bjørn Mork Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcserial.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 0d5fe59..996015c 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -105,7 +105,13 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE(0x1410, 0xa021)}, /* Novatel Gobi 3000 Composite */ {USB_DEVICE(0x413c, 0x8193)}, /* Dell Gobi 3000 QDL */ {USB_DEVICE(0x413c, 0x8194)}, /* Dell Gobi 3000 Composite */ + {USB_DEVICE(0x1199, 0x9010)}, /* Sierra Wireless Gobi 3000 QDL */ + {USB_DEVICE(0x1199, 0x9012)}, /* Sierra Wireless Gobi 3000 QDL */ {USB_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ + {USB_DEVICE(0x1199, 0x9014)}, /* Sierra Wireless Gobi 3000 QDL */ + {USB_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ + {USB_DEVICE(0x1199, 0x9018)}, /* Sierra Wireless Gobi 3000 QDL */ + {USB_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ {USB_DEVICE(0x12D1, 0x14F0)}, /* Sony Gobi 3000 QDL */ {USB_DEVICE(0x12D1, 0x14F1)}, /* Sony Gobi 3000 Composite */ { } /* Terminating entry */ -- cgit v1.1 From e00a54d772210d450e5c1a801534c3c8a448549f Mon Sep 17 00:00:00 2001 From: Evan McNabb Date: Fri, 25 May 2012 22:46:14 -0400 Subject: USB: ftdi-sio: Add support for RT Systems USB-RTS01 serial adapter Add support for RT Systems USB-RTS01 USB to Serial adapter: http://www.rtsystemsinc.com/Photos/USBRTS01.html Tested by controlling Icom IC-718 amateur radio transceiver via hamlib. Signed-off-by: Evan McNabb Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8c084ea..bc912e5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -737,6 +737,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_RTS01_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index f3c7c78..5661c7e 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -784,6 +784,7 @@ #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ #define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */ #define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */ +#define RTSYSTEMS_RTS01_PID 0x9e57 /* USB-RTS01 Radio Cable */ /* -- cgit v1.1 From 5bbfa6f427c1d7244a5ee154ab8fa37265a5e049 Mon Sep 17 00:00:00 2001 From: Mikko Tuumanen Date: Fri, 1 Jun 2012 11:28:55 +0300 Subject: USB: serial: cp210x: add Optris MS Pro usb id Signed-off-by: Mikko Tuumanen Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 1b19262..73d25cd 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -82,6 +82,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ { USB_DEVICE(0x10C4, 0x806F) }, /* IMS USB to RS422 Converter Cable */ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ + { USB_DEVICE(0x10C4, 0x80C4) }, /* Cygnal Integrated Products, Inc., Optris infrared thermometer */ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ -- cgit v1.1 From 19a3dd1575e954e8c004413bee3e12d3962f2525 Mon Sep 17 00:00:00 2001 From: Tom Cassidy Date: Wed, 6 Jun 2012 17:08:48 +1000 Subject: USB: serial: sierra: Add support for Sierra Wireless AirCard 320U modem Add support for Sierra Wireless AirCard 320U modem Signed-off-by: Tomas Cassidy Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index ba54a0a..d423d36 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -294,6 +294,10 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, + /* AT&T Direct IP LTE modems */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), + .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist + }, { USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, -- cgit v1.1 From 42ca7da1c2363dbef4ba1b6917c4c02274b6a5e2 Mon Sep 17 00:00:00 2001 From: Andrew Bird Date: Mon, 28 May 2012 12:43:06 +0100 Subject: USB: option: Updated Huawei K4605 has better id Later firmwares for this device now have proper subclass and protocol info so we can identify it nicely without needing to use the blacklist. I'm not removing the old 0xff matching as there may be devices in the field that still need that. Signed-off-by: Andrew Bird Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f3e4a47..d9cb552 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -667,6 +667,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) }, -- cgit v1.1 From 1aa3c63cf0a79153ee13c8f82e4eb6c40b66a161 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 22 May 2012 20:45:13 +0100 Subject: USB: mct_u232: Fix incorrect TIOCMSET return The low level helper returns 1 on success. The ioctl should however return 0. As this is the only user of the helper return, make the helper return 0 or an error code. Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=43009 Signed-off-by: Alan Cox Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mct_u232.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index d0ec1aa..a71fa0a 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -309,13 +309,16 @@ static int mct_u232_set_modem_ctrl(struct usb_serial *serial, MCT_U232_SET_REQUEST_TYPE, 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE, WDR_TIMEOUT); - if (rc < 0) - dev_err(&serial->dev->dev, - "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); + kfree(buf); + dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); - kfree(buf); - return rc; + if (rc < 0) { + dev_err(&serial->dev->dev, + "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); + return rc; + } + return 0; } /* mct_u232_set_modem_ctrl */ static int mct_u232_get_modem_stat(struct usb_serial *serial, -- cgit v1.1 From 4273f9878b0a8271df055e3c8f2e7f08c6a4a2f4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 May 2012 17:57:52 +0200 Subject: USB: option: fix port-data abuse Commit 8b4c6a3ab596961b78465 ("USB: option: Use generic USB wwan code") moved option port-data allocation to usb_wwan_startup but still cast the port data to the old struct... Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d9cb552..9c2f7b2 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1265,35 +1265,6 @@ static struct usb_serial_driver * const serial_drivers[] = { static bool debug; -/* per port private data */ - -#define N_IN_URB 4 -#define N_OUT_URB 4 -#define IN_BUFLEN 4096 -#define OUT_BUFLEN 4096 - -struct option_port_private { - /* Input endpoints and buffer for this port */ - struct urb *in_urbs[N_IN_URB]; - u8 *in_buffer[N_IN_URB]; - /* Output endpoints and buffer for this port */ - struct urb *out_urbs[N_OUT_URB]; - u8 *out_buffer[N_OUT_URB]; - unsigned long out_busy; /* Bit vector of URBs in use */ - int opened; - struct usb_anchor delayed; - - /* Settings for the port */ - int rts_state; /* Handshaking pins (outputs) */ - int dtr_state; - int cts_state; /* Handshaking pins (inputs) */ - int dsr_state; - int dcd_state; - int ri_state; - - unsigned long tx_start_time[N_OUT_URB]; -}; - module_usb_serial_driver(serial_drivers, option_ids); static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, @@ -1367,7 +1338,8 @@ static void option_instat_callback(struct urb *urb) int err; int status = urb->status; struct usb_serial_port *port = urb->context; - struct option_port_private *portdata = usb_get_serial_port_data(port); + struct usb_wwan_port_private *portdata = + usb_get_serial_port_data(port); dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); @@ -1427,7 +1399,7 @@ static int option_send_setup(struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct usb_wwan_intf_private *intfdata = (struct usb_wwan_intf_private *) serial->private; - struct option_port_private *portdata; + struct usb_wwan_port_private *portdata; int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; int val = 0; -- cgit v1.1 From b9c3aab315b51f81649a0d737c4c73783fbd8de0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 May 2012 18:22:48 +0200 Subject: USB: option: fix memory leak Fix memory leak introduced by commit 383cedc3bb435de7a2 ("USB: serial: full autosuspend support for the option driver") which allocates usb-serial data but never frees it. Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 9c2f7b2..d12ee2f 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -47,6 +47,7 @@ /* Function prototypes */ static int option_probe(struct usb_serial *serial, const struct usb_device_id *id); +static void option_release(struct usb_serial *serial); static int option_send_setup(struct usb_serial_port *port); static void option_instat_callback(struct urb *urb); @@ -1251,7 +1252,7 @@ static struct usb_serial_driver option_1port_device = { .ioctl = usb_wwan_ioctl, .attach = usb_wwan_startup, .disconnect = usb_wwan_disconnect, - .release = usb_wwan_release, + .release = option_release, .read_int_callback = option_instat_callback, #ifdef CONFIG_PM .suspend = usb_wwan_suspend, @@ -1333,6 +1334,15 @@ static int option_probe(struct usb_serial *serial, return 0; } +static void option_release(struct usb_serial *serial) +{ + struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); + + usb_wwan_release(serial); + + kfree(priv); +} + static void option_instat_callback(struct urb *urb) { int err; -- cgit v1.1 From b9c87663eead64c767e72a373ae6f8a94bead459 Mon Sep 17 00:00:00 2001 From: Tony Zelenoff Date: Tue, 5 Jun 2012 17:58:04 +0400 Subject: USB: mos7840: Fix compilation of usb serial driver The __devinitconst section can't be referenced from usb_serial_device structure. Thus removed it as it done in other mos* device drivers. Error itself: WARNING: drivers/usb/serial/mos7840.o(.data+0x8): Section mismatch in reference from the variable moschip7840_4port_device to the variable .devinit.rodata:id_table The variable moschip7840_4port_device references the variable __devinitconst id_table [v2] no attach now Signed-off-by: Tony Zelenoff Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7840.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 29160f8..57eca24 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -190,7 +190,7 @@ static int device_type; -static const struct usb_device_id id_table[] __devinitconst = { +static const struct usb_device_id id_table[] = { {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)}, -- cgit v1.1 From 0ef0be15fd2564767f114c249fc4af704d8e16f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AF=B4=E4=B8=8D=E5=BE=97?= Date: Mon, 28 May 2012 21:31:29 +0800 Subject: USB: option: add more YUGA device ids Signed-off-by: gavin zhu Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d12ee2f..e668a24 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -427,7 +427,7 @@ static void option_instat_callback(struct urb *urb); #define SAMSUNG_VENDOR_ID 0x04e8 #define SAMSUNG_PRODUCT_GT_B3730 0x6889 -/* YUGA products www.yuga-info.com*/ +/* YUGA products www.yuga-info.com gavin.kx@qq.com */ #define YUGA_VENDOR_ID 0x257A #define YUGA_PRODUCT_CEM600 0x1601 #define YUGA_PRODUCT_CEM610 0x1602 @@ -444,6 +444,8 @@ static void option_instat_callback(struct urb *urb); #define YUGA_PRODUCT_CEU516 0x160C #define YUGA_PRODUCT_CEU528 0x160D #define YUGA_PRODUCT_CEU526 0x160F +#define YUGA_PRODUCT_CEU881 0x161F +#define YUGA_PRODUCT_CEU882 0x162F #define YUGA_PRODUCT_CWM600 0x2601 #define YUGA_PRODUCT_CWM610 0x2602 @@ -459,23 +461,26 @@ static void option_instat_callback(struct urb *urb); #define YUGA_PRODUCT_CWU518 0x260B #define YUGA_PRODUCT_CWU516 0x260C #define YUGA_PRODUCT_CWU528 0x260D +#define YUGA_PRODUCT_CWU581 0x260E #define YUGA_PRODUCT_CWU526 0x260F - -#define YUGA_PRODUCT_CLM600 0x2601 -#define YUGA_PRODUCT_CLM610 0x2602 -#define YUGA_PRODUCT_CLM500 0x2603 -#define YUGA_PRODUCT_CLM510 0x2604 -#define YUGA_PRODUCT_CLM800 0x2605 -#define YUGA_PRODUCT_CLM900 0x2606 - -#define YUGA_PRODUCT_CLU718 0x2607 -#define YUGA_PRODUCT_CLU716 0x2608 -#define YUGA_PRODUCT_CLU728 0x2609 -#define YUGA_PRODUCT_CLU726 0x260A -#define YUGA_PRODUCT_CLU518 0x260B -#define YUGA_PRODUCT_CLU516 0x260C -#define YUGA_PRODUCT_CLU528 0x260D -#define YUGA_PRODUCT_CLU526 0x260F +#define YUGA_PRODUCT_CWU582 0x261F +#define YUGA_PRODUCT_CWU583 0x262F + +#define YUGA_PRODUCT_CLM600 0x3601 +#define YUGA_PRODUCT_CLM610 0x3602 +#define YUGA_PRODUCT_CLM500 0x3603 +#define YUGA_PRODUCT_CLM510 0x3604 +#define YUGA_PRODUCT_CLM800 0x3605 +#define YUGA_PRODUCT_CLM900 0x3606 + +#define YUGA_PRODUCT_CLU718 0x3607 +#define YUGA_PRODUCT_CLU716 0x3608 +#define YUGA_PRODUCT_CLU728 0x3609 +#define YUGA_PRODUCT_CLU726 0x360A +#define YUGA_PRODUCT_CLU518 0x360B +#define YUGA_PRODUCT_CLU516 0x360C +#define YUGA_PRODUCT_CLU528 0x360D +#define YUGA_PRODUCT_CLU526 0x360F /* Viettel products */ #define VIETTEL_VENDOR_ID 0x2262 @@ -1216,6 +1221,11 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU881) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU882) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU581) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU582) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU583) }, { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) }, { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */ -- cgit v1.1 From 6dae14216c85eea13db7b12c469475c5d30e5499 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Jun 2012 00:28:23 +0200 Subject: serial: sh-sci: Fix probe error paths When probing fails, the driver must not try to cleanup resources that have not been initialized. Fix this. Signed-off-by: Laurent Pinchart Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 4604153..27df2ad 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2179,6 +2179,16 @@ static int __devinit sci_init_single(struct platform_device *dev, return 0; } +static void sci_cleanup_single(struct sci_port *port) +{ + sci_free_gpios(port); + + clk_put(port->iclk); + clk_put(port->fclk); + + pm_runtime_disable(port->port.dev); +} + #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE static void serial_console_putchar(struct uart_port *port, int ch) { @@ -2360,14 +2370,10 @@ static int sci_remove(struct platform_device *dev) cpufreq_unregister_notifier(&port->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); - sci_free_gpios(port); - uart_remove_one_port(&sci_uart_driver, &port->port); - clk_put(port->iclk); - clk_put(port->fclk); + sci_cleanup_single(port); - pm_runtime_disable(&dev->dev); return 0; } @@ -2392,7 +2398,13 @@ static int __devinit sci_probe_single(struct platform_device *dev, if (ret) return ret; - return uart_add_one_port(&sci_uart_driver, &sciport->port); + ret = uart_add_one_port(&sci_uart_driver, &sciport->port); + if (ret) { + sci_cleanup_single(sciport); + return ret; + } + + return 0; } static int __devinit sci_probe(struct platform_device *dev) @@ -2413,24 +2425,22 @@ static int __devinit sci_probe(struct platform_device *dev) ret = sci_probe_single(dev, dev->id, p, sp); if (ret) - goto err_unreg; + return ret; sp->freq_transition.notifier_call = sci_notifier; ret = cpufreq_register_notifier(&sp->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); - if (unlikely(ret < 0)) - goto err_unreg; + if (unlikely(ret < 0)) { + sci_cleanup_single(sp); + return ret; + } #ifdef CONFIG_SH_STANDARD_BIOS sh_bios_gdb_detach(); #endif return 0; - -err_unreg: - sci_remove(dev); - return ret; } static int sci_suspend(struct device *dev) -- cgit v1.1 From b6c5ef6f6d3e46d6200b141c30ac000a11b851df Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Jun 2012 00:28:24 +0200 Subject: serial: sh-sci: Make probe fail for ports that exceed the maximum count The driver supports a maximum number of ports configurable at compile time. Make sure the probe() method fails when registering a port that exceeds the maximum instead of returning success without registering the port. This fixes a crash at system suspend time, when the driver tried to suspend a non-registered port using the UART core. Signed-off-by: Laurent Pinchart Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 27df2ad..1bd9163 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2391,7 +2391,7 @@ static int __devinit sci_probe_single(struct platform_device *dev, index+1, SCI_NPORTS); dev_notice(&dev->dev, "Consider bumping " "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n"); - return 0; + return -EINVAL; } ret = sci_init_single(dev, sciport, index, p); -- cgit v1.1 From 4149268e7816d719b0fde8e89aaa6db8c168fc43 Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Fri, 18 May 2012 13:57:19 -0700 Subject: target: Add TFO->put_session() caller for HW fabric session shutdown This patch adds an optional target_core_fabric_ops->put_session() caller within the existing target_put_session() code path. This is required by tcm_qla2xxx code in order to invoke it's own fabric specific session shutdown handler using se_session->sess_kref. Signed-off-by: Joern Engel Cc: Roland Dreier Cc: Arun Easi Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index b05fdc0..634d0f3 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -315,7 +315,7 @@ void transport_register_session( } EXPORT_SYMBOL(transport_register_session); -static void target_release_session(struct kref *kref) +void target_release_session(struct kref *kref) { struct se_session *se_sess = container_of(kref, struct se_session, sess_kref); @@ -332,6 +332,12 @@ EXPORT_SYMBOL(target_get_session); void target_put_session(struct se_session *se_sess) { + struct se_portal_group *tpg = se_sess->se_tpg; + + if (tpg->se_tpg_tfo->put_session != NULL) { + tpg->se_tpg_tfo->put_session(se_sess); + return; + } kref_put(&se_sess->sess_kref, target_release_session); } EXPORT_SYMBOL(target_put_session); -- cgit v1.1 From aaf68b753313f1e67fd2e8996e32ab2813f441fa Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Fri, 18 May 2012 13:58:23 -0700 Subject: tcm_qla2xxx: Convert to TFO->put_session() usage This patch converts tcm_qla2xxx code to use an internal kref_put() for se_session->sess_kref in order to ensure that qla_hw_data->hardware_lock can be held while calling qlt_unreg_sess() for the final put. Signed-off-by: Joern Engel Cc: Roland Dreier Cc: Arun Easi Signed-off-by: Nicholas Bellinger --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 436598f..3cee5b6 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -844,9 +844,28 @@ static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct qla_tgt_sess *sess) se_nacl, nacl->nport_wwnn, nacl->nport_id); } +static void tcm_qla2xxx_release_session(struct kref *kref) +{ + struct se_session *se_sess = container_of(kref, + struct se_session, sess_kref); + + qlt_unreg_sess(se_sess->fabric_sess_ptr); +} + +static void tcm_qla2xxx_put_session(struct se_session *se_sess) +{ + struct qla_tgt_sess *sess = se_sess->fabric_sess_ptr; + struct qla_hw_data *ha = sess->vha->hw; + unsigned long flags; + + spin_lock_irqsave(&ha->hardware_lock, flags); + kref_put(&se_sess->sess_kref, tcm_qla2xxx_release_session); + spin_unlock_irqrestore(&ha->hardware_lock, flags); +} + static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess) { - target_put_session(sess->se_sess); + tcm_qla2xxx_put_session(sess->se_sess); } static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess) @@ -1731,6 +1750,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { .new_cmd_map = NULL, .check_stop_free = tcm_qla2xxx_check_stop_free, .release_cmd = tcm_qla2xxx_release_cmd, + .put_session = tcm_qla2xxx_put_session, .shutdown_session = tcm_qla2xxx_shutdown_session, .close_session = tcm_qla2xxx_close_session, .sess_get_index = tcm_qla2xxx_sess_get_index, @@ -1779,6 +1799,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, .release_cmd = tcm_qla2xxx_release_cmd, + .put_session = tcm_qla2xxx_put_session, .shutdown_session = tcm_qla2xxx_shutdown_session, .close_session = tcm_qla2xxx_close_session, .sess_get_index = tcm_qla2xxx_sess_get_index, -- cgit v1.1 From f2d5d9b90b095ab0e8097b2b0793f4a56ed98147 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Fri, 18 May 2012 15:37:53 -0700 Subject: tcm_qla2xxx: Clear session s_id + loop_id earlier during shutdown This patch adds a new tcm_qla2xxx_clear_sess_lookup() call to clear session specific s_id + loop_id entries used for se_node_acl pointer lookup ahead of releasing se_session within the process context workqueue callback in tcm_qla2xxx_free_session(). It makes the call in existing tcm_qla2xxx_clear_nacl_from_fcport_map() code invoked from qlt_unreg_sess() in interrupt context w/ hardware_lock held, ahead of the process context callback into qlt_free_session_done() -> tcm_qla2xxx_free_session(). We are doing this to address a race between incoming ATIO or TMR packets using stale se_node_acl pointer once session shutdown has been invoked via qlt_unreg_sess() in qla_target.c LLD code, and when the entire tcm_qla2xxx endpoint has not been forced into shutdown w/ echo 0 > ../$QLA2XXX_PORT/enable Cc: Joern Engel Cc: Roland Dreier Cc: Arun Easi Signed-off-by: Nicholas Bellinger --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 48 ++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 3cee5b6..a641c97 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -821,6 +821,8 @@ static int tcm_qla2xxx_setup_nacl_from_rport( return 0; } +static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, + struct tcm_qla2xxx_nacl *, struct qla_tgt_sess *); /* * Expected to be called with struct qla_hw_data->hardware_lock held */ @@ -842,6 +844,16 @@ static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct qla_tgt_sess *sess) pr_debug("Removed from fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%06x\n", se_nacl, nacl->nport_wwnn, nacl->nport_id); + /* + * Now clear the se_nacl and session pointers from our HW lport lookup + * table mapping for this initiator's fabric S_ID and LOOP_ID entries. + * + * This is done ahead of callbacks into tcm_qla2xxx_free_session() -> + * target_wait_for_sess_cmds() before the session waits for outstanding + * I/O to complete, to avoid a race between session shutdown execution + * and incoming ATIOs or TMRs picking up a stale se_node_act reference. + */ + tcm_qla2xxx_clear_sess_lookup(lport, nacl, sess); } static void tcm_qla2xxx_release_session(struct kref *kref) @@ -1409,6 +1421,25 @@ static void tcm_qla2xxx_set_sess_by_loop_id( nacl->qla_tgt_sess, new_se_nacl, new_se_nacl->initiatorname); } +/* + * Should always be called with qla_hw_data->hardware_lock held. + */ +static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *lport, + struct tcm_qla2xxx_nacl *nacl, struct qla_tgt_sess *sess) +{ + struct se_session *se_sess = sess->se_sess; + unsigned char be_sid[3]; + + be_sid[0] = sess->s_id.b.domain; + be_sid[1] = sess->s_id.b.area; + be_sid[2] = sess->s_id.b.al_pa; + + tcm_qla2xxx_set_sess_by_s_id(lport, NULL, nacl, se_sess, + sess, be_sid); + tcm_qla2xxx_set_sess_by_loop_id(lport, NULL, nacl, se_sess, + sess, sess->loop_id); +} + static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) { struct qla_tgt *tgt = sess->tgt; @@ -1417,8 +1448,6 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) struct se_node_acl *se_nacl; struct tcm_qla2xxx_lport *lport; struct tcm_qla2xxx_nacl *nacl; - unsigned char be_sid[3]; - unsigned long flags; BUG_ON(in_interrupt()); @@ -1438,21 +1467,6 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) return; } target_wait_for_sess_cmds(se_sess, 0); - /* - * And now clear the se_nacl and session pointers from our HW lport - * mappings for fabric S_ID and LOOP_ID. - */ - memset(&be_sid, 0, 3); - be_sid[0] = sess->s_id.b.domain; - be_sid[1] = sess->s_id.b.area; - be_sid[2] = sess->s_id.b.al_pa; - - spin_lock_irqsave(&ha->hardware_lock, flags); - tcm_qla2xxx_set_sess_by_s_id(lport, NULL, nacl, se_sess, - sess, be_sid); - tcm_qla2xxx_set_sess_by_loop_id(lport, NULL, nacl, se_sess, - sess, sess->loop_id); - spin_unlock_irqrestore(&ha->hardware_lock, flags); transport_deregister_session_configfs(sess->se_sess); transport_deregister_session(sess->se_sess); -- cgit v1.1 From 59e4f541baf728dbb426949bfa9f6862387ffd0e Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 4 Jun 2012 23:24:51 -0700 Subject: target: Return error to initiator if SET TARGET PORT GROUPS emulation fails The error paths in target_emulate_set_target_port_groups() are all essentially "rc = -EINVAL; goto out;" but the code at "out:" ignores rc and always returns success. This means that even if eg explicit ALUA is turned off, the initiator will always see a good SCSI status for SET TARGET PORT GROUPS. Fix this by returning rc as is intended. It appears this bug was added by the following patch: commit 05d1c7c0d0db4cc25548d9aadebb416888a82327 Author: Andy Grover Date: Wed Jul 20 19:13:28 2011 +0000 target: Make all control CDBs scatter-gather Signed-off-by: Roland Dreier Cc: Andy Grover Cc: Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_alua.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index e624b83..9179997 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -374,8 +374,9 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) out: transport_kunmap_data_sg(cmd); - target_complete_cmd(cmd, GOOD); - return 0; + if (!rc) + target_complete_cmd(cmd, GOOD); + return rc; } static inline int core_alua_state_nonoptimized( -- cgit v1.1 From 3578ddba1ae93263d373e7bc85fd38d1f0368b78 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 4 Jun 2012 23:37:34 -0700 Subject: tcm_qla2xxx: Don't insert nacls without sessions into the btree When we create an explicit node ACL in tcm_qla2xxx_make_nodeacl(), there is a call to tcm_qla2xxx_setup_nacl_from_rport(), which puts the node ACL into the lport_fcport_map even though there is no session yet for the initiator. Since the only time we remove entries from this map is when we free a session, this means that if we later delete this node ACL without the initiator ever creating a session, we'll leave the nacl pointer in the btree pointing at freed memory. This is especially bad if that initiator later does send us a command that would cause us to create a dynamic ACL and session: we'll find the stale freed nacl pointer in the btree and end up with use-after-free. We could add more code to clear the btree entry when deleting the explicit nacl, but the original insertion is pointless: without a session attached, we'll just have to update the entry when a session appears anyway. So we can just delete tcm_qla2xxx_setup_nacl_from_rport() and the code that calls it. Signed-off-by: Roland Dreier Cc: Chad Dupuis Cc: Giridhar Malavali Cc: Arun Easi Signed-off-by: Nicholas Bellinger --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 73 -------------------------------------- 1 file changed, 73 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index a641c97..acc3b115 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -762,65 +762,6 @@ static u16 tcm_qla2xxx_set_fabric_sense_len(struct se_cmd *se_cmd, struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; -static int tcm_qla2xxx_setup_nacl_from_rport( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl, - struct tcm_qla2xxx_lport *lport, - struct tcm_qla2xxx_nacl *nacl, - u64 rport_wwnn) -{ - struct scsi_qla_host *vha = lport->qla_vha; - struct Scsi_Host *sh = vha->host; - struct fc_host_attrs *fc_host = shost_to_fc_host(sh); - struct fc_rport *rport; - unsigned long flags; - void *node; - int rc; - - /* - * Scan the existing rports, and create a session for the - * explict NodeACL is an matching rport->node_name already - * exists. - */ - spin_lock_irqsave(sh->host_lock, flags); - list_for_each_entry(rport, &fc_host->rports, peers) { - if (rport_wwnn != rport->node_name) - continue; - - pr_debug("Located existing rport_wwpn and rport->node_name: 0x%016LX, port_id: 0x%04x\n", - rport->node_name, rport->port_id); - nacl->nport_id = rport->port_id; - - spin_unlock_irqrestore(sh->host_lock, flags); - - spin_lock_irqsave(&vha->hw->hardware_lock, flags); - node = btree_lookup32(&lport->lport_fcport_map, rport->port_id); - if (node) { - rc = btree_update32(&lport->lport_fcport_map, - rport->port_id, se_nacl); - } else { - rc = btree_insert32(&lport->lport_fcport_map, - rport->port_id, se_nacl, - GFP_ATOMIC); - } - spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); - - if (rc) { - pr_err("Unable to insert se_nacl into fcport_map"); - WARN_ON(rc > 0); - return rc; - } - - pr_debug("Inserted into fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%08x\n", - se_nacl, rport_wwnn, nacl->nport_id); - - return 1; - } - spin_unlock_irqrestore(sh->host_lock, flags); - - return 0; -} - static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, struct tcm_qla2xxx_nacl *, struct qla_tgt_sess *); /* @@ -890,14 +831,10 @@ static struct se_node_acl *tcm_qla2xxx_make_nodeacl( struct config_group *group, const char *name) { - struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; - struct tcm_qla2xxx_lport *lport = container_of(se_wwn, - struct tcm_qla2xxx_lport, lport_wwn); struct se_node_acl *se_nacl, *se_nacl_new; struct tcm_qla2xxx_nacl *nacl; u64 wwnn; u32 qla2xxx_nexus_depth; - int rc; if (tcm_qla2xxx_parse_wwn(name, &wwnn, 1) < 0) return ERR_PTR(-EINVAL); @@ -924,16 +861,6 @@ static struct se_node_acl *tcm_qla2xxx_make_nodeacl( nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); nacl->nport_wwnn = wwnn; tcm_qla2xxx_format_wwn(&nacl->nport_name[0], TCM_QLA2XXX_NAMELEN, wwnn); - /* - * Setup a se_nacl handle based on an a matching struct fc_rport setup - * via drivers/scsi/qla2xxx/qla_init.c:qla2x00_reg_remote_port() - */ - rc = tcm_qla2xxx_setup_nacl_from_rport(se_tpg, se_nacl, lport, - nacl, wwnn); - if (rc < 0) { - tcm_qla2xxx_release_fabric_acl(se_tpg, se_nacl_new); - return ERR_PTR(rc); - } return se_nacl; } -- cgit v1.1 From 092e1dc3f227ebef9ad45c26ef05c283ca4495a5 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 11 Jun 2012 18:23:15 -0700 Subject: qla2xxx: Don't crash if we can't find cmd for failed CTIO In qlt_do_ctio_completion(), there's no point in calling qlt_term_ctio_exchange() with a NULL cmd -- all that it does is crash in a NULL pointer dereference, since it does qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); and dereferencing &cmd->atio is a bad idea if cmd itself is NULL. If we really need to do this, we could take the values from the failed CTIO we're processing, but it's not clear if it's worth the replumbing to do that. Signed-off-by: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/scsi/qla2xxx/qla_target.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 04f80eb..c263f90 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -2477,11 +2477,9 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, } cmd = qlt_ctio_to_cmd(vha, handle, ctio); - if (cmd == NULL) { - if (status != CTIO_SUCCESS) - qlt_term_ctio_exchange(vha, ctio, NULL, status); + if (cmd == NULL) return; - } + se_cmd = &cmd->se_cmd; tfo = se_cmd->se_tfo; -- cgit v1.1 From fae9eaf81323eda64f28b9f4f4aeffb807e5b5f4 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 11 Jun 2012 18:23:16 -0700 Subject: qla2xxx: Don't leak commands we give up on in qlt_do_work() If we go to the "out_term:" exit path in qlt_do_work(), we call qlt_send_term_exchange() with a NULL cmd, which means that it can't possibly free the cmd for us. Add an explicit call to free the command memory, so we don't leak the allocation. This will also fix warnings about "BUG qla_tgt_cmd_cachep: Objects remaining on kmem_cache_close" from slub when unloading the qla2xxx target module. Signed-off-by: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/scsi/qla2xxx/qla_target.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index c263f90..e912920 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -2725,10 +2725,12 @@ static void qlt_do_work(struct work_struct *work) out_term: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf020, "Terminating work cmd %p", cmd); /* - * cmd has not sent to target yet, so pass NULL as the second argument + * cmd has not sent to target yet, so pass NULL as the second + * argument to qlt_send_term_exchange() and free the memory here. */ spin_lock_irqsave(&ha->hardware_lock, flags); qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); + kmem_cache_free(qla_tgt_cmd_cachep, cmd); spin_unlock_irqrestore(&ha->hardware_lock, flags); if (sess) ha->tgt.tgt_ops->put_sess(sess); -- cgit v1.1 From 9389c3c943da7e5f903eebf79d596601537afe01 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 11 Jun 2012 18:31:30 -0700 Subject: tcm_qla2xxx: tcm_qla2xxx_handle_tmr() can be static Signed-off-by: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index acc3b115..2f12c09 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -652,8 +652,8 @@ static int tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) /* * Called from qla_target.c:qlt_issue_task_mgmt() */ -int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun, - uint8_t tmr_func, uint32_t tag) +static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun, + uint8_t tmr_func, uint32_t tag) { struct qla_tgt_sess *sess = mcmd->sess; struct se_cmd *se_cmd = &mcmd->se_cmd; -- cgit v1.1 From d4f75b567bb63b51e5ecd42af1e82d5aed5100dd Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 11 Jun 2012 18:31:31 -0700 Subject: tcm_qla2xxx: Handle malformed wwn strings properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we make a variable an unsigned int and then expect it to be < 0 on a bad character, we're going to have a bad time. Fix the tcm_qla2xxx code to actually notice if hex_to_bin() returns a negative variable. This was detected by the compiler warning: scsi/qla2xxx/tcm_qla2xxx.c: In function ‘tcm_qla2xxx_npiv_extract_wwn’: scsi/qla2xxx/tcm_qla2xxx.c:148:3: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits] Signed-off-by: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 2f12c09..6e64314 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -137,13 +137,15 @@ static char *tcm_qla2xxx_get_fabric_name(void) */ static int tcm_qla2xxx_npiv_extract_wwn(const char *ns, u64 *nm) { - unsigned int i, j, value; + unsigned int i, j; u8 wwn[8]; memset(wwn, 0, sizeof(wwn)); /* Validate and store the new name */ for (i = 0, j = 0; i < 16; i++) { + int value; + value = hex_to_bin(*ns++); if (value >= 0) j = (j << 4) | value; -- cgit v1.1 From 5134de2815ac723ecfba4a1c7b2a90fa4d8dcfd9 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 3 Jun 2012 22:27:01 +0530 Subject: qla2xxx: Remove version.h header file inclusion version.h header file is no longer required for qla_target code. Signed-off-by: Sachin Kamat Signed-off-by: Nicholas Bellinger --- drivers/scsi/qla2xxx/qla_target.c | 1 - drivers/scsi/qla2xxx/qla_target.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index e912920..6986552 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 9ec19bc..9f9ef16 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h @@ -919,7 +919,6 @@ struct qla_tgt_srr_ctio { #define QLA_TGT_XMIT_STATUS 2 #define QLA_TGT_XMIT_ALL (QLA_TGT_XMIT_STATUS|QLA_TGT_XMIT_DATA) -#include extern struct qla_tgt_data qla_target; /* -- cgit v1.1 From ecd57ae28eb34e2b34fac1c5b74bb876efa665c0 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 11 Jun 2012 11:26:41 +0900 Subject: video: s3c-fb: clear SHADOWCON register when clearing hardware window registers All bits of SHADOWCON register should be cleared when clearing hardware window registers; however, some bits of SHADOWCON register are not cleared previously. Signed-off-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat --- drivers/video/s3c-fb.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 5f9d8e690..b5c29399 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -1348,8 +1348,14 @@ static void s3c_fb_clear_win(struct s3c_fb *sfb, int win) writel(0, regs + VIDOSD_A(win, sfb->variant)); writel(0, regs + VIDOSD_B(win, sfb->variant)); writel(0, regs + VIDOSD_C(win, sfb->variant)); - reg = readl(regs + SHADOWCON); - writel(reg & ~SHADOWCON_WINx_PROTECT(win), regs + SHADOWCON); + + if (sfb->variant.has_shadowcon) { + reg = readl(sfb->regs + SHADOWCON); + reg &= ~(SHADOWCON_WINx_PROTECT(win) | + SHADOWCON_CHx_ENABLE(win) | + SHADOWCON_CHx_LOCAL_ENABLE(win)); + writel(reg, sfb->regs + SHADOWCON); + } } static int __devinit s3c_fb_probe(struct platform_device *pdev) -- cgit v1.1 From b67989515defba7412acff01162e5bb1f0f5923a Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 11 Jun 2012 11:27:27 +0900 Subject: video: s3c-fb: fix possible division by zero in s3c_fb_calc_pixclk Divider value can be zero and it makes division by zero from debug message in s3c_fb_calc_pixclk; therefore, it should be fixed. Signed-off-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat --- drivers/video/s3c-fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index b5c29399..ea7b661 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -361,7 +361,7 @@ static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) result = (unsigned int)tmp / 1000; dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", - pixclk, clk, result, clk / result); + pixclk, clk, result, result ? clk / result : clk); return result; } -- cgit v1.1 From bcb7ad7bcbef030e6ba71ede1f9866368aca7c99 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 13 Jun 2012 21:28:09 +0530 Subject: ath9k: Fix softlockup in AR9485 steps to recreate: load latest ath9k driver with AR9485 stop the network-manager and wpa_supplicant bring the interface up Call Trace: [] ? ath_hw_check+0xe0/0xe0 [ath9k] [] __const_udelay+0x28/0x30 [] ar9003_get_pll_sqsum_dvc+0x4a/0x80 [ath9k_hw] [] ath_hw_pll_work+0x5b/0xe0 [ath9k] [] process_one_work+0x11e/0x470 [] worker_thread+0x15f/0x360 [] ? manage_workers+0x230/0x230 [] kthread+0x93/0xa0 [] kernel_thread_helper+0x4/0x10 [] ? kthread_freezable_should_stop+0x70/0x70 [] ? gs_change+0x13/0x13 ensure that the PLL-WAR for AR9485/AR9340 is executed only if the STA is associated (or) IBSS/AP mode had started beaconing. Ideally this WAR is needed to recover from some rare beacon stuck during stress testing. Before the STA is associated/IBSS had started beaconing, PLL4(0x1618c) always seem to have zero even though we had configured PLL3(0x16188) to query about PLL's locking status. When we keep on polling infinitely PLL4's 8th bit(ie check for PLL locking measurements is done), machine hangs due to softlockup. fixes https://bugzilla.redhat.com/show_bug.cgi?id=811142 Reported-by: Rolf Offermanns Cc: stable@vger.kernel.org [3.0+] Tested-by: Mohammed Shafi Shajakhan Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ac41f1e..dac1a27 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -971,6 +971,15 @@ void ath_hw_pll_work(struct work_struct *work) hw_pll_work.work); u32 pll_sqsum; + /* + * ensure that the PLL WAR is executed only + * after the STA is associated (or) if the + * beaconing had started in interfaces that + * uses beacons. + */ + if (!(sc->sc_flags & SC_OP_BEACONS)) + return; + if (AR_SREV_9485(sc->sc_ah)) { ath9k_ps_wakeup(sc); -- cgit v1.1 From c2fb8a3fa25513de8fedb38509b1f15a5bbee47b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 13 Jun 2012 11:20:19 -0400 Subject: USB: add NO_D3_DURING_SLEEP flag and revert 151b61284776be2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch (as1558) fixes a problem affecting several ASUS computers: The machine crashes or corrupts memory when going into suspend if the ehci-hcd driver is bound to any controllers. Users have been forced to unbind or unload ehci-hcd before putting their systems to sleep. After extensive testing, it was determined that the machines don't like going into suspend when any EHCI controllers are in the PCI D3 power state. Presumably this is a firmware bug, but there's nothing we can do about it except to avoid putting the controllers in D3 during system sleep. The patch adds a new flag to indicate whether the problem is present, and avoids changing the controller's power state if the flag is set. Runtime suspend is unaffected; this matters only for system suspend. However as a side effect, the controller will not respond to remote wakeup requests while the system is asleep. Hence USB wakeup is not functional -- but of course, this is already true in the current state of affairs. A similar patch has already been applied as commit 151b61284776be2d6f02d48c23c3625678960b97 (USB: EHCI: fix crash during suspend on ASUS computers). The patch supersedes that one and reverts it. There are two differences: The old patch added the flag at the USB level; this patch adds it at the PCI level. The old patch applied to all chipsets with the same vendor, subsystem vendor, and product IDs; this patch makes an exception for a known-good system (based on DMI information). Signed-off-by: Alan Stern Tested-by: Dâniel Fraga Tested-by: Andrey Rahmatullin Tested-by: Steven Rostedt Cc: stable Reviewed-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 5 +++++ drivers/pci/quirks.c | 26 ++++++++++++++++++++++++++ drivers/usb/core/hcd-pci.c | 9 --------- drivers/usb/host/ehci-pci.c | 8 -------- 4 files changed, 31 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e834..77cb54a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1744,6 +1744,11 @@ int pci_prepare_to_sleep(struct pci_dev *dev) if (target_state == PCI_POWER_ERROR) return -EIO; + /* Some devices mustn't be in D3 during system sleep */ + if (target_state == PCI_D3hot && + (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP)) + return 0; + pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); error = pci_set_power_state(dev, target_state); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2a75216..194b243a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2929,6 +2929,32 @@ static void __devinit disable_igfx_irq(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); +/* + * The Intel 6 Series/C200 Series chipset's EHCI controllers on many + * ASUS motherboards will cause memory corruption or a system crash + * if they are in D3 while the system is put into S3 sleep. + */ +static void __devinit asus_ehci_no_d3(struct pci_dev *dev) +{ + const char *sys_info; + static const char good_Asus_board[] = "P8Z68-V"; + + if (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP) + return; + if (dev->subsystem_vendor != PCI_VENDOR_ID_ASUSTEK) + return; + sys_info = dmi_get_system_info(DMI_BOARD_NAME); + if (sys_info && memcmp(sys_info, good_Asus_board, + sizeof(good_Asus_board) - 1) == 0) + return; + + dev_info(&dev->dev, "broken D3 during system sleep on ASUS\n"); + dev->dev_flags |= PCI_DEV_FLAGS_NO_D3_DURING_SLEEP; + device_set_wakeup_capable(&dev->dev, false); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c26, asus_ehci_no_d3); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c2d, asus_ehci_no_d3); + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 57ed9e4..622b4a4 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -493,15 +493,6 @@ static int hcd_pci_suspend_noirq(struct device *dev) pci_save_state(pci_dev); - /* - * Some systems crash if an EHCI controller is in D3 during - * a sleep transition. We have to leave such controllers in D0. - */ - if (hcd->broken_pci_sleep) { - dev_dbg(dev, "Staying in PCI D0\n"); - return retval; - } - /* If the root hub is dead rather than suspended, disallow remote * wakeup. usb_hc_died() should ensure that both hosts are marked as * dying, so we only need to check the primary roothub. diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index bc94d7b..1234817 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -144,14 +144,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) hcd->has_tt = 1; tdi_reset(ehci); } - if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) { - /* EHCI #1 or #2 on 6 Series/C200 Series chipset */ - if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) { - ehci_info(ehci, "broken D3 during system sleep on ASUS\n"); - hcd->broken_pci_sleep = 1; - device_set_wakeup_capable(&pdev->dev, false); - } - } break; case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { -- cgit v1.1 From 1d29cfa57471a5e4b8a7c2a7433eeba170d3ad92 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 29 May 2012 18:46:06 -0700 Subject: driver core: fixup reversed deferred probe order If driver requests probe deferral, it will be added to deferred_probe_pending_list by driver_deferred_probe_add(), but, it used list_add(). Because of that, deferred probe will be run as reversed order. This patch uses list_add_tail(), and solved this issue. Signed-off-by: Kuninori Morimoto Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 1b1cbb5..dcb8a6e 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -100,7 +100,7 @@ static void driver_deferred_probe_add(struct device *dev) mutex_lock(&deferred_probe_mutex); if (list_empty(&dev->p->deferred_probe)) { dev_dbg(dev, "Added to deferred list\n"); - list_add(&dev->p->deferred_probe, &deferred_probe_pending_list); + list_add_tail(&dev->p->deferred_probe, &deferred_probe_pending_list); } mutex_unlock(&deferred_probe_mutex); } -- cgit v1.1 From aa189ecdc0c7fad2166ba6d133df8bd214550f68 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 29 May 2012 16:39:10 +0300 Subject: misc: mei: set IRQF_ONESHOT for msi request_threaded_irq when the default irq quick handler is used then IRQF_ONESHOT must be set otherwise the request fails and following error is displayed: genirq: Threaded irq requested with handler=NULL and !ONESHOT for irq ... Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index c703332..88e5953 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -982,7 +982,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, err = request_threaded_irq(pdev->irq, NULL, mei_interrupt_thread_handler, - 0, mei_driver_name, dev); + IRQF_ONESHOT, mei_driver_name, dev); else err = request_threaded_irq(pdev->irq, mei_interrupt_quick_handler, -- cgit v1.1 From a44cab4aff7e72e7052521121fd8ceca51351534 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 29 May 2012 16:39:11 +0300 Subject: misc: mei: unregister misc device in pci_remove function Since the misc device is registered only in the pci probe function it has to be also unregistered in the counterpart pci remove function and not in the module exit function. In case of probe failure the driver was oopsing in module exit function. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 88e5953..a5a17e7 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -1101,6 +1101,8 @@ static void __devexit mei_remove(struct pci_dev *pdev) pci_release_regions(pdev); pci_disable_device(pdev); + + misc_deregister(&mei_misc_device); } #ifdef CONFIG_PM static int mei_pci_suspend(struct device *device) @@ -1216,7 +1218,6 @@ module_init(mei_init_module); */ static void __exit mei_exit_module(void) { - misc_deregister(&mei_misc_device); pci_unregister_driver(&mei_driver); pr_debug("unloaded successfully.\n"); -- cgit v1.1 From 1e69d64a28cf3cabd095ada3a49f081c97f997dd Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 29 May 2012 16:39:12 +0300 Subject: misc: mei: fix stalled read This bug caused severe connectivity issue in the LMS application (LMS is described in Documentation/misc-devices/mei/mei.txt) The bug was introduced in patch: commit 1ccb7b6249f9bc50678e2a383084ed0a34cc9239 staging/mei: propagate error codes up in the write flow The patch has reverted the return value logic of some fo function but the conditional in _mei_irq_thread_read function was not swapped making read always entering the error path Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 93936f1..23f5463 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -835,7 +835,7 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_io_list *cmpl_list) { - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + + if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_flow_control))) { /* return the cancel routine */ list_del(&cb_pos->cb_list); -- cgit v1.1 From 954c3f8a5f1b7716be9eee978b3bc85bae92d7c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 30 May 2012 10:00:14 +0200 Subject: USB: serial: Enforce USB driver and USB serial driver match MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to make sure that the USB serial driver we find matches the USB driver whose probe we are currently executing. Otherwise we will end up with USB serial devices bound to the correct serial driver but wrong USB driver. An example of such cross-probing, where the usbserial_generic USB driver has found the sierra serial driver: May 29 18:26:15 nemi kernel: [ 4442.559246] usbserial_generic 4-4:1.0: Sierra USB modem converter detected May 29 18:26:20 nemi kernel: [ 4447.556747] usbserial_generic 4-4:1.2: Sierra USB modem converter detected May 29 18:26:25 nemi kernel: [ 4452.557288] usbserial_generic 4-4:1.3: Sierra USB modem converter detected sysfs view of the same problem: bjorn@nemi:~$ ls -l /sys/bus/usb/drivers/sierra/ total 0 --w------- 1 root root 4096 May 29 18:23 bind lrwxrwxrwx 1 root root 0 May 29 18:23 module -> ../../../../module/usbserial --w------- 1 root root 4096 May 29 18:23 uevent --w------- 1 root root 4096 May 29 18:23 unbind bjorn@nemi:~$ ls -l /sys/bus/usb-serial/drivers/sierra/ total 0 --w------- 1 root root 4096 May 29 18:23 bind lrwxrwxrwx 1 root root 0 May 29 18:23 module -> ../../../../module/sierra -rw-r--r-- 1 root root 4096 May 29 18:23 new_id lrwxrwxrwx 1 root root 0 May 29 18:32 ttyUSB0 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.0/ttyUSB0 lrwxrwxrwx 1 root root 0 May 29 18:32 ttyUSB1 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.2/ttyUSB1 lrwxrwxrwx 1 root root 0 May 29 18:32 ttyUSB2 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.3/ttyUSB2 --w------- 1 root root 4096 May 29 18:23 uevent --w------- 1 root root 4096 May 29 18:23 unbind bjorn@nemi:~$ ls -l /sys/bus/usb/drivers/usbserial_generic/ total 0 lrwxrwxrwx 1 root root 0 May 29 18:33 4-4:1.0 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.0 lrwxrwxrwx 1 root root 0 May 29 18:33 4-4:1.2 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.2 lrwxrwxrwx 1 root root 0 May 29 18:33 4-4:1.3 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb4/4-4/4-4:1.3 --w------- 1 root root 4096 May 29 18:33 bind lrwxrwxrwx 1 root root 0 May 29 18:33 module -> ../../../../module/usbserial --w------- 1 root root 4096 May 29 18:22 uevent --w------- 1 root root 4096 May 29 18:33 unbind bjorn@nemi:~$ ls -l /sys/bus/usb-serial/drivers/generic/ total 0 --w------- 1 root root 4096 May 29 18:33 bind lrwxrwxrwx 1 root root 0 May 29 18:33 module -> ../../../../module/usbserial -rw-r--r-- 1 root root 4096 May 29 18:33 new_id --w------- 1 root root 4096 May 29 18:22 uevent --w------- 1 root root 4096 May 29 18:33 unbind So we end up with a mismatch between the USB driver and the USB serial driver. The reason for the above is simple: The USB driver probe will succeed if *any* registered serial driver matches, and will use that serial driver for all serial driver functions. This makes ref counting go wrong. We count the USB driver as used, but not the USB serial driver. This may result in Oops'es as demonstrated by Johan Hovold : [11811.646396] drivers/usb/serial/usb-serial.c: get_free_serial 1 [11811.646443] drivers/usb/serial/usb-serial.c: get_free_serial - minor base = 0 [11811.646460] drivers/usb/serial/usb-serial.c: usb_serial_probe - registering ttyUSB0 [11811.646766] usb 6-1: pl2303 converter now attached to ttyUSB0 [11812.264197] USB Serial deregistering driver FTDI USB Serial Device [11812.264865] usbcore: deregistering interface driver ftdi_sio [11812.282180] USB Serial deregistering driver pl2303 [11812.283141] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0 [11812.283272] usbcore: deregistering interface driver pl2303 [11812.301056] USB Serial deregistering driver generic [11812.301186] usbcore: deregistering interface driver usbserial_generic [11812.301259] drivers/usb/serial/usb-serial.c: usb_serial_disconnect [11812.301823] BUG: unable to handle kernel paging request at f8e7438c [11812.301845] IP: [] usb_serial_disconnect+0xb5/0x100 [usbserial] [11812.301871] *pde = 357ef067 *pte = 00000000 [11812.301957] Oops: 0000 [#1] PREEMPT SMP [11812.301983] Modules linked in: usbserial(-) [last unloaded: pl2303] [11812.302008] [11812.302019] Pid: 1323, comm: modprobe Tainted: G W 3.4.0-rc7+ #101 Dell Inc. Vostro 1520/0T816J [11812.302115] EIP: 0060:[] EFLAGS: 00010246 CPU: 1 [11812.302130] EIP is at usb_serial_disconnect+0xb5/0x100 [usbserial] [11812.302141] EAX: f508a180 EBX: f508a180 ECX: 00000000 EDX: f8e74300 [11812.302151] ESI: f5050800 EDI: 00000001 EBP: f5141e78 ESP: f5141e58 [11812.302160] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [11812.302170] CR0: 8005003b CR2: f8e7438c CR3: 34848000 CR4: 000007d0 [11812.302180] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 [11812.302189] DR6: ffff0ff0 DR7: 00000400 [11812.302199] Process modprobe (pid: 1323, ti=f5140000 task=f61e2bc0 task.ti=f5140000) [11812.302209] Stack: [11812.302216] f8e3be0f f8e3b29c f8e3ae00 00000000 f513641c f5136400 f513641c f507a540 [11812.302325] f5141e98 c133d2c1 00000000 00000000 f509c400 f513641c f507a590 f5136450 [11812.302372] f5141ea8 c12f0344 f513641c f507a590 f5141ebc c12f0c67 00000000 f507a590 [11812.302419] Call Trace: [11812.302439] [] usb_unbind_interface+0x51/0x190 [11812.302456] [] __device_release_driver+0x64/0xb0 [11812.302469] [] driver_detach+0x97/0xa0 [11812.302483] [] bus_remove_driver+0x6c/0xe0 [11812.302500] [] ? __mutex_unlock_slowpath+0xcd/0x140 [11812.302514] [] driver_unregister+0x49/0x80 [11812.302528] [] ? printk+0x1d/0x1f [11812.302540] [] usb_deregister+0x5d/0xb0 [11812.302557] [] ? usb_serial_deregister+0x45/0x50 [usbserial] [11812.302575] [] usb_serial_deregister_drivers+0x2d/0x40 [usbserial] [11812.302593] [] usb_serial_generic_deregister+0x12/0x20 [usbserial] [11812.302611] [] usb_serial_exit+0x8/0x32 [usbserial] [11812.302716] [] sys_delete_module+0x158/0x260 [11812.302730] [] ? mntput+0x1e/0x30 [11812.302746] [] ? sysenter_exit+0xf/0x18 [11812.302746] [] ? trace_hardirqs_on_caller+0xec/0x170 [11812.302746] [] sysenter_do_call+0x12/0x36 [11812.302746] Code: 24 02 00 00 e8 dd f3 20 c8 f6 86 74 02 00 00 02 74 b4 8d 86 4c 02 00 00 47 e8 78 55 4b c8 0f b6 43 0e 39 f8 7f a9 8b 53 04 89 d8 92 8c 00 00 00 89 d8 e8 0e ff ff ff 8b 45 f0 c7 44 24 04 2f [11812.302746] EIP: [] usb_serial_disconnect+0xb5/0x100 [usbserial] SS:ESP 0068:f5141e58 [11812.302746] CR2: 00000000f8e7438c Fix by only evaluating serial drivers pointing back to the USB driver we are currently probing. This still allows two or more drivers to match the same device, running their serial driver probes to sort out which one to use. Cc: stable@vger.kernel.org # 3.0, 3.2, 3.3, 3.4 Signed-off-by: Bjørn Mork Reviewed-by: Felipe Balbi Tested-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 6a1b609..6e8c527 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -659,12 +659,14 @@ exit: static struct usb_serial_driver *search_serial_device( struct usb_interface *iface) { - const struct usb_device_id *id; + const struct usb_device_id *id = NULL; struct usb_serial_driver *drv; + struct usb_driver *driver = to_usb_driver(iface->dev.driver); /* Check if the usb id matches a known device */ list_for_each_entry(drv, &usb_serial_driver_list, driver_list) { - id = get_iface_id(drv, iface); + if (drv->usb_driver == driver) + id = get_iface_id(drv, iface); if (id) return drv; } -- cgit v1.1 From 0b84704a2d6fdf55a3dcdd2a1f2ac8b48913c84b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 31 May 2012 17:03:52 -0400 Subject: USB: serial-generic: use a single set of device IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The usb-serial-generic driver uses different device IDs for its USB matching and its serial matching. This can lead to problems: The driver can end up getting bound to a USB interface without being allowed to bind to the corresponding serial port. This patch (as1557) fixes the problem by using the same device ID table (the one that can be altered by the "vendor=" and "product=" module parameters) for both purposes. The unused table is removed. Now the driver will bind only to the intended devices. Signed-off-by: Alan Stern CC: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 105a6d8..9b026bf 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -39,13 +39,6 @@ MODULE_PARM_DESC(product, "User specified USB idProduct"); static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ -/* we want to look at all devices, as the vendor/product id can change - * depending on the command line argument */ -static const struct usb_device_id generic_serial_ids[] = { - {.driver_info = 42}, - {} -}; - /* All of the device info needed for the Generic Serial Converter */ struct usb_serial_driver usb_serial_generic_device = { .driver = { @@ -79,7 +72,8 @@ int usb_serial_generic_register(int _debug) USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; /* register our generic driver with ourselves */ - retval = usb_serial_register_drivers(serial_drivers, "usbserial_generic", generic_serial_ids); + retval = usb_serial_register_drivers(serial_drivers, + "usbserial_generic", generic_device_ids); #endif return retval; } -- cgit v1.1 From 169dc388685f8a1c1e09546882a114ac850a5d6b Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 11 Jun 2012 12:18:30 +0300 Subject: misc: mei: Disable MSI when IRQ registration fails Since MSI is enabled right before that, we should disable it when registration fails. Signed-off-by: Samuel Ortiz Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index a5a17e7..7de1389 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -992,7 +992,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", pdev->irq); - goto unmap_memory; + goto disable_msi; } INIT_DELAYED_WORK(&dev->timer_work, mei_timer); if (mei_hw_init(dev)) { @@ -1023,8 +1023,8 @@ release_irq: mei_disable_interrupts(dev); flush_scheduled_work(); free_irq(pdev->irq, dev); +disable_msi: pci_disable_msi(pdev); -unmap_memory: pci_iounmap(pdev, dev->mem_addr); free_device: kfree(dev); -- cgit v1.1 From 49fbd3f1c3a67b99c053600a1cd7e5d0be48bed6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 11 Jun 2012 12:18:31 +0300 Subject: misc: mei: set WDIOF_ALARMONLY on mei watchdog mei watchdog doesn't reboot the system it only produces event therefore mark it as WDIOF_ALARMONLY. This patch depends on: commit 2bbeed016dd96045ec82c3a309afddcc3a0db1d2 Author: Alan Cox watchdog: Add a flag to indicate the watchdog doesn't reboot things Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/wd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 6be5605..e2ec050 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -341,7 +341,7 @@ static const struct watchdog_ops wd_ops = { }; static const struct watchdog_info wd_info = { .identity = INTEL_AMT_WATCHDOG_ID, - .options = WDIOF_KEEPALIVEPING, + .options = WDIOF_KEEPALIVEPING | WDIOF_ALARMONLY, }; static struct watchdog_device amt_wd_dev = { -- cgit v1.1 From d6cb3e41386f20fb0777d0b59a2def82c65d37f7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 12 Jun 2012 23:50:04 +0000 Subject: bnx2x: fix checksum validation bnx2x driver incorrectly sets ip_summed to CHECKSUM_UNNECESSARY on encapsulated segments. TCP stack happily accepts frames with bad checksums, if they are inside a GRE or IPIP encapsulation. Our understanding is that if no IP or L4 csum validation was done by the hardware, we should leave ip_summed as is (CHECKSUM_NONE), since hardware doesn't provide CHECKSUM_COMPLETE support in its cqe. Then, if IP/L4 checksumming was done by the hardware, set CHECKSUM_UNNECESSARY if no error was flagged. Patch based on findings and analysis from Robert Evans Signed-off-by: Eric Dumazet Cc: Eilon Greenstein Cc: Yaniv Rosner Cc: Merav Sicron Cc: Tom Herbert Cc: Robert Evans Cc: Willem de Bruijn Acked-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 15 -------------- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 27 +++++++++++++++++++------ 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index e30e2a2..7de8241 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -747,21 +747,6 @@ struct bnx2x_fastpath { #define ETH_RX_ERROR_FALGS ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG -#define BNX2X_IP_CSUM_ERR(cqe) \ - (!((cqe)->fast_path_cqe.status_flags & \ - ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG) && \ - ((cqe)->fast_path_cqe.type_error_flags & \ - ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG)) - -#define BNX2X_L4_CSUM_ERR(cqe) \ - (!((cqe)->fast_path_cqe.status_flags & \ - ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG) && \ - ((cqe)->fast_path_cqe.type_error_flags & \ - ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)) - -#define BNX2X_RX_CSUM_OK(cqe) \ - (!(BNX2X_L4_CSUM_ERR(cqe) || BNX2X_IP_CSUM_ERR(cqe))) - #define BNX2X_PRS_FLAG_OVERETH_IPV4(flags) \ (((le16_to_cpu(flags) & \ PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) >> \ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index ad0743b..cbc56f2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -617,6 +617,25 @@ static int bnx2x_alloc_rx_data(struct bnx2x *bp, return 0; } +static void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe, + struct bnx2x_fastpath *fp) +{ + /* Do nothing if no IP/L4 csum validation was done */ + + if (cqe->fast_path_cqe.status_flags & + (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG | + ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)) + return; + + /* If both IP/L4 validation were done, check if an error was found. */ + + if (cqe->fast_path_cqe.type_error_flags & + (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | + ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)) + fp->eth_q_stats.hw_csum_err++; + else + skb->ip_summed = CHECKSUM_UNNECESSARY; +} int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) { @@ -806,13 +825,9 @@ reuse_rx: skb_checksum_none_assert(skb); - if (bp->dev->features & NETIF_F_RXCSUM) { + if (bp->dev->features & NETIF_F_RXCSUM) + bnx2x_csum_validate(skb, cqe, fp); - if (likely(BNX2X_RX_CSUM_OK(cqe))) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else - fp->eth_q_stats.hw_csum_err++; - } skb_record_rx_queue(skb, fp->rx_queue); -- cgit v1.1 From afff07e61a5243e14ee3f0a272a0380cd744a8a3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 13 Jun 2012 11:44:58 +0200 Subject: usb-storage: Add 090c:1000 to unusal-devs This device gives a bogus answer to get_capacity(16): [ 8628.278614] scsi 8:0:0:0: Direct-Access USB 2.0 USB Flash Drive 1100 PQ: 0 ANSI: 4 [ 8628.279452] sd 8:0:0:0: Attached scsi generic sg4 type 0 [ 8628.280338] sd 8:0:0:0: [sdd] 35747322042253313 512-byte logical blocks: (18.3 EB/15.8 EiB) So set the quirk flag to avoid using get_capacity(16) with it: [11731.386014] usb-storage 2-1.6:1.0: Quirks match for vid 090c pid 1000: 80000 [11731.386075] scsi9 : usb-storage 2-1.6:1.0 [11731.386172] usbcore: registered new interface driver usb-storage [11731.386175] USB Mass Storage support registered. [11732.387394] scsi 9:0:0:0: Direct-Access USB 2.0 USB Flash Drive 1100 PQ: 0 ANSI: 4 [11732.388462] sd 9:0:0:0: Attached scsi generic sg3 type 0 [11732.389432] sd 9:0:0:0: [sdc] 7975296 512-byte logical blocks: (4.08 GB/3.80 GiB) Which makes the capacity look a lot more sane :) Signed-off-by: Hans de Goede Tested-by: Simon Raffeiner Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 1719886..caf22bf 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1107,6 +1107,13 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, USB_SC_RBC, USB_PR_BULK, NULL, 0 ), +/* Feiya QDI U2 DISK, reported by Hans de Goede */ +UNUSUAL_DEV( 0x090c, 0x1000, 0x0000, 0xffff, + "Feiya", + "QDI U2 DISK", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_READ_CAPACITY_16 ), + /* aeb */ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, "Feiya", -- cgit v1.1 From 55558c33d6d46cb6f426b729f4119e3b2f12f02b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 22 May 2012 20:54:34 +0300 Subject: USB: Checking the wrong variable in usb_disable_lpm() We check "u1_params" instead of checking "u2_params". Signed-off-by: Dan Carpenter Signed-off-by: Sarah Sharp --- drivers/usb/core/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 04fb834..25a7422 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3379,7 +3379,7 @@ int usb_disable_lpm(struct usb_device *udev) return 0; udev->lpm_disable_count++; - if ((udev->u1_params.timeout == 0 && udev->u1_params.timeout == 0)) + if ((udev->u1_params.timeout == 0 && udev->u2_params.timeout == 0)) return 0; /* If LPM is enabled, attempt to disable it. */ -- cgit v1.1 From e25e62aecac42379e113c63a674a86ae3ebbec8d Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 7 Jun 2012 11:10:32 -0700 Subject: xhci: Fix error path return value. This patch fixes an issue discovered by Dan Carpenter: The patch 3b3db026414b: "xhci: Add infrastructure for host-specific LPM policies." from May 9, 2012, leads to the following warning: drivers/usb/host/xhci.c:3909 xhci_get_timeout_no_hub_lpm() warn: signedness bug returning '-22' 3906 default: 3907 dev_warn(&udev->dev, "%s: Can't get timeout for non-U1 or U2 state.\n", 3908 __func__); 3909 return -EINVAL; ^^^^^^^^^^^^^^ This should be a u16 like USB3_LPM_DISABLED or something. 3910 } 3911 3912 if (sel <= max_sel_pel && pel <= max_sel_pel) 3913 return USB3_LPM_DEVICE_INITIATED; Signed-off-by: Sarah Sharp Reported-by: Dan Carpenter --- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index afdc73e..1d4958f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3906,7 +3906,7 @@ static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, default: dev_warn(&udev->dev, "%s: Can't get timeout for non-U1 or U2 state.\n", __func__); - return -EINVAL; + return USB3_LPM_DISABLED; } if (sel <= max_sel_pel && pel <= max_sel_pel) -- cgit v1.1 From 46ed8f00d8982e49f8fe2c1a9cea192f640cb3ba Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 1 Jun 2012 10:06:23 +0200 Subject: xhci: Fix invalid loop check in xhci_free_tt_info() xhci_free_tt_info() may access the invalid memory when it removes the last entry but the list is not empty. Then tt_next reaches to the list head but it still tries to check the tt_info of that entry. This patch fixes the bug and cleans up the messy code by rewriting with a simple list_for_each_entry_safe(). This patch should be backported to kernels as old as 3.2, that contain the commit 839c817ce67178ca3c7c7ad534c571bba1e69ebe "xhci: Store information about roothubs and TTs." Signed-off-by: Takashi Iwai Signed-off-by: Sarah Sharp Reviewed-by: Oliver Neukum Cc: --- drivers/usb/host/xhci-mem.c | 39 ++++++++++----------------------------- 1 file changed, 10 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index ec4338e..898dfc8 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -793,10 +793,9 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, int slot_id) { - struct list_head *tt; struct list_head *tt_list_head; - struct list_head *tt_next; - struct xhci_tt_bw_info *tt_info; + struct xhci_tt_bw_info *tt_info, *next; + bool slot_found = false; /* If the device never made it past the Set Address stage, * it may not have the real_port set correctly. @@ -808,34 +807,16 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci, } tt_list_head = &(xhci->rh_bw[virt_dev->real_port - 1].tts); - if (list_empty(tt_list_head)) - return; - - list_for_each(tt, tt_list_head) { - tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list); - if (tt_info->slot_id == slot_id) + list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) { + /* Multi-TT hubs will have more than one entry */ + if (tt_info->slot_id == slot_id) { + slot_found = true; + list_del(&tt_info->tt_list); + kfree(tt_info); + } else if (slot_found) { break; + } } - /* Cautionary measure in case the hub was disconnected before we - * stored the TT information. - */ - if (tt_info->slot_id != slot_id) - return; - - tt_next = tt->next; - tt_info = list_entry(tt, struct xhci_tt_bw_info, - tt_list); - /* Multi-TT hubs will have more than one entry */ - do { - list_del(tt); - kfree(tt_info); - tt = tt_next; - if (list_empty(tt_list_head)) - break; - tt_next = tt->next; - tt_info = list_entry(tt, struct xhci_tt_bw_info, - tt_list); - } while (tt_info->slot_id == slot_id); } int xhci_alloc_tt_info(struct xhci_hcd *xhci, -- cgit v1.1 From 32f1d2c536d0c26c5814cb0e6a0606c42d02fac1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 1 Jun 2012 10:06:24 +0200 Subject: xhci: Don't free endpoints in xhci_mem_cleanup() This patch fixes a few issues introduced in the recent fix [f8a9e72d: USB: fix resource leak in xhci power loss path] - The endpoints listed in bw table are just links and each entry is an array member of dev->eps[]. But the commit above adds a kfree() call to these instances, and thus it results in memory corruption. - It clears only the first entry of rh_bw[], but there can be multiple ports. - It'd be safer to clear the list_head of ep as well, not only removing from the list, as it's checked in xhci_discover_or_reset_device(). This patch should be backported to kernels as old as 3.2, that contain the commit 839c817ce67178ca3c7c7ad534c571bba1e69ebe "xhci: Store information about roothubs and TTs." Signed-off-by: Takashi Iwai Signed-off-by: Sarah Sharp Reviewed-by: Oliver Neukum Cc: --- drivers/usb/host/xhci-mem.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 898dfc8..77689bd 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1772,17 +1772,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) { struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); struct dev_info *dev_info, *next; - struct list_head *tt_list_head; - struct list_head *tt; - struct list_head *endpoints; - struct list_head *ep, *q; - struct xhci_tt_bw_info *tt_info; - struct xhci_interval_bw_table *bwt; - struct xhci_virt_ep *virt_ep; - unsigned long flags; int size; - int i; + int i, j, num_ports; /* Free the Event Ring Segment Table and the actual Event Ring */ size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); @@ -1841,21 +1833,22 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) } spin_unlock_irqrestore(&xhci->lock, flags); - bwt = &xhci->rh_bw->bw_table; - for (i = 0; i < XHCI_MAX_INTERVAL; i++) { - endpoints = &bwt->interval_bw[i].endpoints; - list_for_each_safe(ep, q, endpoints) { - virt_ep = list_entry(ep, struct xhci_virt_ep, bw_endpoint_list); - list_del(&virt_ep->bw_endpoint_list); - kfree(virt_ep); + num_ports = HCS_MAX_PORTS(xhci->hcs_params1); + for (i = 0; i < num_ports; i++) { + struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; + for (j = 0; j < XHCI_MAX_INTERVAL; j++) { + struct list_head *ep = &bwt->interval_bw[j].endpoints; + while (!list_empty(ep)) + list_del_init(ep->next); } } - tt_list_head = &xhci->rh_bw->tts; - list_for_each_safe(tt, q, tt_list_head) { - tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list); - list_del(tt); - kfree(tt_info); + for (i = 0; i < num_ports; i++) { + struct xhci_tt_bw_info *tt, *n; + list_for_each_entry_safe(tt, n, &xhci->rh_bw[i].tts, tt_list) { + list_del(&tt->tt_list); + kfree(tt); + } } xhci->num_usb2_ports = 0; -- cgit v1.1 From 622eb783fe6ff4c1baa47db16c3a5db97f9e6e50 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Wed, 13 Jun 2012 10:51:57 +0800 Subject: xHCI: Increase the timeout for controller save/restore state operation When system software decides to power down the xHC with the intent of resuming operation at a later time, it will ask xHC to save the internal state and restore it when resume to correctly recover from a power event. Two bits are used to enable this operation: Save State and Restore State. xHCI spec 4.23.2 says software should "Set the Controller Save/Restore State flag in the USBCMD register and wait for the Save/Restore State Status flag in the USBSTS register to transition to '0'". However, it does not define how long software should wait for the SSS/RSS bit to transition to 0. Currently the timeout is set to 1ms. There is bug report (https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1002697) indicates that the timeout is too short for ASMedia ASM1042 host controller to save/restore the state successfully. Increase the timeout to 10ms helps to resolve the issue. This patch should be backported to stable kernels as old as 2.6.37, that contain the commit 5535b1d5f8885695c6ded783c692e3c0d0eda8ca "USB: xHCI: PCI power management implementation" Signed-off-by: Andiry Xu Signed-off-by: Sarah Sharp Cc: Ming Lei Cc: stable@vger.kernel.org --- drivers/usb/host/xhci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1d4958f..a979cd0 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -795,8 +795,8 @@ int xhci_suspend(struct xhci_hcd *xhci) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_CSS; xhci_writel(xhci, command, &xhci->op_regs->command); - if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10*100)) { - xhci_warn(xhci, "WARN: xHC CMD_CSS timeout\n"); + if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) { + xhci_warn(xhci, "WARN: xHC save state timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } @@ -848,8 +848,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) command |= CMD_CRS; xhci_writel(xhci, command, &xhci->op_regs->command); if (handshake(xhci, &xhci->op_regs->status, - STS_RESTORE, 0, 10*100)) { - xhci_dbg(xhci, "WARN: xHC CMD_CSS timeout\n"); + STS_RESTORE, 0, 10 * 1000)) { + xhci_warn(xhci, "WARN: xHC restore state timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } -- cgit v1.1 From 4f7a67e2dd49fbfba002c453bc24bf00e701cc71 Mon Sep 17 00:00:00 2001 From: Ricardo Martins Date: Tue, 22 May 2012 18:02:03 +0100 Subject: USB: fix PS3 EHCI systems After commit aaa0ef289afe9186f81e2340114ea413eef0492a "PS3 EHCI QH read work-around", Terratec Grabby (em28xx) stopped working with AMD Geode LX 800 (USB controller AMD CS5536). Since this is a PS3 only fix, the following patch adds a conditional block around it. Signed-off-by: Ricardo Martins Acked-by: Alan Stern Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b100f5f..800be38 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -671,7 +671,9 @@ static int ehci_init(struct usb_hcd *hcd) hw = ehci->async->hw; hw->hw_next = QH_NEXT(ehci, ehci->async->qh_dma); hw->hw_info1 = cpu_to_hc32(ehci, QH_HEAD); +#if defined(CONFIG_PPC_PS3) hw->hw_info1 |= cpu_to_hc32(ehci, (1 << 7)); /* I = 1 */ +#endif hw->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT); hw->hw_qtd_next = EHCI_LIST_END(ehci); ehci->async->qh_state = QH_STATE_LINKED; -- cgit v1.1 From 07828b10985393cd875eac1545fba47107e97bf9 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Tue, 22 May 2012 13:47:25 -0300 Subject: USB: EHCI: Fix build warning in xilinx ehci driver This fixes the following warning: In file included from drivers/usb/host/ehci-hcd.c:1246:0: drivers/usb/host/ehci-xilinx-of.c:293:2: warning: initialization from incompatible pointer type [enabled by default] drivers/usb/host/ehci-xilinx-of.c:293:2: warning: (near initialization for 'ehci_hcd_xilinx_of_driver.shutdown') [enabled by default] Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-xilinx-of.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index 9c2cc46..e9713d5 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -270,14 +270,12 @@ static int ehci_hcd_xilinx_of_remove(struct platform_device *op) * * Properly shutdown the hcd, call driver's shutdown routine. */ -static int ehci_hcd_xilinx_of_shutdown(struct platform_device *op) +static void ehci_hcd_xilinx_of_shutdown(struct platform_device *op) { struct usb_hcd *hcd = dev_get_drvdata(&op->dev); if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); - - return 0; } -- cgit v1.1 From 0658a3366db7e27fa32c12e886230bb58c414c92 Mon Sep 17 00:00:00 2001 From: Jan Safrata Date: Tue, 22 May 2012 14:04:50 +0200 Subject: usb: use usb_serial_put in usb_serial_probe errors The use of kfree(serial) in error cases of usb_serial_probe was invalid - usb_serial structure allocated in create_serial() gets reference of usb_device that needs to be put, so we need to use usb_serial_put() instead of simple kfree(). Signed-off-by: Jan Safrata Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 6e8c527..27483f9 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -757,7 +757,7 @@ static int usb_serial_probe(struct usb_interface *interface, if (retval) { dbg("sub driver rejected device"); - kfree(serial); + usb_serial_put(serial); module_put(type->driver.owner); return retval; } @@ -829,7 +829,7 @@ static int usb_serial_probe(struct usb_interface *interface, */ if (num_bulk_in == 0 || num_bulk_out == 0) { dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); - kfree(serial); + usb_serial_put(serial); module_put(type->driver.owner); return -ENODEV; } @@ -843,7 +843,7 @@ static int usb_serial_probe(struct usb_interface *interface, if (num_ports == 0) { dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); - kfree(serial); + usb_serial_put(serial); module_put(type->driver.owner); return -EIO; } -- cgit v1.1 From c4828d96900453f1ad506b1488928307711a8b28 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Mon, 11 Jun 2012 21:38:29 +0200 Subject: USB: ohci-hub: Mark ohci_finish_controller_resume() as __maybe_unused ohci_finish_controller_resume() is intended to be used in platform specific drivers ohci-*.c, included from ohci-hcd.c. Some of them don't actually use ohci_finish_controller_resume(), so mark it as __maybe_unused. Signed-off-by: Roland Stigge Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 836772d..2f3619e 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -317,7 +317,7 @@ static int ohci_bus_resume (struct usb_hcd *hcd) } /* Carry out the final steps of resuming the controller device */ -static void ohci_finish_controller_resume(struct usb_hcd *hcd) +static void __maybe_unused ohci_finish_controller_resume(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); int port; -- cgit v1.1 From 354ab8567ae3107a8cbe7228c3181990ba598aac Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Tue, 5 Jun 2012 15:34:27 +0300 Subject: Fix OMAP EHCI suspend/resume failure (i693) Its observed with some PHY, the 60Mhz clock gets cut too soon for OMAP EHCI, leaving OMAP-EHCI in a bad state. So on starting port suspend, make sure the 60Mhz clock to EHCI is kept alive using an internal clock, so that EHCi can cleanly transition its hw state machine on a port suspend. Its not proven if this is the issue hit on USB3333, but the symptoms look very similar. Signed-off-by: Anand Gadiyar Signed-off-by: Vikram Pandita Signed-off-by: Volodymyr Mieshkov Acked-by: Alan Stern Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 168 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index a44294d..17cfb8a 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -43,6 +43,7 @@ #include #include #include +#include /* EHCI Register Set */ #define EHCI_INSNREG04 (0xA0) @@ -55,6 +56,15 @@ #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 +/* Errata i693 */ +static struct clk *utmi_p1_fck; +static struct clk *utmi_p2_fck; +static struct clk *xclk60mhsp1_ck; +static struct clk *xclk60mhsp2_ck; +static struct clk *usbhost_p1_fck; +static struct clk *usbhost_p2_fck; +static struct clk *init_60m_fclk; + /*-------------------------------------------------------------------------*/ static const struct hc_driver ehci_omap_hc_driver; @@ -70,6 +80,41 @@ static inline u32 ehci_read(void __iomem *base, u32 reg) return __raw_readl(base + reg); } +/* Erratum i693 workaround sequence */ +static void omap_ehci_erratum_i693(struct ehci_hcd *ehci) +{ + int ret = 0; + + /* Switch to the internal 60 MHz clock */ + ret = clk_set_parent(utmi_p1_fck, init_60m_fclk); + if (ret != 0) + ehci_err(ehci, "init_60m_fclk set parent" + "failed error:%d\n", ret); + + ret = clk_set_parent(utmi_p2_fck, init_60m_fclk); + if (ret != 0) + ehci_err(ehci, "init_60m_fclk set parent" + "failed error:%d\n", ret); + + clk_enable(usbhost_p1_fck); + clk_enable(usbhost_p2_fck); + + /* Wait 1ms and switch back to the external clock */ + mdelay(1); + ret = clk_set_parent(utmi_p1_fck, xclk60mhsp1_ck); + if (ret != 0) + ehci_err(ehci, "xclk60mhsp1_ck set parent" + "failed error:%d\n", ret); + + ret = clk_set_parent(utmi_p2_fck, xclk60mhsp2_ck); + if (ret != 0) + ehci_err(ehci, "xclk60mhsp2_ck set parent" + "failed error:%d\n", ret); + + clk_disable(usbhost_p1_fck); + clk_disable(usbhost_p2_fck); +} + static void omap_ehci_soft_phy_reset(struct platform_device *pdev, u8 port) { struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev); @@ -100,6 +145,50 @@ static void omap_ehci_soft_phy_reset(struct platform_device *pdev, u8 port) } } +static int omap_ehci_hub_control( + struct usb_hcd *hcd, + u16 typeReq, + u16 wValue, + u16 wIndex, + char *buf, + u16 wLength +) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + u32 __iomem *status_reg = &ehci->regs->port_status[ + (wIndex & 0xff) - 1]; + u32 temp; + unsigned long flags; + int retval = 0; + + spin_lock_irqsave(&ehci->lock, flags); + + if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { + temp = ehci_readl(ehci, status_reg); + if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { + retval = -EPIPE; + goto done; + } + + temp &= ~PORT_WKCONN_E; + temp |= PORT_WKDISC_E | PORT_WKOC_E; + ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); + + omap_ehci_erratum_i693(ehci); + + set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); + goto done; + } + + spin_unlock_irqrestore(&ehci->lock, flags); + + /* Handle the hub control events here */ + return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); +done: + spin_unlock_irqrestore(&ehci->lock, flags); + return retval; +} + static void disable_put_regulator( struct ehci_hcd_omap_platform_data *pdata) { @@ -264,8 +353,76 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) /* root ports should always stay powered */ ehci_port_power(omap_ehci, 1); + /* get clocks */ + utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); + if (IS_ERR(utmi_p1_fck)) { + ret = PTR_ERR(utmi_p1_fck); + dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); + goto err_add_hcd; + } + + xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); + if (IS_ERR(xclk60mhsp1_ck)) { + ret = PTR_ERR(xclk60mhsp1_ck); + dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); + goto err_utmi_p1_fck; + } + + utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); + if (IS_ERR(utmi_p2_fck)) { + ret = PTR_ERR(utmi_p2_fck); + dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); + goto err_xclk60mhsp1_ck; + } + + xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); + if (IS_ERR(xclk60mhsp2_ck)) { + ret = PTR_ERR(xclk60mhsp2_ck); + dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); + goto err_utmi_p2_fck; + } + + usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); + if (IS_ERR(usbhost_p1_fck)) { + ret = PTR_ERR(usbhost_p1_fck); + dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); + goto err_xclk60mhsp2_ck; + } + + usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); + if (IS_ERR(usbhost_p2_fck)) { + ret = PTR_ERR(usbhost_p2_fck); + dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); + goto err_usbhost_p1_fck; + } + + init_60m_fclk = clk_get(dev, "init_60m_fclk"); + if (IS_ERR(init_60m_fclk)) { + ret = PTR_ERR(init_60m_fclk); + dev_err(dev, "init_60m_fclk failed error:%d\n", ret); + goto err_usbhost_p2_fck; + } + return 0; +err_usbhost_p2_fck: + clk_put(usbhost_p2_fck); + +err_usbhost_p1_fck: + clk_put(usbhost_p1_fck); + +err_xclk60mhsp2_ck: + clk_put(xclk60mhsp2_ck); + +err_utmi_p2_fck: + clk_put(utmi_p2_fck); + +err_xclk60mhsp1_ck: + clk_put(xclk60mhsp1_ck); + +err_utmi_p1_fck: + clk_put(utmi_p1_fck); + err_add_hcd: disable_put_regulator(pdata); pm_runtime_put_sync(dev); @@ -294,6 +451,15 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) disable_put_regulator(dev->platform_data); iounmap(hcd->regs); usb_put_hcd(hcd); + + clk_put(utmi_p1_fck); + clk_put(utmi_p2_fck); + clk_put(xclk60mhsp1_ck); + clk_put(xclk60mhsp2_ck); + clk_put(usbhost_p1_fck); + clk_put(usbhost_p2_fck); + clk_put(init_60m_fclk); + pm_runtime_put_sync(dev); pm_runtime_disable(dev); @@ -364,7 +530,7 @@ static const struct hc_driver ehci_omap_hc_driver = { * root hub support */ .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, + .hub_control = omap_ehci_hub_control, .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, -- cgit v1.1 From fdec53d5203ee3d44be7c09d1524e3a6287d46a7 Mon Sep 17 00:00:00 2001 From: Javi Merino Date: Wed, 13 Jun 2012 15:07:00 +0100 Subject: DMA: PL330: Fix racy mutex unlock pl330_update() stores a pointer to the thrd->req that finished, which contains a pointer to the corresponding pl330_req. This is done with the pl330_lock held. Then, it iterates through the req_done list, calling the callback for each of the requests that are done. The problem is that the driver releases the lock before calling the callback for each of the callbacks. pl330_submit_req() running in another processor can then acquire the lock and insert another request in one of the thrd->req that hasn't been processed yet, replacing the pointer to pl330_req there. When the callback returns in pl330_update() and the next rqdone is popped from the list, it dereferences the pl330_req pointer to the just scheduled pl330_req, instead of the one that has finished, calling pl330 with the wrong r. This patch fixes this by storing the pointer to pl330_req directly in the list. Signed-off-by: Javi Merino Cc: Jassi Brar Acked-by: Jassi Brar Signed-off-by: Vinod Koul --- drivers/dma/pl330.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 3ce7d55..e4feba6 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -392,6 +392,8 @@ struct pl330_req { struct pl330_reqcfg *cfg; /* Pointer to first xfer in the request. */ struct pl330_xfer *x; + /* Hook to attach to DMAC's list of reqs with due callback */ + struct list_head rqd; }; /* @@ -461,8 +463,6 @@ struct _pl330_req { /* Number of bytes taken to setup MC for the req */ u32 mc_len; struct pl330_req *r; - /* Hook to attach to DMAC's list of reqs with due callback */ - struct list_head rqd; }; /* ToBeDone for tasklet */ @@ -1683,7 +1683,7 @@ static void pl330_dotask(unsigned long data) /* Returns 1 if state was updated, 0 otherwise */ static int pl330_update(const struct pl330_info *pi) { - struct _pl330_req *rqdone; + struct pl330_req *rqdone, *tmp; struct pl330_dmac *pl330; unsigned long flags; void __iomem *regs; @@ -1750,7 +1750,10 @@ static int pl330_update(const struct pl330_info *pi) if (active == -1) /* Aborted */ continue; - rqdone = &thrd->req[active]; + /* Detach the req */ + rqdone = thrd->req[active].r; + thrd->req[active].r = NULL; + mark_free(thrd, active); /* Get going again ASAP */ @@ -1762,20 +1765,11 @@ static int pl330_update(const struct pl330_info *pi) } /* Now that we are in no hurry, do the callbacks */ - while (!list_empty(&pl330->req_done)) { - struct pl330_req *r; - - rqdone = container_of(pl330->req_done.next, - struct _pl330_req, rqd); - - list_del_init(&rqdone->rqd); - - /* Detach the req */ - r = rqdone->r; - rqdone->r = NULL; + list_for_each_entry_safe(rqdone, tmp, &pl330->req_done, rqd) { + list_del(&rqdone->rqd); spin_unlock_irqrestore(&pl330->lock, flags); - _callback(r, PL330_ERR_NONE); + _callback(rqdone, PL330_ERR_NONE); spin_lock_irqsave(&pl330->lock, flags); } -- cgit v1.1 From b9b52918abe88d9135dd570fb394b9c432eb1cfd Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 12 Jun 2012 10:49:51 +0100 Subject: ARM: 7422/1: mmc: mmci: Allocate platform memory during Device Tree boot When booting with Device Tree enabled, platform specific information is gathered by parsing the DT binary. Platform data is subsequently populated with the result. The memory required for this is not automatically allocated during Device Tree boot, so we'll do it here instead. Acked-by: Linus Walleij Signed-off-by: Lee Jones Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f0fcce4..0045ee0 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1276,6 +1276,12 @@ static int __devinit mmci_probe(struct amba_device *dev, return -EINVAL; } + if (!plat) { + plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); + if (!plat) + return -ENOMEM; + } + if (np) mmci_dt_populate_generic_pdata(np, plat); -- cgit v1.1 From 7b33dc2b050b71de0e202885a26caffbc864d072 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Jun 2012 21:36:09 +0300 Subject: RDMA/ocrdma: Fix off by one in ocrdma_query_gid() The dev->sgid_tbl[] array is allocated in ocrdma_alloc_resources(). It has OCRDMA_MAX_SGID elements so the test here is off by one. Signed-off-by: Dan Carpenter Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index d55d459..2e2e7ae 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -53,7 +53,7 @@ int ocrdma_query_gid(struct ib_device *ibdev, u8 port, dev = get_ocrdma_dev(ibdev); memset(sgid, 0, sizeof(*sgid)); - if (index > OCRDMA_MAX_SGID) + if (index >= OCRDMA_MAX_SGID) return -EINVAL; memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); -- cgit v1.1 From 6c4707f3f8c44ec18282e1c014c80e1c257042f9 Mon Sep 17 00:00:00 2001 From: Otto Meta Date: Wed, 6 Jun 2012 18:46:21 +0200 Subject: usb: cdc-acm: fix devices not unthrottled on open Currently CDC-ACM devices stay throttled when their TTY is closed while throttled, stalling further communication attempts after the next open. Unthrottling during open/activate got lost starting with kernel 3.0.0 and this patch reintroduces it. Signed-off-by: Otto Meta Cc: stable Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index f2a120e..36a2a0b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -567,6 +567,14 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) usb_autopm_put_interface(acm->control); + /* + * Unthrottle device in case the TTY was closed while throttled. + */ + spin_lock_irq(&acm->read_lock); + acm->throttled = 0; + acm->throttle_req = 0; + spin_unlock_irq(&acm->read_lock); + if (acm_submit_read_urbs(acm, GFP_KERNEL)) goto error_submit_read_urbs; -- cgit v1.1 From 5897b038296ea84e501ba5f957e11939f8cf9be0 Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Tue, 12 Jun 2012 09:34:33 +0900 Subject: usb: ehci-sh: fix illegal phy_init() running when platform_data is NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the platform_data is not set, pdata will be uninitialized value. Since the driver has the following code, if the condition is true when the pdata is uninitialized value, the driver may jump to the illegal phy_init(). if (pdata && pdata->phy_init) pdata->phy_init(); This patch also fixes the following warning: CC drivers/usb/host/ehci-hcd.o drivers/usb/host/ehci-sh.c: In function ‘ehci_hcd_sh_probe’: drivers/usb/host/ehci-sh.c:104: warning: ‘pdata’ may be used uninitialized in this function Signed-off-by: Yoshihiro Shimoda Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sh.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index ca819cd..e7cb392 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -126,8 +126,7 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) goto fail_create_hcd; } - if (pdev->dev.platform_data != NULL) - pdata = pdev->dev.platform_data; + pdata = pdev->dev.platform_data; /* initialize hcd */ hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev, -- cgit v1.1 From b3a3dd074f7053ef824ad077e5331b52220ceba1 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 12 Jun 2012 20:23:52 +0200 Subject: USB: fix gathering of interface associations TEAC's UD-H01 (and probably other devices) have a gap in the interface number allocation of their descriptors: Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 220 bNumInterfaces 3 [...] Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 [...] Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 2 bInterfaceCount 2 bFunctionClass 1 Audio bFunctionSubClass 0 bFunctionProtocol 32 iFunction 4 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 [...] Once a configuration is selected, usb_set_configuration() walks the known interfaces of a given configuration and calls find_iad() on each of them to set the interface association pointer the interface is included in. The problem here is that the loop variable is taken for the interface number in the comparison logic that gathers the association. Which is fine as long as the descriptors are sane. In the case above, however, the logic gets out of sync and the interface association fields of all interfaces beyond the interface number gap are wrong. Fix this by passing the interface's bInterfaceNumber to find_iad() instead. Signed-off-by: Daniel Mack Reported-by: bEN Reported-by: Ivan Perrone Tested-by: ivan perrone Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index b548cf1..bdd1c67 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1838,7 +1838,6 @@ free_interfaces: intfc = cp->intf_cache[i]; intf->altsetting = intfc->altsetting; intf->num_altsetting = intfc->num_altsetting; - intf->intf_assoc = find_iad(dev, cp, i); kref_get(&intfc->ref); alt = usb_altnum_to_altsetting(intf, 0); @@ -1851,6 +1850,8 @@ free_interfaces: if (!alt) alt = &intf->altsetting[0]; + intf->intf_assoc = + find_iad(dev, cp, alt->desc.bInterfaceNumber); intf->cur_altsetting = alt; usb_enable_interface(dev, intf, true); intf->dev.parent = &dev->dev; -- cgit v1.1 From c3b15452e253ab0629cd9e400d3fb6d76c76cb73 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Jun 2012 16:43:53 +0100 Subject: Extcon: Don't try to create duplicate link names We can't create a link from the device to the compatibility switch class since we already create a link from the device to to the extcon class object and we try to use the same name for both links. This causes a loud complaint from sysfs on boot. Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon_class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon_class.c index f598a70..159aeb0 100644 --- a/drivers/extcon/extcon_class.c +++ b/drivers/extcon/extcon_class.c @@ -762,7 +762,7 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev) #if defined(CONFIG_ANDROID) if (switch_class) ret = class_compat_create_link(switch_class, edev->dev, - dev); + NULL); #endif /* CONFIG_ANDROID */ spin_lock_init(&edev->lock); -- cgit v1.1 From a529ae4ba3acfd97210769e3445e8d8b07ca1112 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Thu, 14 Jun 2012 15:45:09 +0200 Subject: iio: drop wrong reference from Kconfig The documentation lives in drivers/staging/iio/Documentation, but according to Jonathan it's obsolete and needs fixing. Signed-off-by: Jiri Kosina Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 56eecef..2ec93da 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -8,8 +8,7 @@ menuconfig IIO help The industrial I/O subsystem provides a unified framework for drivers for many different types of embedded sensors using a - number of different physical interfaces (i2c, spi, etc). See - Documentation/iio for more information. + number of different physical interfaces (i2c, spi, etc). if IIO -- cgit v1.1 From 9f77186dd13125bef301f9136b6075f5530f3d85 Mon Sep 17 00:00:00 2001 From: Ben Chan Date: Thu, 14 Jun 2012 13:18:56 -0700 Subject: staging: gdm72xx: Release netlink socket properly This patch modifies the gdm72xx driver to properly release a netlink socket using netlink_kernel_release. It fixes the following kernel crash, which occurs after repeatedly suspending and resuming a system. kernel BUG at /home/benchan/trunk/src/third_party/kernel/files/mm/slub.c:3471! invalid opcode: 0000 [#1] SMP CPU 2 Modules linked in: asix usbnet snd_hda_codec_hdmi snd_hda_codec_cirrus i2c_dev uinput snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_timer bluetooth snd_page_alloc fuse aesni_intel cryptd isl29018(C) aes_x86_64 industrialio(C) memconsole nm10_gpio rtc_cmos nf_conntrack_ipv6 nf_defrag_ipv6 r8169 ath9k mac80211 ip6table_filter ath9k_common ath9k_hw ath cfg80211 xt_mark ip6_tables uvcvideo videobuf2_core videodev videobuf2_vmalloc videobuf2_memops gdmwm(C) joydev Pid: 3125, comm: kworker/u:30 Tainted: G WC 3.4.0 #1 RIP: 0010:[] [] kfree+0x67/0xca RSP: 0018:ffff880134977d60 EFLAGS: 00010246 RAX: 4000000000000400 RBX: ffffffff818832a0 RCX: 0000000000000000 RDX: 4000000000000000 RSI: 0000000000000000 RDI: ffffffff818832a0 RBP: ffff880134977d80 R08: 00000000ffffffff R09: ffffea00000620c0 R10: ffffffff8111b729 R11: ffff880149fb3840 R12: ffffffff81a08840 R13: ffffffff813f5bc3 R14: ffffffff8138ed84 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff88014fb00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 00007f7cad963110 CR3: 000000000180b000 CR4: 00000000000407e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process kworker/u:30 (pid: 3125, threadinfo ffff880134976000, task ffff8801330647e0) Stack: 0000000000000002 ffffffff818832a0 ffffffff81a08840 ffff880134977df0 ffff880134977da0 ffffffff813f5bc3 ffff880134977df0 ffffffff81883250 ffff880134977dd0 ffffffff8138e64c 0000000180150010 ffffffff81883250 Call Trace: [] ipv4_sysctl_exit_net+0x23/0x27 [] ops_exit_list+0x27/0x50 [] cleanup_net+0xee/0x17c [] process_one_work+0x199/0x2b8 [] worker_thread+0x13c/0x222 [] ? manage_workers.isra.26+0x171/0x171 [] kthread+0x8b/0x93 [] kernel_thread_helper+0x4/0x10 [] ? __init_kthread_worker+0x39/0x39 [] ? gs_change+0xb/0xb Code: 83 c4 10 49 83 3c 24 00 eb e4 48 83 fb 10 76 76 48 89 df e8 17 e1 ff ff 49 89 c1 48 8b 00 a8 80 75 15 49 f7 01 00 c0 00 00 75 02 <0f> 0b 4c 89 cf e8 b8 b4 fd ff eb 4f 4c 8b 55 08 49 8b 79 30 48 RIP [] kfree+0x67/0xca RSP Signed-off-by: Ben Chan Cc: Sage Ahn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/netlink_k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 292af0f..5166513 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -104,7 +104,7 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type, void netlink_exit(struct sock *sock) { - sock_release(sock->sk_socket); + netlink_kernel_release(sock); } int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) -- cgit v1.1 From e8d4e8be860d935099ffcf695dcd29b55ae50b36 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Fri, 15 Jun 2012 11:54:00 +0530 Subject: usb: dwc3: fix giveback of queued request in ep_dequeue In case of ep_dequeue , if dequeued request was submitted for dma transfer, then endpoint is stopped. Once endpoint is stooped, callback for the dequeued request must be called. Signed-off-by: Pratyush Anand Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 3df1a19..ec70df7 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1091,7 +1091,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, if (r == req) { /* wait until it is processed */ dwc3_stop_active_transfer(dwc, dep->number); - goto out0; + goto out1; } dev_err(dwc->dev, "request %p was not queued to %s\n", request, ep->name); @@ -1099,6 +1099,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, goto out0; } +out1: /* giveback the request */ dwc3_gadget_giveback(dep, req, -ECONNRESET); -- cgit v1.1 From 3026b0e942c65c65c8fc80d391d004228b52b916 Mon Sep 17 00:00:00 2001 From: Lubomir Schmidt Date: Fri, 15 Jun 2012 15:12:17 -0500 Subject: staging: r8712u: Add new USB IDs There are two new devices for this driver. Signed-off-by: Larry Finger Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/usb_intf.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index 9bd18e2..69f616c 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -102,6 +102,8 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { /* - */ {USB_DEVICE(0x20F4, 0x646B)}, {USB_DEVICE(0x083A, 0xC512)}, + {USB_DEVICE(0x25D4, 0x4CA1)}, + {USB_DEVICE(0x25D4, 0x4CAB)}, /* RTL8191SU */ /* Realtek */ -- cgit v1.1 From e2ae715d66bf4becfb85eb84b7150e23cf27df30 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 15 Jun 2012 14:07:51 +0200 Subject: kmsg - kmsg_dump() use iterator to receive log buffer content Provide an iterator to receive the log buffer content, and convert all kmsg_dump() users to it. The structured data in the kmsg buffer now contains binary data, which should no longer be copied verbatim to the kmsg_dump() users. The iterator should provide reliable access to the buffer data, and also supports proper log line-aware chunking of data while iterating. Signed-off-by: Kay Sievers Tested-by: Tony Luck Reported-by: Anton Vorontsov Tested-by: Anton Vorontsov Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/mtdoops.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index ae36d7e..551e316 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -304,32 +304,17 @@ static void find_next_position(struct mtdoops_context *cxt) } static void mtdoops_do_dump(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, const char *s1, unsigned long l1, - const char *s2, unsigned long l2) + enum kmsg_dump_reason reason) { struct mtdoops_context *cxt = container_of(dumper, struct mtdoops_context, dump); - unsigned long s1_start, s2_start; - unsigned long l1_cpy, l2_cpy; - char *dst; - - if (reason != KMSG_DUMP_OOPS && - reason != KMSG_DUMP_PANIC) - return; /* Only dump oopses if dump_oops is set */ if (reason == KMSG_DUMP_OOPS && !dump_oops) return; - dst = cxt->oops_buf + MTDOOPS_HEADER_SIZE; /* Skip the header */ - l2_cpy = min(l2, record_size - MTDOOPS_HEADER_SIZE); - l1_cpy = min(l1, record_size - MTDOOPS_HEADER_SIZE - l2_cpy); - - s2_start = l2 - l2_cpy; - s1_start = l1 - l1_cpy; - - memcpy(dst, s1 + s1_start, l1_cpy); - memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); + kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE, + record_size - MTDOOPS_HEADER_SIZE, NULL); /* Panics must be written immediately */ if (reason != KMSG_DUMP_OOPS) @@ -375,6 +360,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) return; } + cxt->dump.max_reason = KMSG_DUMP_OOPS; cxt->dump.dump = mtdoops_do_dump; err = kmsg_dump_register(&cxt->dump); if (err) { -- cgit v1.1 From d9cb9bd63eb27ac19f26a8547128c053f43a5da8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 15 Jun 2012 00:20:44 +0000 Subject: can: c_can: precedence error in c_can_chip_config() (CAN_CTRLMODE_LISTENONLY & CAN_CTRLMODE_LOOPBACK) is (0x02 & 0x01) which is zero so the condition is never true. The intent here was to test that both flags were set. Cc: # 2.6.39+ Signed-off-by: Dan Carpenter Acked-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/c_can/c_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 8dc84d6..86cd532 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -590,8 +590,8 @@ static void c_can_chip_config(struct net_device *dev) priv->write_reg(priv, &priv->regs->control, CONTROL_ENABLE_AR); - if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & - CAN_CTRLMODE_LOOPBACK)) { + if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) && + (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) { /* loopback + silent mode : useful for hot self-test */ priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); -- cgit v1.1 From bc14786a100cc6a81cd060e8031ec481241b418c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 13 Jun 2012 09:45:16 +0000 Subject: bnx2x: fix panic when TX ring is full There is a off by one error in the minimal number of BD in bnx2x_start_xmit() and bnx2x_tx_int() before stopping/resuming tx queue. A full size GSO packet, with data included in skb->head really needs (MAX_SKB_FRAGS + 4) BDs, because of bnx2x_tx_split() This error triggers if BQL is disabled and heavy TCP transmit traffic occurs. bnx2x_tx_split() definitely can be called, remove a wrong comment. Reported-by: Tomas Hruby Signed-off-by: Eric Dumazet Cc: Eilon Greenstein Cc: Yaniv Rosner Cc: Merav Sicron Cc: Tom Herbert Cc: Robert Evans Cc: Willem de Bruijn Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index cbc56f2..8098eea 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -190,7 +190,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata) if ((netif_tx_queue_stopped(txq)) && (bp->state == BNX2X_STATE_OPEN) && - (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3)) + (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4)) netif_tx_wake_queue(txq); __netif_tx_unlock(txq); @@ -2516,8 +2516,6 @@ int bnx2x_poll(struct napi_struct *napi, int budget) /* we split the first BD into headers and data BDs * to ease the pain of our fellow microcode engineers * we use one mapping for both BDs - * So far this has only been observed to happen - * in Other Operating Systems(TM) */ static noinline u16 bnx2x_tx_split(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, @@ -3171,7 +3169,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) txdata->tx_bd_prod += nbd; - if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 3)) { + if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 4)) { netif_tx_stop_queue(txq); /* paired memory barrier is in bnx2x_tx_int(), we have to keep @@ -3180,7 +3178,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) smp_mb(); fp->eth_q_stats.driver_xoff++; - if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3) + if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4) netif_tx_wake_queue(txq); } txdata->tx_pkt++; -- cgit v1.1 From 0f6efff92524c65fc3ef41c8b936c526580f1db0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Jun 2012 08:34:24 +0000 Subject: qlcnic: off by one in qlcnic_init_pci_info() The adapter->npars[] array has QLCNIC_MAX_PCI_FUNC elements. We allocate it that way a few lines earlier in the function. So this test is off by one. Signed-off-by: Dan Carpenter Acked-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 46e77a2..ad98f4d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -479,7 +479,7 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { pfn = pci_info[i].id; - if (pfn > QLCNIC_MAX_PCI_FUNC) { + if (pfn >= QLCNIC_MAX_PCI_FUNC) { ret = QL_STATUS_INVALID_PARAM; goto err_eswitch; } -- cgit v1.1 From e5a867a51d9b009f90d5dca6a320608e4e8a37ec Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 16 Jun 2012 07:41:28 +0100 Subject: drm/udl: only bind to the video devices on the hub. This is ported from udlfb. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=832188 Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/udl_drv.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 4d02c46..6e52069 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -13,8 +13,21 @@ static struct drm_driver driver; +/* + * There are many DisplayLink-based graphics products, all with unique PIDs. + * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff) + * We also require a match on SubClass (0x00) and Protocol (0x00), + * which is compatible with all known USB 2.0 era graphics chips and firmware, + * but allows DisplayLink to increment those for any future incompatible chips + */ static struct usb_device_id id_table[] = { - {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,}, + {.idVendor = 0x17e9, .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0x00, + .bInterfaceProtocol = 0x00, + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS | + USB_DEVICE_ID_MATCH_INT_PROTOCOL,}, {}, }; MODULE_DEVICE_TABLE(usb, id_table); -- cgit v1.1 From 0ec0612a80f957000999c3f7b31a84e3558c719d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 15:54:57 -0400 Subject: drm/radeon: fix regression in dynpm due to multi-ring rework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not all asics have all rings, so make sure the ring is ready before attempting to check it in the dynpm work handler. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=43367 Signed-off-by: Alex Deucher Reviewed-by: Jerome Glisse Reviewed-by: Christian König Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_pm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 0882554..5b37e28 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -801,9 +801,13 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) int i; for (i = 0; i < RADEON_NUM_RINGS; ++i) { - not_processed += radeon_fence_count_emitted(rdev, i); - if (not_processed >= 3) - break; + struct radeon_ring *ring = &rdev->ring[i]; + + if (ring->ready) { + not_processed += radeon_fence_count_emitted(rdev, i); + if (not_processed >= 3) + break; + } } if (not_processed >= 3) { /* should upclock */ -- cgit v1.1 From 489797d510dfbce15120492d7ef6f956928b99f2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 12 Jun 2012 16:10:39 +0100 Subject: drm/radeon/prime: reserve/unreserve around pin I finally got to test this code a bit more and hit the ttm no reserved assert, so add the reservations around the pinning. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_prime.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c index 8ddab4c7..6bef46a 100644 --- a/drivers/gpu/drm/radeon/radeon_prime.c +++ b/drivers/gpu/drm/radeon/radeon_prime.c @@ -169,11 +169,17 @@ struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, struct radeon_bo *bo = gem_to_radeon_bo(obj); int ret = 0; + ret = radeon_bo_reserve(bo, false); + if (unlikely(ret != 0)) + return ERR_PTR(ret); + /* pin buffer into GTT */ ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL); - if (ret) + if (ret) { + radeon_bo_unreserve(bo); return ERR_PTR(ret); - + } + radeon_bo_unreserve(bo); return dma_buf_export(bo, &radeon_dmabuf_ops, obj->size, flags); } -- cgit v1.1 From ce020ea53264f1460ae619cfc12f968dbd0b8974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Sun, 10 Jun 2012 23:39:55 +0200 Subject: drm via: initialize object_idr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The field obejct_idr of struct drm_via_private was introduced with the commit http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=77ee8f3825054f23b17e9c8f728f061defd86cdc . In that patch idr_init(&dev->object_name_idr) was called instead of idr_init(&dev_priv->object_idr) by mistake, leaving the dev_priv->object_idr uninitialized. To be more exact, the object_idr buffer is filled with zeros because of kzalloc(), but the dev_priv->object_idr.lock spinlock can cause system freeze at lib/idr.c:move_to_free_list() when spin_lock_irqsave() is called on this spinlock. The patch was tested on Clevo D4J, model D410J laptop, on the following hardware, without AGP kernel module loaded: # lspci -s 01:00.0 -n 01:00.0 0300: 1106:3108 (rev 01) # lspci -s 01:00.0 -v 01:00.0 VGA compatible controller: VIA Technologies, Inc. K8M800/K8N800/K8N800A [S3 UniChrome Pro] (rev 01) (prog-if 00 [VGA controller]) Subsystem: CLEVO/KAPOK Computer Device 4702 Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 16 Memory at f0000000 (32-bit, prefetchable) [size=64M] Memory at d1000000 (32-bit, non-prefetchable) [size=16M] Expansion ROM at [disabled] Capabilities: [60] Power Management version 2 Capabilities: [70] AGP version 3.0 Signed-off-by: Márton Németh Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/via/via_map.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c index 1f18225..c126182 100644 --- a/drivers/gpu/drm/via/via_map.c +++ b/drivers/gpu/drm/via/via_map.c @@ -100,12 +100,11 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv == NULL) return -ENOMEM; + idr_init(&dev_priv->object_idr); dev->dev_private = (void *)dev_priv; dev_priv->chipset = chipset; - idr_init(&dev->object_name_idr); - pci_set_master(dev->pdev); ret = drm_vblank_init(dev, 1); -- cgit v1.1 From 648ccc7d35e3416fdc739d2e520e85de3125361b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Mon, 11 Jun 2012 19:09:25 +0200 Subject: drm sis: initialize object_idr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The filed object_idr of struct drm_sis_private was introduced with commit http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=6de8a748881f1cd9d795454da2b6db616d5ca3d7 . The idr_init(&dev->object_name_idr) is called instead of idr_init(&dev_priv->object_idr) by mistake, leaving object_idr uninitialized. Correct this. This patch was not tested because of lack of hardware. Signed-off-by: Márton Németh Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/sis/sis_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 30d98d1..dd14cd1 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -47,9 +47,9 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv == NULL) return -ENOMEM; + idr_init(&dev_priv->object_idr); dev->dev_private = (void *)dev_priv; dev_priv->chipset = chipset; - idr_init(&dev->object_name_idr); return 0; } -- cgit v1.1 From 6b53a0507b6e728c53f2fc60912a8511f151e5d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 11 Jun 2012 12:34:01 +0200 Subject: drm/radeon: enable HDMI on DCE5 (AKA NI excluding Aruba) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After recent changes HDMI code is ready to be enabled on DCE5. This patch just changes conditions to execute already present code on DCE5. Signed-off-by: Rafał Miłecki Reviewed-by: Alex Deucher Tested-by: Christian König Tested-by: Andre Heider Tested-by: Zoltán Böszörményi Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_encoders.c | 4 +++- drivers/gpu/drm/radeon/evergreen_hdmi.c | 3 --- drivers/gpu/drm/radeon/ni.c | 5 +++++ drivers/gpu/drm/radeon/r600_audio.c | 2 +- drivers/gpu/drm/radeon/r600_hdmi.c | 7 ++----- 5 files changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index e7b1ec5..486ccdf 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1926,7 +1926,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { r600_hdmi_enable(encoder); - if (ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE6(rdev)) + ; /* TODO (use pointers instead of if-s?) */ + else if (ASIC_IS_DCE4(rdev)) evergreen_hdmi_setmode(encoder, adjusted_mode); else r600_hdmi_setmode(encoder, adjusted_mode); diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index a51f880..65c5416 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -156,9 +156,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) - return; - /* Silent, r600_hdmi_enable will raise WARN for us */ if (!dig->afmt->enabled) return; diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 3186522..b7bf18e 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1303,6 +1303,10 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; + r = r600_audio_init(rdev); + if (r) + return r; + return 0; } @@ -1329,6 +1333,7 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { + r600_audio_fini(rdev); /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 7479a5c..79b5591 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -57,7 +57,7 @@ static bool radeon_dig_encoder(struct drm_encoder *encoder) */ static int r600_audio_chipset_supported(struct radeon_device *rdev) { - return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE5(rdev)) + return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE6(rdev)) || rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740; diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 969c275..82a0a4c 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -322,9 +322,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) - return; - /* Silent, r600_hdmi_enable will raise WARN for us */ if (!dig->afmt->enabled) return; @@ -483,7 +480,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder) uint32_t offset; u32 hdmi; - if (ASIC_IS_DCE5(rdev)) + if (ASIC_IS_DCE6(rdev)) return; /* Silent, r600_hdmi_enable will raise WARN for us */ @@ -543,7 +540,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) + if (ASIC_IS_DCE6(rdev)) return; /* Called for ATOM_ENCODER_MODE_HDMI only */ -- cgit v1.1 From b866d1334ba2d544bc575d75357dea6bdcdc7f46 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 22:06:36 +0200 Subject: drm/radeon: add some additional 6xx/7xx/EG register init - SMX_SAR_CTL0 needs to be programmed correctly to prevent problems with memory exports in certain cases. - VC_ENHANCE needs to be initialized on 6xx/7xx. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 3 +++ drivers/gpu/drm/radeon/evergreend.h | 1 + drivers/gpu/drm/radeon/r600.c | 1 + drivers/gpu/drm/radeon/r600d.h | 1 + drivers/gpu/drm/radeon/rv770.c | 5 ++++- drivers/gpu/drm/radeon/rv770d.h | 3 +++ 6 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 01550d0..7fb3d2e 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1932,6 +1932,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev) smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); WREG32(SMX_DC_CTL0, smx_dc_ctl0); + if (rdev->family <= CHIP_SUMO2) + WREG32(SMX_SAR_CTL0, 0x00010000); + WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 2773039..b50b15c 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -503,6 +503,7 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 +#define SMX_SAR_CTL0 0xA008 #define SMX_DC_CTL0 0xA020 #define USE_HASH_FUNCTION (1 << 0) #define NUMBER_OF_SETS(x) ((x) << 1) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index f30dc95..bff6272 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1839,6 +1839,7 @@ void r600_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3))); WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095)); + WREG32(VC_ENHANCE, 0); } diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index a0dbf1f..c6857e8 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -485,6 +485,7 @@ #define TC_L2_SIZE(x) ((x)<<5) #define L2_DISABLE_LATE_HIT (1<<9) +#define VC_ENHANCE 0x9714 #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4ad0281..b4f51c5 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -616,6 +616,9 @@ static void rv770_gpu_init(struct radeon_device *rdev) ACK_FLUSH_CTL(3) | SYNC_FLUSH_CTL)); + if (rdev->family != CHIP_RV770) + WREG32(SMX_SAR_CTL0, 0x00003f3f); + db_debug3 = RREG32(DB_DEBUG3); db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f); switch (rdev->family) { @@ -792,7 +795,7 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3))); - + WREG32(VC_ENHANCE, 0); } void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index fdc0898..b0adfc5 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -211,6 +211,7 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 +#define SMX_SAR_CTL0 0xA008 #define SMX_DC_CTL0 0xA020 #define USE_HASH_FUNCTION (1 << 0) #define CACHE_DEPTH(x) ((x) << 1) @@ -310,6 +311,8 @@ #define TCP_CNTL 0x9610 #define TCP_CHAN_STEER 0x9614 +#define VC_ENHANCE 0x9714 + #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) #define VC_ONLY 0 -- cgit v1.1 From 7c77bf2a1a8bf67d580a3b189b37fded0a13ab78 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 22:06:37 +0200 Subject: drm/radeon: add support for STRMOUT_BASE_UPDATE on 7xx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Required for streamout. Bump drm minor. Marek v2: fix pkt->count check Signed-off-by: Alex Deucher Reviewed-by: Michel Dänzer Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_cs.c | 42 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/r600d.h | 1 + drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- 3 files changed, 45 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0133f5f..ca87f7a 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -2079,6 +2079,48 @@ static int r600_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } break; + case PACKET3_STRMOUT_BASE_UPDATE: + if (p->family < CHIP_RV770) { + DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n"); + return -EINVAL; + } + if (pkt->count != 1) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE packet count\n"); + return -EINVAL; + } + if (idx_value > 3) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE index\n"); + return -EINVAL; + } + { + u64 offset; + + r = r600_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE reloc\n"); + return -EINVAL; + } + + if (reloc->robj != track->vgt_strmout_bo[idx_value]) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo does not match\n"); + return -EINVAL; + } + + offset = radeon_get_ib_value(p, idx+1) << 8; + if (offset != track->vgt_strmout_bo_offset[idx_value]) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo offset does not match: 0x%llx, 0x%x\n", + offset, track->vgt_strmout_bo_offset[idx_value]); + return -EINVAL; + } + + if ((offset + 4) > radeon_bo_size(reloc->robj)) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE bo too small: 0x%llx, 0x%lx\n", + offset + 4, radeon_bo_size(reloc->robj)); + return -EINVAL; + } + ib[idx+1] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + } + break; case PACKET3_SURFACE_BASE_UPDATE: if (p->family >= CHIP_RV770 || p->family == CHIP_R600) { DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index c6857e8..025fd5b 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -1164,6 +1164,7 @@ #define PACKET3_SET_CTL_CONST 0x6F #define PACKET3_SET_CTL_CONST_OFFSET 0x0003cff0 #define PACKET3_SET_CTL_CONST_END 0x0003e200 +#define PACKET3_STRMOUT_BASE_UPDATE 0x72 /* r7xx */ #define PACKET3_SURFACE_BASE_UPDATE 0x73 diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 03e5f5d..2c4d53f 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -58,9 +58,10 @@ * 2.14.0 - add evergreen tiling informations * 2.15.0 - add max_pipes query * 2.16.0 - fix evergreen 2D tiled surface calculation + * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 16 +#define KMS_DRIVER_MINOR 17 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); -- cgit v1.1 From b708a1d5ea7880b399dbd45cacafff6ae8d73171 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 11 Jun 2012 14:39:56 -0400 Subject: drm/i915: don't enumerate HDMID if an eDP panel is already active on the port This prevents the HDMI detect functions from poking at an eDP connected panel, which can lead to trouble. [danvet: Note that we have some other reports of DP vs. HDMI fighting, but the general case is a much bigger fish to fry.] References: https://bugs.freedesktop.org/show_bug.cgi?id=42278 Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e0aa064..a7c727d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6558,7 +6558,7 @@ static void intel_setup_outputs(struct drm_device *dev) if (I915_READ(HDMIC) & PORT_DETECTED) intel_hdmi_init(dev, HDMIC); - if (I915_READ(HDMID) & PORT_DETECTED) + if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED) intel_hdmi_init(dev, HDMID); if (I915_READ(PCH_DP_C) & DP_DETECTED) -- cgit v1.1 From 351cfc34db8decb0c5cc1aac7cf1780a0e45c8b1 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 12 Jun 2012 13:20:47 +0200 Subject: drm/i915: eDP aux needs vdd The new oui probe has been missing these. This issue has been introduce in commit 0d198328538276c4459ef5de081e68ae60e6c4c2 Author: Adam Jackson Date: Mon May 14 16:05:47 2012 -0400 drm/i915/dp: Probe branch/sink OUIs v2: Do the eDP vdd dance of simply not probing the OUI on eDP panels as suggested by Chris Wilson. v3: Fix up the error path fail - I suck. Cc: Adam Jackson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=50808 Reported-by: Linus Torvalds Bugreport: http://permalink.gmane.org/gmane.comp.video.dri.devel/69695 Tested-by: Yang Guang Reviewed-by: Jesse Barnes Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 296cfc2..c574ff0 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1973,6 +1973,8 @@ intel_dp_probe_oui(struct intel_dp *intel_dp) if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) return; + ironlake_edp_panel_vdd_on(intel_dp); + if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3)) DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); @@ -1980,6 +1982,8 @@ intel_dp_probe_oui(struct intel_dp *intel_dp) if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3)) DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); + + ironlake_edp_panel_vdd_off(intel_dp, false); } static bool -- cgit v1.1 From 6b4e0a93ff6e45714c72bdce193f719ed94810e3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 14 Jun 2012 22:15:00 +0200 Subject: Revert "drm/i915/dp: Use auxch precharge value of 5 everywhere" This reverts commit 092945e11c5b84f66dd08f0b87fb729715d377bc. This commit prevents a DP screen from properly training the link. Oddly enough it works, once the machine has been warm-booted with an older kernel. According to DP docs this _should_ have been the right precharge time. Also, the commit that originally introduces this was just general snb DP enabling and didn't mention any specific reason for this special value. Whatever, trust the reporter that this makes things worse and let's just revert it. v2: Less spelling fail. Cc: Adam Jackson Cc: Jesse Barnes Reported-by: "Wouter M. Koolen" Buglink: https://lkml.org/lkml/2012/6/14/301 Cc: stable@vger.kernel.org (only for 3.4) Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c574ff0..a4b3887 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -371,7 +371,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, int recv_bytes; uint32_t status; uint32_t aux_clock_divider; - int try, precharge = 5; + int try, precharge; intel_dp_check_edp(intel_dp); /* The clock divider is based off the hrawclk, @@ -391,6 +391,11 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, else aux_clock_divider = intel_hrawclk(dev) / 2; + if (IS_GEN6(dev)) + precharge = 3; + else + precharge = 5; + /* Try to wait for any previous AUX channel activity */ for (try = 0; try < 3; try++) { status = I915_READ(ch_ctl); -- cgit v1.1 From d6f24d0fa6cdf3431a2fe3330a74bc6c5871f496 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 14 Jun 2012 15:28:33 -0400 Subject: drm/i915: cache the EDID for eDP panels They aren't going anywhere, and probing on DDC can cause the panel to blank briefly, so read them up front and cache them for later queries. v2: fix potential NULL derefs in intel_dp_get_edid_modes and intel_dp_get_edid (Jani) copy full EDID length, including extension blocks (Takashi) free EDID on teardown (Takashi) v3: malloc a new EDID buffer that's big enough for the memcpy (Chris) v4: change handling of NULL EDIDs, just preserve the NULL behavior across detects and mode list fetches rather than trying to re-fetch the EDID (Chris) v5: be glad that Chris is around to remind me to hit C-x C-s before committing. References: https://bugs.freedesktop.org/show_bug.cgi?id=46856 Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 49 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a4b3887..c044932 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -32,6 +32,7 @@ #include "drm.h" #include "drm_crtc.h" #include "drm_crtc_helper.h" +#include "drm_edid.h" #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" @@ -67,6 +68,8 @@ struct intel_dp { struct drm_display_mode *panel_fixed_mode; /* for eDP */ struct delayed_work panel_vdd_work; bool want_panel_vdd; + struct edid *edid; /* cached EDID for eDP */ + int edid_mode_count; }; /** @@ -2125,10 +2128,22 @@ intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) { struct intel_dp *intel_dp = intel_attached_dp(connector); struct edid *edid; + int size; + + if (is_edp(intel_dp)) { + if (!intel_dp->edid) + return NULL; + + size = (intel_dp->edid->extensions + 1) * EDID_LENGTH; + edid = kmalloc(size, GFP_KERNEL); + if (!edid) + return NULL; + + memcpy(edid, intel_dp->edid, size); + return edid; + } - ironlake_edp_panel_vdd_on(intel_dp); edid = drm_get_edid(connector, adapter); - ironlake_edp_panel_vdd_off(intel_dp, false); return edid; } @@ -2138,9 +2153,17 @@ intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *ada struct intel_dp *intel_dp = intel_attached_dp(connector); int ret; - ironlake_edp_panel_vdd_on(intel_dp); + if (is_edp(intel_dp)) { + drm_mode_connector_update_edid_property(connector, + intel_dp->edid); + ret = drm_add_edid_modes(connector, intel_dp->edid); + drm_edid_to_eld(connector, + intel_dp->edid); + connector->display_info.raw_edid = NULL; + return intel_dp->edid_mode_count; + } + ret = intel_ddc_get_modes(connector, adapter); - ironlake_edp_panel_vdd_off(intel_dp, false); return ret; } @@ -2330,6 +2353,7 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder) i2c_del_adapter(&intel_dp->adapter); drm_encoder_cleanup(encoder); if (is_edp(intel_dp)) { + kfree(intel_dp->edid); cancel_delayed_work_sync(&intel_dp->panel_vdd_work); ironlake_panel_vdd_off_sync(intel_dp); } @@ -2513,11 +2537,14 @@ intel_dp_init(struct drm_device *dev, int output_reg) break; } + intel_dp_i2c_init(intel_dp, intel_connector, name); + /* Cache some DPCD data in the eDP case */ if (is_edp(intel_dp)) { bool ret; struct edp_power_seq cur, vbt; u32 pp_on, pp_off, pp_div; + struct edid *edid; pp_on = I915_READ(PCH_PP_ON_DELAYS); pp_off = I915_READ(PCH_PP_OFF_DELAYS); @@ -2585,9 +2612,19 @@ intel_dp_init(struct drm_device *dev, int output_reg) intel_dp_destroy(&intel_connector->base); return; } - } - intel_dp_i2c_init(intel_dp, intel_connector, name); + ironlake_edp_panel_vdd_on(intel_dp); + edid = drm_get_edid(connector, &intel_dp->adapter); + if (edid) { + drm_mode_connector_update_edid_property(connector, + edid); + intel_dp->edid_mode_count = + drm_add_edid_modes(connector, edid); + drm_edid_to_eld(connector, edid); + intel_dp->edid = edid; + } + ironlake_edp_panel_vdd_off(intel_dp, false); + } intel_encoder->hot_plug = intel_dp_hot_plug; -- cgit v1.1 From 50a2984543aa2581d08580f8468533ce0ade8a62 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Sat, 16 Jun 2012 20:27:14 +0000 Subject: bnx2x: fix I2C non-respondent issue When I2C is not responding it's usually due to a previous unexpected reset during I2C operation. We release it by powering down and up the SFP+ module. Signed-off-by: Yaniv Rosner Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 52 +++++++++++++----------- 1 file changed, 29 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index a3fb721..51d7ab6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -40,6 +40,7 @@ #define I2C_BSC0 0 #define I2C_BSC1 1 #define I2C_WA_RETRY_CNT 3 +#define I2C_WA_PWR_ITER (I2C_WA_RETRY_CNT - 1) #define MCPR_IMC_COMMAND_READ_OP 1 #define MCPR_IMC_COMMAND_WRITE_OP 2 @@ -7659,6 +7660,28 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, return -EINVAL; } +static void bnx2x_warpcore_power_module(struct link_params *params, + struct bnx2x_phy *phy, + u8 power) +{ + u32 pin_cfg; + struct bnx2x *bp = params->bp; + + pin_cfg = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & + PORT_HW_CFG_E3_PWR_DIS_MASK) >> + PORT_HW_CFG_E3_PWR_DIS_SHIFT; + + if (pin_cfg == PIN_CFG_NA) + return; + DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", + power, pin_cfg); + /* Low ==> corresponding SFP+ module is powered + * high ==> the SFP+ module is powered down + */ + bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); +} static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, @@ -7678,6 +7701,12 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* 4 byte aligned address */ addr32 = addr & (~0x3); do { + if (cnt == I2C_WA_PWR_ITER) { + bnx2x_warpcore_power_module(params, phy, 0); + /* Note that 100us are not enough here */ + usleep_range(1000,1000); + bnx2x_warpcore_power_module(params, phy, 1); + } rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, data_array); } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT)); @@ -8200,29 +8229,6 @@ static void bnx2x_set_sfp_module_fault_led(struct link_params *params, bnx2x_set_e1e2_module_fault_led(params, gpio_mode); } -static void bnx2x_warpcore_power_module(struct link_params *params, - struct bnx2x_phy *phy, - u8 power) -{ - u32 pin_cfg; - struct bnx2x *bp = params->bp; - - pin_cfg = (REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & - PORT_HW_CFG_E3_PWR_DIS_MASK) >> - PORT_HW_CFG_E3_PWR_DIS_SHIFT; - - if (pin_cfg == PIN_CFG_NA) - return; - DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", - power, pin_cfg); - /* Low ==> corresponding SFP+ module is powered - * high ==> the SFP+ module is powered down - */ - bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); -} - static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy, struct link_params *params) { -- cgit v1.1 From 5481388bc705de27ca37241a42c6612c86f2cc3b Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Sat, 16 Jun 2012 20:27:15 +0000 Subject: bnx2x: fix link for BCM57711 with 84823 phy Signed-off-by: Yaniv Rosner Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 51d7ab6..6e7d5c0 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -9754,7 +9754,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, msleep(1); - if (!(CHIP_IS_E1(bp))) + if (!(CHIP_IS_E1x(bp))) port = BP_PATH(bp); else port = params->port; -- cgit v1.1 From 6b03976288538a94e072bbfcd12d69a20daea8aa Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Mon, 21 May 2012 16:31:12 +0300 Subject: remoteproc/omap: fix dev_err typo For some reason one of the dev_err invocations is using a wrong device so fix that. Signed-off-by: Ohad Ben-Cohen Cc: stable@vger.kernel.org --- drivers/remoteproc/omap_remoteproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index 69425c4..de138e3 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -182,7 +182,7 @@ static int __devinit omap_rproc_probe(struct platform_device *pdev) ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) { - dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret); + dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret); return ret; } -- cgit v1.1 From fcc14ac1a86931f38da047cf8fb634c6db7b58bc Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 17 Jun 2012 18:05:05 +0200 Subject: hwmon: (coretemp) Improve support of recent Atom CPU models Document the new Atom series (Tunnel Creek and Medfield) as being supported, and list TjMax for the Atom E600 series. Also enable the Atom tjmax heuristic for these Atom CPU models. Signed-off-by: Jean Delvare Reviewed-by: Guenter Roeck Cc: Alexander Stein Cc: Fenghua Yu Cc: "R, Durgadoss" --- drivers/hwmon/coretemp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index b9d5123..495add5 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -210,7 +210,8 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, /* Atom CPUs */ - if (c->x86_model == 0x1c) { + if (c->x86_model == 0x1c || c->x86_model == 0x26 + || c->x86_model == 0x27) { usemsr_ee = 0; host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); -- cgit v1.1 From 5592906f8b01282ea3c2acaf641fd067ad4bb3dc Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 17 Jun 2012 18:05:05 +0200 Subject: hwmon: (coretemp) Add support for Atom D2000 and N2000 series CPU models Document the Atom series D2000 and N2000 (Cedar Trail) as being supported. List and set TjMax for those series. Cc: Fenghua Yu Cc: "R, Durgadoss" Signed-off-by: Guenter Roeck Signed-off-by: Jean Delvare --- drivers/hwmon/coretemp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 495add5..42c2f43 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -224,6 +224,9 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, tjmax = 90000; pci_dev_put(host_bridge); + } else if (c->x86_model == 0x36) { + usemsr_ee = 0; + tjmax = 100000; } if (c->x86_model > 0xe && usemsr_ee) { -- cgit v1.1 From 41e58a1f2b90c88d94b4bd84beb9927a4c2704e9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 17 Jun 2012 18:05:05 +0200 Subject: hwmon: (coretemp) Improve support for TjMax detection on Atom CPUs Atom CPUs don't have a register to retrieve TjMax. Detection so far was incomplete. Use the X86 model ID to improve it. Signed-off-by: Guenter Roeck Signed-off-by: Jean Delvare --- drivers/hwmon/coretemp.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 42c2f43..2271683 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -191,6 +191,24 @@ static ssize_t show_temp(struct device *dev, return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN; } +struct tjmax { + char const *id; + int tjmax; +}; + +static struct tjmax __cpuinitconst tjmax_table[] = { + { "CPU D410", 100000 }, + { "CPU D425", 100000 }, + { "CPU D510", 100000 }, + { "CPU D525", 100000 }, + { "CPU N450", 100000 }, + { "CPU N455", 100000 }, + { "CPU N470", 100000 }, + { "CPU N475", 100000 }, + { "CPU 230", 100000 }, + { "CPU 330", 125000 }, +}; + static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) { @@ -202,6 +220,13 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, int err; u32 eax, edx; struct pci_dev *host_bridge; + int i; + + /* explicit tjmax table entries override heuristics */ + for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) { + if (strstr(c->x86_model_id, tjmax_table[i].id)) + return tjmax_table[i].tjmax; + } /* Early chips have no MSR for TjMax */ -- cgit v1.1 From 1268a172cdb00353f107e6cc964dccff29047077 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 17 Jun 2012 18:05:06 +0200 Subject: hwmon: (coretemp) Drop needless initialization The value is overridden a few lines later. Signed-off-by: Jean Delvare Acked-by: Guenter Roeck --- drivers/hwmon/coretemp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 2271683..7f1feb2 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -801,7 +801,7 @@ MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); static int __init coretemp_init(void) { - int i, err = -ENODEV; + int i, err; /* * CPUID.06H.EAX[0] indicates whether the CPU has thermal -- cgit v1.1 From 9d88fc0b3503e80ab1a5c9fb3b3f074302f44b33 Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Wed, 13 Jun 2012 17:27:16 +0900 Subject: regulator: Fix the s5m8767a problem of the division by null If ramp_delay is 0, delay value can be divided by zero. This patch can fix the problem. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 290d6fc..9caadb4 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -451,7 +451,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, desc = reg_voltage_map[reg_id]; - if (old_sel < new_sel) + if ((old_sel < new_sel) && s5m8767->ramp_delay) return DIV_ROUND_UP(desc->step * (new_sel - old_sel), s5m8767->ramp_delay * 1000); return 0; -- cgit v1.1 From f7f3f1ad9ee13c962122e36752ef6908aff920a2 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 30 May 2012 12:47:26 +0800 Subject: regulator: Change ab8500 match names to reflect Device Tree The 'name' field in 'struct of_regulator_match' expects to match with its corresponding regulator device node in the Device Tree. This patch renames each of the regulators in the ab8500 regulator driver so this is true. Signed-off-by: Lee Jones Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index e1b8c54..a739f5c 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -794,17 +794,17 @@ static __devinit int ab8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match ab8500_regulator_matches[] = { - { .name = "LDO-AUX1", .driver_data = (void *) AB8500_LDO_AUX1, }, - { .name = "LDO-AUX2", .driver_data = (void *) AB8500_LDO_AUX2, }, - { .name = "LDO-AUX3", .driver_data = (void *) AB8500_LDO_AUX3, }, - { .name = "LDO-INTCORE", .driver_data = (void *) AB8500_LDO_INTCORE, }, - { .name = "LDO-TVOUT", .driver_data = (void *) AB8500_LDO_TVOUT, }, - { .name = "LDO-USB", .driver_data = (void *) AB8500_LDO_USB, }, - { .name = "LDO-AUDIO", .driver_data = (void *) AB8500_LDO_AUDIO, }, - { .name = "LDO-ANAMIC1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, - { .name = "LDO-ANAMIC2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, - { .name = "LDO-DMIC", .driver_data = (void *) AB8500_LDO_DMIC, }, - { .name = "LDO-ANA", .driver_data = (void *) AB8500_LDO_ANA, }, + { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, }, + { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, }, + { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, }, + { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, }, + { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, }, + { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, }, + { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, }, + { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, + { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, + { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, }, + { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, }, }; static __devinit int -- cgit v1.1 From ea851f4f08eb366e829abb8f1b2f1741a19ed696 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 30 May 2012 12:47:27 +0800 Subject: regulator: Change db8500-prcmu match names to reflect Device Tree The 'name' field in 'struct of_regulator_match' expects to match with its corresponding regulator device node in the Device Tree. This patch renames each of the regulators in the db8500-prcum regulator driver so this is true. Signed-off-by: Lee Jones Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/db8500-prcmu.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 968f97f..9dbb491 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -452,26 +452,26 @@ static __devinit int db8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match db8500_regulator_matches[] = { - { .name = "db8500-vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, - { .name = "db8500-varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, - { .name = "db8500-vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, - { .name = "db8500-vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, - { .name = "db8500-vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, - { .name = "db8500-vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, - { .name = "db8500-vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, - { .name = "db8500-vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, - { .name = "db8500-sva-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, - { .name = "db8500-sva-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, - { .name = "db8500-sva-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, - { .name = "db8500-sia-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, - { .name = "db8500-sia-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, - { .name = "db8500-sia-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, - { .name = "db8500-sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, - { .name = "db8500-b2r2-mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, - { .name = "db8500-esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, - { .name = "db8500-esram12-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, - { .name = "db8500-esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, - { .name = "db8500-esram34-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, + { .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, + { .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, + { .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, + { .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, + { .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, + { .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, + { .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, + { .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, + { .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, + { .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, + { .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, + { .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, + { .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, + { .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, + { .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, + { .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, + { .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, + { .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, + { .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, + { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, }; static __devinit int -- cgit v1.1 From 14e1e9f5cadb7cff3a2846c27cc1b9c8f207ee18 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 13 Jun 2012 14:06:07 -0300 Subject: pinctrl: mxs: Use kfree to fix build error commit 0bf7481 (pinctrl: pinctrl-mxs: Take care of frees if the kzalloc fails) introduced the following build error: drivers/pinctrl/pinctrl-mxs.c:140:3: error: implicit declaration of function 'free' Use kfree function instead. Signed-off-by: Fabio Estevam Acked-by: Devendra Naga Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-mxs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index afb50ee..4ba4636 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -137,7 +137,7 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, free_group: if (!purecfg) - free(group); + kfree(group); free: kfree(new_map); return ret; -- cgit v1.1 From daf731748f978efb4f741d19b499236e03bf667f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 22 May 2012 11:46:45 +0200 Subject: pinctrl/nomadik: document Alt-C glitch This documentation comment existed in an earlier patch set for GPIO consolidation, so I'm saving it for maintainability of the code. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index e8937e7..3e7e47d 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1438,7 +1438,27 @@ static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function, dev_dbg(npct->dev, "enable group %s, %u pins\n", g->name, g->npins); - /* Handle this special glitch on altfunction C */ + /* + * If we're setting altfunc C by setting both AFSLA and AFSLB to 1, + * we may pass through an undesired state. In this case we take + * some extra care. + * + * Safe sequence used to switch IOs between GPIO and Alternate-C mode: + * - Save SLPM registers (since we have a shadow register in the + * nmk_chip we're using that as backup) + * - Set SLPM=0 for the IOs you want to switch and others to 1 + * - Configure the GPIO registers for the IOs that are being switched + * - Set IOFORCE=1 + * - Modify the AFLSA/B registers for the IOs that are being switched + * - Set IOFORCE=0 + * - Restore SLPM registers + * - Any spurious wake up event during switch sequence to be ignored + * and cleared + * + * We REALLY need to save ALL slpm registers, because the external + * IOFORCE will switch *all* ports to their sleepmode setting to as + * to avoid glitches. (Not just one port!) + */ glitch = (g->altsetting == NMK_GPIO_ALT_C); if (glitch) { -- cgit v1.1 From 6b57c0155cb78d15b0d93b2c7f66ad9536862476 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 14 Jun 2012 13:55:25 +0800 Subject: regulator: tps65023: Fix mask for LDOs output voltage select control According to the datasheet: The LDO_CTRL registers are used to set the output voltage of LDO1 and LDO2. LDO_CTRL[7] and LDO_CTRL[3] are reserved and should always be written to 0. Thus the mask for TPS65023_LDO_1 and TPS65023_LDO_2 should be 0x07 and 0x70 respectively. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65023-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index f841bd0..8f1be85 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -71,7 +71,7 @@ /* LDO_CTRL bitfields */ #define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4) -#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x0F << ((ldo_id)*4)) +#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x07 << ((ldo_id)*4)) /* Number of step-down converters available */ #define TPS65023_NUM_DCDC 3 -- cgit v1.1 From f43380981716c9b48bf2809e4cd1cb0c6b71429d Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Sun, 17 Jun 2012 21:13:34 +0100 Subject: ARM: 7426/1: mmc: mmci: Remove wrong error handling of gpio 0 Zero is a valid GPIO and shouldn't be handled as an error return code from of_get_named_gpio(). It was a leftover from old code before getting pdata->gpio_*() was modified. Signed-off-by: Roland Stigge Acked-by: Linus Walleij Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0045ee0..78d3e48 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1216,12 +1216,7 @@ static void mmci_dt_populate_generic_pdata(struct device_node *np, int bus_width = 0; pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0); - if (!pdata->gpio_wp) - pdata->gpio_wp = -1; - pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0); - if (!pdata->gpio_cd) - pdata->gpio_cd = -1; if (of_get_property(np, "cd-inverted", NULL)) pdata->cd_invert = true; -- cgit v1.1 From 2805b9ab7c836cfbe01e86129983e36205078cb2 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Sun, 17 Jun 2012 21:14:27 +0100 Subject: ARM: 7427/1: mmc: mmci: Defer probe() in case of yet uninitialized GPIOs If the GPIOs used by the MMCI driver are not registered yet when the driver is probe()d, they can't be used. This happens if the mmci driver is probed before the respective GPIO controller (e.g. on the LPC32xx EA3250 board, the PCA9532 GPIO controller would be initialized via DT after mmci). Therefore, we defer mmci in this case. Signed-off-by: Roland Stigge Acked-by: Linus Walleij Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 78d3e48..50ff19a 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1425,6 +1425,10 @@ static int __devinit mmci_probe(struct amba_device *dev, writel(0, host->base + MMCIMASK1); writel(0xfff, host->base + MMCICLEAR); + if (plat->gpio_cd == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_gpio_cd; + } if (gpio_is_valid(plat->gpio_cd)) { ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); if (ret == 0) @@ -1448,6 +1452,10 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret >= 0) host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd); } + if (plat->gpio_wp == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_gpio_wp; + } if (gpio_is_valid(plat->gpio_wp)) { ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); if (ret == 0) -- cgit v1.1 From b6138ed60457ef1e9150692f6790eb4a2a696308 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Sat, 16 Jun 2012 23:29:00 +0000 Subject: ixgbe: Fix PHC loophole allowing misconfiguration of increment register This patch fixes a potential hole when configuring the cycle counter used to generate the nanosecond time clock. This clock is based off of the SYSTIME registers along with the TIMINCA registers. The TIMINCA register determines the increment to be added to the SYSTIME registers every DMA clock tick. This register needs to be reconfigured whenever the link-speed changes. However, the value calculated stays the same when link is down and when link is up. Misconfiguration can occur if the link status changes due to a reset, which causes the TIMINCA register to be reset. This reset puts the device in an unstable state where the SYSTIME registers stop incrementing and the PTP protocol does not function. The solution is to double check the TIMINCA value and always reset the value if the register is zero. This prevents a misconfiguration bug that halts the PHC. Signed-off-by: Jacob Keller Acked-by: Don Skidmore Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index ddc6a4d..dcebd12 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -708,6 +708,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; u32 incval = 0; + u32 timinca = 0; u32 shift = 0; u32 cycle_speed; unsigned long flags; @@ -730,8 +731,16 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) break; } - /* Bail if the cycle speed didn't change */ - if (adapter->cycle_speed == cycle_speed) + /* + * grab the current TIMINCA value from the register so that it can be + * double checked. If the register value has been cleared, it must be + * reset to the correct value for generating a cyclecounter. If + * TIMINCA is zero, the SYSTIME registers do not increment at all. + */ + timinca = IXGBE_READ_REG(hw, IXGBE_TIMINCA); + + /* Bail if the cycle speed didn't change and TIMINCA is non-zero */ + if (adapter->cycle_speed == cycle_speed && timinca) return; /* disable the SDP clock out */ -- cgit v1.1 From b7e5887e0e414bde0a2f311ae3fbea5611562e29 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Wed, 13 Jun 2012 19:51:43 +0000 Subject: be2net: reduce gso_max_size setting to account for ethernet header. The maximum size of packet that can be handled by controller including ethernet header is 65535. Reducing gso_max_size accordingly. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index fdb50ce..501dfa9 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3237,7 +3237,7 @@ static void be_netdev_init(struct net_device *netdev) netdev->flags |= IFF_MULTICAST; - netif_set_gso_max_size(netdev, 65535); + netif_set_gso_max_size(netdev, 65535 - ETH_HLEN); netdev->netdev_ops = &be_netdev_ops; -- cgit v1.1 From 97f1d8cd8d61642d01af1fc181f3103314128c3b Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Wed, 13 Jun 2012 19:51:44 +0000 Subject: be2net: Modify error message to incorporate subsystem Modify IOCTL error message to print subsystem also. Signed-off-by: Vasundhara Volam Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 8d06ea3..921c208 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -122,15 +122,15 @@ static int be_mcc_compl_process(struct be_adapter *adapter, goto done; if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) { - dev_warn(&adapter->pdev->dev, "This domain(VM) is not " - "permitted to execute this cmd (opcode %d)\n", - opcode); + dev_warn(&adapter->pdev->dev, + "opcode %d-%d is not permitted\n", + opcode, subsystem); } else { extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & CQE_STATUS_EXTD_MASK; - dev_err(&adapter->pdev->dev, "Cmd (opcode %d) failed:" - "status %d, extd-status %d\n", - opcode, compl_status, extd_status); + dev_err(&adapter->pdev->dev, + "opcode %d-%d failed:status %d-%d\n", + opcode, subsystem, compl_status, extd_status); } } done: -- cgit v1.1 From 0b3f0e7ae0765c81c7d659811595ea5058ae05a7 Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Wed, 13 Jun 2012 19:51:45 +0000 Subject: be2net: Increase statistics structure size for skyhawk. Increasing the hardware statistics structure to accomodate statistics for skyhawk. Signed-off-by: Vasundhara Volam Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 9625bf4..b3f3fc3 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -1566,7 +1566,7 @@ struct be_hw_stats_v1 { u32 rsvd0[BE_TXP_SW_SZ]; struct be_erx_stats_v1 erx; struct be_pmem_stats pmem; - u32 rsvd1[3]; + u32 rsvd1[18]; }; struct be_cmd_req_get_stats_v1 { -- cgit v1.1 From 86a2f415e6cdc5dbb2163b31abf4d36f26f7e3da Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 14 Jun 2012 01:18:42 +0000 Subject: usbnet: sanitise overlong driver information strings As seen on smsc75xx, driver_info->description being longer than 32 characters messes up 'ethtool -i' output. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 9f58330..d4f7256 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -876,9 +876,9 @@ void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) { struct usbnet *dev = netdev_priv(net); - strncpy (info->driver, dev->driver_name, sizeof info->driver); - strncpy (info->version, DRIVER_VERSION, sizeof info->version); - strncpy (info->fw_version, dev->driver_info->description, + strlcpy (info->driver, dev->driver_name, sizeof info->driver); + strlcpy (info->version, DRIVER_VERSION, sizeof info->version); + strlcpy (info->fw_version, dev->driver_info->description, sizeof info->fw_version); usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); } -- cgit v1.1 From df2bcc4af2616b18efeaa3d044fe15ce891c5d21 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Thu, 14 Jun 2012 22:39:27 +0000 Subject: bonding: show all the link status of slaves There are four link statuses of a bonding slave, the procfs code shows a wrong status when using downdelay/updelay: (slave->link == BOND_LINK_UP) ? "up" : "down" It doesn't respect the rest two statuses. This patch fixes it. Cc: Jay Vosburgh Cc: Andy Gospodarek Cc: "David S. Miller" Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- drivers/net/bonding/bond_procfs.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index ad284ba..3cea38d 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c @@ -150,14 +150,25 @@ static void bond_info_show_master(struct seq_file *seq) } } +static const char *bond_slave_link_status(s8 link) +{ + static const char * const status[] = { + [BOND_LINK_UP] = "up", + [BOND_LINK_FAIL] = "going down", + [BOND_LINK_DOWN] = "down", + [BOND_LINK_BACK] = "going back", + }; + + return status[link]; +} + static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave) { struct bonding *bond = seq->private; seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); - seq_printf(seq, "MII Status: %s\n", - (slave->link == BOND_LINK_UP) ? "up" : "down"); + seq_printf(seq, "MII Status: %s\n", bond_slave_link_status(slave->link)); if (slave->speed == SPEED_UNKNOWN) seq_printf(seq, "Speed: %s\n", "Unknown"); else -- cgit v1.1 From 10aa5a35e34fb00a2dd814447199f08756eb307b Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 18 Jun 2012 11:27:04 +0100 Subject: SPI: fix over-eager devm_xxx() conversion 1a77b127ae (OMAP : SPI : use devm_* functions) converted the SPI device controller state to use devm_kzalloc(). Unfortunately, this is used against an unbound struct device, which results in the following when the device is bound to its driver: ------------[ cut here ]------------ WARNING: at /home/rmk/git/linux-rmk/drivers/base/dd.c:257 driver_probe_device+0x78/0x21c() Modules linked in: Backtrace: [] (dump_backtrace+0x0/0x10c) from [] (dump_stack+0x18/0x1c) r7:00000000 r6:c01ff28c r5:c040050c r4:00000101 [] (dump_stack+0x0/0x1c) from [] (warn_slowpath_common+0x58/0x70) [] (warn_slowpath_common+0x0/0x70) from [] (warn_slowpath_null+0x24/0x2c) [] (warn_slowpath_null+0x0/0x2c) from [] (driver_probe_device+0x78/0x21c) [] (driver_probe_device+0x0/0x21c) from [] (__driver_attach+0x6c/0x90) [] (__driver_attach+0x0/0x90) from [] (bus_for_each_dev+0x58/0x98) [] (bus_for_each_dev+0x0/0x98) from [] (driver_attach+0x20/0x28) [] (driver_attach+0x0/0x28) from [] (bus_add_driver+0xb4/0x230) [] (bus_add_driver+0x0/0x230) from [] (driver_register+0xac/0x138) [] (driver_register+0x0/0x138) from [] (spi_register_driver+0x4c/0x60) [] (spi_register_driver+0x0/0x60) from [] (ks8851_init+0x14/0x1c) [] (ks8851_init+0x0/0x1c) from [] (do_one_initcall+0x9c/0x164) [] (do_one_initcall+0x0/0x164) from [] (kernel_init+0x128/0x210) [] (kernel_init+0x0/0x210) from [] (do_exit+0x0/0x72c) ---[ end trace 4dcda79f5e89dd84 ]--- ks8851 spi1.0: message enable is 0 ks8851 spi1.0: eth0: revision 0, MAC 08:00:28:01:4d:c6, IRQ 194, has EEPROM Fix this by partially reverting the original commit. Signed-off-by: Russell King --- drivers/spi/spi-omap2-mcspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 46ef5fe..0c73dd4 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -801,7 +801,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) mcspi_dma = &mcspi->dma_channels[spi->chip_select]; if (!cs) { - cs = devm_kzalloc(&spi->dev , sizeof *cs, GFP_KERNEL); + cs = kzalloc(sizeof *cs, GFP_KERNEL); if (!cs) return -ENOMEM; cs->base = mcspi->base + spi->chip_select * 0x14; @@ -842,6 +842,7 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) cs = spi->controller_state; list_del(&cs->node); + kfree(cs); } if (spi->chip_select < spi->master->num_chipselect) { -- cgit v1.1 From 70c276a6abdb1a466a9026da631c396fee2984bd Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 25 May 2012 18:06:33 -0300 Subject: [media] Revert "[media] media: mx2_camera: Fix mbus format handling" This reverts commit d509835e32bd761a2b7b446034a273da568e5573. That commit breaks support for the generic pass-through mode in the driver for formats, not natively supported by it. Besides due to a merge conflict it also breaks driver compilation: drivers/media/video/mx2_camera.c: In function 'mx2_camera_set_bus_param': drivers/media/video/mx2_camera.c:937: error: 'pixfmt' undeclared (first use in this function) drivers/media/video/mx2_camera.c:937: error: (Each undeclared identifier is reported only once drivers/media/video/mx2_camera.c:937: error: for each function it appears in.) Signed-off-by: Guennadi Liakhovetski Cc: Javier Martin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mx2_camera.c | 52 ++++------------------------------------ 1 file changed, 5 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index ded26b7..41f9a25 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -345,19 +345,6 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { PRP_INTR_CH2OVF, } }, - { - .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8, - .out_fmt = V4L2_PIX_FMT_YUV420, - .cfg = { - .channel = 2, - .in_fmt = PRP_CNTL_DATA_IN_YUV422, - .out_fmt = PRP_CNTL_CH2_OUT_YUV420, - .src_pixel = 0x22000888, /* YUV422 (YUYV) */ - .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR | - PRP_INTR_CH2FC | PRP_INTR_LBOVF | - PRP_INTR_CH2OVF, - } - }, }; static struct mx2_fmt_cfg *mx27_emma_prp_get_format( @@ -984,7 +971,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx2_camera_dev *pcdev = ici->priv; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; - const struct soc_camera_format_xlate *xlate; unsigned long common_flags; int ret; int bytesperline; @@ -1029,31 +1015,14 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) return ret; } - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); - if (!xlate) { - dev_warn(icd->parent, "Format %x not found\n", pixfmt); - return -EINVAL; - } - - if (xlate->code == V4L2_MBUS_FMT_YUYV8_2X8) { - csicr1 |= CSICR1_PACK_DIR; - csicr1 &= ~CSICR1_SWAP16_EN; - dev_dbg(icd->parent, "already yuyv format, don't convert\n"); - } else if (xlate->code == V4L2_MBUS_FMT_UYVY8_2X8) { - csicr1 &= ~CSICR1_PACK_DIR; - csicr1 |= CSICR1_SWAP16_EN; - dev_dbg(icd->parent, "convert uyvy mbus format into yuyv\n"); - } else { - dev_warn(icd->parent, "mbus format not supported\n"); - return -EINVAL; - } - if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) csicr1 |= CSICR1_REDGE; if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) csicr1 |= CSICR1_SOF_POL; if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) csicr1 |= CSICR1_HSYNC_POL; + if (pcdev->platform_flags & MX2_CAMERA_SWAP16) + csicr1 |= CSICR1_SWAP16_EN; if (pcdev->platform_flags & MX2_CAMERA_EXT_VSYNC) csicr1 |= CSICR1_EXT_VSYNC; if (pcdev->platform_flags & MX2_CAMERA_CCIR) @@ -1064,6 +1033,8 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) csicr1 |= CSICR1_GCLK_MODE; if (pcdev->platform_flags & MX2_CAMERA_INV_DATA) csicr1 |= CSICR1_INV_DATA; + if (pcdev->platform_flags & MX2_CAMERA_PACK_DIR_MSB) + csicr1 |= CSICR1_PACK_DIR; pcdev->csicr1 = csicr1; @@ -1138,8 +1109,7 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, return 0; } - if (code == V4L2_MBUS_FMT_YUYV8_2X8 || - code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (code == V4L2_MBUS_FMT_YUYV8_2X8) { formats++; if (xlate) { /* @@ -1155,18 +1125,6 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, } } - if (code == V4L2_MBUS_FMT_UYVY8_2X8) { - formats++; - if (xlate) { - xlate->host_fmt = - soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_2X8); - xlate->code = code; - dev_dbg(dev, "Providing host format %s for sensor code %d\n", - xlate->host_fmt->name, code); - xlate++; - } - } - /* Generic pass-trough */ formats++; if (xlate) { -- cgit v1.1 From ac6e4c1560f8d3d18e6ba265d84ff03810496f4f Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 26 May 2012 15:25:26 -0300 Subject: [media] USB: Staging: media: lirc: initialize spinlocks before usage Initialize the spinlock for each hardware time. Signed-off-by: Sasha Levin Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_serial.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 3295ea6..97ef670 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -129,6 +129,7 @@ static void send_space_homebrew(long length); static struct lirc_serial hardware[] = { [LIRC_HOMEBREW] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_HOMEBREW].lock), .signal_pin = UART_MSR_DCD, .signal_pin_change = UART_MSR_DDCD, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), @@ -145,6 +146,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_IRDEO] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IRDEO].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = UART_MCR_OUT2, @@ -156,6 +158,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_IRDEO_REMOTE] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IRDEO_REMOTE].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), @@ -167,6 +170,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_ANIMAX] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_ANIMAX].lock), .signal_pin = UART_MSR_DCD, .signal_pin_change = UART_MSR_DDCD, .on = 0, @@ -177,6 +181,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_IGOR] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IGOR].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), @@ -201,6 +206,7 @@ static struct lirc_serial hardware[] = { * See also http://www.nslu2-linux.org for this device */ [LIRC_NSLU2] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_NSLU2].lock), .signal_pin = UART_MSR_CTS, .signal_pin_change = UART_MSR_DCTS, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), -- cgit v1.1 From bdca5036332311bea183dc628c69e3cb50a9369e Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Tue, 29 May 2012 17:19:27 -0300 Subject: [media] em28xx: Add remote control support for Terratec's Cinergy HTC Stick HD The Cinergy HTC Stick HD uses the same remote control as the TerraTec Cinergy XS products. Thus the same keymap could be re-used. Signed-off-by: Martin Blumenstingl Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 20a7e24..92da7c2 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -974,6 +974,7 @@ struct em28xx_board em28xx_boards[] = { [EM2884_BOARD_CINERGY_HTC_STICK] = { .name = "Terratec Cinergy HTC Stick", .has_dvb = 1, + .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, #if 0 .tuner_type = TUNER_PHILIPS_TDA8290, .tuner_addr = 0x41, -- cgit v1.1 From b83f671566f8a3b9796bed7416d25e07866ff408 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Wed, 30 May 2012 15:47:40 -0300 Subject: [media] em28xx: Show a warning if the board does not support remote controls This simply shows a little warning if the board does not have remote control support. This should make it easier for users to see if they have misconfigured their system or if the driver simply does not have rc-support for their card (yet). Signed-off-by: Martin Blumenstingl Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-input.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index fce5f76..5e30c4f 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -527,6 +527,8 @@ static int em28xx_ir_init(struct em28xx *dev) if (dev->board.ir_codes == NULL) { /* No remote control support */ + em28xx_warn("Remote control support is not available for " + "this card.\n"); return 0; } -- cgit v1.1 From ac852edb47b15900886ba2564eeeb13b3b526e3e Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 7 Jun 2012 04:54:29 -0400 Subject: hwmon: (applesmc) Limit key length in warning messages Key lookups may call read_smc() with a fixed-length key string, and if the lookup fails, trailing stack content may appear in the kernel log. Fixed with this patch. Signed-off-by: Henrik Rydberg Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/applesmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index f082e48..70d62f5 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -215,7 +215,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) int i; if (send_command(cmd) || send_argument(key)) { - pr_warn("%s: read arg fail\n", key); + pr_warn("%.4s: read arg fail\n", key); return -EIO; } @@ -223,7 +223,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) for (i = 0; i < len; i++) { if (__wait_status(0x05)) { - pr_warn("%s: read data fail\n", key); + pr_warn("%.4s: read data fail\n", key); return -EIO; } buffer[i] = inb(APPLESMC_DATA_PORT); -- cgit v1.1 From 2355375efdf10f43680d420023baa97796bfcdff Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 10:16:32 -0700 Subject: hwmon: (emc2103) Fix use of an uninitilized variable in error case Fix: emc2103.c: In function set_pwm_enable: emc2103.c:463:12: warning: conf_reg may be used uninitialized in this function by checking the return value from read_u8_from_i2c(). This fixes a real problem, as conf_reg is really uninitialized if read_u8_from_i2c returns an error. Signed-off-by: Guenter Roeck Reviewed-by: Robert Coulson Acked-by: Jean Delvare --- drivers/hwmon/emc2103.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c index 9691f66..e7d234b 100644 --- a/drivers/hwmon/emc2103.c +++ b/drivers/hwmon/emc2103.c @@ -451,11 +451,15 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, data->fan_rpm_control = true; break; default: - mutex_unlock(&data->update_lock); - return -EINVAL; + count = -EINVAL; + goto err; } - read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); + result = read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); + if (result) { + count = result; + goto err; + } if (data->fan_rpm_control) conf_reg |= 0x80; @@ -463,7 +467,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, conf_reg &= ~0x80; i2c_smbus_write_byte_data(client, REG_FAN_CONF1, conf_reg); - +err: mutex_unlock(&data->update_lock); return count; } -- cgit v1.1 From cba5d0b20e7c75dc06e3a609059f17f11c843d94 Mon Sep 17 00:00:00 2001 From: Janne Huttunen Date: Wed, 30 May 2012 05:28:46 -0300 Subject: [media] cxd2820r: Fix an incorrect modulation type bitmask Fix an incorrect modulation type bitmask. This allows QAM256 also to be correctly reported. Signed-off-by: Janne Huttunen Acked-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/cxd2820r_c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c index 9454049..ed3b0ba6 100644 --- a/drivers/media/dvb/frontends/cxd2820r_c.c +++ b/drivers/media/dvb/frontends/cxd2820r_c.c @@ -121,7 +121,7 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe) if (ret) goto error; - switch ((buf[0] >> 0) & 0x03) { + switch ((buf[0] >> 0) & 0x07) { case 0: c->modulation = QAM_16; break; -- cgit v1.1 From 4e6bb2a5fb9265a222e3a86b215f4c5e6bcd61de Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Fri, 8 Jun 2012 04:46:38 -0300 Subject: [media] s5p-mfc: Bug fix of timestamp/timecode copy mechanism Fixed the code copying timecode/timestamp to corresponding frames between OUTPUT and CAPTURE. Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/regs-mfc.h | 5 +++++ drivers/media/video/s5p-mfc/s5p_mfc_opr.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/s5p-mfc/regs-mfc.h b/drivers/media/video/s5p-mfc/regs-mfc.h index 053a8a8..a19bece 100644 --- a/drivers/media/video/s5p-mfc/regs-mfc.h +++ b/drivers/media/video/s5p-mfc/regs-mfc.h @@ -164,10 +164,15 @@ decoded pic */ #define S5P_FIMV_SI_DISPLAY_Y_ADR 0x2010 /* luma addr of displayed pic */ #define S5P_FIMV_SI_DISPLAY_C_ADR 0x2014 /* chroma addrof displayed pic */ + #define S5P_FIMV_SI_CONSUMED_BYTES 0x2018 /* Consumed number of bytes to decode a frame */ #define S5P_FIMV_SI_DISPLAY_STATUS 0x201c /* status of decoded picture */ +#define S5P_FIMV_SI_DECODE_Y_ADR 0x2024 /* luma addr of decoded pic */ +#define S5P_FIMV_SI_DECODE_C_ADR 0x2028 /* chroma addrof decoded pic */ +#define S5P_FIMV_SI_DECODE_STATUS 0x202c /* status of decoded picture */ + #define S5P_FIMV_SI_CH0_SB_ST_ADR 0x2044 /* start addr of stream buf */ #define S5P_FIMV_SI_CH0_SB_FRM_SIZE 0x2048 /* size of stream buf */ #define S5P_FIMV_SI_CH0_DESC_ADR 0x204c /* addr of descriptor buf */ diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h index db83836..5932d1c 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h +++ b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h @@ -57,10 +57,12 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq); S5P_FIMV_SI_DISPLAY_Y_ADR) << \ MFC_OFFSET_SHIFT) #define s5p_mfc_get_dec_y_adr() (readl(dev->regs_base + \ - S5P_FIMV_SI_DISPLAY_Y_ADR) << \ + S5P_FIMV_SI_DECODE_Y_ADR) << \ MFC_OFFSET_SHIFT) #define s5p_mfc_get_dspl_status() readl(dev->regs_base + \ S5P_FIMV_SI_DISPLAY_STATUS) +#define s5p_mfc_get_dec_status() readl(dev->regs_base + \ + S5P_FIMV_SI_DECODE_STATUS) #define s5p_mfc_get_frame_type() (readl(dev->regs_base + \ S5P_FIMV_DECODE_FRAME_TYPE) \ & S5P_FIMV_DECODE_FRAME_MASK) -- cgit v1.1 From 9f4161a6b8796dc41dc3924d7869622f7975706a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Fri, 8 Jun 2012 04:47:34 -0300 Subject: [media] v4l: mem2mem_testdev: Fix race conditions in driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mem2mem_testdev allows multiple instances to be opened in parallel. Source and destination queue data are being shared between all instances, which can lead to kernel oops due to race conditions (most likely to happen inside device_run()). Attached patch fixes mentioned problem by storing queue data per device context. Signed-off-by: Tomasz Moń Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mem2mem_testdev.c | 50 ++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index d2dec58..3945556 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c @@ -110,22 +110,6 @@ enum { V4L2_M2M_DST = 1, }; -/* Source and destination queue data */ -static struct m2mtest_q_data q_data[2]; - -static struct m2mtest_q_data *get_q_data(enum v4l2_buf_type type) -{ - switch (type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - return &q_data[V4L2_M2M_SRC]; - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return &q_data[V4L2_M2M_DST]; - default: - BUG(); - } - return NULL; -} - #define V4L2_CID_TRANS_TIME_MSEC V4L2_CID_PRIVATE_BASE #define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_PRIVATE_BASE + 1) @@ -198,8 +182,26 @@ struct m2mtest_ctx { int aborting; struct v4l2_m2m_ctx *m2m_ctx; + + /* Source and destination queue data */ + struct m2mtest_q_data q_data[2]; }; +static struct m2mtest_q_data *get_q_data(struct m2mtest_ctx *ctx, + enum v4l2_buf_type type) +{ + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + return &ctx->q_data[V4L2_M2M_SRC]; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + return &ctx->q_data[V4L2_M2M_DST]; + default: + BUG(); + } + return NULL; +} + + static struct v4l2_queryctrl *get_ctrl(int id) { int i; @@ -223,7 +225,7 @@ static int device_process(struct m2mtest_ctx *ctx, int tile_w, bytes_left; int width, height, bytesperline; - q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT); + q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); width = q_data->width; height = q_data->height; @@ -436,7 +438,7 @@ static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) if (!vq) return -EINVAL; - q_data = get_q_data(f->type); + q_data = get_q_data(ctx, f->type); f->fmt.pix.width = q_data->width; f->fmt.pix.height = q_data->height; @@ -535,7 +537,7 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) if (!vq) return -EINVAL; - q_data = get_q_data(f->type); + q_data = get_q_data(ctx, f->type); if (!q_data) return -EINVAL; @@ -747,7 +749,7 @@ static int m2mtest_queue_setup(struct vb2_queue *vq, struct m2mtest_q_data *q_data; unsigned int size, count = *nbuffers; - q_data = get_q_data(vq->type); + q_data = get_q_data(ctx, vq->type); size = q_data->width * q_data->height * q_data->fmt->depth >> 3; @@ -775,7 +777,7 @@ static int m2mtest_buf_prepare(struct vb2_buffer *vb) dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type); - q_data = get_q_data(vb->vb2_queue->type); + q_data = get_q_data(ctx, vb->vb2_queue->type); if (vb2_plane_size(vb, 0) < q_data->sizeimage) { dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n", @@ -860,6 +862,9 @@ static int m2mtest_open(struct file *file) ctx->transtime = MEM2MEM_DEF_TRANSTIME; ctx->num_processed = 0; + ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0]; + ctx->q_data[V4L2_M2M_DST].fmt = &formats[0]; + ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); if (IS_ERR(ctx->m2m_ctx)) { @@ -986,9 +991,6 @@ static int m2mtest_probe(struct platform_device *pdev) goto err_m2m; } - q_data[V4L2_M2M_SRC].fmt = &formats[0]; - q_data[V4L2_M2M_DST].fmt = &formats[0]; - return 0; v4l2_m2m_release(dev->m2m_dev); -- cgit v1.1 From afd14f48a732758d6fbbc3a5fc5b211742102c4b Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 12 Jun 2012 07:12:58 -0300 Subject: [media] v4l/s5p-mfc: corrected encoder v4l control definitions Patch corrects definition of H264 level control and changes bare numbers to enums in two other cases. Signed-off-by: Andrzej Hajda Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/s5p_mfc_enc.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index acedb20..9c19aa8 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -243,12 +243,6 @@ static struct mfc_control controls[] = { .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_0, .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - .menu_skip_mask = ~( - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_2) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_0) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_1) - ), }, { .id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, @@ -494,7 +488,7 @@ static struct mfc_control controls[] = { .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED, .maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED, - .default_value = 0, + .default_value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED, .menu_skip_mask = 0, }, { @@ -534,7 +528,7 @@ static struct mfc_control controls[] = { .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, .maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE, - .default_value = 0, + .default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, .menu_skip_mask = 0, }, { -- cgit v1.1 From 0749ae350133204c2562c69f4265842141cacf12 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 12 Jun 2012 09:46:26 -0300 Subject: [media] v4l/s5p-mfc: added image size align in VIDIOC_TRY_FMT Image size for MFC encoder should have size between 8x4 and 1920x1080 with even width and height. Signed-off-by: Andrzej Hajda Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/s5p_mfc_enc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index 9c19aa8..03d8334 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -901,6 +901,8 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) mfc_err("failed to try output format\n"); return -EINVAL; } + v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1, + &pix_fmt_mp->height, 4, 1080, 1, 0); } else { mfc_err("invalid buf type\n"); return -EINVAL; -- cgit v1.1 From f60935c17f0c99d4d70fa7e90cfdba3e7008282d Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Thu, 14 Jun 2012 05:58:07 -0300 Subject: [media] s5p-mfc: Fix setting controls Fixed s_ctrl function when setting the following controls: - V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER - V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/s5p_mfc_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index c25ec02..4dd32fc 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c @@ -627,13 +627,13 @@ static int s5p_mfc_dec_s_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY: - ctx->loop_filter_mpeg4 = ctrl->val; + ctx->display_delay = ctrl->val; break; case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE: ctx->display_delay_enable = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: - ctx->display_delay = ctrl->val; + ctx->loop_filter_mpeg4 = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: ctx->slice_interface = ctrl->val; -- cgit v1.1 From 618a2a3a72e2e41a523d25c17b85521858a41e28 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 11 Jun 2012 06:58:42 -0300 Subject: [media] s5p-mfc: Fix checkpatch error in s5p_mfc_shm.h file Fixes the following error: ERROR: open brace '{' following enum go on the same line +enum MFC_SHM_OFS +{ Signed-off-by: Sachin Kamat Acked-by: Kamil Debski Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/s5p_mfc_shm.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h b/drivers/media/video/s5p-mfc/s5p_mfc_shm.h index 764eac6..cf962a4 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h +++ b/drivers/media/video/s5p-mfc/s5p_mfc_shm.h @@ -13,8 +13,7 @@ #ifndef S5P_MFC_SHM_H_ #define S5P_MFC_SHM_H_ -enum MFC_SHM_OFS -{ +enum MFC_SHM_OFS { EXTENEDED_DECODE_STATUS = 0x00, /* D */ SET_FRAME_TAG = 0x04, /* D */ GET_FRAME_TAG_TOP = 0x08, /* D */ -- cgit v1.1 From 4c4ed22632bfafd5367a5a864a8039f5b6efbbab Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Fri, 15 Jun 2012 13:40:32 -0300 Subject: [media] s5p-fimc: Fix control creation function Fixed the size of the V4L2_CID_COLORFX control cluster. Prior to this fix V4L2_CID_ROTATE was also icluded in the cluster preventing application from enabling rotation. Reported-by: Marek Szyprowski Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index fedcd56..92fc5a2 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -615,7 +615,7 @@ int fimc_ctrls_create(struct fimc_ctx *ctx) ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS; if (!handler->error) { - v4l2_ctrl_cluster(3, &ctrls->colorfx); + v4l2_ctrl_cluster(2, &ctrls->colorfx); ctrls->ready = true; } -- cgit v1.1 From 099987f0aaf28771261b91a41240b9228f2e32b2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 14 Jun 2012 09:54:07 -0300 Subject: [media] smia: Fix compile failures Fix compile of smia code. Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=43337 Signed-off-by: Alan Cox Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/smiapp/Kconfig | 2 +- drivers/media/video/smiapp/smiapp-core.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/smiapp/Kconfig b/drivers/media/video/smiapp/Kconfig index f7b35ff..fb99ff1 100644 --- a/drivers/media/video/smiapp/Kconfig +++ b/drivers/media/video/smiapp/Kconfig @@ -1,6 +1,6 @@ config VIDEO_SMIAPP tristate "SMIA++/SMIA sensor support" - depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK select VIDEO_SMIAPP_PLL ---help--- This is a generic driver for SMIA++/SMIA camera modules. diff --git a/drivers/media/video/smiapp/smiapp-core.c b/drivers/media/video/smiapp/smiapp-core.c index f518026..e8c93c8 100644 --- a/drivers/media/video/smiapp/smiapp-core.c +++ b/drivers/media/video/smiapp/smiapp-core.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include -- cgit v1.1 From 155cb06c89f13af3e3e6bd520b9c62762f532d7b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 16 Jun 2012 11:36:08 +0800 Subject: extcon: Fix wrong index in max8997_extcon_cable[] Currently, the index of "Dock-desk" and "Dock-card" are the same. Thus the latter one overrides the first one. Then we have problem when calling extcon_find_cable_index() because edev->supported_cable[7] only matches "Dock-card". Signed-off-by: Axel Lin Acked-by: Kyungmin Park Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon-max8997.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 23416e4..5ecf176 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -116,8 +116,8 @@ const char *max8997_extcon_cable[] = { [5] = "Charge-downstream", [6] = "MHL", [7] = "Dock-desk", - [7] = "Dock-card", - [8] = "JIG", + [8] = "Dock-card", + [9] = "JIG", NULL, }; -- cgit v1.1 From 3f1dc550b069e9fbfe375844f3c76f2cdd12f05c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 16 Jun 2012 11:55:18 +0800 Subject: extcon: Set platform drvdata in gpio_extcon_probe() and fix irq leak Add missing platform_set_drvdata() in gpio_extcon_probe(), otherwise calling platform_get_drvdata in gpio_extcon_remove() returns NULL. Also add missing free_irq call in gpio_extcon_remove(). Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon_gpio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c index fe7a07b..8a0dcc1 100644 --- a/drivers/extcon/extcon_gpio.c +++ b/drivers/extcon/extcon_gpio.c @@ -125,6 +125,7 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) if (ret < 0) goto err_request_irq; + platform_set_drvdata(pdev, extcon_data); /* Perform initial detection */ gpio_extcon_work(&extcon_data->work.work); @@ -146,6 +147,7 @@ static int __devexit gpio_extcon_remove(struct platform_device *pdev) struct gpio_extcon_data *extcon_data = platform_get_drvdata(pdev); cancel_delayed_work_sync(&extcon_data->work); + free_irq(extcon_data->irq, extcon_data); gpio_free(extcon_data->gpio); extcon_dev_unregister(&extcon_data->edev); devm_kfree(&pdev->dev, extcon_data); -- cgit v1.1 From 96c9f05b39a5a3239cf0588cc86a1b95cac652c4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 16 Jun 2012 21:25:11 +0800 Subject: extcon: max8997: Add missing kfree for info->edev in max8997_muic_remove() extcon_dev_unregister(info->edev) doest not free info->edev, we need to call kfree(info->edev) here. Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman --- drivers/extcon/extcon-max8997.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 5ecf176..a4ed30b 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -514,6 +514,7 @@ static int __devexit max8997_muic_remove(struct platform_device *pdev) extcon_dev_unregister(info->edev); + kfree(info->edev); kfree(info); return 0; -- cgit v1.1 From ea1e76a3f92f8565d395c549b9ca836c7eaa44b9 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 13 Jun 2012 13:35:44 +0300 Subject: Bluetooth: btmrvl: Do not send vendor events to bluetooth stack Vendor-specific events shall be processed in driver and not sent to bluetooth stack where they screw up HCI command countings. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- drivers/bluetooth/btmrvl_drv.h | 2 +- drivers/bluetooth/btmrvl_main.c | 14 ++++++++++++-- drivers/bluetooth/btmrvl_sdio.c | 8 +++++--- 3 files changed, 18 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index 94f2d65..27068d1 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h @@ -136,7 +136,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv); void btmrvl_interrupt(struct btmrvl_private *priv); -void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); +bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 681ca9d..dc304de 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -44,23 +44,33 @@ void btmrvl_interrupt(struct btmrvl_private *priv) } EXPORT_SYMBOL_GPL(btmrvl_interrupt); -void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) +bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) { struct hci_event_hdr *hdr = (void *) skb->data; struct hci_ev_cmd_complete *ec; - u16 opcode, ocf; + u16 opcode, ocf, ogf; if (hdr->evt == HCI_EV_CMD_COMPLETE) { ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); opcode = __le16_to_cpu(ec->opcode); ocf = hci_opcode_ocf(opcode); + ogf = hci_opcode_ogf(opcode); + if (ocf == BT_CMD_MODULE_CFG_REQ && priv->btmrvl_dev.sendcmdflag) { priv->btmrvl_dev.sendcmdflag = false; priv->adapter->cmd_complete = true; wake_up_interruptible(&priv->adapter->cmd_wait_q); } + + if (ogf == OGF) { + BT_DBG("vendor event skipped: ogf 0x%4.4x", ogf); + kfree_skb(skb); + return false; + } } + + return true; } EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt); diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index a853244..0cd61d9 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -562,10 +562,12 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) skb_put(skb, buf_len); skb_pull(skb, SDIO_HEADER_LEN); - if (type == HCI_EVENT_PKT) - btmrvl_check_evtpkt(priv, skb); + if (type == HCI_EVENT_PKT) { + if (btmrvl_check_evtpkt(priv, skb)) + hci_recv_frame(skb); + } else + hci_recv_frame(skb); - hci_recv_frame(skb); hdev->stat.byte_rx += buf_len; break; -- cgit v1.1 From 48d7d0ad9022b36be9fd8a236fb58ad4c0f3b80c Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Sun, 17 Jun 2012 22:52:09 +0000 Subject: phy/micrel: change phy_id_mask for KSZ9021 and KS8001 On a freescale imx6q platform, a hardware phy chip KSZ9021 is recognized as a KS8001 chip by the current driver like this: eth0: Freescale FEC PHY driver [Micrel KS8001 or KS8721] KSZ9021 has phy_id 0x00221610, while KSZ8001 has phy_id 0x0022161a, the current phy_id_mask (0x00fffff0/0x00ffff10) can't distinguish them. So change phy_id_mask to resolve this problem. Although the micrel datasheet says that the 4 LSB of phyid2 register contains the chip revision number and the current driver is designed to follow this rule, in reality the chip implementation doesn't follow it. Cc: David J. Choi Cc: David S. Miller Cc: Nobuhiro Iwamatsu Signed-off-by: Hui Wang Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 590f902..9d6c80c 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -161,7 +161,7 @@ static struct phy_driver ks8051_driver = { static struct phy_driver ks8001_driver = { .phy_id = PHY_ID_KS8001, .name = "Micrel KS8001 or KS8721", - .phy_id_mask = 0x00fffff0, + .phy_id_mask = 0x00ffffff, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, @@ -174,7 +174,7 @@ static struct phy_driver ks8001_driver = { static struct phy_driver ksz9021_driver = { .phy_id = PHY_ID_KSZ9021, - .phy_id_mask = 0x000fff10, + .phy_id_mask = 0x000ffffe, .name = "Micrel KSZ9021 Gigabit PHY", .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), @@ -240,8 +240,8 @@ MODULE_AUTHOR("David J. Choi"); MODULE_LICENSE("GPL"); static struct mdio_device_id __maybe_unused micrel_tbl[] = { - { PHY_ID_KSZ9021, 0x000fff10 }, - { PHY_ID_KS8001, 0x00fffff0 }, + { PHY_ID_KSZ9021, 0x000ffffe }, + { PHY_ID_KS8001, 0x00ffffff }, { PHY_ID_KS8737, 0x00fffff0 }, { PHY_ID_KS8041, 0x00fffff0 }, { PHY_ID_KS8051, 0x00fffff0 }, -- cgit v1.1 From 76591bea9714a58d8924154068c78d702eb2cb17 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 03:04:52 +0200 Subject: ath9k: fix a tx rate duration calculation bug The rate pointer variable for a rate series is used in a loop before it is initialized. This went unnoticed because it was used earlier for the RTS/CTS rate. This bug can lead to the wrong PHY type being passed to the duration calculation function. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d59dd01..efb7f00 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1001,13 +1001,13 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, } /* legacy rates */ + rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; if ((tx_info->band == IEEE80211_BAND_2GHZ) && !(rate->flags & IEEE80211_RATE_ERP_G)) phy = WLAN_RC_PHY_CCK; else phy = WLAN_RC_PHY_OFDM; - rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; info->rates[i].Rate = rate->hw_value; if (rate->hw_value_short) { if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) -- cgit v1.1 From 80b08a8d8829a58b5db14b1417151094cc28face Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Jun 2012 03:04:53 +0200 Subject: ath9k: fix invalid pointer access in the tx path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After setup_frame_info has been called, only info->control.rates is still valid, other control fields have been overwritten by the ath_frame_info data. Move the access to info->control.vif for checking short preamble to setup_frame_info before it gets overwritten. This regression was introduced in commit d47a61aa "ath9k: Fix multi-VIF BSS handling" Signed-off-by: Felix Fietkau Reported-by: Thomas Hühn Acked-by: Sujith Manoharan Cc: stable@vger.kernel.org [3.4] Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/xmit.c | 29 +++++++++++++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a277cf6..4866550 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -214,6 +214,7 @@ struct ath_frame_info { enum ath9k_key_type keytype; u8 keyix; u8 retries; + u8 rtscts_rate; }; struct ath_buf_state { diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index efb7f00..4d57139 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -938,6 +938,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, struct ieee80211_tx_rate *rates; const struct ieee80211_rate *rate; struct ieee80211_hdr *hdr; + struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); int i; u8 rix = 0; @@ -948,18 +949,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, /* set dur_update_en for l-sig computation except for PS-Poll frames */ info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); - - /* - * We check if Short Preamble is needed for the CTS rate by - * checking the BSS's global flag. - * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. - */ - rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); - info->rtscts_rate = rate->hw_value; - - if (tx_info->control.vif && - tx_info->control.vif->bss_conf.use_short_preamble) - info->rtscts_rate |= rate->hw_value_short; + info->rtscts_rate = fi->rtscts_rate; for (i = 0; i < 4; i++) { bool is_40, is_sgi, is_sp; @@ -1776,10 +1766,22 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + const struct ieee80211_rate *rate; struct ath_frame_info *fi = get_frame_info(skb); struct ath_node *an = NULL; enum ath9k_key_type keytype; + bool short_preamble = false; + + /* + * We check if Short Preamble is needed for the CTS rate by + * checking the BSS's global flag. + * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. + */ + if (tx_info->control.vif && + tx_info->control.vif->bss_conf.use_short_preamble) + short_preamble = true; + rate = ieee80211_get_rts_cts_rate(hw, tx_info); keytype = ath9k_cmn_get_hw_crypto_keytype(skb); if (sta) @@ -1794,6 +1796,9 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, fi->keyix = ATH9K_TXKEYIX_INVALID; fi->keytype = keytype; fi->framelen = framelen; + fi->rtscts_rate = rate->hw_value; + if (short_preamble) + fi->rtscts_rate |= rate->hw_value_short; } u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) -- cgit v1.1 From 6617942e15a16e97a1e2e93cee26f45e26243f43 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 15 Jun 2012 16:03:29 -0400 Subject: ath5k: remove _bh from inner locks spin_unlock_bh(&txq->lock) already disables softirqs so we don't want to do it here. Fixes smatch warnings: drivers/net/wireless/ath/ath5k/base.c:1048 ath5k_drain_tx_buffs() error: double lock 'bottom_half:' drivers/net/wireless/ath/ath5k/base.c:1056 ath5k_drain_tx_buffs() error: double unlock 'bottom_half:' Reported-by: Johannes Berg Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index fbaa309..44ad6fe 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1045,11 +1045,11 @@ ath5k_drain_tx_buffs(struct ath5k_hw *ah) ath5k_txbuf_free_skb(ah, bf); - spin_lock_bh(&ah->txbuflock); + spin_lock(&ah->txbuflock); list_move_tail(&bf->list, &ah->txbuf); ah->txbuf_len++; txq->txq_len--; - spin_unlock_bh(&ah->txbuflock); + spin_unlock(&ah->txbuflock); } txq->link = NULL; txq->txq_poll_mark = false; -- cgit v1.1 From 73dc3b90232780462f3771901024a160559b4532 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 15 Jun 2012 16:21:53 -0700 Subject: mwifiex: fix uAP TX packet timeout issue When running heavy traffic we stop the tx queue if the pending packet count reaches certain threshold. Later, the tx queue should be woken up as soon as the packet count falls below the threshold. Current code wakes TX queue up on STA interface only. Removing the check for STA interface will allow both STA and AP interfaces to resume transmit when tx_pending count becomes low. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/txrx.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index e2faec4..cecb272 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -161,15 +161,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, goto done; for (i = 0; i < adapter->priv_num; i++) { - tpriv = adapter->priv[i]; - if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) && - (tpriv->media_connected)) { - if (netif_queue_stopped(tpriv->netdev)) - mwifiex_wake_up_net_dev_queue(tpriv->netdev, - adapter); - } + if (tpriv->media_connected && + netif_queue_stopped(tpriv->netdev)) + mwifiex_wake_up_net_dev_queue(tpriv->netdev, adapter); } done: dev_kfree_skb_any(skb); -- cgit v1.1 From 7f59ebb5f34380696d16094fa1090485ec077fb1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 18 Jun 2012 10:48:14 +0300 Subject: airo: copying wrong data in airo_get_aplist() "qual" used to be declared on the stack, but then in 998a5a7d6a ("airo: reduce stack memory footprint") we made it dynamically allocated. Unfortunately the memcpy() here was missed and it's still copying stack memory instead of the data that we want. In other words, "&qual" should be "qual". Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 520a4b2..a747c63 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -7233,8 +7233,8 @@ static int airo_get_aplist(struct net_device *dev, } } else { dwrq->flags = 1; /* Should be define'd */ - memcpy(extra + sizeof(struct sockaddr)*i, - &qual, sizeof(struct iw_quality)*i); + memcpy(extra + sizeof(struct sockaddr) * i, qual, + sizeof(struct iw_quality) * i); } dwrq->length = i; -- cgit v1.1 From 858faa57dd9e2b91f3f870fbb1185982e42f5a2b Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Fri, 15 Jun 2012 15:49:54 -0700 Subject: mwifiex: fix wrong return values in add_virtual_intf() error cases add_virtual_intf() needs to return an ERR_PTR(), instead of NULL, on errors, otherwise cfg80211 will crash. Reported-by: Johannes Berg Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 015fec3..ce61b6f 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1484,7 +1484,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev; if (!adapter) - return NULL; + return ERR_PTR(-EFAULT); switch (type) { case NL80211_IFTYPE_UNSPECIFIED: @@ -1494,12 +1494,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (priv->bss_mode) { wiphy_err(wiphy, "cannot create multiple sta/adhoc ifaces\n"); - return NULL; + return ERR_PTR(-EINVAL); } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) - return NULL; + return ERR_PTR(-ENOMEM); wdev->wiphy = wiphy; priv->wdev = wdev; @@ -1522,12 +1522,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (priv->bss_mode) { wiphy_err(wiphy, "Can't create multiple AP interfaces"); - return NULL; + return ERR_PTR(-EINVAL); } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) - return NULL; + return ERR_PTR(-ENOMEM); priv->wdev = wdev; wdev->wiphy = wiphy; @@ -1544,14 +1544,15 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, break; default: wiphy_err(wiphy, "type not supported\n"); - return NULL; + return ERR_PTR(-EINVAL); } dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, ether_setup, 1); if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); - goto error; + priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; + return ERR_PTR(-ENOMEM); } mwifiex_init_priv_params(priv, dev); @@ -1582,7 +1583,9 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, /* Register network device */ if (register_netdevice(dev)) { wiphy_err(wiphy, "cannot register virtual network device\n"); - goto error; + free_netdev(dev); + priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; + return ERR_PTR(-EFAULT); } sema_init(&priv->async_sem, 1); @@ -1594,12 +1597,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, mwifiex_dev_debugfs_init(priv); #endif return dev; -error: - if (dev && (dev->reg_state == NETREG_UNREGISTERED)) - free_netdev(dev); - priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; - - return NULL; } EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); -- cgit v1.1 From 4dd81e895655c59bd19d7a8f03a5de1310f4aeb6 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 14 Jun 2012 20:49:09 +0000 Subject: RDMA/cma: QP type check on received REQs should be AND not OR Change || check to the intended && when checking the QP type in a received connection request against the listening endpoint. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/cma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 55d5642..2e826f9 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1184,7 +1184,7 @@ static void cma_set_req_event_data(struct rdma_cm_event *event, static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event) { - return (((ib_event->event == IB_CM_REQ_RECEIVED) || + return (((ib_event->event == IB_CM_REQ_RECEIVED) && (ib_event->param.req_rcvd.qp_type == id->qp_type)) || ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) && (id->qp_type == IB_QPT_UD)) || -- cgit v1.1 From adc0fa413917bd973469560388446c52ce43b995 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 18 May 2012 02:07:53 +0000 Subject: igb: Fix incorrect RAR address entries for i210/i211 device. i210/i211 device has only 16 RAR address filters like 82575, instead of 32 like i350. This patch removes the entries for i210/i211 in the get_invariants function which was setting them for 32. This ensures that they will get the default value which is the correct one. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/e1000_82575.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index e650839..5e84eaa 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -206,8 +206,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) mac->rar_entry_count = E1000_RAR_ENTRIES_82580; break; case e1000_i350: - case e1000_i210: - case e1000_i211: mac->rar_entry_count = E1000_RAR_ENTRIES_I350; break; default: -- cgit v1.1 From 0e808bcc483773b4bcb45f02792b24ccfa428b68 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 18 May 2012 05:40:46 +0000 Subject: Kconfig: Fix Kconfig for Intel ixgbe and igb PTP support. Fix Kconfig file to make sure that PTP and IGB/IXGBE are both either in-kernel or modules, not mixed. Having the build status mixed causes compile errors. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/Kconfig | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 79b07ec..0cafe4f 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -122,8 +122,10 @@ config IGB_DCA config IGB_PTP bool "PTP Hardware Clock (PHC)" - default y - depends on IGB && PTP_1588_CLOCK + default n + depends on IGB && EXPERIMENTAL + select PPS + select PTP_1588_CLOCK ---help--- Say Y here if you want to use PTP Hardware Clock (PHC) in the driver. Only the basic clock operations have been implemented. @@ -223,7 +225,9 @@ config IXGBE_DCB config IXGBE_PTP bool "PTP Clock Support" default n - depends on IXGBE && PTP_1588_CLOCK + depends on IXGBE && EXPERIMENTAL + select PPS + select PTP_1588_CLOCK ---help--- Say Y here if you want support for 1588 Timestamping with a PHC device, using the PTP 1588 Clock support. This is -- cgit v1.1 From 8633c0846160af0b8cfb983bbccd94ae42922af8 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 16 Jun 2012 07:31:19 +0000 Subject: ixgbe: Fix memory leak in ixgbe when receiving traffic on DDP enabled rings This patch fixes a memory leak that was introduced in the 3.4 kernel. The leak occurred when FCoE was enabled and traffic was passed over the FCoE rings reserved for FCoE. The memory leak was due to us not populating the compound page information on the order 1 pages needed for FCoE. Signed-off-by: Alexander Duyck Tested-by: Phil Schmitt Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 17ad6a3..cbb05d6 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1148,7 +1148,7 @@ static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, /* alloc new page for storage */ if (likely(!page)) { - page = alloc_pages(GFP_ATOMIC | __GFP_COLD, + page = alloc_pages(GFP_ATOMIC | __GFP_COLD | __GFP_COMP, ixgbe_rx_pg_order(rx_ring)); if (unlikely(!page)) { rx_ring->rx_stats.alloc_rx_page_failed++; -- cgit v1.1 From 8386a00f1443f676e8b614f654e2e324fdc0b3b3 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 14 Jun 2012 16:00:53 +0800 Subject: regulator: tps6524x: Fix get_voltage_sel for fixed voltage get_voltage_sel() should return selector rather than voltage. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps6524x-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index b88b3df..1b299aa 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c @@ -482,7 +482,7 @@ static int get_voltage_sel(struct regulator_dev *rdev) info = &supply_info[rdev_get_id(rdev)]; if (info->flags & FIXED_VOLTAGE) - return info->fixed_voltage; + return 0; ret = read_field(hw, &info->voltage); if (ret < 0) -- cgit v1.1 From cae6247db0b93673d170bc0e02aff85f53bc422c Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 16 Jun 2012 22:26:46 +0300 Subject: wl1251: fix TSF calculation Cast MSB part of current TSF to u64 to prevent loss of most significant bits. MSB should also be shifted by 32. Patch based on old maemo patch by: Yuri Kululin Yuri Ershov Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl1251/acx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c index ad87a1a..db6430c 100644 --- a/drivers/net/wireless/ti/wl1251/acx.c +++ b/drivers/net/wireless/ti/wl1251/acx.c @@ -869,7 +869,7 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime) } *mactime = tsf_info->current_tsf_lsb | - (tsf_info->current_tsf_msb << 31); + ((u64)tsf_info->current_tsf_msb << 32); out: kfree(tsf_info); -- cgit v1.1 From 0d776fcdafed91403b1f453473771664ef7a66bd Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 16 Jun 2012 22:26:47 +0300 Subject: wl1251: always report beacon loss to the stack Always report beacon loss to the stack, not only when in powersave state. This is because there's possibility that the driver disables PSM before it handles old BSS_LOSE_EVENT, so beacon loss has to be reported. Patch based on old maemo patch by: Janne Ylalehto Juuso Oikarinen Luciano Coelho Yuri Ershov Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl1251/event.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c index 9f15cca..5ec50a4 100644 --- a/drivers/net/wireless/ti/wl1251/event.c +++ b/drivers/net/wireless/ti/wl1251/event.c @@ -76,8 +76,7 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) } } - if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && - wl->station_mode != STATION_ACTIVE_MODE) { + if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); /* indicate to the stack, that beacons have been lost */ -- cgit v1.1 From a859e4d6590b2429f518aa712b9e3edd367398d7 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 16 Jun 2012 22:26:48 +0300 Subject: wl1251: Fix memory leaks in SPI initialization This patch fixes two memory leaks in the SPI initialization code. Patch based on old maemo patch by: Yuri Ershov Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl1251/spi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c index 87f6305..567660c 100644 --- a/drivers/net/wireless/ti/wl1251/spi.c +++ b/drivers/net/wireless/ti/wl1251/spi.c @@ -73,6 +73,8 @@ static void wl1251_spi_reset(struct wl1251 *wl) spi_sync(wl_to_spi(wl), &m); wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); + + kfree(cmd); } static void wl1251_spi_wake(struct wl1251 *wl) @@ -127,6 +129,8 @@ static void wl1251_spi_wake(struct wl1251 *wl) spi_sync(wl_to_spi(wl), &m); wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); + + kfree(cmd); } static void wl1251_spi_reset_wake(struct wl1251 *wl) -- cgit v1.1 From f18e3c6b67f448ec47b3a5b242789bd3d5644879 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Mon, 18 Jun 2012 13:13:30 +0530 Subject: ath9k_hw: avoid possible infinite loop in ar9003_get_pll_sqsum_dvc "ath9k: Fix softlockup in AR9485" with commit id 64bc1239c790e051ff677e023435d770d2ffa174 fixed the reported issue, yet its better to avoid the possible infinite loop in ar9003_get_pll_sqsum_dvc by having a timeout as suggested by ath9k maintainers. http://www.spinics.net/lists/linux-wireless/msg92126.html. Based on my testing PLL's locking measurement is done in ~200us (2 iterations). Cc: stable@vger.kernel.org Cc: Rolf Offermanns Cc: Sujith Manoharan Cc: Senthil Balasubramanian Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 7db1890..1c68e56 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -784,13 +784,25 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) { + struct ath_common *common = ath9k_hw_common(ah); + int i = 0; + REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); udelay(100); REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); - while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) + while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) { + udelay(100); + if (WARN_ON_ONCE(i >= 100)) { + ath_err(common, "PLL4 meaurement not done\n"); + break; + } + + i++; + } + return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; } EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); -- cgit v1.1 From 882b7b7d11d65e8eccce738f1ce97cdfdb998f9f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Jun 2012 08:46:25 +0200 Subject: iwlwifi: remove log_event debugfs file debugging is disabled When debugging is disabled, the event log functions aren't functional in the way that the debugfs file expects. This leads to the debugfs access crashing. Since the event log functions aren't functional then, remove the debugfs file when CONFIG_IWLWIFI_DEBUG is not set. Cc: stable@kernel.org Reported-by: Lekensteyn Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index e7c157e..7f97dec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2239,6 +2239,7 @@ static ssize_t iwl_dbgfs_echo_test_write(struct file *file, return count; } +#ifdef CONFIG_IWLWIFI_DEBUG static ssize_t iwl_dbgfs_log_event_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -2276,6 +2277,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, return count; } +#endif static ssize_t iwl_dbgfs_calib_disabled_read(struct file *file, char __user *user_buf, @@ -2345,7 +2347,9 @@ DEBUGFS_READ_FILE_OPS(bt_traffic); DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); DEBUGFS_WRITE_FILE_OPS(echo_test); +#ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_READ_WRITE_FILE_OPS(log_event); +#endif DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled); /* @@ -2405,7 +2409,9 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); +#ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); +#endif if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); -- cgit v1.1 From 931cb03afed7b541392295f3afc4638da32f08a0 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 20 Jun 2012 16:29:20 +0530 Subject: ath9k_htc: configure bssid on ASSOC/IBSS change After the change "mac80211: remove spurious BSSID change flag", BSS_CHANGED_BSSID will not be passed on association or IBSS status changes. So it could be better to program bssid on ASSOC or IBSS change notification. Not doing so, is affecting the packet transmission. Cc: stable@vger.kernel.org [3.4+] Reported-by: Michael Leun Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 2b8f61c..abbd6ef 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1496,6 +1496,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; if (priv->ah->opmode == NL80211_IFTYPE_STATION) { + ath9k_htc_choose_set_bssid(priv); if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) ath9k_htc_start_ani(priv); else if (priv->num_sta_assoc_vif == 0) @@ -1503,13 +1504,11 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, } } - if (changed & BSS_CHANGED_BSSID) { + if (changed & BSS_CHANGED_IBSS) { if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { common->curaid = bss_conf->aid; memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); ath9k_htc_set_bssid(priv); - } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) { - ath9k_htc_choose_set_bssid(priv); } } -- cgit v1.1 From b7019b2f31fe7bec9f6f5dc1bf54cb0e0d73e047 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 15:58:25 -0400 Subject: drm/radeon: SI tiling fixes for display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use the correct union for getting the tiling info - Properly init the PIPE_CONFIG field for SI Signed-off-by: Alex Deucher Reviewed-by: Michel Dänzer Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 10 ++++- drivers/gpu/drm/radeon/si_reg.h | 72 ++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 01d77d1..3904d79 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1149,7 +1149,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } if (tiling_flags & RADEON_TILING_MACRO) { - if (rdev->family >= CHIP_CAYMAN) + if (rdev->family >= CHIP_TAHITI) + tmp = rdev->config.si.tile_config; + else if (rdev->family >= CHIP_CAYMAN) tmp = rdev->config.cayman.tile_config; else tmp = rdev->config.evergreen.tile_config; @@ -1177,6 +1179,12 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } else if (tiling_flags & RADEON_TILING_MICRO) fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); + if ((rdev->family == CHIP_TAHITI) || + (rdev->family == CHIP_PITCAIRN)) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); + else if (rdev->family == CHIP_VERDE) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); + switch (radeon_crtc->crtc_id) { case 0: WREG32(AVIVO_D1VGA_CONTROL, 0); diff --git a/drivers/gpu/drm/radeon/si_reg.h b/drivers/gpu/drm/radeon/si_reg.h index eda938a..501f9d43 100644 --- a/drivers/gpu/drm/radeon/si_reg.h +++ b/drivers/gpu/drm/radeon/si_reg.h @@ -30,4 +30,76 @@ #define SI_DC_GPIO_HPD_EN 0x65b8 #define SI_DC_GPIO_HPD_Y 0x65bc +#define SI_GRPH_CONTROL 0x6804 +# define SI_GRPH_DEPTH(x) (((x) & 0x3) << 0) +# define SI_GRPH_DEPTH_8BPP 0 +# define SI_GRPH_DEPTH_16BPP 1 +# define SI_GRPH_DEPTH_32BPP 2 +# define SI_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2) +# define SI_ADDR_SURF_2_BANK 0 +# define SI_ADDR_SURF_4_BANK 1 +# define SI_ADDR_SURF_8_BANK 2 +# define SI_ADDR_SURF_16_BANK 3 +# define SI_GRPH_Z(x) (((x) & 0x3) << 4) +# define SI_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6) +# define SI_ADDR_SURF_BANK_WIDTH_1 0 +# define SI_ADDR_SURF_BANK_WIDTH_2 1 +# define SI_ADDR_SURF_BANK_WIDTH_4 2 +# define SI_ADDR_SURF_BANK_WIDTH_8 3 +# define SI_GRPH_FORMAT(x) (((x) & 0x7) << 8) +/* 8 BPP */ +# define SI_GRPH_FORMAT_INDEXED 0 +/* 16 BPP */ +# define SI_GRPH_FORMAT_ARGB1555 0 +# define SI_GRPH_FORMAT_ARGB565 1 +# define SI_GRPH_FORMAT_ARGB4444 2 +# define SI_GRPH_FORMAT_AI88 3 +# define SI_GRPH_FORMAT_MONO16 4 +# define SI_GRPH_FORMAT_BGRA5551 5 +/* 32 BPP */ +# define SI_GRPH_FORMAT_ARGB8888 0 +# define SI_GRPH_FORMAT_ARGB2101010 1 +# define SI_GRPH_FORMAT_32BPP_DIG 2 +# define SI_GRPH_FORMAT_8B_ARGB2101010 3 +# define SI_GRPH_FORMAT_BGRA1010102 4 +# define SI_GRPH_FORMAT_8B_BGRA1010102 5 +# define SI_GRPH_FORMAT_RGB111110 6 +# define SI_GRPH_FORMAT_BGR101111 7 +# define SI_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11) +# define SI_ADDR_SURF_BANK_HEIGHT_1 0 +# define SI_ADDR_SURF_BANK_HEIGHT_2 1 +# define SI_ADDR_SURF_BANK_HEIGHT_4 2 +# define SI_ADDR_SURF_BANK_HEIGHT_8 3 +# define SI_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13) +# define SI_ADDR_SURF_TILE_SPLIT_64B 0 +# define SI_ADDR_SURF_TILE_SPLIT_128B 1 +# define SI_ADDR_SURF_TILE_SPLIT_256B 2 +# define SI_ADDR_SURF_TILE_SPLIT_512B 3 +# define SI_ADDR_SURF_TILE_SPLIT_1KB 4 +# define SI_ADDR_SURF_TILE_SPLIT_2KB 5 +# define SI_ADDR_SURF_TILE_SPLIT_4KB 6 +# define SI_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18) +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_1 0 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_2 1 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_4 2 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_8 3 +# define SI_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) +# define SI_GRPH_ARRAY_LINEAR_GENERAL 0 +# define SI_GRPH_ARRAY_LINEAR_ALIGNED 1 +# define SI_GRPH_ARRAY_1D_TILED_THIN1 2 +# define SI_GRPH_ARRAY_2D_TILED_THIN1 4 +# define SI_GRPH_PIPE_CONFIG(x) (((x) & 0x1f) << 24) +# define SI_ADDR_SURF_P2 0 +# define SI_ADDR_SURF_P4_8x16 4 +# define SI_ADDR_SURF_P4_16x16 5 +# define SI_ADDR_SURF_P4_16x32 6 +# define SI_ADDR_SURF_P4_32x32 7 +# define SI_ADDR_SURF_P8_16x16_8x16 8 +# define SI_ADDR_SURF_P8_16x32_8x16 9 +# define SI_ADDR_SURF_P8_32x32_8x16 10 +# define SI_ADDR_SURF_P8_16x32_16x16 11 +# define SI_ADDR_SURF_P8_32x32_16x16 12 +# define SI_ADDR_SURF_P8_32x32_16x32 13 +# define SI_ADDR_SURF_P8_32x64_32x32 14 + #endif -- cgit v1.1 From 10d8935f46e5028847b179757ecbf9238b13d129 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 20 Jun 2012 12:53:02 -0700 Subject: Viresh has moved viresh.kumar@st.com email-id doesn't exist anymore as I have left the company. Replace ST's id with viresh.linux@gmail.com. It also updates .mailmap file to fix address for 'git shortlog' Signed-off-by: Viresh Kumar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ata/pata_arasan_cf.c | 4 ++-- drivers/clk/spear/clk-aux-synth.c | 2 +- drivers/clk/spear/clk-frac-synth.c | 2 +- drivers/clk/spear/clk-gpt-synth.c | 2 +- drivers/clk/spear/clk-vco-pll.c | 2 +- drivers/clk/spear/clk.c | 2 +- drivers/clk/spear/clk.h | 2 +- drivers/clk/spear/spear1310_clock.c | 2 +- drivers/clk/spear/spear1340_clock.c | 2 +- drivers/clk/spear/spear3xx_clock.c | 2 +- drivers/clk/spear/spear6xx_clock.c | 2 +- drivers/dma/dw_dmac.c | 2 +- drivers/mfd/stmpe-i2c.c | 2 +- drivers/mfd/stmpe-spi.c | 4 ++-- drivers/mmc/host/sdhci-spear.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear.c | 2 +- drivers/pinctrl/spear/pinctrl-spear.h | 2 +- drivers/pinctrl/spear/pinctrl-spear1310.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear1340.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear300.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear310.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear320.c | 4 ++-- drivers/pinctrl/spear/pinctrl-spear3xx.c | 2 +- drivers/pinctrl/spear/pinctrl-spear3xx.h | 2 +- drivers/watchdog/sp805_wdt.c | 4 ++-- 25 files changed, 34 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 3239517..ac6a5be 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -4,7 +4,7 @@ * Arasan Compact Flash host controller source file * * Copyright (C) 2011 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -959,7 +959,7 @@ static struct platform_driver arasan_cf_driver = { module_platform_driver(arasan_cf_driver); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("Arasan ATA Compact Flash driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c index af34074..6756e7c 100644 --- a/drivers/clk/spear/clk-aux-synth.c +++ b/drivers/clk/spear/clk-aux-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c index 4dbdb3f..958aa3a 100644 --- a/drivers/clk/spear/clk-frac-synth.c +++ b/drivers/clk/spear/clk-frac-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c index b471c97..1afc18c 100644 --- a/drivers/clk/spear/clk-gpt-synth.c +++ b/drivers/clk/spear/clk-gpt-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c index dcd4bdf..5f1b6ba 100644 --- a/drivers/clk/spear/clk-vco-pll.c +++ b/drivers/clk/spear/clk-vco-pll.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk.c b/drivers/clk/spear/clk.c index 376d4e5..7cd6378 100644 --- a/drivers/clk/spear/clk.c +++ b/drivers/clk/spear/clk.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h index 3321c46..9317376 100644 --- a/drivers/clk/spear/clk.h +++ b/drivers/clk/spear/clk.h @@ -2,7 +2,7 @@ * Clock framework definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 42b68df..8f05652 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -4,7 +4,7 @@ * SPEAr1310 machine clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index f130919..e3ea721 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -4,7 +4,7 @@ * SPEAr1340 machine clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 440bb3e..01dd6da 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -2,7 +2,7 @@ * SPEAr3xx machines clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index f9a20b3..554d64b 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -2,7 +2,7 @@ * SPEAr6xx machines clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index e23dc82..7212961 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -1626,4 +1626,4 @@ module_exit(dw_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 373f423..947a06a 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -6,7 +6,7 @@ * * License Terms: GNU General Public License, version 2 * Author: Rabin Vincent for ST-Ericsson - * Author: Viresh Kumar for ST Microelectronics + * Author: Viresh Kumar for ST Microelectronics */ #include diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c index afd4590..9edfe86 100644 --- a/drivers/mfd/stmpe-spi.c +++ b/drivers/mfd/stmpe-spi.c @@ -4,7 +4,7 @@ * Copyright (C) ST Microelectronics SA 2011 * * License Terms: GNU General Public License, version 2 - * Author: Viresh Kumar for ST Microelectronics + * Author: Viresh Kumar for ST Microelectronics */ #include @@ -146,4 +146,4 @@ module_exit(stmpe_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c index 1fe32df..423da81 100644 --- a/drivers/mmc/host/sdhci-spear.c +++ b/drivers/mmc/host/sdhci-spear.c @@ -4,7 +4,7 @@ * Support of SDHCI platform devices for spear soc family * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * Inspired by sdhci-pltfm.c * @@ -289,5 +289,5 @@ static struct platform_driver sdhci_driver = { module_platform_driver(sdhci_driver); MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index 5ae50aa..b3f6b28 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * Inspired from: * - U300 Pinctl drivers diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h index 9155783..d950eb7 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.h +++ b/drivers/pinctrl/spear/pinctrl-spear.h @@ -2,7 +2,7 @@ * Driver header file for the ST Microelectronics SPEAr pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index fff168b..d6cca8c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr1310 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -2192,7 +2192,7 @@ static void __exit spear1310_pinctrl_exit(void) } module_exit(spear1310_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr1310 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear1310_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c index a8ab2a6..a0eb057 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/drivers/pinctrl/spear/pinctrl-spear1340.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr1340 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -1983,7 +1983,7 @@ static void __exit spear1340_pinctrl_exit(void) } module_exit(spear1340_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr1340 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear1340_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c index 9c82a35..4dfc284 100644 --- a/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/drivers/pinctrl/spear/pinctrl-spear300.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr300 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -702,7 +702,7 @@ static void __exit spear300_pinctrl_exit(void) } module_exit(spear300_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c index 1a97076..9688369 100644 --- a/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/drivers/pinctrl/spear/pinctrl-spear310.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr310 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -425,7 +425,7 @@ static void __exit spear310_pinctrl_exit(void) } module_exit(spear310_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, SPEAr310_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index de726e6..020b1e0 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr320 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -3462,7 +3462,7 @@ static void __exit spear320_pinctrl_exit(void) } module_exit(spear320_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ST Microelectronics SPEAr320 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear320_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c index 91c883b..0242378 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.c +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr3xx pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h index 5d5fdd8..31f4434 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h @@ -2,7 +2,7 @@ * Header file for the ST Microelectronics SPEAr3xx pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index afcd136..e4841c3 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -4,7 +4,7 @@ * Watchdog driver for ARM SP805 watchdog module * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2 or later. This program is licensed "as is" without any @@ -331,6 +331,6 @@ static struct amba_driver sp805_wdt_driver = { module_amba_driver(sp805_wdt_driver); -MODULE_AUTHOR("Viresh Kumar "); +MODULE_AUTHOR("Viresh Kumar "); MODULE_DESCRIPTION("ARM SP805 Watchdog Driver"); MODULE_LICENSE("GPL"); -- cgit v1.1 From 1e2c4e59d2b8797973471b4a287a43eac12a0f40 Mon Sep 17 00:00:00 2001 From: Dmitry Shmygov Date: Wed, 20 Jun 2012 15:51:40 +0400 Subject: USB: option: add id for Cellient MEN-200 Add vendor and product ID to option.c driver for Cellient MEN-200 EVDO Rev.B 450MHz data module. http://cellient.com Signed-off-by: Dmitry Shmygov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e668a24..396d968 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -497,6 +497,10 @@ static void option_instat_callback(struct urb *urb); /* MediaTek products */ #define MEDIATEK_VENDOR_ID 0x0e8d +/* Cellient products */ +#define CELLIENT_VENDOR_ID 0x2692 +#define CELLIENT_PRODUCT_MEN200 0x9005 + /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { OPTION_BLACKLIST_NONE = 0, @@ -1233,6 +1237,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x02, 0x01) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x02, 0x01) }, /* MediaTek MT6276M modem & app port */ + { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); -- cgit v1.1 From 0e3534c0417fef6e6535db8867a04798f2024e3f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 20 Jun 2012 18:30:30 -0700 Subject: media: pms.c needs linux/slab.h drivers/media/video/pms.c uses kzalloc() and kfree() so it should include to fix build errors and a warning. drivers/media/video/pms.c:1047:2: error: implicit declaration of function 'kzalloc' drivers/media/video/pms.c:1047:6: warning: assignment makes pointer from integer without a cast drivers/media/video/pms.c:1116:2: error: implicit declaration of function 'kfree' Found in mmotm but applies to mainline. Signed-off-by: Randy Dunlap Cc: Hans Verkuil Signed-off-by: Linus Torvalds --- drivers/media/video/pms.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index af2d908..c370c2d 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include -- cgit v1.1 From b196a4980ff7bb54db478e2a408dc8b12be15304 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 19 Jun 2012 11:33:06 +0200 Subject: drm/edid: don't return stack garbage from supports_rb We need to initialize this to false, because the is_rb callback only ever sets it to true. Noticed while reading through the code. Cc: stable@vger.kernel.org Signed-Off-by: Daniel Vetter Reviewed-by: Adam Jackson Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_edid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index eb92fe2..5873e48 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -610,7 +610,7 @@ static bool drm_monitor_supports_rb(struct edid *edid) { if (edid->revision >= 4) { - bool ret; + bool ret = false; drm_for_each_detailed_block((u8 *)edid, is_rb, &ret); return ret; } -- cgit v1.1 From e734568b675c985db2026848fefaac01c22977a5 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 8 Jun 2012 16:16:04 +0100 Subject: oprofile: perf: use NR_CPUS instead or nr_cpumask_bits for static array The OProfile perf backend uses a static array to keep track of the perf events on the system. When compiling with CONFIG_CPUMASK_OFFSTACK=y && SMP, nr_cpumask_bits is not a compile-time constant and the build will fail with: oprofile_perf.c:28: error: variably modified 'perf_events' at file scope This patch uses NR_CPUs instead of nr_cpumask_bits for the array initialisation. If this causes space problems in the future, we can always move to dynamic allocation for the events array. Cc: Matt Fleming Reported-by: Russell King - ARM Linux Signed-off-by: Will Deacon Cc: # v2.6.37+ Signed-off-by: Robert Richter --- drivers/oprofile/oprofile_perf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c index da14432..efc4b7f 100644 --- a/drivers/oprofile/oprofile_perf.c +++ b/drivers/oprofile/oprofile_perf.c @@ -25,7 +25,7 @@ static int oprofile_perf_enabled; static DEFINE_MUTEX(oprofile_perf_mutex); static struct op_counter_config *counter_config; -static struct perf_event **perf_events[nr_cpumask_bits]; +static struct perf_event **perf_events[NR_CPUS]; static int num_counters; /* -- cgit v1.1 From dc8738d95bb45d20b2141f1fe3e1cafb05be09f9 Mon Sep 17 00:00:00 2001 From: Moiz Sonasath Date: Tue, 12 Jun 2012 20:17:12 +0300 Subject: usb: otg: twl6030-usb: Fix twl writes There were mistakes in writing to few twl registers. There was interchange in the parameters being passed to twl6030_writeb(). Signed-off-by: Moiz Sonasath Signed-off-by: Ruslan Bilovol Signed-off-by: Felipe Balbi --- drivers/usb/otg/twl6030-usb.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index d2a9a8e..0eabb04 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -305,9 +305,8 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) regulator_enable(twl->usb3v3); twl->asleep = 1; - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x1); - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, - 0x10); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); status = USB_EVENT_ID; otg->default_a = true; twl->phy.state = OTG_STATE_A_IDLE; @@ -316,12 +315,10 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) atomic_notifier_call_chain(&twl->phy.notifier, status, otg->gadget); } else { - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, - 0x10); - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, - 0x1); + twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); } - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_LATCH_CLR, status); + twl6030_writeb(twl, TWL_MODULE_USB, status, USB_ID_INT_LATCH_CLR); return IRQ_HANDLED; } @@ -343,7 +340,7 @@ static int twl6030_enable_irq(struct usb_phy *x) { struct twl6030_usb *twl = phy_to_twl(x); - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, 0x1); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); -- cgit v1.1 From d7dbdb5e5fe809aa3d4c33b33943c94321dfdd06 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Wed, 20 Jun 2012 09:37:57 -0300 Subject: usb: gadget: lpc32xx_udc: fix build error with debugfs enabled If CONFIG_USB_GADGET_DEBUG_FILES is enabled, lpc32xx_udc breaks compilation because of a missing include file. Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 262acfd..2ab0388 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -61,6 +61,7 @@ #include #include #ifdef CONFIG_USB_GADGET_DEBUG_FILES +#include #include #endif -- cgit v1.1 From 8c778db9f01a1b6c785890b5fd83c7addfd3eb3a Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Thu, 21 Jun 2012 17:18:12 +0530 Subject: usb: musb: host: release dma channels if no active io Currently DMA channels are allocated and they remain allocated even if there is no active data transfer. Added channel_release() whenever there is no pending request. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_host.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index ef8d744..e090c79 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -375,11 +375,21 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, */ if (list_empty(&qh->hep->urb_list)) { struct list_head *head; + struct dma_controller *dma = musb->dma_controller; - if (is_in) + if (is_in) { ep->rx_reinit = 1; - else + if (ep->rx_channel) { + dma->channel_release(ep->rx_channel); + ep->rx_channel = NULL; + } + } else { ep->tx_reinit = 1; + if (ep->tx_channel) { + dma->channel_release(ep->tx_channel); + ep->tx_channel = NULL; + } + } /* Clobber old pointers to this qh */ musb_ep_set_qh(ep, is_in, NULL); -- cgit v1.1 From 58bf8062d0b293b8e1028e5b0342082002886bd4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 21 Jun 2012 14:55:22 +0200 Subject: drm/i915: rip out the PM_IIR WARN After banging my head against this for the past few months, I still don't see how this could possible race under the premise that once an irq bit is masked in PM_IMR and reset in PM_IIR it won't show up again until we unmask it in PM_IMR. Still, we have reports of this being seen in the wild. Now Bspec has this little bit of lovely language in the PMIIR register: Public SNB Docs, Vol3Part2, 2.5.14 "PMIIR": "For each bit, the IIR can store a second pending interrupt if two or more of the same interrupt conditions occur before the first condition is cleared. Upon clearing the interrupt, the IIR bit will momentarily go low, then return high to indicate there is another interrupt pending." Now if we presume that PMIMR only prevent new interrupts from being queued, we could easily end up masking an interrupt and clearing it, but the 2nd pending interrupt setting the bit in PMIIR right away again. Which leads, the next time the irq handler runs, to hitting the WARN. Also, no bad side effects of this have ever been reported. And we've tracked down our issues with the gpu turbo getting stuck to bogus interrupt generation limits in th RPLIMIT register. So let's just rip out this WARN as bogus and call it a day. The only shallow thing here is that this 2-deep irq queue in the hw makes you wonder how racy the windows irq handler is ... Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=42907 Cc: stable@vger.kernel.org Acked-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b1fe0ed..ed3224c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -412,7 +412,6 @@ static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, */ spin_lock_irqsave(&dev_priv->rps_lock, flags); - WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); dev_priv->pm_iir |= pm_iir; I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir); POSTING_READ(GEN6_PMIMR); -- cgit v1.1 From 6db65cbb941f9d433659bdad02b307f6d94465df Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Jun 2012 15:30:41 +0200 Subject: drm/i915: Fix eDP blank screen after S3 resume on HP desktops This patch fixes the problem on some HP desktop machines with eDP which give blank screens after S3 resume. It turned out that BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2. Otherwise it doesn't take effect on these SNB machines. Tested with 3.5-rc3 kernel. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=49233 Cc: Signed-off-by: Takashi Iwai Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_suspend.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 0ede02a..a748e5c 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -740,8 +740,11 @@ static void i915_restore_display(struct drm_device *dev) if (HAS_PCH_SPLIT(dev)) { I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); - I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); + /* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2; + * otherwise we get blank eDP screen after S3 on some machines + */ I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); + I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); -- cgit v1.1 From b9f90eb2740203ff2592efe640409ad48335d1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Thu, 21 Jun 2012 02:45:58 +0000 Subject: net: qmi_wwan: fix Gobi device probing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ignoring interfaces with additional descriptors is not a reliable method for locating the correct interface on Gobi devices. There is at least one device where this method fails: https://bbs.archlinux.org/viewtopic.php?id=143506 The result is that the AT command port (interface #2) is hidden from qcserial, preventing traditional serial modem usage: [ 15.562552] qmi_wwan 4-1.6:1.0: cdc-wdm0: USB WDM device [ 15.562691] qmi_wwan 4-1.6:1.0: wwan0: register 'qmi_wwan' at usb-0000:00:1d.0-1.6, Qualcomm Gobi wwan/QMI device, 1e:df:3c:3a:4e:3b [ 15.563383] qmi_wwan: probe of 4-1.6:1.1 failed with error -22 [ 15.564189] qmi_wwan 4-1.6:1.2: cdc-wdm1: USB WDM device [ 15.564302] qmi_wwan 4-1.6:1.2: wwan1: register 'qmi_wwan' at usb-0000:00:1d.0-1.6, Qualcomm Gobi wwan/QMI device, 1e:df:3c:3a:4e:3b [ 15.564328] qmi_wwan: probe of 4-1.6:1.3 failed with error -22 [ 15.569376] qcserial 4-1.6:1.1: Qualcomm USB modem converter detected [ 15.569440] usb 4-1.6: Qualcomm USB modem converter now attached to ttyUSB0 [ 15.570372] qcserial 4-1.6:1.3: Qualcomm USB modem converter detected [ 15.570430] usb 4-1.6: Qualcomm USB modem converter now attached to ttyUSB1 Use static interface numbers taken from the interface map in qcserial for all Gobi devices instead: Gobi 1K USB layout: 0: serial port (doesn't respond) 1: serial port (doesn't respond) 2: AT-capable modem port 3: QMI/net Gobi 2K+ USB layout: 0: QMI/net 1: DM/DIAG (use libqcdm from ModemManager for communication) 2: AT-capable modem port 3: NMEA This should be more reliable over all, and will also prevent the noisy "probe failed" messages. The whitelisting logic is expected to be replaced by direct interface number matching in 3.6. Reported-by: Heinrich Siebmanns (Harvey) Cc: # v3.4: 0000188 USB: qmi_wwan: Make forced int 4 whitelist generic Cc: # v3.4: f7142e6 USB: qmi_wwan: Add ZTE (Vodafone) K3520-Z Cc: # v3.4 Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 83 ++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3b20678..3767a12 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -257,29 +257,6 @@ err: return rv; } -/* Gobi devices uses identical class/protocol codes for all interfaces regardless - * of function. Some of these are CDC ACM like and have the exact same endpoints - * we are looking for. This leaves two possible strategies for identifying the - * correct interface: - * a) hardcoding interface number, or - * b) use the fact that the wwan interface is the only one lacking additional - * (CDC functional) descriptors - * - * Let's see if we can get away with the generic b) solution. - */ -static int qmi_wwan_bind_gobi(struct usbnet *dev, struct usb_interface *intf) -{ - int rv = -EINVAL; - - /* ignore any interface with additional descriptors */ - if (intf->cur_altsetting->extralen) - goto err; - - rv = qmi_wwan_bind_shared(dev, intf); -err: - return rv; -} - static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf) { struct usb_driver *subdriver = (void *)dev->data[0]; @@ -347,15 +324,15 @@ static const struct driver_info qmi_wwan_shared = { .manage_power = qmi_wwan_manage_power, }; -static const struct driver_info qmi_wwan_gobi = { - .description = "Qualcomm Gobi wwan/QMI device", +static const struct driver_info qmi_wwan_force_int0 = { + .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_gobi, + .bind = qmi_wwan_bind_shared, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, + .data = BIT(0), /* interface whitelist bitmap */ }; -/* ZTE suck at making USB descriptors */ static const struct driver_info qmi_wwan_force_int1 = { .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, @@ -365,6 +342,15 @@ static const struct driver_info qmi_wwan_force_int1 = { .data = BIT(1), /* interface whitelist bitmap */ }; +static const struct driver_info qmi_wwan_force_int3 = { + .description = "Qualcomm WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind_shared, + .manage_power = qmi_wwan_manage_power, + .data = BIT(3), /* interface whitelist bitmap */ +}; + static const struct driver_info qmi_wwan_force_int4 = { .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, @@ -390,16 +376,23 @@ static const struct driver_info qmi_wwan_force_int4 = { static const struct driver_info qmi_wwan_sierra = { .description = "Sierra Wireless wwan/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_gobi, + .bind = qmi_wwan_bind_shared, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ }; #define HUAWEI_VENDOR_ID 0x12D1 + +/* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ +#define QMI_GOBI1K_DEVICE(vend, prod) \ + USB_DEVICE(vend, prod), \ + .driver_info = (unsigned long)&qmi_wwan_force_int3 + +/* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */ #define QMI_GOBI_DEVICE(vend, prod) \ USB_DEVICE(vend, prod), \ - .driver_info = (unsigned long)&qmi_wwan_gobi + .driver_info = (unsigned long)&qmi_wwan_force_int0 static const struct usb_device_id products[] = { { /* Huawei E392, E398 and possibly others sharing both device id and more... */ @@ -510,20 +503,24 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_sierra, }, - {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ - {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ - {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ - {QMI_GOBI_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ - {QMI_GOBI_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ - {QMI_GOBI_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ - {QMI_GOBI_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ + + /* Gobi 1000 devices */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ + {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ + {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ + {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ + + /* Gobi 2000 and 3000 devices */ {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ -- cgit v1.1 From fb13c47b8e5ce707268bd38cfd082da377eac4b7 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 19 Jun 2012 21:15:51 +0000 Subject: usbnet: clear OPEN flag in failure path Without clearing OPEN flag in failure path, runtime or system resume may submit interrupt/rx URB and start tx queue mistakenly on a interface in DOWN state. Signed-off-by: Ming Lei Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index d4f7256..815493c 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -796,11 +796,13 @@ int usbnet_open (struct net_device *net) if (info->manage_power) { retval = info->manage_power(dev, 1); if (retval < 0) - goto done; + goto done_manage_power_error; usb_autopm_put_interface(dev->intf); } return retval; +done_manage_power_error: + clear_bit(EVENT_DEV_OPEN, &dev->flags); done: usb_autopm_put_interface(dev->intf); done_nopm: -- cgit v1.1 From 5eeb3132eb4c5e9ca92e5247fe4575fe9f8c3efe Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 19 Jun 2012 21:15:52 +0000 Subject: usbnet: decrease suspend count if returning -EBUSY for runtime suspend This patch decreases dev->suspend_count in the -EBUSY failure path of usbnet_suspend. Without the change, the later runtime suspend will do nothing except for increasing dev->suspend_count. Signed-off-by: Ming Lei Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 815493c..1e46f69 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1515,6 +1515,7 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) spin_lock_irq(&dev->txq.lock); /* don't autosuspend while transmitting */ if (dev->txq.qlen && PMSG_IS_AUTO(message)) { + dev->suspend_count--; spin_unlock_irq(&dev->txq.lock); return -EBUSY; } else { -- cgit v1.1 From 65841fd5132c3941cdf5df09e70df3ed28323212 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 19 Jun 2012 21:15:53 +0000 Subject: usbnet: handle remote wakeup asap If usbnet is resumed by remote wakeup, generally there are some packets comming to be handled, so allocate and submit rx URBs in usbnet_resume to avoid delays introduced by tasklet. Otherwise, usbnet may have been runtime suspended before the usbnet_bh is executed to schedule Rx URBs. Without the patch, usbnet can't recieve any packets from peer in runtime suspend state if runtime PM is enabled and autosuspend_delay is set as zero. Signed-off-by: Ming Lei Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 1e46f69..aba769d 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1204,6 +1204,21 @@ deferred: } EXPORT_SYMBOL_GPL(usbnet_start_xmit); +static void rx_alloc_submit(struct usbnet *dev, gfp_t flags) +{ + struct urb *urb; + int i; + + /* don't refill the queue all at once */ + for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { + urb = usb_alloc_urb(0, flags); + if (urb != NULL) { + if (rx_submit(dev, urb, flags) == -ENOLINK) + return; + } + } +} + /*-------------------------------------------------------------------------*/ // tasklet (work deferred from completions, in_irq) or timer @@ -1243,26 +1258,14 @@ static void usbnet_bh (unsigned long param) !timer_pending (&dev->delay) && !test_bit (EVENT_RX_HALT, &dev->flags)) { int temp = dev->rxq.qlen; - int qlen = RX_QLEN (dev); - - if (temp < qlen) { - struct urb *urb; - int i; - - // don't refill the queue all at once - for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) { - urb = usb_alloc_urb (0, GFP_ATOMIC); - if (urb != NULL) { - if (rx_submit (dev, urb, GFP_ATOMIC) == - -ENOLINK) - return; - } - } + + if (temp < RX_QLEN(dev)) { + rx_alloc_submit(dev, GFP_ATOMIC); if (temp != dev->rxq.qlen) netif_dbg(dev, link, dev->net, "rxqlen %d --> %d\n", temp, dev->rxq.qlen); - if (dev->rxq.qlen < qlen) + if (dev->rxq.qlen < RX_QLEN(dev)) tasklet_schedule (&dev->bh); } if (dev->txq.qlen < TX_QLEN (dev)) @@ -1572,6 +1575,13 @@ int usbnet_resume (struct usb_interface *intf) spin_unlock_irq(&dev->txq.lock); if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { + /* handle remote wakeup ASAP */ + if (!dev->wait && + netif_device_present(dev->net) && + !timer_pending(&dev->delay) && + !test_bit(EVENT_RX_HALT, &dev->flags)) + rx_alloc_submit(dev, GFP_KERNEL); + if (!(dev->txq.qlen >= TX_QLEN(dev))) netif_tx_wake_all_queues(dev->net); tasklet_schedule (&dev->bh); -- cgit v1.1 From eb2dc35d99028b698cdedba4f5522bc43e576bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fran=C3=A7ois=20romieu?= Date: Wed, 20 Jun 2012 12:09:18 +0000 Subject: r8169: RxConfig hack for the 8168evl. The 8168evl (RTL_GIGA_MAC_VER_34) based Gigabyte GA-990FXA motherboards are very prone to NETDEV watchdog problems without this change. See https://bugzilla.kernel.org/show_bug.cgi?id=42899 for instance. I don't know why it *works*. It's depressingly effective though. For the record: - the problem may go along IOMMU (AMD-Vi) errors but it really looks like a red herring. - the patch sets the RX_MULTI_EN bit. If the 8168c doc is any guide, the chipset now fetches several Rx descriptors at a time. - long ago the driver ignored the RX_MULTI_EN bit. e542a2269f232d61270ceddd42b73a4348dee2bb changed the RxConfig settings. Whatever the problem it's now labeled a regression. - Realtek's own driver can identify two different 8168evl devices (CFG_METHOD_16 and CFG_METHOD_17) where the r8169 driver only sees one. It sucks. Signed-off-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 7260aa7..d7a04e0 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3894,6 +3894,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_22: case RTL_GIGA_MAC_VER_23: case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_34: RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); break; default: -- cgit v1.1 From a18e08bdcf845efb7344cea146e683df746bbfb4 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 20 Jun 2012 15:26:34 +0000 Subject: net: sh_eth: fix the condition to fix the cur_tx/dirty_rx The following commit couldn't work if the RMCR is not set to 1. "net: sh_eth: fix the rxdesc pointer when rx descriptor empty happens" commit id 79fba9f51755c704c0a7d7b7f0df10874dc0a744 If RMCR is not set, the controller will clear the EDRRR after it received a frame. In this case, the driver doesn't need to fix the value of cur_rx/dirty_rx. The driver only needs it when the controll detects receive descriptors are empty. Signed-off-by: Yoshihiro Shimoda Tested-by: Guennadi Liakhovetski Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 667169b..79bf09b 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1011,7 +1011,7 @@ static int sh_eth_txfree(struct net_device *ndev) } /* Packet receive function */ -static int sh_eth_rx(struct net_device *ndev) +static int sh_eth_rx(struct net_device *ndev, u32 intr_status) { struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_rxdesc *rxdesc; @@ -1102,9 +1102,11 @@ static int sh_eth_rx(struct net_device *ndev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) { - /* fix the values for the next receiving */ - mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) - - sh_eth_read(ndev, RDLAR)) >> 4; + /* fix the values for the next receiving if RDE is set */ + if (intr_status & EESR_RDE) + mdp->cur_rx = mdp->dirty_rx = + (sh_eth_read(ndev, RDFAR) - + sh_eth_read(ndev, RDLAR)) >> 4; sh_eth_write(ndev, EDRRR_R, EDRRR); } @@ -1273,7 +1275,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) EESR_RTSF | /* short frame recv */ EESR_PRE | /* PHY-LSI recv error */ EESR_CERF)){ /* recv frame CRC error */ - sh_eth_rx(ndev); + sh_eth_rx(ndev, intr_status); } /* Tx Check */ -- cgit v1.1 From 6a0bdffa0073857870a4ed1b4489762146359eb4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 20 Jun 2012 16:04:19 -0400 Subject: SCSI & usb-storage: add try_rc_10_first flag Several bug reports have been received recently for USB mass-storage devices that don't handle READ CAPACITY(16) commands properly. They report bogus sizes, in some cases becoming unusable as a result. The bugs were triggered by commit 09b6b51b0b6c1b9bb61815baf205e4d74c89ff04 (SCSI & usb-storage: add flags for VPD pages and REPORT LUNS), which caused usb-storage to stop overriding the SCSI level reported by devices. By default, the sd driver will try READ CAPACITY(16) first for any device whose level is above SCSI_SPC_2. It seems likely that any device large enough to require the use of READ CAPACITY(16) (i.e., 2 TB or more) would be able to handle READ CAPACITY(10) commands properly. Indeed, I don't know of any devices that don't handle READ CAPACITY(10) properly. Therefore this patch (as1559) adds a new flag telling the sd driver to try READ CAPACITY(10) before READ CAPACITY(16), and sets this flag for every USB mass-storage device. If a device really is larger than 2 TB, sd will fall back to READ CAPACITY(16) just as it used to. This fixes Bugzilla #43391. Signed-off-by: Alan Stern Acked-by: Hans de Goede CC: "James E.J. Bottomley" CC: Matthew Dharm Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sd.c | 2 ++ drivers/usb/storage/scsiglue.c | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 6f0a4c6..6f72b80 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1899,6 +1899,8 @@ static int sd_try_rc16_first(struct scsi_device *sdp) { if (sdp->host->max_cmd_len < 16) return 0; + if (sdp->try_rc_10_first) + return 0; if (sdp->scsi_level > SCSI_SPC_2) return 1; if (scsi_device_protection(sdp)) diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index a324a5d..11418da 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -202,6 +202,12 @@ static int slave_configure(struct scsi_device *sdev) if (us->fflags & US_FL_NO_READ_CAPACITY_16) sdev->no_read_capacity_16 = 1; + /* + * Many devices do not respond properly to READ_CAPACITY_16. + * Tell the SCSI layer to try READ_CAPACITY_10 first. + */ + sdev->try_rc_10_first = 1; + /* assume SPC3 or latter devices support sense size > 18 */ if (sdev->scsi_level > SCSI_SPC_2) us->fflags |= US_FL_SANE_SENSE; -- cgit v1.1 From 0070513b5e005161a7a7fd9a3f48f982b41eb094 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 20 Jun 2012 16:04:30 -0400 Subject: usb-storage: revert commit afff07e61a52 (Add 090c:1000 to unusal-devs) This patch (as1560) reverts commit afff07e61a5243e14ee3f0a272a0380cd744a8a3 (usb-storage: Add 090c:1000 to unusal-devs). It is no longer needed, because usb-storage now tells the sd driver to try READ CAPACITY(10) before READ CAPACITY(16) for every USB mass-storage device. Signed-off-by: Alan Stern Acked-by: Hans de Goede CC: Matthew Dharm Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index caf22bf..1719886 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1107,13 +1107,6 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, USB_SC_RBC, USB_PR_BULK, NULL, 0 ), -/* Feiya QDI U2 DISK, reported by Hans de Goede */ -UNUSUAL_DEV( 0x090c, 0x1000, 0x0000, 0xffff, - "Feiya", - "QDI U2 DISK", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_NO_READ_CAPACITY_16 ), - /* aeb */ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, "Feiya", -- cgit v1.1 From a68de074613abd028b2ce63366d18db9c29e15d2 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Fri, 22 Jun 2012 13:36:20 +0100 Subject: regulator: palmas: fix regmap offsets for enable/disable I forgot to apply the offsets for the regmap helper functions for enable/disable on SMPS10 and the LDO regulators. This means regulators will not enable/disable correctly. Signed-off-by: Graeme Gregory Tested-by: Sebastien Guiriec Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 9b7ca90..795f75a 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -673,7 +673,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].ops = &palmas_ops_smps10; pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL; pmic->desc[id].vsel_mask = SMPS10_VSEL; - pmic->desc[id].enable_reg = PALMAS_SMPS10_STATUS; + pmic->desc[id].enable_reg = + PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + PALMAS_SMPS10_STATUS); pmic->desc[id].enable_mask = SMPS10_BOOST_EN; } @@ -739,7 +741,8 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].type = REGULATOR_VOLTAGE; pmic->desc[id].owner = THIS_MODULE; - pmic->desc[id].enable_reg = palmas_regs_info[id].ctrl_addr; + pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + palmas_regs_info[id].ctrl_addr); pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; if (pdata && pdata->reg_data) -- cgit v1.1 From 02b7d83436ae4b1d86a5df03e72c1c69af7e239d Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Sat, 23 Jun 2012 15:54:34 -0700 Subject: Fix typo in printed messages Coult -> Could Signed-off-by: Linus Torvalds --- drivers/net/wireless/b43/main.c | 2 +- drivers/net/wireless/b43legacy/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index acd03a4..1b988f2 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3767,7 +3767,7 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan) if (prev_status >= B43_STAT_STARTED) { err = b43_wireless_core_start(up_dev); if (err) { - b43err(wl, "Fatal: Coult not start device for " + b43err(wl, "Fatal: Could not start device for " "selected %s-GHz band\n", band_to_string(chan->band)); b43_wireless_core_exit(up_dev); diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index cd9c9bc..eae691e 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2633,7 +2633,7 @@ static int b43legacy_switch_phymode(struct b43legacy_wl *wl, if (prev_status >= B43legacy_STAT_STARTED) { err = b43legacy_wireless_core_start(up_dev); if (err) { - b43legacyerr(wl, "Fatal: Coult not start device for " + b43legacyerr(wl, "Fatal: Could not start device for " "newly selected %s-PHY mode\n", phymode_to_string(new_mode)); b43legacy_wireless_core_exit(up_dev); -- cgit v1.1 From 1f758b23177d588a71b96ad02990e715949bb82f Mon Sep 17 00:00:00 2001 From: Mandeep Singh Baines Date: Sun, 24 Jun 2012 23:31:09 +0200 Subject: PM / Sleep: Prevent waiting forever on asynchronous suspend after abort __device_suspend() must always send a completion. Otherwise, parent devices will wait forever. Commit 1e2ef05b, "PM: Limit race conditions between runtime PM and system sleep (v2)", introduced a regression by short-circuiting the complete_all() for certain error cases. This patch fixes the bug by always signalling a completion. Addresses http://crosbug.com/31972 Tested by injecting an abort. Signed-off-by: Mandeep Singh Baines Cc: stable@vger.kernel.org Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e0fb5b0..9cb845e 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1031,7 +1031,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) dpm_wait_for_children(dev, async); if (async_error) - return 0; + goto Complete; pm_runtime_get_noresume(dev); if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) @@ -1040,7 +1040,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) if (pm_wakeup_pending()) { pm_runtime_put_sync(dev); async_error = -EBUSY; - return 0; + goto Complete; } device_lock(dev); @@ -1097,6 +1097,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) } device_unlock(dev); + + Complete: complete_all(&dev->power.completion); if (error) { -- cgit v1.1 From aa8521ec2889d5d1f2f0ed00c3295b8229135f98 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Wed, 20 Jun 2012 21:18:48 +0200 Subject: hwmon: (applesmc) correct email address for Jesper Juhl I've not had a gmail address for years. This commit updates the address to my actual working one. Signed-off-by: Jesper Juhl Signed-off-by: Guenter Roeck --- drivers/hwmon/applesmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 70d62f5..2cde9ec 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -8,7 +8,7 @@ * * Based on hdaps.c driver: * Copyright (C) 2005 Robert Love - * Copyright (C) 2005 Jesper Juhl + * Copyright (C) 2005 Jesper Juhl * * Fan control based on smcFanControl: * Copyright (C) 2006 Hendrik Holtmann -- cgit v1.1 From d42f0349f3fed647c61c2d432e974bbdafcfb3fb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 25 Jun 2012 07:32:14 +0100 Subject: drm/udl: Make sure to get correct endian keys from vendor descriptor This is a port of commit b49f184b640dcfab7ede394cf2a1ff4fe3d154f5 Author: Ben Collins from udlfb to udl kms driver. The driver was not using le16_to_cpu when reading keys from the vendor descriptor, causing incorrect parsing. Mainly, sku_pixel_limit was not being parsed on big-endian systems. This would result in a blank screen on big-endian CPUs where the DL chips's max mode was smaller than the monitor's native mode. Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/udl_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index a8d5f09..4c2d836 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -61,7 +61,7 @@ static int udl_parse_vendor_descriptor(struct drm_device *dev, u8 length; u16 key; - key = *((u16 *) desc); + key = le16_to_cpu(*((u16 *) desc)); desc += sizeof(u16); length = *desc; desc++; -- cgit v1.1 From e75561b3d2a4eb15080ed73f59f7dc2965c01423 Mon Sep 17 00:00:00 2001 From: Yufeng Shen Date: Fri, 22 Jun 2012 12:31:53 -0400 Subject: HID: magicmouse: Correct report range of major / minor axes In patch "HID: magicmouse: Adjust major / minor axes to scale", touch_major and touch_minor axes are scaled by a factor of four when reported but the max touch_major/minor is not scaled accordingly. This patch scales the max touch_major/minor to be consistent with the reported value. Signed-off-by: Yufeng Shen Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 7cf3ffe..40ac665 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -426,8 +426,10 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h __set_bit(EV_ABS, input->evbit); input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, + 4, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2, + 4, 0); input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0); /* Note: Touch Y position from the device is inverted relative -- cgit v1.1 From bb9a80e5719abae235c7e9c7391a3a17b64a217b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 22 Jun 2012 12:07:25 -0700 Subject: hwmon: Update my e-mail address My old e-mail address won't be valid for much longer. Time to update it. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/jc42.c | 2 +- drivers/hwmon/lineage-pem.c | 2 +- drivers/hwmon/ltc4261.c | 2 +- drivers/hwmon/max16065.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index a9bfd67..e72ba5d 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -590,6 +590,6 @@ abort: module_i2c_driver(jc42_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("JC42 driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c index d264937..bd75d24 100644 --- a/drivers/hwmon/lineage-pem.c +++ b/drivers/hwmon/lineage-pem.c @@ -567,6 +567,6 @@ static struct i2c_driver pem_driver = { module_i2c_driver(pem_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("Lineage CPL PEM hardware monitoring driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 069b7d34..77476a5 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c @@ -292,6 +292,6 @@ static struct i2c_driver ltc4261_driver = { module_i2c_driver(ltc4261_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("LTC4261 driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c index 822261b..019427d 100644 --- a/drivers/hwmon/max16065.c +++ b/drivers/hwmon/max16065.c @@ -692,6 +692,6 @@ static struct i2c_driver max16065_driver = { module_i2c_driver(max16065_driver); -MODULE_AUTHOR("Guenter Roeck "); +MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("MAX16065 driver"); MODULE_LICENSE("GPL"); -- cgit v1.1 From 1f41a6a9947615dca37d80b044ab81616e956a67 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 25 Jun 2012 16:55:41 +0200 Subject: HID: Fix the generic Kconfig options The generic HID driver is obviously not a special driver, so move it outside of the special drivers menu. Explain the usage and make the default follow the HID setting. This should simplify migration from older kernels. While at it, remove the redundant HID_SUPPORT option and modify the HID and USB_HID entries to better explain the bus structure. Reported-by: Jan Beulich Signed-off-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 43 ++++++++++++++++++++----------------------- drivers/hid/usbhid/Kconfig | 8 ++++---- 2 files changed, 24 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index e9c68fe..3089cd6 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1,20 +1,11 @@ # # HID driver configuration # -menuconfig HID_SUPPORT - bool "HID Devices" - depends on INPUT - default y - ---help--- - Say Y here to get to see options for various computer-human interface - device drivers. This option alone does not add any kernel code. - - If you say N, all options in this submenu will be skipped and disabled. - -if HID_SUPPORT +menu "HID support" + depends on INPUT config HID - tristate "Generic HID support" + tristate "HID bus support" depends on INPUT default y ---help--- @@ -23,14 +14,17 @@ config HID most commonly used to refer to the USB-HID specification, but other devices (such as, but not strictly limited to, Bluetooth) are designed using HID specification (this involves certain keyboards, - mice, tablets, etc). This option compiles into kernel the generic - HID layer code (parser, usages, etc.), which can then be used by - transport-specific HID implementation (like USB or Bluetooth). + mice, tablets, etc). This option adds the HID bus to the kernel, + together with generic HID layer code. The HID devices are added and + removed from the HID bus by the transport-layer drivers, such as + usbhid (USB_HID) and hidp (BT_HIDP). For docs and specs, see http://www.usb.org/developers/hidpage/ If unsure, say Y. +if HID + config HID_BATTERY_STRENGTH bool "Battery level reporting for HID devices" depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY @@ -59,23 +53,22 @@ config HIDRAW If unsure, say Y. -source "drivers/hid/usbhid/Kconfig" - -menu "Special HID drivers" - depends on HID - config HID_GENERIC tristate "Generic HID driver" depends on HID - default y + default HID ---help--- - Support for generic HID devices. + Support for generic devices on the HID bus. This includes most + keyboards and mice, joysticks, tablets and digitizers. To compile this driver as a module, choose M here: the module will be called hid-generic. If unsure, say Y. +menu "Special HID drivers" + depends on HID + config HID_A4TECH tristate "A4 tech mice" if EXPERT depends on USB_HID @@ -662,4 +655,8 @@ config HID_ZYDACRON endmenu -endif # HID_SUPPORT +endif # HID + +source "drivers/hid/usbhid/Kconfig" + +endmenu diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig index 0f20fd1..0108c59 100644 --- a/drivers/hid/usbhid/Kconfig +++ b/drivers/hid/usbhid/Kconfig @@ -1,13 +1,13 @@ -comment "USB Input Devices" +menu "USB HID support" depends on USB config USB_HID - tristate "USB Human Interface Device (full HID) support" + tristate "USB HID transport layer" default y depends on USB && INPUT select HID ---help--- - Say Y here if you want full HID support to connect USB keyboards, + Say Y here if you want to connect USB keyboards, mice, joysticks, graphic tablets, or any other HID based devices to your computer via USB, as well as Uninterruptible Power Supply (UPS) and monitor control devices. @@ -81,4 +81,4 @@ config USB_MOUSE endmenu - +endmenu -- cgit v1.1 From 4ad33411308596f2f918603509729922a1ec4411 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 22 Jun 2012 10:58:06 -0700 Subject: x86, cpufeature: Rename X86_FEATURE_DTS to X86_FEATURE_DTHERM It makes sense to label "Digital Thermal Sensor" as "DTS", but unfortunately the string "dts" was already used for "Debug Store", and /proc/cpuinfo is a user space ABI. Therefore, rename this to "dtherm". This conflict went into mainline via the hwmon tree without any x86 maintainer ack, and without any kind of hint in the subject. a4659053 x86/hwmon: fix initialization of coretemp Reported-by: Jean Delvare Link: http://lkml.kernel.org/r/4FE34BCB.5050305@linux.intel.com Cc: Jan Beulich Cc: v2.6.36..v3.4 Signed-off-by: H. Peter Anvin --- drivers/hwmon/coretemp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index b9d5123..0f52799 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -664,7 +664,7 @@ static void __cpuinit get_core_online(unsigned int cpu) * sensors. We check this bit only, all the early CPUs * without thermal sensors will be filtered out. */ - if (!cpu_has(c, X86_FEATURE_DTS)) + if (!cpu_has(c, X86_FEATURE_DTHERM)) return; if (!pdev) { @@ -765,7 +765,7 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { }; static const struct x86_cpu_id coretemp_ids[] = { - { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS }, + { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM }, {} }; MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); -- cgit v1.1 From 3935600a7f341c00b0def2ed8870669ab2c05493 Mon Sep 17 00:00:00 2001 From: Per Ellefsen Date: Sun, 24 Jun 2012 11:01:37 +0000 Subject: caif-hsi: Bugfix - Piggyback'ed embedded CAIF frame lost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When receiving a piggyback'ed descriptor containing an embedded frame, but no payload, the embedded frame was lost. Signed-off-by: Per Ellefsen Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 1520814..1f52ff3 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -693,8 +693,6 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) */ memcpy(rx_buf, (u8 *)piggy_desc, CFHSI_DESC_SHORT_SZ); - /* Mark no embedded frame here */ - piggy_desc->offset = 0; if (desc_pld_len == -EPROTO) goto out_of_sync; } @@ -737,6 +735,8 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) /* Extract any payload in piggyback descriptor. */ if (cfhsi_rx_desc(piggy_desc, cfhsi) < 0) goto out_of_sync; + /* Mark no embedded frame after extracting it */ + piggy_desc->offset = 0; } } -- cgit v1.1 From 1fdc7630b2cba4a5aeb5fc3834c7189716fdbcb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Sun, 24 Jun 2012 11:01:38 +0000 Subject: caif-hsi: Add missing return in error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a missing return, causing access to freed memory. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 1f52ff3..4a27adb 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -1178,6 +1178,7 @@ int cfhsi_probe(struct platform_device *pdev) dev_err(&ndev->dev, "%s: Registration error: %d.\n", __func__, res); free_netdev(ndev); + return -ENODEV; } /* Add CAIF HSI device to list. */ spin_lock(&cfhsi_list_lock); -- cgit v1.1 From 6de0298ec9c1edaf330b71b57346241ece8f3346 Mon Sep 17 00:00:00 2001 From: Davide Gerhard Date: Mon, 25 Jun 2012 09:04:47 +0200 Subject: ipheth: add support for iPad This adds support for the iPad to the ipheth driver. (product id = 0x129a) Signed-off-by: Davide Gerhard Signed-off-by: David S. Miller --- drivers/net/usb/ipheth.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 964031e..a28a983d 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -59,6 +59,7 @@ #define USB_PRODUCT_IPHONE_3G 0x1292 #define USB_PRODUCT_IPHONE_3GS 0x1294 #define USB_PRODUCT_IPHONE_4 0x1297 +#define USB_PRODUCT_IPAD 0x129a #define USB_PRODUCT_IPHONE_4_VZW 0x129c #define USB_PRODUCT_IPHONE_4S 0x12a0 @@ -101,6 +102,10 @@ static struct usb_device_id ipheth_table[] = { IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, { USB_DEVICE_AND_INTERFACE_INFO( + USB_VENDOR_APPLE, USB_PRODUCT_IPAD, + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, + IPHETH_USBINTF_PROTO) }, + { USB_DEVICE_AND_INTERFACE_INFO( USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, -- cgit v1.1 From 5c8e9046662889265c0ff390c144188721cb0844 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Mon, 25 Jun 2012 00:24:11 +0000 Subject: net/mlx4_en: Set correct port parameters during device initialization Set valid port parameters: MTU and flow control configuration when configuring the port during HW device initialization, prior to the net device open() being called. Using invalid parameters (such as all zeros) could lead to bad firmware behavior. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 926d8aa..a80280e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1204,9 +1204,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, en_warn(priv, "Using %d RX rings\n", prof->rx_ring_num); /* Configure port */ + mlx4_en_calc_rx_buf(dev); err = mlx4_SET_PORT_general(mdev->dev, priv->port, - MLX4_EN_MIN_MTU, - 0, 0, 0, 0); + priv->rx_skb_size + ETH_FCS_LEN, + prof->tx_pause, prof->tx_ppp, + prof->rx_pause, prof->rx_ppp); if (err) { en_err(priv, "Failed setting port general configurations " "for port %d, with error %d\n", priv->port, err); -- cgit v1.1 From 9858d2d1acf82758f779e0756d92a011f1d170b3 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Mon, 25 Jun 2012 00:24:12 +0000 Subject: net/mlx4: Use single completion vector after NOP failure Fix a crash at the error flow of NOP command which caused the driver to try and use a completion vector which wasn't allocated. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index ee6f4fe..a0313de 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1975,6 +1975,8 @@ slave_start: if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X) && !mlx4_is_mfunc(dev)) { dev->flags &= ~MLX4_FLAG_MSI_X; + dev->caps.num_comp_vectors = 1; + dev->caps.comp_pool = 0; pci_disable_msix(pdev); err = mlx4_setup_hca(dev); } -- cgit v1.1 From 044ca2a5f2f781c7e4b49c7c0a256913648297ea Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Mon, 25 Jun 2012 00:24:13 +0000 Subject: net/mlx4_en: Release QP range in free_resources Add a missing resource release in ring cleanup. Not doing this leaves a range of QPs that are being reserved, and no one can use them. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 12 ++++++++---- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index a80280e..073b85b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -929,15 +929,20 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv) if (priv->rx_cq[i].buf) mlx4_en_destroy_cq(priv, &priv->rx_cq[i]); } + + if (priv->base_tx_qpn) { + mlx4_qp_release_range(priv->mdev->dev, priv->base_tx_qpn, priv->tx_ring_num); + priv->base_tx_qpn = 0; + } } int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) { struct mlx4_en_port_profile *prof = priv->prof; int i; - int base_tx_qpn, err; + int err; - err = mlx4_qp_reserve_range(priv->mdev->dev, priv->tx_ring_num, 256, &base_tx_qpn); + err = mlx4_qp_reserve_range(priv->mdev->dev, priv->tx_ring_num, 256, &priv->base_tx_qpn); if (err) { en_err(priv, "failed reserving range for TX rings\n"); return err; @@ -949,7 +954,7 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) prof->tx_ring_size, i, TX)) goto err; - if (mlx4_en_create_tx_ring(priv, &priv->tx_ring[i], base_tx_qpn + i, + if (mlx4_en_create_tx_ring(priv, &priv->tx_ring[i], priv->base_tx_qpn + i, prof->tx_ring_size, TXBB_SIZE)) goto err; } @@ -969,7 +974,6 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) err: en_err(priv, "Failed to allocate NIC resources\n"); - mlx4_qp_release_range(priv->mdev->dev, base_tx_qpn, priv->tx_ring_num); return -ENOMEM; } diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 6ae3509..225c20d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -495,6 +495,7 @@ struct mlx4_en_priv { int vids[128]; bool wol; struct device *ddev; + int base_tx_qpn; #ifdef CONFIG_MLX4_EN_DCB struct ieee_ets ets; -- cgit v1.1 From 3a35fc3a13333e7c137de82d8bf12bbc18639633 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 11 May 2012 10:41:18 +0200 Subject: clk: SPEAr600: Fix ethernet clock name for DT based probing Signed-off-by: Stefan Roese Cc: Viresh Kumar Cc: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear6xx_clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index 554d64b..61026ae 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -298,7 +298,7 @@ void __init spear6xx_clk_init(void) clk = clk_register_gate(NULL, "gmac_clk", "ahb_clk", 0, PERIP1_CLK_ENB, GMAC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "gmac"); + clk_register_clkdev(clk, NULL, "e0800000.ethernet"); clk = clk_register_gate(NULL, "i2c_clk", "ahb_clk", 0, PERIP1_CLK_ENB, I2C_CLK_ENB, 0, &_lock); -- cgit v1.1 From 7975059db572eb47f0fb272a62afeae272a4b209 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 6 Jun 2012 14:41:31 +0530 Subject: clk: Allow late cache allocation for clk->parents Parent clocks for muxes are cached in clk->parents to avoid frequent lookups, however the cache allocation happens only during clock registeration and later clk_set_parent() assumes a cache space available and allocated. This is not entirely true for platforms which do early clock registerations wherein the cache allocation using kzalloc could fail during clock registeration. Allow cache allocation to happen later as part of clk_set_parent() to help such cases and avoid crashes assuming a cache being available. While here also replace existing kmalloc() with kzalloc() in the file. Signed-off-by: Rajendra Nayak Signed-off-by: Mike Turquette Cc: stable@kernel.org --- drivers/clk/clk.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 687b00d..df89cbf 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -999,7 +999,7 @@ static struct clk *__clk_init_parent(struct clk *clk) if (!clk->parents) clk->parents = - kmalloc((sizeof(struct clk*) * clk->num_parents), + kzalloc((sizeof(struct clk*) * clk->num_parents), GFP_KERNEL); if (!clk->parents) @@ -1065,9 +1065,13 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) old_parent = clk->parent; /* find index of new parent clock using cached parent ptrs */ - for (i = 0; i < clk->num_parents; i++) - if (clk->parents[i] == parent) - break; + if (clk->parents) + for (i = 0; i < clk->num_parents; i++) + if (clk->parents[i] == parent) + break; + else + clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), + GFP_KERNEL); /* * find index of new parent clock using string name comparison @@ -1076,7 +1080,8 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) if (i == clk->num_parents) for (i = 0; i < clk->num_parents; i++) if (!strcmp(clk->parent_names[i], parent->name)) { - clk->parents[i] = __clk_lookup(parent->name); + if (clk->parents) + clk->parents[i] = __clk_lookup(parent->name); break; } -- cgit v1.1 From bf47b4fd8f9f81cd5ce40e1945c6334d088226d1 Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Fri, 8 Jun 2012 14:04:06 +0100 Subject: clk: Check parent for NULL in clk_change_rate clk_change_rate() is accessing parent's rate without checking if the parent exists at all. In case of root clocks this will cause NULL pointer dereference. This patch follows what clk_calc_new_rates() does in such situation. Signed-off-by: Pawel Moll Signed-off-by: Mike Turquette Cc: stable@kernel.org --- drivers/clk/clk.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index df89cbf..dcbe056 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -850,18 +850,21 @@ static void clk_change_rate(struct clk *clk) { struct clk *child; unsigned long old_rate; + unsigned long best_parent_rate = 0; struct hlist_node *tmp; old_rate = clk->rate; + if (clk->parent) + best_parent_rate = clk->parent->rate; + if (clk->ops->set_rate) - clk->ops->set_rate(clk->hw, clk->new_rate, clk->parent->rate); + clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); if (clk->ops->recalc_rate) - clk->rate = clk->ops->recalc_rate(clk->hw, - clk->parent->rate); + clk->rate = clk->ops->recalc_rate(clk->hw, best_parent_rate); else - clk->rate = clk->parent->rate; + clk->rate = best_parent_rate; if (clk->notifier_count && old_rate != clk->rate) __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); -- cgit v1.1 From d6dc55c1857ff1911780881b74537785d8a4e6e1 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 22 Jun 2012 10:13:20 +0800 Subject: clk: mxs: fix ref_io clock definition The definition of clocks ref_io0 and ref_io1 were inverted. It causes a mmc regression on some boards right away. Fix the regression by correcting the ref_io clock definition. Reported-by: Maxime Ripard Signed-off-by: Shawn Guo Signed-off-by: Mike Turquette --- drivers/clk/mxs/clk-imx28.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index 2826a26..17e85a1 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c @@ -245,8 +245,8 @@ int __init mx28_clocks_init(void) clks[pll2] = mxs_clk_pll("pll2", "ref_xtal", PLL2CTRL0, 23, 50000000); clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll0", FRAC0, 0); clks[ref_emi] = mxs_clk_ref("ref_emi", "pll0", FRAC0, 1); - clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 2); - clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 3); + clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 2); + clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 3); clks[ref_pix] = mxs_clk_ref("ref_pix", "pll0", FRAC1, 0); clks[ref_hsadc] = mxs_clk_ref("ref_hsadc", "pll0", FRAC1, 1); clks[ref_gpmi] = mxs_clk_ref("ref_gpmi", "pll0", FRAC1, 2); -- cgit v1.1 From d03ac61daa8d4d17cd83a5ab98e85b616b90c7ac Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 21 Jun 2012 20:04:25 +0200 Subject: clk: mxs: fix clock lookup after freeing init memory The struct clk_lookup are marked as __initdata, resulting in being removed from memory after the kernel finished booting. However this leads to a NULL pointer de-ref if loading a module which uses clk_get. This patch removes the __initdata from the struct clk_lookup. Signed-off-by: Marc Kleine-Budde Signed-off-by: Shawn Guo Signed-off-by: Mike Turquette --- drivers/clk/mxs/clk-imx23.c | 12 ++++++------ drivers/clk/mxs/clk-imx28.c | 28 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c index f7be225..db2391c 100644 --- a/drivers/clk/mxs/clk-imx23.c +++ b/drivers/clk/mxs/clk-imx23.c @@ -71,7 +71,7 @@ static void __init clk_misc_init(void) __mxs_setl(30 << BP_FRAC_IOFRAC, FRAC); } -static struct clk_lookup uart_lookups[] __initdata = { +static struct clk_lookup uart_lookups[] = { { .dev_id = "duart", }, { .dev_id = "mxs-auart.0", }, { .dev_id = "mxs-auart.1", }, @@ -80,31 +80,31 @@ static struct clk_lookup uart_lookups[] __initdata = { { .dev_id = "80070000.serial", }, }; -static struct clk_lookup hbus_lookups[] __initdata = { +static struct clk_lookup hbus_lookups[] = { { .dev_id = "imx23-dma-apbh", }, { .dev_id = "80004000.dma-apbh", }, }; -static struct clk_lookup xbus_lookups[] __initdata = { +static struct clk_lookup xbus_lookups[] = { { .dev_id = "duart", .con_id = "apb_pclk"}, { .dev_id = "80070000.serial", .con_id = "apb_pclk"}, { .dev_id = "imx23-dma-apbx", }, { .dev_id = "80024000.dma-apbx", }, }; -static struct clk_lookup ssp_lookups[] __initdata = { +static struct clk_lookup ssp_lookups[] = { { .dev_id = "imx23-mmc.0", }, { .dev_id = "imx23-mmc.1", }, { .dev_id = "80010000.ssp", }, { .dev_id = "80034000.ssp", }, }; -static struct clk_lookup lcdif_lookups[] __initdata = { +static struct clk_lookup lcdif_lookups[] = { { .dev_id = "imx23-fb", }, { .dev_id = "80030000.lcdif", }, }; -static struct clk_lookup gpmi_lookups[] __initdata = { +static struct clk_lookup gpmi_lookups[] = { { .dev_id = "imx23-gpmi-nand", }, { .dev_id = "8000c000.gpmi", }, }; diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index 17e85a1..7fad6c8 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c @@ -120,7 +120,7 @@ static void __init clk_misc_init(void) writel_relaxed(val, FRAC0); } -static struct clk_lookup uart_lookups[] __initdata = { +static struct clk_lookup uart_lookups[] = { { .dev_id = "duart", }, { .dev_id = "mxs-auart.0", }, { .dev_id = "mxs-auart.1", }, @@ -135,71 +135,71 @@ static struct clk_lookup uart_lookups[] __initdata = { { .dev_id = "80074000.serial", }, }; -static struct clk_lookup hbus_lookups[] __initdata = { +static struct clk_lookup hbus_lookups[] = { { .dev_id = "imx28-dma-apbh", }, { .dev_id = "80004000.dma-apbh", }, }; -static struct clk_lookup xbus_lookups[] __initdata = { +static struct clk_lookup xbus_lookups[] = { { .dev_id = "duart", .con_id = "apb_pclk"}, { .dev_id = "80074000.serial", .con_id = "apb_pclk"}, { .dev_id = "imx28-dma-apbx", }, { .dev_id = "80024000.dma-apbx", }, }; -static struct clk_lookup ssp0_lookups[] __initdata = { +static struct clk_lookup ssp0_lookups[] = { { .dev_id = "imx28-mmc.0", }, { .dev_id = "80010000.ssp", }, }; -static struct clk_lookup ssp1_lookups[] __initdata = { +static struct clk_lookup ssp1_lookups[] = { { .dev_id = "imx28-mmc.1", }, { .dev_id = "80012000.ssp", }, }; -static struct clk_lookup ssp2_lookups[] __initdata = { +static struct clk_lookup ssp2_lookups[] = { { .dev_id = "imx28-mmc.2", }, { .dev_id = "80014000.ssp", }, }; -static struct clk_lookup ssp3_lookups[] __initdata = { +static struct clk_lookup ssp3_lookups[] = { { .dev_id = "imx28-mmc.3", }, { .dev_id = "80016000.ssp", }, }; -static struct clk_lookup lcdif_lookups[] __initdata = { +static struct clk_lookup lcdif_lookups[] = { { .dev_id = "imx28-fb", }, { .dev_id = "80030000.lcdif", }, }; -static struct clk_lookup gpmi_lookups[] __initdata = { +static struct clk_lookup gpmi_lookups[] = { { .dev_id = "imx28-gpmi-nand", }, { .dev_id = "8000c000.gpmi", }, }; -static struct clk_lookup fec_lookups[] __initdata = { +static struct clk_lookup fec_lookups[] = { { .dev_id = "imx28-fec.0", }, { .dev_id = "imx28-fec.1", }, { .dev_id = "800f0000.ethernet", }, { .dev_id = "800f4000.ethernet", }, }; -static struct clk_lookup can0_lookups[] __initdata = { +static struct clk_lookup can0_lookups[] = { { .dev_id = "flexcan.0", }, { .dev_id = "80032000.can", }, }; -static struct clk_lookup can1_lookups[] __initdata = { +static struct clk_lookup can1_lookups[] = { { .dev_id = "flexcan.1", }, { .dev_id = "80034000.can", }, }; -static struct clk_lookup saif0_lookups[] __initdata = { +static struct clk_lookup saif0_lookups[] = { { .dev_id = "mxs-saif.0", }, { .dev_id = "80042000.saif", }, }; -static struct clk_lookup saif1_lookups[] __initdata = { +static struct clk_lookup saif1_lookups[] = { { .dev_id = "mxs-saif.1", }, { .dev_id = "80046000.saif", }, }; -- cgit v1.1 From 9bd0c15fcfb42f6245447c53347d65ad9e72080b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 26 Jun 2012 12:12:30 +1000 Subject: drm/nouveau/fbcon: using nv_two_heads is not a good idea nv_two_heads() was never meant to be used outside of pre-nv50 code. The code checks for >= NV_10 for 2 CRTCs, then downgrades a few specific chipsets to 1 CRTC based on (pci_device & 0x0ff0). The breakage example seen is on GTX 560Ti, with a pciid of 0x1200, which gets detected as an NV20 (0x020x) with 1 CRTC by nv_two_heads(), causing memory corruption because there's actually 2 CRTCs.. This switches fbcon to use the CRTC count directly from the mode_config structure, which will also fix the same issue on Kepler boards which have 4 CRTCs. Signed-off-by: Ben Skeggs Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 153b9a1..1074bc5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -467,7 +467,7 @@ int nouveau_fbcon_init(struct drm_device *dev) nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs; ret = drm_fb_helper_init(dev, &nfbdev->helper, - nv_two_heads(dev) ? 2 : 1, 4); + dev->mode_config.num_crtc, 4); if (ret) { kfree(nfbdev); return ret; -- cgit v1.1 From d380443cd0271903bf9516bc04cead81676be034 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Wed, 13 Jun 2012 17:10:43 +0530 Subject: mmc: block: fix the data timeout issue with ACMD22 If multi block write operation fails for SD card, during error handling we send the SD_APP_SEND_NUM_WR_BLKS (ACMD22) to know how many blocks were already programmed by card. But mmc_sd_num_wr_blocks() function which sends the ACMD22 calculates the data timeout value from csd.tacc_ns and csd.tacc_clks parameters which will be 0 for block addressed (>2GB cards) SD card. This would result in timeout_ns and timeout_clks being 0 in the mmc_request passed to host driver. This means host controller would program its data timeout timer value with 0 which could result in DATA TIMEOUT errors from controller. To fix this issue, mmc_sd_num_wr_blocks() should instead just call the mmc_set_data_timeout() to calculate the data timeout value. mmc_set_data_timeout() function ensures that non zero timeout value is set even for block addressed SD cards. Signed-off-by: Subhash Jadavani Reviewed-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index dd2d374..276d21c 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -554,7 +554,6 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) struct mmc_request mrq = {NULL}; struct mmc_command cmd = {0}; struct mmc_data data = {0}; - unsigned int timeout_us; struct scatterlist sg; @@ -574,23 +573,12 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) cmd.arg = 0; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - data.timeout_ns = card->csd.tacc_ns * 100; - data.timeout_clks = card->csd.tacc_clks * 100; - - timeout_us = data.timeout_ns / 1000; - timeout_us += data.timeout_clks * 1000 / - (card->host->ios.clock / 1000); - - if (timeout_us > 100000) { - data.timeout_ns = 100000000; - data.timeout_clks = 0; - } - data.blksz = 4; data.blocks = 1; data.flags = MMC_DATA_READ; data.sg = &sg; data.sg_len = 1; + mmc_set_data_timeout(&data, card); mrq.cmd = &cmd; mrq.data = &data; -- cgit v1.1 From fe85227347738eb9b871bc163e7fb0db8b6cd2a0 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jun 2012 18:49:35 +0800 Subject: Revert "mmc: omap_hsmmc: Enable Auto CMD12" This patch reverts the commit dba3c29ea4a1d5d544. After bisecting, this commit dba3c29 is found to ruin micro-SD card data (writing incorrect file, or fs is corrupt after several times mount) on the beagle-xm revB, and reverting the commit will fix the problem. Also from TRM of OMAP3/OMAP4/DM37x, the below is mentioned about the Auto CMD12 Enable bit. - SDIO does not support this feature. - SD card only. Looks it is not suitable to always enable Auto CMD12 in host controller driver. Considered that the commit is not mature enough, so ask to revert it first. Cc: Balaji T K Cc: Venkatraman S Buglink: https://lkml.org/lkml/2012/6/10/225 Reported-by: Paolo Pisati Reported-bisected-and-tested-by: Ming Lei Signed-off-by: Ming Lei Acked-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 9a7a60a..389a3ee 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -85,7 +85,6 @@ #define BRR_ENABLE (1 << 5) #define DTO_ENABLE (1 << 20) #define INIT_STREAM (1 << 1) -#define ACEN_ACMD12 (1 << 2) #define DP_SELECT (1 << 21) #define DDIR (1 << 4) #define DMA_EN 0x1 @@ -117,7 +116,6 @@ #define OMAP_MMC_MAX_CLOCK 52000000 #define DRIVER_NAME "omap_hsmmc" -#define AUTO_CMD12 (1 << 0) /* Auto CMD12 support */ /* * One controller can have multiple slots, like on some omap boards using * omap.c controller driver. Luckily this is not currently done on any known @@ -177,7 +175,6 @@ struct omap_hsmmc_host { int reqs_blocked; int use_reg; int req_in_progress; - unsigned int flags; struct omap_hsmmc_next next_data; struct omap_mmc_platform_data *pdata; @@ -773,8 +770,6 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, cmdtype = 0x3; cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); - if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode)) - cmdreg |= ACEN_ACMD12; if (data) { cmdreg |= DP_SELECT | MSBS | BCE; @@ -847,14 +842,11 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) else data->bytes_xfered = 0; - if (data->stop && ((!(host->flags & AUTO_CMD12)) || data->error)) { - omap_hsmmc_start_command(host, data->stop, NULL); - } else { - if (data->stop) - data->stop->resp[0] = OMAP_HSMMC_READ(host->base, - RSP76); + if (!data->stop) { omap_hsmmc_request_done(host, data->mrq); + return; } + omap_hsmmc_start_command(host, data->stop, NULL); } /* @@ -1859,7 +1851,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) host->mapbase = res->start + pdata->reg_offset; host->base = ioremap(host->mapbase, SZ_4K); host->power_mode = MMC_POWER_OFF; - host->flags = AUTO_CMD12; host->next_data.cookie = 1; platform_set_drvdata(pdev, host); -- cgit v1.1 From c6156328dec52a55f90688cbfad21c83f8711d84 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Tue, 26 Jun 2012 11:56:48 -0300 Subject: usb: phy: Fix Kconfig dependency for Phy drivers USB phy layer driver are only built if usb host is selected, but they are used too by USB_GADGET drivers Signed-off-by: Alexandre Pereira da Silva Acked-by: Roland Stigge Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Makefile | 2 +- drivers/usb/phy/Kconfig | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index c691eea..f5ed3d7 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -46,7 +46,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/ obj-$(CONFIG_USB_SERIAL) += serial/ obj-$(CONFIG_USB) += misc/ -obj-$(CONFIG_USB) += phy/ +obj-$(CONFIG_USB_COMMON) += phy/ obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/ obj-$(CONFIG_USB_ATM) += atm/ diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 3cfabcb..e7cf84f 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -2,11 +2,11 @@ # Physical Layer USB driver configuration # comment "USB Physical Layer drivers" - depends on USB + depends on USB || USB_GADGET config USB_ISP1301 tristate "NXP ISP1301 USB transceiver support" - depends on USB + depends on USB || USB_GADGET depends on I2C help Say Y here to add support for the NXP ISP1301 USB transceiver driver. -- cgit v1.1 From 065b07e7a14676f4138ce4619d229c0be5a74230 Mon Sep 17 00:00:00 2001 From: Forest Bond Date: Fri, 22 Jun 2012 10:30:38 -0400 Subject: USB: option: Add USB ID for Novatel Ovation MC551 This device is also known as the Verizon USB551L. Signed-off-by: Forest Bond Acked-by: Dan Williams Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 396d968..adf8ce7 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -236,6 +236,7 @@ static void option_instat_callback(struct urb *urb); #define NOVATELWIRELESS_PRODUCT_G1 0xA001 #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 #define NOVATELWIRELESS_PRODUCT_G2 0xA010 +#define NOVATELWIRELESS_PRODUCT_MC551 0xB001 /* AMOI PRODUCTS */ #define AMOI_VENDOR_ID 0x1614 @@ -738,6 +739,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, + /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ + { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, -- cgit v1.1 From 3fcc8f96829776cf181918461923d1e3bbb831a2 Mon Sep 17 00:00:00 2001 From: Craig Shelley Date: Tue, 26 Jun 2012 23:20:04 +0100 Subject: USB: CP210x Add 10 Device IDs This patch adds 10 device IDs for CP210x based devices from the following manufacturers: Timewave Clipsal Festo Link Instruments Signed-off-by: Craig Shelley Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 73d25cd..1e71079 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -93,6 +93,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ @@ -134,7 +135,13 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ + { USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */ + { USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ + { USB_DEVICE(0x166A, 0x0304) }, /* Clipsal 5000CT2 C-Bus Black and White Touchscreen */ + { USB_DEVICE(0x166A, 0x0305) }, /* Clipsal C-5000CT2 C-Bus Spectrum Colour Touchscreen */ + { USB_DEVICE(0x166A, 0x0401) }, /* Clipsal L51xx C-Bus Architectural Dimmer */ + { USB_DEVICE(0x166A, 0x0101) }, /* Clipsal 5560884 C-Bus Multi-room Audio Matrix Switcher */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ @@ -146,7 +153,11 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ + { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ + { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ + { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ + { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; -- cgit v1.1 From 57efd44c8cad440fb00ef8078cb018ab2f221373 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Mon, 25 Jun 2012 21:54:46 +0000 Subject: ixgbe: Do not pad FCoE frames as this can cause issues with FCoE DDP FCoE target mode was experiencing issues due to the fact that we were sending up data frames that were padded to 60 bytes after the DDP logic had already stripped the frame down to 52 or 56 depending on the use of VLANs. This was resulting in the FCoE DDP logic having issues since it thought the frame still had data in it due to the padding. To resolve this, adding code so that we do not pad FCoE frames prior to handling them to the stack. CC: Signed-off-by: Alexander Duyck Tested-by: Phil Schmitt Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 4 ++-- drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 14 ++++++++++---- 3 files changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 3ef3c52..7af291e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -196,7 +196,7 @@ enum ixgbe_ring_state_t { __IXGBE_HANG_CHECK_ARMED, __IXGBE_RX_RSC_ENABLED, __IXGBE_RX_CSUM_UDP_ZERO_ERR, - __IXGBE_RX_FCOE_BUFSZ, + __IXGBE_RX_FCOE, }; #define check_for_tx_hang(ring) \ @@ -290,7 +290,7 @@ struct ixgbe_ring_feature { #if defined(IXGBE_FCOE) && (PAGE_SIZE < 8192) static inline unsigned int ixgbe_rx_pg_order(struct ixgbe_ring *ring) { - return test_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state) ? 1 : 0; + return test_bit(__IXGBE_RX_FCOE, &ring->state) ? 1 : 0; } #else #define ixgbe_rx_pg_order(_ring) 0 diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index af1a531..c377706 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -634,7 +634,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, f = &adapter->ring_feature[RING_F_FCOE]; if ((rxr_idx >= f->mask) && (rxr_idx < f->mask + f->indices)) - set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state); + set_bit(__IXGBE_RX_FCOE, &ring->state); } #endif /* IXGBE_FCOE */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index cbb05d6..18ca3bc 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1058,17 +1058,17 @@ static inline void ixgbe_rx_hash(struct ixgbe_ring *ring, #ifdef IXGBE_FCOE /** * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type - * @adapter: address of board private structure + * @ring: structure containing ring specific data * @rx_desc: advanced rx descriptor * * Returns : true if it is FCoE pkt */ -static inline bool ixgbe_rx_is_fcoe(struct ixgbe_adapter *adapter, +static inline bool ixgbe_rx_is_fcoe(struct ixgbe_ring *ring, union ixgbe_adv_rx_desc *rx_desc) { __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; - return (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && + return test_bit(__IXGBE_RX_FCOE, &ring->state) && ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_ETQF_MASK)) == (cpu_to_le16(IXGBE_ETQF_FILTER_FCOE << IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT))); @@ -1549,6 +1549,12 @@ static bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring, skb->truesize -= ixgbe_rx_bufsz(rx_ring); } +#ifdef IXGBE_FCOE + /* do not attempt to pad FCoE Frames as this will disrupt DDP */ + if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) + return false; + +#endif /* if skb_pad returns an error the skb was freed */ if (unlikely(skb->len < 60)) { int pad_len = 60 - skb->len; @@ -1775,7 +1781,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ - if (ixgbe_rx_is_fcoe(adapter, rx_desc)) { + if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) { ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); if (!ddp_bytes) { dev_kfree_skb_any(skb); -- cgit v1.1 From d7ffde35e31a81100d2d0d2c4013cbf527bb32ea Mon Sep 17 00:00:00 2001 From: Jens Freimann Date: Tue, 26 Jun 2012 00:59:58 +0000 Subject: vhost: use USER_DS in vhost_worker thread On some architectures address spaces are set up in a way that this is not necessary to work properly but on some others (like s390) it is. Make sure we operate on the user address space to allow copy_xxx_user() from the vhost_worker() thread by setting it explicitly before calling use_mm() and revert it after unuse_mm(). Signed-off-by: Jens Freimann Signed-off-by: Christian Borntraeger Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/vhost/vhost.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 94dbd25..112156f 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -191,7 +191,9 @@ static int vhost_worker(void *data) struct vhost_dev *dev = data; struct vhost_work *work = NULL; unsigned uninitialized_var(seq); + mm_segment_t oldfs = get_fs(); + set_fs(USER_DS); use_mm(dev->mm); for (;;) { @@ -229,6 +231,7 @@ static int vhost_worker(void *data) } unuse_mm(dev->mm); + set_fs(oldfs); return 0; } -- cgit v1.1 From 6bc96d047fe32d76ef79f3195c52a542edf7c705 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 25 Jun 2012 22:48:41 +0000 Subject: xen/netfront: teardown the device before unregistering it. Fixes: [ 15.470311] WARNING: at /local/scratch/ianc/devel/kernels/linux/fs/sysfs/file.c:498 sysfs_attr_ns+0x95/0xa0() [ 15.470326] sysfs: kobject eth0 without dirent [ 15.470333] Modules linked in: [ 15.470342] Pid: 12, comm: xenwatch Not tainted 3.4.0-x86_32p-xenU #93 and [ 9.150554] BUG: unable to handle kernel paging request at 2b359000 [ 9.150577] IP: [] linkwatch_do_dev+0x81/0xc0 [ 9.150592] *pdpt = 000000002c3c9027 *pde = 0000000000000000 [ 9.150604] Oops: 0002 [#1] SMP [ 9.150613] Modules linked in: This is http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=675190 Reported-by: George Shuklin Signed-off-by: Ian Campbell Tested-by: William Dauchy Cc: stable@kernel.org Cc: 675190@bugs.debian.org Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 2027afe..3089990 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1935,14 +1935,14 @@ static int __devexit xennet_remove(struct xenbus_device *dev) dev_dbg(&dev->dev, "%s\n", dev->nodename); - unregister_netdev(info->netdev); - xennet_disconnect_backend(info); - del_timer_sync(&info->rx_refill_timer); - xennet_sysfs_delif(info->netdev); + unregister_netdev(info->netdev); + + del_timer_sync(&info->rx_refill_timer); + free_percpu(info->stats); free_netdev(info->netdev); -- cgit v1.1 From e9bf5f36b09f8ec6c168ef58ee7d4890545ede1c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 27 Jun 2012 09:26:01 +0100 Subject: drm/nouveau: add license header to prime. Just forgot this when I posted it, and yes I'm the only person to have changed the file since. Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_prime.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index a89240e..a25cf2c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -1,3 +1,26 @@ +/* + * Copyright 2011 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Dave Airlie + */ #include "drmP.h" #include "drm.h" -- cgit v1.1 From 85f2f834e85517307f13e30e630a5fc86f757cb5 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Wed, 27 Jun 2012 16:19:18 +0800 Subject: can: flexcan: use be32_to_cpup to handle the value of dt entry The freescale arm i.MX series platform can support this driver, and usually the arm cpu works in the little endian mode by default, while device tree entry value is stored in big endian format, we should use be32_to_cpup() to handle them, after modification, it can work well both on the le cpu and be cpu. Cc: stable # v3.2+ Cc: Shawn Guo Signed-off-by: Hui Wang Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 38c0690..81d4741 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -939,12 +939,12 @@ static int __devinit flexcan_probe(struct platform_device *pdev) return PTR_ERR(pinctrl); if (pdev->dev.of_node) { - const u32 *clock_freq_p; + const __be32 *clock_freq_p; clock_freq_p = of_get_property(pdev->dev.of_node, "clock-frequency", NULL); if (clock_freq_p) - clock_freq = *clock_freq_p; + clock_freq = be32_to_cpup(clock_freq_p); } if (!clock_freq) { -- cgit v1.1 From 903e0e4ef9120c3d7693599acb95e76e8263fb35 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 18 Jun 2012 16:31:23 -0700 Subject: UBI: correct usage of IS_ENABLED() Commit "e9b4cf2 UBI: fix debugfs-less systems support" fixed one regression but introduced a different regression - the debugfs is now always compiled out. Root cause: IS_ENABLED() arguments should be used with the CONFIG_* prefix. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 09d4f8d..7c13803 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -264,7 +264,7 @@ static struct dentry *dfs_rootdir; */ int ubi_debugfs_init(void) { - if (!IS_ENABLED(DEBUG_FS)) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; dfs_rootdir = debugfs_create_dir("ubi", NULL); @@ -284,7 +284,7 @@ int ubi_debugfs_init(void) */ void ubi_debugfs_exit(void) { - if (IS_ENABLED(DEBUG_FS)) + if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove(dfs_rootdir); } @@ -407,7 +407,7 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) struct dentry *dent; struct ubi_debug_info *d = ubi->dbg; - if (!IS_ENABLED(DEBUG_FS)) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, @@ -477,6 +477,6 @@ out: */ void ubi_debugfs_exit_dev(struct ubi_device *ubi) { - if (IS_ENABLED(DEBUG_FS)) + if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove_recursive(ubi->dbg->dfs_dir); } -- cgit v1.1 From 75cc52358799bd6001e7d1a47847f997f5ae99f0 Mon Sep 17 00:00:00 2001 From: Deepthi Dharwar Date: Mon, 25 Jun 2012 23:59:54 +0200 Subject: PM / ACPI: Fix suspend/resume regression caused by cpuidle cleanup. Commit e978aa7d7d57d04eb5f88a7507c4fb98577def77 ( cpuidle: Move dev->last_residency update to driver enter routine; remove dev->last_state) was breaking suspend on laptops, as reported in the below link - https://lkml.org/lkml/2011/11/11/164 This was fixed in commit 3439a8da16bcad6b0982ece938c9f8299bb53584 (ACPI / cpuidle: Remove acpi_idle_suspend (to fix suspend regression) by removing acpi_idle_suspend flag. - https://lkml.org/lkml/2011/11/14/74 But this did fix did not work on all systems as Suspend/resume regression was reported on Lenovo S10-3 recently by Dave. - https://lkml.org/lkml/2012/5/27/115 It looked like with commit e978aa7d broke suspend and with commit 3439a8da resume was not working with acpi_idle driver. This patch fixes the regression that caused this issue in the first place. acpi_idle_suspend flag is essential on some x86 systems to prevent the cpus from going to deeper C-states when suspend is triggered ( commit b04e7bdb984 ) So reverting the commit 3439a8da is essential. By default, irqs are disabled in cpu_idle arch specific call and re-enabled in idle state return path . During suspend, the acpi_idle_suspend flag is set, which prevents the cpus from going to deeper idle states, it is essential to enabling the irqs in this return path too. To address the suspend issue, we were not re-enabling the interrupts while returning from acpi_idle_enter_bm() routine if acpi_idle_suspend flag is set. and this caused suspend failure. In addition to the above, to improve the readability of the code, return of -ENIVAL is replaced with -EBUSY in acpi_idle_suspend return path. Implying that the system is currently busy when suspend is in progress, which prevents the cpus from entering deeper C-states. Reported-and-Tested-by: Dav Hansen Tested-by: Preeti Murthy Signed-off-by: Deepthi Dharwar Reviewed-by: Srivatsa S Bhat Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_idle.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f3decb3..47a8caa 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -224,6 +224,7 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr, /* * Suspend / resume control */ +static int acpi_idle_suspend; static u32 saved_bm_rld; static void acpi_idle_bm_rld_save(void) @@ -242,13 +243,21 @@ static void acpi_idle_bm_rld_restore(void) int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) { + if (acpi_idle_suspend == 1) + return 0; + acpi_idle_bm_rld_save(); + acpi_idle_suspend = 1; return 0; } int acpi_processor_resume(struct acpi_device * device) { + if (acpi_idle_suspend == 0) + return 0; + acpi_idle_bm_rld_restore(); + acpi_idle_suspend = 0; return 0; } @@ -754,6 +763,12 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, local_irq_disable(); + if (acpi_idle_suspend) { + local_irq_enable(); + cpu_relax(); + return -EBUSY; + } + lapic_timer_state_broadcast(pr, cx, 1); kt1 = ktime_get_real(); acpi_idle_do_entry(cx); @@ -823,6 +838,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, local_irq_disable(); + if (acpi_idle_suspend) { + local_irq_enable(); + cpu_relax(); + return -EBUSY; + } + if (cx->entry_method != ACPI_CSTATE_FFH) { current_thread_info()->status &= ~TS_POLLING; /* @@ -907,14 +928,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, drv, drv->safe_state_index); } else { local_irq_disable(); - acpi_safe_halt(); + if (!acpi_idle_suspend) + acpi_safe_halt(); local_irq_enable(); - return -EINVAL; + return -EBUSY; } } local_irq_disable(); + if (acpi_idle_suspend) { + local_irq_enable(); + cpu_relax(); + return -EBUSY; + } + if (cx->entry_method != ACPI_CSTATE_FFH) { current_thread_info()->status &= ~TS_POLLING; /* -- cgit v1.1 From 7aa1e7f06d6ea1bce3b27630d50769d13da28b1a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 27 Jun 2012 16:43:36 +0200 Subject: Revert "drm/i915: allow PCH PWM override on IVB" This reverts commit f82cfb6bcda164ef3a66b8c3fc549b1f9bdd09ad. This breaks the backlight controls on my IVB asus zenbook with an eDP panel. I guess the right fix would be to read this bit and use either the pch or the cpu register to frob the backlight values. But that is stuff for -next. Cc: Jesse Barnes Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a7c727d..a8538ac 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6921,19 +6921,6 @@ static void i915_disable_vga(struct drm_device *dev) POSTING_READ(vga_reg); } -static void ivb_pch_pwm_override(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - /* - * IVB has CPU eDP backlight regs too, set things up to let the - * PCH regs control the backlight - */ - I915_WRITE(BLC_PWM_CPU_CTL2, PWM_ENABLE); - I915_WRITE(BLC_PWM_CPU_CTL, 0); - I915_WRITE(BLC_PWM_PCH_CTL1, PWM_ENABLE | (1<<30)); -} - void intel_modeset_init_hw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -6950,9 +6937,6 @@ void intel_modeset_init_hw(struct drm_device *dev) gen6_enable_rps(dev_priv); gen6_update_ring_freq(dev_priv); } - - if (IS_IVYBRIDGE(dev)) - ivb_pch_pwm_override(dev); } void intel_modeset_init(struct drm_device *dev) -- cgit v1.1 From e5de32e3ec9d4d5a355659760d5045b80c0a05d8 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 22 Jun 2012 16:41:00 +0100 Subject: watchdog: iTCO_wdt: add platform driver module alias The recent conversion of iTCO_wdt resulted in the driver no longer getting loaded automatically, since it no longer has a MODULE_DEVICE_TABLE() included. As the lpc_ich driver now creates a platform device, auto-loading can easily be done by having a respective module alias in place. Signed-off-by: Jan Beulich Cc: Aaron Sierra Acked-by: Guenter Roeck Cc: Samuel Ortiz Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/iTCO_wdt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index bc47e90..9c2c27c 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -699,3 +699,4 @@ MODULE_DESCRIPTION("Intel TCO WatchDog Timer Driver"); MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); +MODULE_ALIAS("platform:" DRV_NAME); -- cgit v1.1 From a089361cf5f1d6a5295aa5385238bd044998e1e9 Mon Sep 17 00:00:00 2001 From: "Mingarelli, Thomas" Date: Tue, 26 Jun 2012 10:27:00 +0200 Subject: watchdog: hpwdt: Unregister NMI events on exit. This patch is to unregister for NMI events upon exit. Also we are now making the default setting for allow_kdump enabled. Signed-off-by: Thomas Mingarelli Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 2b76381..1eff743 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -146,7 +146,7 @@ struct cmn_registers { } __attribute__((packed)); static unsigned int hpwdt_nmi_decoding; -static unsigned int allow_kdump; +static unsigned int allow_kdump = 1; static unsigned int is_icru; static DEFINE_SPINLOCK(rom_lock); static void *cru_rom_addr; @@ -756,6 +756,8 @@ error: static void hpwdt_exit_nmi_decoding(void) { unregister_nmi_handler(NMI_UNKNOWN, "hpwdt"); + unregister_nmi_handler(NMI_SERR, "hpwdt"); + unregister_nmi_handler(NMI_IO_CHECK, "hpwdt"); if (cru_rom_addr) iounmap(cru_rom_addr); } -- cgit v1.1 From 8b9468d496abd357cc797b27a79d4402f5e0e94d Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Tue, 26 Jun 2012 20:07:21 +0200 Subject: watchdog: core: fix WDIOC_GETSTATUS return value In commit 7a87982420e5e126bfefeb42232d1fd92052794e we added a wrapper for the WDIOC_GETSTATUS ioctl call. The code results however in a different behaviour: it returns an error if the driver doesn't support the status operation. This is not according to the API that says that when we don't support the status operation, that we just should return a 0 value. Only when the device isn't there anymore, we should return an error. Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/watchdog_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 672d169..ef8edec 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -349,7 +349,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, sizeof(struct watchdog_info)) ? -EFAULT : 0; case WDIOC_GETSTATUS: err = watchdog_get_status(wdd, &val); - if (err) + if (err == -ENODEV) return err; return put_user(val, p); case WDIOC_GETBOOTSTATUS: -- cgit v1.1 From b03738430c7537d5f87948e0b35d8aaf2688c6b4 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 20 Jun 2012 09:48:43 +0800 Subject: ACPI video: Still use ACPI backlight control if _DOS doesn't exist This fixes a regression in 3.4-rc1 caused by commit ea9f8856bd6d4ed45885b06a338f7362cd6c60e5 (ACPI video: Harden video bus adding.) Some platforms don't have _DOS control method, but the ACPI backlight still works. We should not invoke _DOS for these platforms. https://bugzilla.kernel.org/show_bug.cgi?id=43168 Cc: Igor Murzov Cc: stable@vger.kernel.org Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 9577b6f..4134b30 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -558,6 +558,8 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; + if (!video->cap._DOS) + return 0; if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) return -EINVAL; -- cgit v1.1 From 5f1601261050251a5ca293378b492a69d590dacb Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Wed, 13 Jun 2012 16:10:45 -0500 Subject: acpi_pad: fix power_saving thread deadlock The acpi_pad driver can get stuck in destroy_power_saving_task() waiting for kthread_stop() to stop a power_saving thread. The problem is that the isolated_cpus_lock mutex is owned when destroy_power_saving_task() calls kthread_stop(), which waits for a power_saving thread to end, and the power_saving thread tries to acquire the isolated_cpus_lock when it calls round_robin_cpu(). This patch fixes the issue by making round_robin_cpu() use its own mutex. https://bugzilla.kernel.org/show_bug.cgi?id=42981 Cc: stable@vger.kernel.org Signed-off-by: Stuart Hayes Signed-off-by: Len Brown --- drivers/acpi/acpi_pad.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index a43fa1a..1502c502 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -36,6 +36,7 @@ #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 static DEFINE_MUTEX(isolated_cpus_lock); +static DEFINE_MUTEX(round_robin_lock); static unsigned long power_saving_mwait_eax; @@ -107,7 +108,7 @@ static void round_robin_cpu(unsigned int tsk_index) if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) return; - mutex_lock(&isolated_cpus_lock); + mutex_lock(&round_robin_lock); cpumask_clear(tmp); for_each_cpu(cpu, pad_busy_cpus) cpumask_or(tmp, tmp, topology_thread_cpumask(cpu)); @@ -116,7 +117,7 @@ static void round_robin_cpu(unsigned int tsk_index) if (cpumask_empty(tmp)) cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus); if (cpumask_empty(tmp)) { - mutex_unlock(&isolated_cpus_lock); + mutex_unlock(&round_robin_lock); return; } for_each_cpu(cpu, tmp) { @@ -131,7 +132,7 @@ static void round_robin_cpu(unsigned int tsk_index) tsk_in_cpu[tsk_index] = preferred_cpu; cpumask_set_cpu(preferred_cpu, pad_busy_cpus); cpu_weight[preferred_cpu]++; - mutex_unlock(&isolated_cpus_lock); + mutex_unlock(&round_robin_lock); set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu)); } -- cgit v1.1