From 38e7afe96c7c0ad900824911c61fdb04078033dc Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sun, 19 Sep 2010 16:25:36 -0700 Subject: Input: uinput - setup MT usage during device creation The input devices created by uinput do not currently handle multitouch properly. All events will appear as if they came from slot zero, and the input event buffers are not adjusted. This patch creates the MT slots during setup, and sets the number of events per packet based on the MT usage. Signed-off-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 0d4266a533a5..360698553eb5 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -404,6 +404,13 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu retval = uinput_validate_absbits(dev); if (retval < 0) goto exit; + if (test_bit(ABS_MT_SLOT, dev->absbit)) { + int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; + input_mt_create_slots(dev, nslot); + input_set_events_per_packet(dev, 6 * nslot); + } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { + input_set_events_per_packet(dev, 60); + } } udev->state = UIST_SETUP_COMPLETE; -- cgit v1.2.2 From d2520a426dc3033c00077e923a553fc6c98c7564 Mon Sep 17 00:00:00 2001 From: Kenneth Waters Date: Tue, 21 Sep 2010 00:58:23 -0700 Subject: Input: joydev - fix JSIOCSAXMAP ioctl Fixed JSIOCSAXMAP ioctl to update absmap, the map from hardware axis to event axis in addition to abspam. This fixes a regression introduced by 999b874f. Signed-off-by: Kenneth Waters Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/joydev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index d85bd8a7967d..22239e988498 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -483,6 +483,9 @@ static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev, memcpy(joydev->abspam, abspam, len); + for (i = 0; i < joydev->nabs; i++) + joydev->absmap[joydev->abspam[i]] = i; + out: kfree(abspam); return retval; -- cgit v1.2.2 From 4a109cc0511209276e58f1dbe53259e7a8f1508b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 24 Sep 2010 10:50:46 +0100 Subject: ASoC: Add Jassi Brar as Samsung maintainer Since Jassi is doing so much good work and can offer such good review for the Samsung CPU support add an entry for the Samsung ASoC drivers to MAINTAINERS listing him. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b5b8baa1d70e..f51409b1527a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4965,6 +4965,12 @@ F: drivers/media/common/saa7146* F: drivers/media/video/*7146* F: include/media/*7146* +SAMSUNG AUDIO (ASoC) DRIVERS +M: Jassi Brar +L: alsa-devel@alsa-project.org (moderated for non-subscribers) +S: Supported +F: sound/soc/s3c24xx + TLG2300 VIDEO4LINUX-2 DRIVER M: Huang Shijie M: Kang Yong -- cgit v1.2.2 From fb0c484f72df9e336605b5659f39eb1ab5e8d946 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 19 Aug 2010 14:42:14 -0300 Subject: V4L/DVB: tm6000: depends on IR_CORE tm6000 uses IR interfaces, so it should depend on IR_CORE. ERROR: "get_rc_map" [drivers/staging/tm6000/tm6000.ko] undefined! ERROR: "ir_input_unregister" [drivers/staging/tm6000/tm6000.ko] undefined! ERROR: "__ir_input_register" [drivers/staging/tm6000/tm6000.ko] undefined! Signed-off-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig index c725356cc346..de7ebb99d8f6 100644 --- a/drivers/staging/tm6000/Kconfig +++ b/drivers/staging/tm6000/Kconfig @@ -1,6 +1,6 @@ config VIDEO_TM6000 tristate "TV Master TM5600/6000/6010 driver" - depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL + depends on VIDEO_DEV && I2C && INPUT && IR_CORE && USB && EXPERIMENTAL select VIDEO_TUNER select MEDIA_TUNER_XC2028 select MEDIA_TUNER_XC5000 -- cgit v1.2.2 From 0f63a14d357b3a80abb5203a574cbb3f8988c2f7 Mon Sep 17 00:00:00 2001 From: lawrence rust Date: Tue, 24 Aug 2010 06:50:48 -0300 Subject: V4L/DVB: cx88: Kconfig: Remove EXPERIMENTAL dependency from VIDEO_CX88_ALSA The cx88-alsa module has been around since January 2006 and has seen no significant changes since September 2007. It is stable in operation and so I believe that the 'experimental' tag is no longer warranted. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 99dbae117591..0fa85cbefbb1 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig @@ -17,7 +17,7 @@ config VIDEO_CX88 config VIDEO_CX88_ALSA tristate "Conexant 2388x DMA audio support" - depends on VIDEO_CX88 && SND && EXPERIMENTAL + depends on VIDEO_CX88 && SND select SND_PCM ---help--- This is a video4linux driver for direct (DMA) audio on -- cgit v1.2.2 From 590a58d18027b18db78f538aca592c2cdb249079 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 12 Aug 2010 04:41:58 -0300 Subject: V4L/DVB: unlock on error path If we return directly here then we miss out on some mutex_unlock()s Signed-off-by: Dan Carpenter Acked-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index b151c7be8a50..1beb2263d18c 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -822,7 +822,8 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) } else { v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, "Wrong buffer/video queue type (%d)\n", f->type); - return -EINVAL; + ret = -EINVAL; + goto s_fmt_out; } pix = &f->fmt.pix; -- cgit v1.2.2 From 028816bc85db5ac6a562c2aff2113c7480d67919 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 12 Aug 2010 04:47:07 -0300 Subject: V4L/DVB: IR: ir-raw-event: null pointer dereference The original code dereferenced ir->raw after freeing it and setting it to NULL. Signed-off-by: Dan Carpenter Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/ir-raw-event.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index 43094e7eccfa..8e0e1b1f8c87 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c @@ -279,9 +279,11 @@ int ir_raw_event_register(struct input_dev *input_dev) "rc%u", (unsigned int)ir->devno); if (IS_ERR(ir->raw->thread)) { + int ret = PTR_ERR(ir->raw->thread); + kfree(ir->raw); ir->raw = NULL; - return PTR_ERR(ir->raw->thread); + return ret; } mutex_lock(&ir_raw_handler_lock); -- cgit v1.2.2 From a8e07124500184f81541ddf3e9669000af9ac4bc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 19 Aug 2010 06:47:50 -0300 Subject: V4L/DVB: opera1: remove unneeded NULL check "fw" is always a non-NULL pointer at this point, and anyway release_firmware() accepts NULL pointers. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/opera1.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c index 6b22ec64ab0c..f896337b4535 100644 --- a/drivers/media/dvb/dvb-usb/opera1.c +++ b/drivers/media/dvb/dvb-usb/opera1.c @@ -483,9 +483,7 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev, } } kfree(p); - if (fw) { - release_firmware(fw); - } + release_firmware(fw); return ret; } -- cgit v1.2.2 From d5337966ce4639c775ff5edf92d78f5fad34ef0d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 19 Aug 2010 06:50:04 -0300 Subject: V4L/DVB: pvrusb2: remove unneeded NULL checks We dereference "maskptr" unconditionally at the start of the function and also inside the call to parse_tlist() towards the end of the function. This function is called from store_val_any() and it always passes a non-NULL pointer. Signed-off-by: Dan Carpenter Acked-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-ctrl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 1b992b847198..55ea914c7fcd 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c @@ -513,7 +513,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, if (ret >= 0) { ret = pvr2_ctrl_range_check(cptr,*valptr); } - if (maskptr) *maskptr = ~0; + *maskptr = ~0; } else if (cptr->info->type == pvr2_ctl_bool) { ret = parse_token(ptr,len,valptr,boolNames, ARRAY_SIZE(boolNames)); @@ -522,7 +522,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, } else if (ret == 0) { *valptr = (*valptr & 1) ? !0 : 0; } - if (maskptr) *maskptr = 1; + *maskptr = 1; } else if (cptr->info->type == pvr2_ctl_enum) { ret = parse_token( ptr,len,valptr, @@ -531,7 +531,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, if (ret >= 0) { ret = pvr2_ctrl_range_check(cptr,*valptr); } - if (maskptr) *maskptr = ~0; + *maskptr = ~0; } else if (cptr->info->type == pvr2_ctl_bitmask) { ret = parse_tlist( ptr,len,maskptr,valptr, -- cgit v1.2.2 From 23e64d55859ea619c17832645e0e56faac84d750 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 19 Aug 2010 07:00:22 -0300 Subject: V4L/DVB: saa7164: move dereference under NULL check The original code dereferenced "port" before checking it for NULL. I moved the test down below the check. Also I changed the comparisons a little so people wouldn't get confused and think "port" and "buf" were ints instead of pointers. (Probably that's what lead to this issue in the first place.) There is only one caller for this function and it passes non-NULL pointers, so this is essentially a cleanup rather than a bugfix. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7164/saa7164-buffer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c index 5713f3a4b76c..ddd25d32723d 100644 --- a/drivers/media/video/saa7164/saa7164-buffer.c +++ b/drivers/media/video/saa7164/saa7164-buffer.c @@ -136,10 +136,11 @@ ret: int saa7164_buffer_dealloc(struct saa7164_tsport *port, struct saa7164_buffer *buf) { - struct saa7164_dev *dev = port->dev; + struct saa7164_dev *dev; - if ((buf == 0) || (port == 0)) + if (!buf || !port) return SAA_ERR_BAD_PARAMETER; + dev = port->dev; dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf); -- cgit v1.2.2 From 29d834912bbcf0d095e6cd0e95b0d9790fdf7957 Mon Sep 17 00:00:00 2001 From: Dmitri Belimov Date: Mon, 23 Aug 2010 10:30:14 -0300 Subject: V4L/DVB: Fix regression for BeholdTV Columbus Some time a go our customers wrote me about problem with our TV card BeholdTV Columbus. It's PCMCIA TV card for notebook. As I understand v4l has some regression with autodetect address of tuners. I can set incorrect I2C address and had report about detect tuner. No any TV of course. When I set correct tuner type and I2C address of the tuners all works well. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index ec697fcd406e..bb8d83d8ddaf 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -4323,13 +4323,13 @@ struct saa7134_board saa7134_boards[] = { }, [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { /* Beholder Intl. Ltd. 2008 */ - /*Dmitry Belimov */ - .name = "Beholder BeholdTV Columbus TVFM", + /* Dmitry Belimov */ + .name = "Beholder BeholdTV Columbus TV/FM", .audio_clock = 0x00187de7, .tuner_type = TUNER_ALPS_TSBE5_PAL, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, + .radio_type = TUNER_TEA5767, + .tuner_addr = 0xc2 >> 1, + .radio_addr = 0xc0 >> 1, .tda9887_conf = TDA9887_PRESENT, .gpiomask = 0x000A8004, .inputs = {{ -- cgit v1.2.2 From 882787ff8fdeb0be790547ee9b22b281095e95da Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 3 Sep 2010 06:57:19 -0300 Subject: V4L/DVB: gspca - main: Fix a crash of some webcams on ARM arch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When plugging some webcams on ARM, the system crashes. This is because we alloc buffer for an urb through usb_buffer_alloc, the alloced buffer is already in DMA coherent region, so we should set the flag of this urb to URB_NO_TRANSFER_DMA_MAP, otherwise when we submit this urb, the hcd core will handle this address as an non-DMA address and call dma_map_single/sg to map it. On arm architecture, dma_map_single a DMA coherent address will be catched by a BUG_ON(). Signed-off-by: Jason Wang Signed-off-by: Jean-François Moine Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index b9846106913e..78abc1c1f9d5 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -223,6 +223,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, usb_rcvintpipe(dev, ep->bEndpointAddress), buffer, buffer_len, int_irq, (void *)gspca_dev, interval); + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; gspca_dev->int_urb = urb; ret = usb_submit_urb(urb, GFP_KERNEL); if (ret < 0) { -- cgit v1.2.2 From c13df9cf6b1cad7fd088c9acceb98b6bffd9ca31 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Fri, 27 Aug 2010 18:21:14 -0300 Subject: V4L/DVB: mceusb: add two new ASUS device IDs Reported in lirc sf.net tracker and on lirc mailing list Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/mceusb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index ac6bb2c01a48..bc620e10ef77 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c @@ -120,6 +120,10 @@ static struct usb_device_id mceusb_dev_table[] = { { USB_DEVICE(VENDOR_PHILIPS, 0x0613) }, /* Philips eHome Infrared Transceiver */ { USB_DEVICE(VENDOR_PHILIPS, 0x0815) }, + /* Philips/Spinel plus IR transceiver for ASUS */ + { USB_DEVICE(VENDOR_PHILIPS, 0x206c) }, + /* Philips/Spinel plus IR transceiver for ASUS */ + { USB_DEVICE(VENDOR_PHILIPS, 0x2088) }, /* Realtek MCE IR Receiver */ { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, /* SMK/Toshiba G83C0004D410 */ -- cgit v1.2.2 From 3bfb317f97cfddbbec67bbe8e35ad38af3507397 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 3 Sep 2010 10:50:24 -0300 Subject: V4L/DVB: Don't identify PV SBTVD Hybrid as a DibCom device As reported by Carlos, Prolink Pixelview SBTVD Hybrid is based on Conexant cx231xx + Fujitsu 86A20S demodulator. However, both shares the same USB ID. So, we need to use USB bcdDevice, in order to properly discover what's the board. We know for sure that bcd 0x100 is used for a dib0700 device, while bcd 0x4001 is used for a cx23102 device. This patch reserves two ranges, the first one from 0x0000-0x3f00 for dib0700, and the second from 0x4000-0x4fff for cx231xx devices. This may need fixes in the future, as we get access to other devices. Thanks-to: Carlos Americo Domiciano Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 2 +- drivers/media/video/cx231xx/Makefile | 1 + drivers/media/video/cx231xx/cx231xx-cards.c | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index f634d2e784b2..ce66c5a96ba8 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1781,7 +1781,7 @@ struct usb_device_id dib0700_usb_id_table[] = { /* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, - { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) }, + { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) }, { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, /* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/video/cx231xx/Makefile index 755dd0ce65ff..6f2b57384488 100644 --- a/drivers/media/video/cx231xx/Makefile +++ b/drivers/media/video/cx231xx/Makefile @@ -11,4 +11,5 @@ EXTRA_CFLAGS += -Idrivers/media/video EXTRA_CFLAGS += -Idrivers/media/common/tuners EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 6bdc0ef18119..5b7c9a948a0a 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c @@ -32,6 +32,7 @@ #include #include +#include "dvb-usb-ids.h" #include "xc5000.h" #include "cx231xx.h" @@ -175,6 +176,8 @@ struct usb_device_id cx231xx_id_table[] = { .driver_info = CX231XX_BOARD_CNXT_RDE_250}, {USB_DEVICE(0x0572, 0x58A1), .driver_info = CX231XX_BOARD_CNXT_RDU_250}, + {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff), + .driver_info = CX231XX_BOARD_UNKNOWN}, {}, }; -- cgit v1.2.2 From 04cab131ce2a267b6777a98d68fbc0cae44d4ba8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 8 Sep 2010 12:58:12 -0300 Subject: V4L/DVB: rc-core: increase repeat time As reported by Anton Blanchard , double IR events on 2.6.36-rc2 and a DViCO FusionHDTV DVB-T Dual Express are happening: [ 1351.032084] ir_keydown: i2c IR (FusionHDTV): key down event, key 0x0067, scancode 0x0051 [ 1351.281284] ir_keyup: keyup key 0x0067 ie one key down event and one key up event 250ms later. So, we need to increase the repeat timeout, to avoid this bug to hit. As we're doing it at core, this fix is not needed anymore at dib0700 driver. Thanks-to: Anton Blanchard Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/ir-keytable.c | 7 +++++++ drivers/media/dvb/dvb-usb/dib0700_core.c | 3 --- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 7e82a9df726b..d00ef194f2e8 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -510,6 +510,13 @@ int __ir_input_register(struct input_dev *input_dev, (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? " in raw mode" : ""); + /* + * Default delay of 250ms is too short for some protocols, expecially + * since the timeout is currently set to 250ms. Increase it to 500ms, + * to avoid wrong repetition of the keycodes. + */ + input_dev->rep[REP_DELAY] = 500; + return 0; out_event: diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index fe818348b8a3..48397f103d32 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -673,9 +673,6 @@ static int dib0700_probe(struct usb_interface *intf, else dev->props.rc.core.bulk_mode = false; - /* Need a higher delay, to avoid wrong repeat */ - dev->rc_input_dev->rep[REP_DELAY] = 500; - dib0700_rc_setup(dev); return 0; -- cgit v1.2.2 From 67332ba83242f814490884161fee8676a9fd8a09 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 6 Sep 2010 18:26:08 -0300 Subject: V4L/DVB: IR: fix duty cycle capability Due to typo lirc bridge enabled wrong capability. Signed-off-by: Maxim Levitsky Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/ir-lirc-codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c index 77b5946413c0..e63f757d5d72 100644 --- a/drivers/media/IR/ir-lirc-codec.c +++ b/drivers/media/IR/ir-lirc-codec.c @@ -267,7 +267,7 @@ static int ir_lirc_register(struct input_dev *input_dev) features |= LIRC_CAN_SET_SEND_CARRIER; if (ir_dev->props->s_tx_duty_cycle) - features |= LIRC_CAN_SET_REC_DUTY_CYCLE; + features |= LIRC_CAN_SET_SEND_DUTY_CYCLE; } if (ir_dev->props->s_rx_carrier_range) -- cgit v1.2.2 From e0172fd373ab77a83ea952fd6a75c612e1b0bf9e Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 6 Sep 2010 18:26:09 -0300 Subject: V4L/DVB: IR: fix keys beeing stuck down forever The logic in ir_timer_keyup was inverted. In case that values aren't equal, the meaning of the time_is_after_eq_jiffies(ir->keyup_jiffies) is that ir->keyup_jiffies is after the the jiffies or equally that that jiffies are before the the ir->keyup_jiffies which is exactly the situation we want to avoid (that the timeout is in the future) Confusing Eh? Signed-off-by: Maxim Levitsky Acked-by: Jarod Wilson Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/ir-keytable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index d00ef194f2e8..7961d59f5cac 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -319,7 +319,7 @@ static void ir_timer_keyup(unsigned long cookie) * a keyup event might follow immediately after the keydown. */ spin_lock_irqsave(&ir->keylock, flags); - if (time_is_after_eq_jiffies(ir->keyup_jiffies)) + if (time_is_before_eq_jiffies(ir->keyup_jiffies)) ir_keyup(ir); spin_unlock_irqrestore(&ir->keylock, flags); } -- cgit v1.2.2 From 00a220aa98133dc43c6f7016c218aaf3afd66e11 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 6 Sep 2010 18:26:10 -0300 Subject: V4L/DVB: IR: extend MCE keymap These keys are found on remote bundled with Toshiba Qosmio F50-10q. Found and tested by, Sami R Signed-off-by: Maxim Levitsky Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/keymaps/rc-rc6-mce.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c index 64264f7f838f..39557ad401b6 100644 --- a/drivers/media/IR/keymaps/rc-rc6-mce.c +++ b/drivers/media/IR/keymaps/rc-rc6-mce.c @@ -19,6 +19,7 @@ static struct ir_scancode rc6_mce[] = { { 0x800f0416, KEY_PLAY }, { 0x800f0418, KEY_PAUSE }, + { 0x800f046e, KEY_PLAYPAUSE }, { 0x800f0419, KEY_STOP }, { 0x800f0417, KEY_RECORD }, @@ -37,6 +38,8 @@ static struct ir_scancode rc6_mce[] = { { 0x800f0411, KEY_VOLUMEDOWN }, { 0x800f0412, KEY_CHANNELUP }, { 0x800f0413, KEY_CHANNELDOWN }, + { 0x800f043a, KEY_BRIGHTNESSUP }, + { 0x800f0480, KEY_BRIGHTNESSDOWN }, { 0x800f0401, KEY_NUMERIC_1 }, { 0x800f0402, KEY_NUMERIC_2 }, -- cgit v1.2.2 From 90e12cec707204930934acdb5efce5f94a163a5f Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Tue, 7 Sep 2010 12:50:45 -0300 Subject: V4L/DVB: dib7770: enable the current mirror To improve performance on DiB7770-devices enabling the current mirror is needed. This patch adds an option to the dib7000p-driver to do that and it creates a separate device-entry in dib0700-device to use those changes on hardware which is using the DiB7770. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 53 ++++++++++++++++++++++++++++- drivers/media/dvb/frontends/dib7000p.c | 2 ++ drivers/media/dvb/frontends/dib7000p.h | 3 ++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index ce66c5a96ba8..385ce1c0a934 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -940,6 +940,57 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) return adap->fe == NULL ? -ENODEV : 0; } +/* STK7770P */ +static struct dib7000p_config dib7770p_dib7000p_config = { + .output_mpeg2_in_188_bytes = 1, + + .agc_config_count = 1, + .agc = &dib7070_agc_config, + .bw = &dib7070_bw_config_12_mhz, + .tuner_is_baseband = 1, + .spur_protect = 1, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .hostbus_diversity = 1, + .enable_current_mirror = 1, +}; + +static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct usb_device_descriptor *p = &adap->dev->udev->descriptor; + if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) && + p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E)) + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); + else + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + &dib7770p_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } + + adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + &dib7770p_dib7000p_config); + return adap->fe == NULL ? -ENODEV : 0; +} + /* DIB807x generic */ static struct dibx000_agc_config dib807x_agc_config[2] = { { @@ -2406,7 +2457,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, - .frontend_attach = stk7070p_frontend_attach, + .frontend_attach = stk7770p_frontend_attach, .tuner_attach = dib7770p_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 2e28b973dfd3..73f59ab06c86 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -260,6 +260,8 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad // dprintk( "908: %x, 909: %x\n", reg_908, reg_909); + reg_908 |= (state->cfg.enable_current_mirror & 1) << 7; + dib7000p_write_word(state, 908, reg_908); dib7000p_write_word(state, 909, reg_909); } diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 805dd13a97ee..04a744938cca 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -33,6 +33,9 @@ struct dib7000p_config { int (*agc_control) (struct dvb_frontend *, u8 before); u8 output_mode; + + u8 enable_current_mirror : 1; + }; #define DEFAULT_DIB7000P_I2C_ADDRESS 18 -- cgit v1.2.2 From 970d14c6cca8c71307a4d23fe373c5895175b2d7 Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Tue, 7 Sep 2010 12:50:46 -0300 Subject: V4L/DVB: dib7000p: add disable sample and hold, and diversity delay parameter This patch improves the overall driver performance in diversity-reception scenarios. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 1 + drivers/media/dvb/frontends/dib7000p.c | 6 +++++- drivers/media/dvb/frontends/dib7000p.h | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 385ce1c0a934..e06acd1fecb6 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -956,6 +956,7 @@ static struct dib7000p_config dib7770p_dib7000p_config = { .hostbus_diversity = 1, .enable_current_mirror = 1, + .disable_sample_and_hold = 0, }; static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap) diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 73f59ab06c86..3aed0d433921 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -260,6 +260,7 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad // dprintk( "908: %x, 909: %x\n", reg_908, reg_909); + reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4; reg_908 |= (state->cfg.enable_current_mirror & 1) << 7; dib7000p_write_word(state, 908, reg_908); @@ -780,7 +781,10 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte default: case GUARD_INTERVAL_1_32: value *= 1; break; } - state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO + if (state->cfg.diversity_delay == 0) + state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo + else + state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo /* deactive the possibility of diversity reception if extended interleaver */ state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 04a744938cca..da17345bf5bd 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -33,8 +33,10 @@ struct dib7000p_config { int (*agc_control) (struct dvb_frontend *, u8 before); u8 output_mode; + u8 disable_sample_and_hold : 1; u8 enable_current_mirror : 1; + u8 diversity_delay; }; -- cgit v1.2.2 From 3cdadc50bbe8f04c1231c8af614cafd7ddd622bf Mon Sep 17 00:00:00 2001 From: Richard Zidlicky Date: Tue, 24 Aug 2010 09:52:36 -0300 Subject: V4L/DVB: dvb: fix smscore_getbuffer() logic Drivers shouldn't sleep while holding a spinlock. A previous workaround were to release the spinlock before callinc schedule(). This patch uses a different approach: it just waits for the siano hardware to answer. Signed-off-by: Richard Zidlicky Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index d93468cd3a85..ff3b0fa901b3 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -1098,33 +1098,26 @@ EXPORT_SYMBOL_GPL(smscore_onresponse); * * @return pointer to descriptor on success, NULL on error. */ -struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) + +struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev) { struct smscore_buffer_t *cb = NULL; unsigned long flags; - DEFINE_WAIT(wait); - spin_lock_irqsave(&coredev->bufferslock, flags); - - /* This function must return a valid buffer, since the buffer list is - * finite, we check that there is an available buffer, if not, we wait - * until such buffer become available. - */ - - prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE); - if (list_empty(&coredev->buffers)) { - spin_unlock_irqrestore(&coredev->bufferslock, flags); - schedule(); - spin_lock_irqsave(&coredev->bufferslock, flags); + if (!list_empty(&coredev->buffers)) { + cb = (struct smscore_buffer_t *) coredev->buffers.next; + list_del(&cb->entry); } + spin_unlock_irqrestore(&coredev->bufferslock, flags); + return cb; +} - finish_wait(&coredev->buffer_mng_waitq, &wait); - - cb = (struct smscore_buffer_t *) coredev->buffers.next; - list_del(&cb->entry); +struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) +{ + struct smscore_buffer_t *cb = NULL; - spin_unlock_irqrestore(&coredev->bufferslock, flags); + wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev))); return cb; } -- cgit v1.2.2 From c10469c637602c2385e2993d8c730cc44fd47d23 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 11 Sep 2010 11:37:51 -0300 Subject: V4L/DVB: cx231xx: Avoid an OOPS when card is unknown (card=0) As reported by: Carlos Americo Domiciano : [ 220.033500] cx231xx v4l2 driver loaded. [ 220.033571] cx231xx #0: New device Conexant Corporation Polaris AV Capturb @ 480 Mbps (1554:5010) with 6 interfaces [ 220.033577] cx231xx #0: registering interface 0 [ 220.033591] cx231xx #0: registering interface 1 [ 220.033654] cx231xx #0: registering interface 6 [ 220.033910] cx231xx #0: Identified as Unknown CX231xx video grabber (card=0) [ 220.033946] BUG: unable to handle kernel NULL pointer dereference at (null) [ 220.033955] IP: [] cx231xx_pre_card_setup+0x5d/0xb0 [cx231xx] Thanks-to: Carlos Americo Domiciano Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx231xx/cx231xx-cards.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 5b7c9a948a0a..f2a4900014bc 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c @@ -229,14 +229,16 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) dev->board.name, dev->model); /* set the direction for GPIO pins */ - cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); - cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); - cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); + if (dev->board.tuner_gpio) { + cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); + cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); + cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); - /* request some modules if any required */ + /* request some modules if any required */ - /* reset the Tuner */ - cx231xx_gpio_set(dev, dev->board.tuner_gpio); + /* reset the Tuner */ + cx231xx_gpio_set(dev, dev->board.tuner_gpio); + } /* set the mode to Analog mode initially */ cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); -- cgit v1.2.2 From 2fc11536cf5c0b8eb4eb7e01a2a672a189e9280f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 7 Sep 2010 06:10:45 -0300 Subject: V4L/DVB: videobuf-dma-sg: set correct size in last sg element This fixes a nasty memory corruption bug when using userptr I/O. The function videobuf_pages_to_sg() sets up the scatter-gather list for the DMA transfer to the userspace pages. The first transfer is setup correctly (the size is set to PAGE_SIZE - offset), but all other transfers have size PAGE_SIZE. This is wrong for the last transfer which may be less than PAGE_SIZE. Most, if not all, drivers will program the boards DMA engine correctly, i.e. even though the size in the last sg element is wrong, they will do their own size calculations and make sure the right amount is DMA-ed, and so seemingly prevent memory corruption. However, behind the scenes the dynamic DMA mapping support (in lib/swiotlb.c) may create bounce buffers if the memory pages are not in DMA-able memory. This happens for example on a 64-bit linux with a board that only supports 32-bit DMA. These bounce buffers DO use the information in the sg list to determine the size. So while the DMA engine transfers the correct amount of data, when the data is 'bounced' back too much is copied, causing buffer overwrites. The fix is simple: calculate and set the correct size for the last sg list element. Signed-off-by: Hans Verkuil Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-dma-sg.c | 11 +++++++---- include/media/videobuf-dma-sg.h | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 06f9a9c2a39a..2ad0bc252b0e 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -94,7 +94,7 @@ err: * must free the memory. */ static struct scatterlist *videobuf_pages_to_sg(struct page **pages, - int nr_pages, int offset) + int nr_pages, int offset, size_t size) { struct scatterlist *sglist; int i; @@ -110,12 +110,14 @@ static struct scatterlist *videobuf_pages_to_sg(struct page **pages, /* DMA to highmem pages might not work */ goto highmem; sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset); + size -= PAGE_SIZE - offset; for (i = 1; i < nr_pages; i++) { if (NULL == pages[i]) goto nopage; if (PageHighMem(pages[i])) goto highmem; - sg_set_page(&sglist[i], pages[i], PAGE_SIZE, 0); + sg_set_page(&sglist[i], pages[i], min(PAGE_SIZE, size), 0); + size -= min(PAGE_SIZE, size); } return sglist; @@ -170,7 +172,8 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, first = (data & PAGE_MASK) >> PAGE_SHIFT; last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT; - dma->offset = data & ~PAGE_MASK; + dma->offset = data & ~PAGE_MASK; + dma->size = size; dma->nr_pages = last-first+1; dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL); if (NULL == dma->pages) @@ -252,7 +255,7 @@ int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma) if (dma->pages) { dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages, - dma->offset); + dma->offset, dma->size); } if (dma->vaddr) { dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr, diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h index 97e07f46a0fa..aa4ebb42a565 100644 --- a/include/media/videobuf-dma-sg.h +++ b/include/media/videobuf-dma-sg.h @@ -48,6 +48,7 @@ struct videobuf_dmabuf { /* for userland buffer */ int offset; + size_t size; struct page **pages; /* for kernel buffers */ -- cgit v1.2.2 From 04d174e99a6eca2f62b56c10ae1d7d0499d83e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Mon, 13 Sep 2010 05:22:37 -0300 Subject: V4L/DVB: gspca - sn9c20x: Bad transfer size of Bayer images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the end of frame marker does not contain any pixel, it must not be transferred. Reported-by: Ivo Jager Signed-off-by: Jean-François Moine Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sn9c20x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 83a718f0f3f9..9052d5702556 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -2357,8 +2357,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, (data[33] << 10); avg_lum >>= 9; atomic_set(&sd->avg_lum, avg_lum); - gspca_frame_add(gspca_dev, LAST_PACKET, - data, len); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); return; } if (gspca_dev->last_packet_type == LAST_PACKET) { -- cgit v1.2.2 From 1b376dac05058ac5c9616a507d95c19ea5ea2646 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Thu, 9 Sep 2010 14:45:22 -0300 Subject: V4L/DVB: tm6000: bugfix data handling Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-input.c | 61 ++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c index 32f7a0af6938..54f7667cc706 100644 --- a/drivers/staging/tm6000/tm6000-input.c +++ b/drivers/staging/tm6000/tm6000-input.c @@ -46,7 +46,7 @@ MODULE_PARM_DESC(enable_ir, "enable ir (default is enable"); } struct tm6000_ir_poll_result { - u8 rc_data[4]; + u16 rc_data; }; struct tm6000_IR { @@ -60,9 +60,9 @@ struct tm6000_IR { int polling; struct delayed_work work; u8 wait:1; + u8 key:1; struct urb *int_urb; u8 *urb_data; - u8 key:1; int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *); @@ -122,13 +122,14 @@ static void tm6000_ir_urb_received(struct urb *urb) if (urb->status != 0) printk(KERN_INFO "not ready\n"); - else if (urb->actual_length > 0) + else if (urb->actual_length > 0) { memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length); - dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], - ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); + dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], + ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); - ir->key = 1; + ir->key = 1; + } rc = usb_submit_urb(urb, GFP_ATOMIC); } @@ -140,30 +141,47 @@ static int default_polling_getkey(struct tm6000_IR *ir, int rc; u8 buf[2]; - if (ir->wait && !&dev->int_in) { - poll_result->rc_data[0] = 0xff; + if (ir->wait && !&dev->int_in) return 0; - } if (&dev->int_in) { - poll_result->rc_data[0] = ir->urb_data[0]; - poll_result->rc_data[1] = ir->urb_data[1]; + if (ir->ir.ir_type == IR_TYPE_RC5) + poll_result->rc_data = ir->urb_data[0]; + else + poll_result->rc_data = ir->urb_data[0] | ir->urb_data[1] << 8; } else { tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); msleep(10); tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); msleep(10); - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 1); + if (ir->ir.ir_type == IR_TYPE_RC5) { + rc = tm6000_read_write_usb(dev, USB_DIR_IN | + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + REQ_02_GET_IR_CODE, 0, 0, buf, 1); - msleep(10); + msleep(10); - dprintk("read data=%02x\n", buf[0]); - if (rc < 0) - return rc; + dprintk("read data=%02x\n", buf[0]); + if (rc < 0) + return rc; - poll_result->rc_data[0] = buf[0]; + poll_result->rc_data = buf[0]; + } else { + rc = tm6000_read_write_usb(dev, USB_DIR_IN | + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + REQ_02_GET_IR_CODE, 0, 0, buf, 2); + + msleep(10); + + dprintk("read data=%04x\n", buf[0] | buf[1] << 8); + if (rc < 0) + return rc; + + poll_result->rc_data = buf[0] | buf[1] << 8; + } + if ((poll_result->rc_data & 0x00ff) != 0xff) + ir->key = 1; } return 0; } @@ -180,12 +198,11 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir) return; } - dprintk("ir->get_key result data=%02x %02x\n", - poll_result.rc_data[0], poll_result.rc_data[1]); + dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); - if (poll_result.rc_data[0] != 0xff && ir->key == 1) { + if (ir->key) { ir_input_keydown(ir->input->input_dev, &ir->ir, - poll_result.rc_data[0] | poll_result.rc_data[1] << 8); + (u32)poll_result.rc_data); ir_input_nokey(ir->input->input_dev, &ir->ir); ir->key = 0; -- cgit v1.2.2 From 5384a12b23160e11ff949a94172051476d308b66 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Tue, 27 Jul 2010 09:06:07 -0300 Subject: V4L/DVB: mx2_camera: fix a race causing NULL dereference The mx25_camera_irq irq handler may get called after the camera has been deactivated (from mx2_camera_deactivate). Detect this situation, and bail out. Signed-off-by: Baruch Siach Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mx2_camera.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 66ff174151b5..b6ea67221d1d 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -378,6 +378,9 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, spin_lock_irqsave(&pcdev->lock, flags); + if (*fb_active == NULL) + goto out; + vb = &(*fb_active)->vb; dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); @@ -402,6 +405,7 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, *fb_active = buf; +out: spin_unlock_irqrestore(&pcdev->lock, flags); } -- cgit v1.2.2 From 6b6d33c746ace7bd0dbbdde674d3fb1100ab081d Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Tue, 3 Aug 2010 07:57:44 -0300 Subject: V4L/DVB: mt9m111: cropcap and s_crop check if type is VIDEO_CAPTURE Signed-off-by: Philipp Wiesner Signed-off-by: Michael Grzeschik Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mt9m111.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 758a4db27d65..28df1752202e 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -447,6 +447,9 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n", __func__, rect.left, rect.top, rect.width, rect.height); + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + ret = mt9m111_make_rect(client, &rect); if (!ret) mt9m111->rect = rect; @@ -466,12 +469,14 @@ static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) { + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + a->bounds.left = MT9M111_MIN_DARK_COLS; a->bounds.top = MT9M111_MIN_DARK_ROWS; a->bounds.width = MT9M111_MAX_WIDTH; a->bounds.height = MT9M111_MAX_HEIGHT; a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; a->pixelaspect.numerator = 1; a->pixelaspect.denominator = 1; -- cgit v1.2.2 From 01f5a394eac48b74c84434e95e74cd172b0682c3 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Tue, 3 Aug 2010 07:57:45 -0300 Subject: V4L/DVB: mt9m111: added current colorspace at g_fmt Signed-off-by: Michael Grzeschik Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mt9m111.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 28df1752202e..c71af4e0e517 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -492,6 +492,7 @@ static int mt9m111_g_fmt(struct v4l2_subdev *sd, mf->width = mt9m111->rect.width; mf->height = mt9m111->rect.height; mf->code = mt9m111->fmt->code; + mf->colorspace = mt9m111->fmt->colorspace; mf->field = V4L2_FIELD_NONE; return 0; -- cgit v1.2.2 From 23f0cb62ba3a1a11ab02cb0675f28befc56c89b9 Mon Sep 17 00:00:00 2001 From: Ionut Gabriel Popescu Date: Fri, 3 Sep 2010 18:20:41 -0300 Subject: V4L/DVB: mt9v022.c: Fixed compilation warning The drivers/media/video/mt9v022.c file, on line 405, tries a "case 0" o a v4l2_mbus_pixelcode enum which don't have an 0 value element, so I got a compile warning. That "case" is useless so it can be removed. Signed-off-by: Ionut Gabriel Popescu Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mt9v022.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index e7cd23cd6394..b48473c7896b 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -402,9 +402,6 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) return -EINVAL; break; - case 0: - /* No format change, only geometry */ - break; default: return -EINVAL; } -- cgit v1.2.2 From b17a200f923070104a5b97085ed09ba0f682f637 Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Fri, 10 Sep 2010 02:02:32 -0300 Subject: V4L/DVB: v4l: mem2mem_testdev: fix errorenous comparison Output buffer has to be at least the size of input buffer, not the other way around. Signed-off-by: Pawel Osciak Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mem2mem_testdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index 4525335f9bd4..d31ec2565056 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c @@ -239,7 +239,7 @@ static int device_process(struct m2mtest_ctx *ctx, return -EFAULT; } - if (in_buf->vb.size < out_buf->vb.size) { + if (in_buf->vb.size > out_buf->vb.size) { v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n"); return -EINVAL; } -- cgit v1.2.2 From 71088bad7426650e4ea5fb4182580ea8458442e7 Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Fri, 10 Sep 2010 02:05:48 -0300 Subject: V4L/DVB: v4l: mem2mem_testdev: add missing release for video_device Video device was not being released on driver remove. Signed-off-by: Pawel Osciak Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mem2mem_testdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index d31ec2565056..a7210d981388 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c @@ -1014,6 +1014,7 @@ static int m2mtest_remove(struct platform_device *pdev) v4l2_m2m_release(dev->m2m_dev); del_timer_sync(&dev->timer); video_unregister_device(dev->vfd); + video_device_release(dev->vfd); v4l2_device_unregister(&dev->v4l2_dev); kfree(dev); -- cgit v1.2.2 From fc00a1d90d7b64e44c2475833cc3021066f67ea7 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Thu, 16 Sep 2010 20:54:47 -0300 Subject: V4L/DVB: cx25840: Fix typo in volume control initialization: 65335 vs. 65535 The wrong value for the volume control limit, 65335 vs. 65535, prevents proper cx25840 v4l2_subdevice initialization. Reported-by: Igor M. liplianin Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 86ca8c2359dd..f5a3e74c3c7c 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1996,7 +1996,7 @@ static int cx25840_probe(struct i2c_client *client, state->volume = v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, - 0, 65335, 65535 / 100, default_volume); + 0, 65535, 65535 / 100, default_volume); state->mute = v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); -- cgit v1.2.2 From 405707985594169cfd0b1d97d29fcb4b4c6f2ac9 Mon Sep 17 00:00:00 2001 From: Dan Rosenberg Date: Wed, 15 Sep 2010 18:44:22 -0300 Subject: V4L/DVB: ivtvfb: prevent reading uninitialized stack memory The FBIOGET_VBLANK device ioctl allows unprivileged users to read 16 bytes of uninitialized stack memory, because the "reserved" member of the fb_vblank struct declared on the stack is not altered or zeroed before being copied back to the user. This patch takes care of it. Signed-off-by: Dan Rosenberg Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtvfb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index be03a712731c..f0316d02f09f 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -466,6 +466,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar struct fb_vblank vblank; u32 trace; + memset(&vblank, 0, sizeof(struct fb_vblank)); + vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC; trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16; -- cgit v1.2.2 From 9275b32bced808bd57bdf3884748ed1126ba90e0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 12 Sep 2010 08:31:29 -0300 Subject: V4L/DVB: uvcvideo: Fix support for Medion Akoya All-in-one PC integrated webcam The camera requires the STREAM_NO_FID quirk. Add a corresponding entry in the device IDs list. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 8bdd940f32e6..63756ca41539 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -2091,6 +2091,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_PROBE_DEF }, + /* IMC Networks (Medion Akoya) */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x13d3, + .idProduct = 0x5103, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_STREAM_NO_FID }, /* Syntek (HP Spartan) */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, -- cgit v1.2.2 From 86d8b6abbbc973a1dd7d3c8f9e3c3e06131703b2 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 16 Sep 2010 12:37:26 -0300 Subject: V4L/DVB: uvcvideo: Restrict frame rates for Chicony CNF7129 webcam At all frame rates except 30fps and 5fps the camera produces very dark pictures. Auto-exposure is probably disabled by the camera at all frame rates except 30fps, making them pretty unusable. Work around the problem by introducing a new RESTRICT_FRAME_RATE quirk that disables all the frame rates except the default one. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 15 +++++++++++++++ drivers/media/video/uvc/uvcvideo.h | 1 + 2 files changed, 16 insertions(+) diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 63756ca41539..2ac85d8984f0 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -486,6 +486,12 @@ static int uvc_parse_format(struct uvc_device *dev, max(frame->dwFrameInterval[0], frame->dwDefaultFrameInterval)); + if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) { + frame->bFrameIntervalType = 1; + frame->dwFrameInterval[0] = + frame->dwDefaultFrameInterval; + } + uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n", frame->wWidth, frame->wHeight, 10000000/frame->dwDefaultFrameInterval, @@ -2026,6 +2032,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceClass = USB_CLASS_VENDOR_SPEC, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0 }, + /* Chicony CNF7129 (Asus EEE 100HE) */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x04f2, + .idProduct = 0xb071, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_RESTRICT_FRAME_RATE }, /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index bdacf3beabf5..892e0e51916c 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -182,6 +182,7 @@ struct uvc_xu_control { #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 #define UVC_QUIRK_PROBE_DEF 0x00000100 +#define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 -- cgit v1.2.2 From 81c69fc200bfa2f3a8b2fed614d1c6670c4a7e14 Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Mon, 6 Sep 2010 03:53:43 -0300 Subject: V4L/DVB: v4l: s5p-fimc: Fix return value on probe() failure On failed create_workqueue() fimc_probe() was returning 0. Signed-off-by: Pawel Osciak Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 1beb2263d18c..8cd1ef073926 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -1415,8 +1415,10 @@ static int fimc_probe(struct platform_device *pdev) } fimc->work_queue = create_workqueue(dev_name(&fimc->pdev->dev)); - if (!fimc->work_queue) + if (!fimc->work_queue) { + ret = -ENOMEM; goto err_irq; + } ret = fimc_register_m2m_device(fimc); if (ret) -- cgit v1.2.2 From ddc79e0fdc16c05c3ff7f9b6ae9052bda0506108 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 6 Sep 2010 03:53:44 -0300 Subject: V4L/DVB: v4l: s5p-fimc: Fix 3-planar formats handling and pixel offset error on S5PV210 SoCs Fix DMA engine pixel offset calculation for 3-planar YUV formats. On S5PV210 SoCs horizontal offset is applied as number of pixels, not bytes per line. [mchehab@redhat.com: CodingStyle cleanup] Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-fimc/fimc-core.c | 87 ++++++++++++++------------------ 1 file changed, 37 insertions(+), 50 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 8cd1ef073926..6961c55baf9b 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -393,6 +393,37 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx) dbg("ctx->out_order_1p= %d", ctx->out_order_1p); } +static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) +{ + struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; + + f->dma_offset.y_h = f->offs_h; + if (!variant->pix_hoff) + f->dma_offset.y_h *= (f->fmt->depth >> 3); + + f->dma_offset.y_v = f->offs_v; + + f->dma_offset.cb_h = f->offs_h; + f->dma_offset.cb_v = f->offs_v; + + f->dma_offset.cr_h = f->offs_h; + f->dma_offset.cr_v = f->offs_v; + + if (!variant->pix_hoff) { + if (f->fmt->planes_cnt == 3) { + f->dma_offset.cb_h >>= 1; + f->dma_offset.cr_h >>= 1; + } + if (f->fmt->color == S5P_FIMC_YCBCR420) { + f->dma_offset.cb_v >>= 1; + f->dma_offset.cr_v >>= 1; + } + } + + dbg("in_offset: color= %d, y_h= %d, y_v= %d", + f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v); +} + /** * fimc_prepare_config - check dimensions, operation and color mode * and pre-calculate offset and the scaling coefficients. @@ -406,7 +437,6 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) { struct fimc_frame *s_frame, *d_frame; struct fimc_vid_buffer *buf = NULL; - struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; int ret = 0; s_frame = &ctx->s_frame; @@ -419,61 +449,16 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) swap(d_frame->width, d_frame->height); } - /* Prepare the output offset ratios for scaler. */ - d_frame->dma_offset.y_h = d_frame->offs_h; - if (!variant->pix_hoff) - d_frame->dma_offset.y_h *= (d_frame->fmt->depth >> 3); - - d_frame->dma_offset.y_v = d_frame->offs_v; + /* Prepare the DMA offset ratios for scaler. */ + fimc_prepare_dma_offset(ctx, &ctx->s_frame); + fimc_prepare_dma_offset(ctx, &ctx->d_frame); - d_frame->dma_offset.cb_h = d_frame->offs_h; - d_frame->dma_offset.cb_v = d_frame->offs_v; - - d_frame->dma_offset.cr_h = d_frame->offs_h; - d_frame->dma_offset.cr_v = d_frame->offs_v; - - if (!variant->pix_hoff && d_frame->fmt->planes_cnt == 3) { - d_frame->dma_offset.cb_h >>= 1; - d_frame->dma_offset.cb_v >>= 1; - d_frame->dma_offset.cr_h >>= 1; - d_frame->dma_offset.cr_v >>= 1; - } - - dbg("out offset: color= %d, y_h= %d, y_v= %d", - d_frame->fmt->color, - d_frame->dma_offset.y_h, d_frame->dma_offset.y_v); - - /* Prepare the input offset ratios for scaler. */ - s_frame->dma_offset.y_h = s_frame->offs_h; - if (!variant->pix_hoff) - s_frame->dma_offset.y_h *= (s_frame->fmt->depth >> 3); - s_frame->dma_offset.y_v = s_frame->offs_v; - - s_frame->dma_offset.cb_h = s_frame->offs_h; - s_frame->dma_offset.cb_v = s_frame->offs_v; - - s_frame->dma_offset.cr_h = s_frame->offs_h; - s_frame->dma_offset.cr_v = s_frame->offs_v; - - if (!variant->pix_hoff && s_frame->fmt->planes_cnt == 3) { - s_frame->dma_offset.cb_h >>= 1; - s_frame->dma_offset.cb_v >>= 1; - s_frame->dma_offset.cr_h >>= 1; - s_frame->dma_offset.cr_v >>= 1; - } - - dbg("in offset: color= %d, y_h= %d, y_v= %d", - s_frame->fmt->color, s_frame->dma_offset.y_h, - s_frame->dma_offset.y_v); - - fimc_set_yuv_order(ctx); - - /* Check against the scaler ratio. */ if (s_frame->height > (SCALER_MAX_VRATIO * d_frame->height) || s_frame->width > (SCALER_MAX_HRATIO * d_frame->width)) { err("out of scaler range"); return -EINVAL; } + fimc_set_yuv_order(ctx); } /* Input DMA mode is not allowed when the scaler is disabled. */ @@ -1495,6 +1480,7 @@ static struct samsung_fimc_variant fimc2_variant_s5p = { }; static struct samsung_fimc_variant fimc01_variant_s5pv210 = { + .pix_hoff = 1, .has_inp_rot = 1, .has_out_rot = 1, .min_inp_pixsize = 16, @@ -1509,6 +1495,7 @@ static struct samsung_fimc_variant fimc01_variant_s5pv210 = { }; static struct samsung_fimc_variant fimc2_variant_s5pv210 = { + .pix_hoff = 1, .min_inp_pixsize = 16, .min_out_pixsize = 32, -- cgit v1.2.2 From a08c7c68f702e2a2797a4035b6c0a756c4886c26 Mon Sep 17 00:00:00 2001 From: Brian Rogers Date: Wed, 22 Sep 2010 08:06:43 -0300 Subject: V4L/DVB: ir-core: Fix null dereferences in the protocols sysfs interface For some cards, ir_dev->props and ir_dev->raw are both NULL. These cards are using built-in IR decoding instead of raw, and can't easily be made to switch protocols. So upon reading /sys/class/rc/rc?/protocols on such a card, return 'builtin' as the supported and enabled protocol. Return -EINVAL on any attempts to change the protocol. And most important of all, don't crash. Signed-off-by: Brian Rogers Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/ir-sysfs.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index 96dafc425c8e..46d42467f9b4 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c @@ -67,13 +67,14 @@ static ssize_t show_protocols(struct device *d, char *tmp = buf; int i; - if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { enabled = ir_dev->rc_tab.ir_type; allowed = ir_dev->props->allowed_protos; - } else { + } else if (ir_dev->raw) { enabled = ir_dev->raw->enabled_protocols; allowed = ir_raw_get_allowed_protocols(); - } + } else + return sprintf(tmp, "[builtin]\n"); IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", (long long)allowed, @@ -121,10 +122,14 @@ static ssize_t store_protocols(struct device *d, int rc, i, count = 0; unsigned long flags; - if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) type = ir_dev->rc_tab.ir_type; - else + else if (ir_dev->raw) type = ir_dev->raw->enabled_protocols; + else { + IR_dprintk(1, "Protocol switching not supported\n"); + return -EINVAL; + } while ((tmp = strsep((char **) &data, " \n")) != NULL) { if (!*tmp) @@ -185,7 +190,7 @@ static ssize_t store_protocols(struct device *d, } } - if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); ir_dev->rc_tab.ir_type = type; spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); -- cgit v1.2.2 From b2b476f53a9d24b00a313adf7f6ca92515a2af54 Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Tue, 20 Jul 2010 13:49:16 -0300 Subject: V4L/DVB: v4l: videobuf: prevent passing a NULL to dma_free_coherent() When a driver that uses videobuf-dma-contig is used with the USERPTR memory access method a kernel oops might happen: a NULL address may be passed to dma_free_coherent(). This happens when an application calls REQBUFS and then exits without queuing any buffers. This patch fixes that bug. Signed-off-by: Pawel Osciak Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-dma-contig.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 372b87efcd05..6ff9e4bac3ea 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c @@ -393,8 +393,10 @@ void videobuf_dma_contig_free(struct videobuf_queue *q, } /* read() method */ - dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); - mem->vaddr = NULL; + if (mem->vaddr) { + dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); + mem->vaddr = NULL; + } } EXPORT_SYMBOL_GPL(videobuf_dma_contig_free); -- cgit v1.2.2 From cc6e853c5e49ea3698e87415672d818c6d7a5ee9 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Sun, 5 Sep 2010 02:42:33 -0300 Subject: V4L/DVB: v4l: radio: si470x: fix unneeded free_irq() call In case of error during probe() the driver calls free_irq() function on not yet allocated irq. This patches fixes the call sequence in case of the error. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si470x/radio-si470x-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 67a4ec8768a6..4ce541a5eb47 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -395,7 +395,7 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, radio->registers[POWERCFG] = POWERCFG_ENABLE; if (si470x_set_register(radio, POWERCFG) < 0) { retval = -EIO; - goto err_all; + goto err_video; } msleep(110); -- cgit v1.2.2 From 59bfee6e0682635c269fb271422e2595fa441c21 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 30 Sep 2010 14:14:22 +0200 Subject: i2c: Remove obsolete cleanup for clientdata A few new i2c-drivers came into the kernel which clear the clientdata-pointer on exit. This is obsolete meanwhile, so fix it and hope the word will spread. Signed-off-by: Wolfram Sang Acked-by: Mark Brown Signed-off-by: Jean Delvare --- drivers/misc/bh1780gli.c | 1 - drivers/regulator/ad5398.c | 1 - drivers/regulator/isl6271a-regulator.c | 2 -- drivers/rtc/rtc-ds3232.c | 2 -- 4 files changed, 6 deletions(-) diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c index 714c6b487313..d5f3a3fd2319 100644 --- a/drivers/misc/bh1780gli.c +++ b/drivers/misc/bh1780gli.c @@ -190,7 +190,6 @@ static int __devexit bh1780_remove(struct i2c_client *client) ddata = i2c_get_clientdata(client); sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group); - i2c_set_clientdata(client, NULL); kfree(ddata); return 0; diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index df1fb53c09d2..a4be41614eeb 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c @@ -256,7 +256,6 @@ static int __devexit ad5398_remove(struct i2c_client *client) regulator_unregister(chip->rdev); kfree(chip); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index d61ecb885a8c..b8cc6389a541 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -191,8 +191,6 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c) struct isl_pmic *pmic = i2c_get_clientdata(i2c); int i; - i2c_set_clientdata(i2c, NULL); - for (i = 0; i < 3; i++) regulator_unregister(pmic->rdev[i]); diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 9daed8db83d3..9de8516e3531 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -268,7 +268,6 @@ out_irq: free_irq(client->irq, client); out_free: - i2c_set_clientdata(client, NULL); kfree(ds3232); return ret; } @@ -287,7 +286,6 @@ static int __devexit ds3232_remove(struct i2c_client *client) } rtc_device_unregister(ds3232->rtc); - i2c_set_clientdata(client, NULL); kfree(ds3232); return 0; } -- cgit v1.2.2 From 753419f59e10d7181e43f0b9cc5beff43ef3f7a4 Mon Sep 17 00:00:00 2001 From: Vishwanath BS Date: Thu, 30 Sep 2010 14:14:22 +0200 Subject: i2c: Fix for suspend/resume issue In current i2c core driver, call to pm_runtime_set_active from i2c_device_pm_resume will unconditionally enable i2c module and increment child count of the parent. Because of this, in CPU Idle path, i2c does not idle, preventing Core to enter retention. Also i2c module will not be suspended upon system suspend as pm_runtime_set_suspended is not called from i2c_device_pm_suspend. This issue is fixed by removing pm_runtime_set_active call from resume path which is not necessary. This fix has been tested on OMAP4430. Signed-off-by: Partha Basak Signed-off-by: Vishwanath BS Acked-by: Rafael J. Wysocki Cc: Kevin Hilman Cc: Ben Dooks Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 6649176de940..13927d54cb4e 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -216,12 +216,6 @@ static int i2c_device_pm_resume(struct device *dev) else ret = i2c_legacy_resume(dev); - if (!ret) { - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - } - return ret; } -- cgit v1.2.2 From 6abb930af064fb1cf4177d32e2c7bfb89eee0fe5 Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Thu, 30 Sep 2010 14:14:22 +0200 Subject: i2c-pca: Fix waitforcompletion() return value ret is still -1, if during the polling read_byte() returns at once with I2C_PCA_CON_SI set. So ret > 0 would lead *_waitforcompletion() to return 0, in spite of the proper behavior. The routine was rewritten, so that ret has always a proper value, before returning. Signed-off-by: Yegor Yefremov Reviewed-by: Wolfram Sang Cc: stable@kernel.org Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-pca-isa.c | 12 ++++++++---- drivers/i2c/busses/i2c-pca-platform.c | 11 +++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index bbd77603a417..29933f87d8fa 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -71,8 +71,8 @@ static int pca_isa_readbyte(void *pd, int reg) static int pca_isa_waitforcompletion(void *pd) { - long ret = ~0; unsigned long timeout; + long ret; if (irq > -1) { ret = wait_event_timeout(pca_wait, @@ -81,11 +81,15 @@ static int pca_isa_waitforcompletion(void *pd) } else { /* Do polling */ timeout = jiffies + pca_isa_ops.timeout; - while (((pca_isa_readbyte(pd, I2C_PCA_CON) - & I2C_PCA_CON_SI) == 0) - && (ret = time_before(jiffies, timeout))) + do { + ret = time_before(jiffies, timeout); + if (pca_isa_readbyte(pd, I2C_PCA_CON) + & I2C_PCA_CON_SI) + break; udelay(100); + } while (ret); } + return ret > 0; } diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index ef5c78487eb7..5f6d7f89e225 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -80,8 +80,8 @@ static void i2c_pca_pf_writebyte32(void *pd, int reg, int val) static int i2c_pca_pf_waitforcompletion(void *pd) { struct i2c_pca_pf_data *i2c = pd; - long ret = ~0; unsigned long timeout; + long ret; if (i2c->irq) { ret = wait_event_timeout(i2c->wait, @@ -90,10 +90,13 @@ static int i2c_pca_pf_waitforcompletion(void *pd) } else { /* Do polling */ timeout = jiffies + i2c->adap.timeout; - while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) - & I2C_PCA_CON_SI) == 0) - && (ret = time_before(jiffies, timeout))) + do { + ret = time_before(jiffies, timeout); + if (i2c->algo_data.read_byte(i2c, I2C_PCA_CON) + & I2C_PCA_CON_SI) + break; udelay(100); + } while (ret); } return ret > 0; -- cgit v1.2.2 From 64b4782fc9e4bdc59ae90897e2258e4ec938690e Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 30 Sep 2010 14:14:22 +0200 Subject: i2c: Fix checks which cause legacy suspend to never get called For devices which are not adapted to runtime PM a call to pm_runtime_suspended always returns true. Hence the pm_runtime_suspended checks below prevent legacy suspend from getting called. So do a pm_runtime_suspended check only for devices with a dev_pm_ops populated (which hence do not rely on the legacy suspend.) Signed-off-by: Rajendra Nayak Acked-by: Rafael J. Wysocki Cc: Ben Dooks Cc: Mark Brown Cc: Kevin Hilman Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 13927d54cb4e..9b3cac13a4a8 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -197,11 +197,12 @@ static int i2c_device_pm_suspend(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - if (pm_runtime_suspended(dev)) - return 0; - - if (pm) - return pm->suspend ? pm->suspend(dev) : 0; + if (pm) { + if (pm_runtime_suspended(dev)) + return 0; + else + return pm->suspend ? pm->suspend(dev) : 0; + } return i2c_legacy_suspend(dev, PMSG_SUSPEND); } @@ -223,11 +224,12 @@ static int i2c_device_pm_freeze(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - if (pm_runtime_suspended(dev)) - return 0; - - if (pm) - return pm->freeze ? pm->freeze(dev) : 0; + if (pm) { + if (pm_runtime_suspended(dev)) + return 0; + else + return pm->freeze ? pm->freeze(dev) : 0; + } return i2c_legacy_suspend(dev, PMSG_FREEZE); } @@ -236,11 +238,12 @@ static int i2c_device_pm_thaw(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - if (pm_runtime_suspended(dev)) - return 0; - - if (pm) - return pm->thaw ? pm->thaw(dev) : 0; + if (pm) { + if (pm_runtime_suspended(dev)) + return 0; + else + return pm->thaw ? pm->thaw(dev) : 0; + } return i2c_legacy_resume(dev); } @@ -249,11 +252,12 @@ static int i2c_device_pm_poweroff(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - if (pm_runtime_suspended(dev)) - return 0; - - if (pm) - return pm->poweroff ? pm->poweroff(dev) : 0; + if (pm) { + if (pm_runtime_suspended(dev)) + return 0; + else + return pm->poweroff ? pm->poweroff(dev) : 0; + } return i2c_legacy_suspend(dev, PMSG_HIBERNATE); } -- cgit v1.2.2 From 925bb9c649cf8d7200549b395f2ae291833dd494 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 30 Sep 2010 14:14:23 +0200 Subject: of/i2c: Fix module load order issue caused by of_i2c.c Commit 959e85f7, "i2c: add OF-style registration and binding" caused a module dependency loop where of_i2c.c calls functions in i2c-core, and i2c-core calls of_i2c_register_devices() in of_i2c. This means that when i2c support is built as a module when CONFIG_OF is set, then neither i2c_core nor of_i2c are able to be loaded. This patch fixes the problem by moving the of_i2c_register_devices() calls back into the device drivers. Device drivers already specifically request the core code to parse the device tree for devices anyway by setting the of_node pointer, so it isn't a big deal to also call the registration function. The drivers just become slightly more verbose. Signed-off-by: Grant Likely Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-cpm.c | 5 +++++ drivers/i2c/busses/i2c-ibm_iic.c | 3 +++ drivers/i2c/busses/i2c-mpc.c | 1 + drivers/i2c/i2c-core.c | 4 ---- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index f7bd2613cecc..f2de3be35df3 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -677,6 +677,11 @@ static int __devinit cpm_i2c_probe(struct platform_device *ofdev, dev_dbg(&ofdev->dev, "hw routines for %s registered.\n", cpm->adap.name); + /* + * register OF I2C devices + */ + of_i2c_register_devices(&cpm->adap); + return 0; out_shut: cpm_i2c_shutdown(cpm); diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 43ca32fddde2..89eedf45d30e 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -761,6 +761,9 @@ static int __devinit iic_probe(struct platform_device *ofdev, dev_info(&ofdev->dev, "using %s mode\n", dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); + /* Now register all the child nodes */ + of_i2c_register_devices(adap); + return 0; error_cleanup: diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index a1c419a716af..b74e6dc6886c 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -632,6 +632,7 @@ static int __devinit fsl_i2c_probe(struct platform_device *op, dev_err(i2c->dev, "failed to add adapter\n"); goto fail_add; } + of_i2c_register_devices(&i2c->adap); return result; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 9b3cac13a4a8..bea4c5021d26 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -874,9 +873,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap) if (adap->nr < __i2c_first_dynamic_bus_num) i2c_scan_static_board_info(adap); - /* Register devices from the device tree */ - of_i2c_register_devices(adap); - /* Notify drivers */ mutex_lock(&core_lock); bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter); -- cgit v1.2.2 From 8c462b6047da80491b8cb6be878e8bf9313ac3e1 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Tue, 24 Aug 2010 15:35:42 -0700 Subject: Bluetooth: Only enable L2CAP FCS for ERTM or streaming This fixes a bug which caused the FCS setting to show L2CAP_FCS_CRC16 with L2CAP modes other than ERTM or streaming. At present, this only affects the FCS value shown with getsockopt() for basic mode. Signed-off-by: Mat Martineau Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index fadf26b4ed7c..c7847035562b 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -3071,6 +3071,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd return 0; } +static inline void set_default_fcs(struct l2cap_pinfo *pi) +{ + /* FCS is enabled only in ERTM or streaming mode, if one or both + * sides request it. + */ + if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING) + pi->fcs = L2CAP_FCS_NONE; + else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV)) + pi->fcs = L2CAP_FCS_CRC16; +} + static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; @@ -3135,9 +3146,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr goto unlock; if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { - if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || - l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) - l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; + set_default_fcs(l2cap_pi(sk)); sk->sk_state = BT_CONNECTED; @@ -3225,9 +3234,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { - if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || - l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) - l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; + set_default_fcs(l2cap_pi(sk)); sk->sk_state = BT_CONNECTED; l2cap_pi(sk)->next_tx_seq = 0; -- cgit v1.2.2 From 8183b775bc5b79b6b1e250019c9dd930554dfa94 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 1 Sep 2010 15:17:25 +0300 Subject: Bluetooth: fix MTU L2CAP configuration parameter When receiving L2CAP negative configuration response with respect to MTU parameter we modify wrong field. MTU here means proposed value of MTU that the remote device intends to transmit. So for local L2CAP socket it is pi->imtu. Signed-off-by: Andrei Emeltchenko Acked-by: Ville Tervo Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index c7847035562b..9fad312e53f2 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -2771,10 +2771,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, case L2CAP_CONF_MTU: if (val < L2CAP_DEFAULT_MIN_MTU) { *result = L2CAP_CONF_UNACCEPT; - pi->omtu = L2CAP_DEFAULT_MIN_MTU; + pi->imtu = L2CAP_DEFAULT_MIN_MTU; } else - pi->omtu = val; - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); + pi->imtu = val; + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); break; case L2CAP_CONF_FLUSH_TO: -- cgit v1.2.2 From ccbb84af28594e19fd4bf27ff2828c80d03b6081 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 30 Aug 2010 18:44:44 -0300 Subject: Bluetooth: Simplify L2CAP Streaming mode sending As we don't have any error control on the Streaming mode, i.e., we don't need to keep a copy of the skb for later resending we don't need to call skb_clone() on it. Then we can go one further here, and dequeue the skb before sending it, that also means we don't need to look to sk->sk_send_head anymore. The patch saves memory and time when sending Streaming mode data, so it is good to mainline. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 9fad312e53f2..f2062aace406 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1441,33 +1441,23 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) static void l2cap_streaming_send(struct sock *sk) { - struct sk_buff *skb, *tx_skb; + struct sk_buff *skb; struct l2cap_pinfo *pi = l2cap_pi(sk); u16 control, fcs; - while ((skb = sk->sk_send_head)) { - tx_skb = skb_clone(skb, GFP_ATOMIC); - - control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); + while ((skb = skb_dequeue(TX_QUEUE(sk)))) { + control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; - put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); + put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); if (pi->fcs == L2CAP_FCS_CRC16) { - fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); - put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); + fcs = crc16(0, (u8 *)skb->data, skb->len - 2); + put_unaligned_le16(fcs, skb->data + skb->len - 2); } - l2cap_do_send(sk, tx_skb); + l2cap_do_send(sk, skb); pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; - - if (skb_queue_is_last(TX_QUEUE(sk), skb)) - sk->sk_send_head = NULL; - else - sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb); - - skb = skb_dequeue(TX_QUEUE(sk)); - kfree_skb(skb); } } -- cgit v1.2.2 From fad003b6c8e3d944d4453fd569b0702ef1af82b3 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Sat, 14 Aug 2010 00:48:07 -0300 Subject: Bluetooth: Fix inconsistent lock state with RFCOMM When receiving a rfcomm connection with the old dund deamon a inconsistent lock state happens. That's because interrupts were already disabled by l2cap_conn_start() when rfcomm_sk_state_change() try to lock the spin_lock. As result we may have a inconsistent lock state for l2cap_conn_start() after rfcomm_sk_state_change() calls bh_lock_sock() and disable interrupts as well. [ 2833.151999] [ 2833.151999] ================================= [ 2833.151999] [ INFO: inconsistent lock state ] [ 2833.151999] 2.6.36-rc3 #2 [ 2833.151999] --------------------------------- [ 2833.151999] inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage. [ 2833.151999] krfcommd/2306 [HC0[0]:SC0[0]:HE1:SE1] takes: [ 2833.151999] (slock-AF_BLUETOOTH){+.?...}, at: [] rfcomm_sk_state_change+0x46/0x170 [rfcomm] [ 2833.151999] {IN-SOFTIRQ-W} state was registered at: [ 2833.151999] [] __lock_acquire+0x5b6/0x1560 [ 2833.151999] [] lock_acquire+0x5a/0x70 [ 2833.151999] [] _raw_spin_lock+0x2c/0x40 [ 2833.151999] [] l2cap_conn_start+0x92/0x640 [l2cap] [ 2833.151999] [] l2cap_sig_channel+0x6bf/0x1320 [l2cap] [ 2833.151999] [] l2cap_recv_frame+0x133/0x770 [l2cap] [ 2833.151999] [] l2cap_recv_acldata+0x1cb/0x390 [l2cap] [ 2833.151999] [] hci_rx_task+0x2ab/0x450 [bluetooth] [ 2833.151999] [] tasklet_action+0xcb/0xe0 [ 2833.151999] [] __do_softirq+0xae/0x150 [ 2833.151999] [] call_softirq+0x1c/0x30 [ 2833.151999] [] do_softirq+0x75/0xb0 [ 2833.151999] [] irq_exit+0x8d/0xa0 [ 2833.151999] [] smp_apic_timer_interrupt+0x6b/0xa0 [ 2833.151999] [] apic_timer_interrupt+0x13/0x20 [ 2833.151999] [] cpu_idle+0x5a/0xb0 [ 2833.151999] [] rest_init+0xad/0xc0 [ 2833.151999] [] start_kernel+0x2dd/0x2e8 [ 2833.151999] [] x86_64_start_reservations+0xf6/0xfa [ 2833.151999] [] x86_64_start_kernel+0xe4/0xeb [ 2833.151999] irq event stamp: 731 [ 2833.151999] hardirqs last enabled at (731): [] local_bh_enable_ip+0x82/0xe0 [ 2833.151999] hardirqs last disabled at (729): [] __do_softirq+0xce/0x150 [ 2833.151999] softirqs last enabled at (730): [] __do_softirq+0xfe/0x150 [ 2833.151999] softirqs last disabled at (711): [] call_softirq+0x1c/0x30 [ 2833.151999] [ 2833.151999] other info that might help us debug this: [ 2833.151999] 2 locks held by krfcommd/2306: [ 2833.151999] #0: (rfcomm_mutex){+.+.+.}, at: [] rfcomm_run+0x174/0xb20 [rfcomm] [ 2833.151999] #1: (&(&d->lock)->rlock){+.+...}, at: [] rfcomm_dlc_accept+0x53/0x100 [rfcomm] [ 2833.151999] [ 2833.151999] stack backtrace: [ 2833.151999] Pid: 2306, comm: krfcommd Tainted: G W 2.6.36-rc3 #2 [ 2833.151999] Call Trace: [ 2833.151999] [] print_usage_bug+0x171/0x180 [ 2833.151999] [] mark_lock+0x333/0x400 [ 2833.151999] [] __lock_acquire+0x63a/0x1560 [ 2833.151999] [] ? __lock_acquire+0xb25/0x1560 [ 2833.151999] [] lock_acquire+0x5a/0x70 [ 2833.151999] [] ? rfcomm_sk_state_change+0x46/0x170 [rfcomm] [ 2833.151999] [] _raw_spin_lock+0x2c/0x40 [ 2833.151999] [] ? rfcomm_sk_state_change+0x46/0x170 [rfcomm] [ 2833.151999] [] rfcomm_sk_state_change+0x46/0x170 [rfcomm] [ 2833.151999] [] rfcomm_dlc_accept+0x69/0x100 [rfcomm] [ 2833.151999] [] rfcomm_check_accept+0x59/0xd0 [rfcomm] [ 2833.151999] [] rfcomm_recv_frame+0x9fb/0x1320 [rfcomm] [ 2833.151999] [] ? _raw_spin_unlock_irqrestore+0x3b/0x60 [ 2833.151999] [] ? trace_hardirqs_on_caller+0x13d/0x180 [ 2833.151999] [] ? trace_hardirqs_on+0xd/0x10 [ 2833.151999] [] rfcomm_run+0x221/0xb20 [rfcomm] [ 2833.151999] [] ? schedule+0x287/0x780 [ 2833.151999] [] ? rfcomm_run+0x0/0xb20 [rfcomm] [ 2833.151999] [] kthread+0x96/0xa0 [ 2833.151999] [] kernel_thread_helper+0x4/0x10 [ 2833.151999] [] ? restore_args+0x0/0x30 [ 2833.151999] [] ? kthread+0x0/0xa0 [ 2833.151999] [] ? kernel_thread_helper+0x0/0x10 Signed-off-by: Gustavo F. Padovan --- net/bluetooth/rfcomm/sock.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 44a623275951..194b3a04cfd3 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -82,11 +82,14 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb) static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) { struct sock *sk = d->owner, *parent; + unsigned long flags; + if (!sk) return; BT_DBG("dlc %p state %ld err %d", d, d->state, err); + local_irq_save(flags); bh_lock_sock(sk); if (err) @@ -108,6 +111,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) } bh_unlock_sock(sk); + local_irq_restore(flags); if (parent && sock_flag(sk, SOCK_ZAPPED)) { /* We have to drop DLC lock here, otherwise -- cgit v1.2.2 From b0239c80fe89d5832a68a0f3121a9d5ec9fb763e Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Wed, 8 Sep 2010 14:59:44 -0300 Subject: Revert "Bluetooth: Don't accept ConfigReq if we aren't in the BT_CONFIG state" This reverts commit 8cb8e6f1684be13b51f8429b15f39c140326b327. That commit introduced a regression with the Bluetooth Profile Tuning Suite(PTS), Reverting this make sure that L2CAP is in a qualificable state. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index f2062aace406..44a8fb0d6c29 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -3089,14 +3089,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (!sk) return -ENOENT; - if (sk->sk_state != BT_CONFIG) { - struct l2cap_cmd_rej rej; - - rej.reason = cpu_to_le16(0x0002); - l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, - sizeof(rej), &rej); + if (sk->sk_state == BT_DISCONN) goto unlock; - } /* Reject if config buffer is too small. */ len = cmd_len - sizeof(*req); -- cgit v1.2.2 From e454c844644683571617896ab2a4ce0109c1943e Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Tue, 21 Sep 2010 16:31:11 -0300 Subject: Bluetooth: Fix deadlock in the ERTM logic The Enhanced Retransmission Mode(ERTM) is a realiable mode of operation of the Bluetooth L2CAP layer. Think on it like a simplified version of TCP. The problem we were facing here was a deadlock. ERTM uses a backlog queue to queue incomimg packets while the user is helding the lock. At some moment the sk_sndbuf can be exceeded and we can't alloc new skbs then the code sleep with the lock to wait for memory, that stalls the ERTM connection once we can't read the acknowledgements packets in the backlog queue to free memory and make the allocation of outcoming skb successful. This patch actually affect all users of bt_skb_send_alloc(), i.e., all L2CAP modes and SCO. We are safe against socket states changes or channels deletion while the we are sleeping wait memory. Checking for the sk->sk_err and sk->sk_shutdown make the code safe, since any action that can leave the socket or the channel in a not usable state set one of the struct members at least. Then we can check both of them when getting the lock again and return with the proper error if something unexpected happens. Signed-off-by: Gustavo F. Padovan Signed-off-by: Ulisses Furquim --- include/net/bluetooth/bluetooth.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 27a902d9b3a9..30fce0128dd7 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -161,12 +161,30 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l { struct sk_buff *skb; + release_sock(sk); if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) { skb_reserve(skb, BT_SKB_RESERVE); bt_cb(skb)->incoming = 0; } + lock_sock(sk); + + if (!skb && *err) + return NULL; + + *err = sock_error(sk); + if (*err) + goto out; + + if (sk->sk_shutdown) { + *err = -ECONNRESET; + goto out; + } return skb; + +out: + kfree_skb(skb); + return NULL; } int bt_err(__u16 code); -- cgit v1.2.2 From c1e0ddbf0a97e1704d7f13b4934f9acca002402d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 17 Sep 2010 23:26:24 -0700 Subject: ACPI: Handle ACPI0007 Device in acpi_early_set_pdc After | commit d8191fa4a33fdc817277da4f2b7f771ff605a41c | Author: Alex Chiang | Date: Mon Feb 22 12:11:39 2010 -0700 | | ACPI: processor: driver doesn't need to evaluate _PDC | | Now that the early _PDC evaluation path knows how to correctly | evaluate _PDC on only physically present processors, there's no | need for the processor driver to evaluate it later when it loads. | | To cover the hotplug case, push _PDC evaluation down into the | hotplug paths. only cpu with Processor Statement get processed with _PDC If bios is using Device object instead of Processor statement. SSDTs for Pstate/Cstate/Tstate can not be loaded dynamically. Need to try to scan ACPI0007 in addition to Processor. That commit is between 2.6.34-rc1 and 2.6.34-rc2, so stable tree for 2.6.34+ need this patch. Signed-off-by: Yinghai Lu Reviewed-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/processor_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index e9699aaed109..df6e1676a6f3 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -352,4 +352,5 @@ void __init acpi_early_processor_set_pdc(void) acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, early_init_pdc, NULL, NULL, NULL); + acpi_get_devices("ACPI0007", early_init_pdc, NULL, NULL); } -- cgit v1.2.2 From 3deb11ef16632fb76daead0db281f6f7d19332f2 Mon Sep 17 00:00:00 2001 From: "Lee, Chun-Yi" Date: Fri, 1 Oct 2010 16:28:29 +0800 Subject: ACPI: add DMI to disable AML Vista compatibility on MSI GX723 Notebook The brightness control hotkey don't work with Vista compatibility because the MSI GX723 includes an infinite while loop in DSDT when brightness control hotkey pressed. The MSI GX723 uses Nvidia video. Perhaps the loop is specific to the Nvidia Vista driver... This patch should be reverted once nouveau grows support to call the ACPI NVIF method. Signed-off-by: Lee, Chun-Yi Signed-off-by: Len Brown --- drivers/acpi/blacklist.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 2bb28b9d91c4..47cb4cb1f377 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -202,6 +202,23 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, }, { + /* + * There have a NVIF method in MSI GX723 DSDT need call by Nvidia + * driver (e.g. nouveau) when user press brightness hotkey. + * Currently, nouveau driver didn't do the job and it causes there + * have a infinite while loop in DSDT when user press hotkey. + * We add MSI GX723's dmi information to this table for workaround + * this issue. + * Will remove MSI GX723 from the table after nouveau grows support. + */ + .callback = dmi_disable_osi_vista, + .ident = "MSI GX723", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), + DMI_MATCH(DMI_PRODUCT_NAME, "GX723"), + }, + }, + { .callback = dmi_disable_osi_vista, .ident = "Sony VGN-NS10J_S", .matches = { -- cgit v1.2.2 From ae878ae280bea286ff2b1e1cb6e609dd8cb4501d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Sun, 3 Oct 2010 14:49:00 -0700 Subject: net: Fix IPv6 PMTU disc. w/ asymmetric routes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maciej Żenczykowski Signed-off-by: David S. Miller --- net/ipv6/route.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8323136bdc54..a275c6e1e25c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1556,14 +1556,13 @@ out: * i.e. Path MTU discovery */ -void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, - struct net_device *dev, u32 pmtu) +static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr, + struct net *net, u32 pmtu, int ifindex) { struct rt6_info *rt, *nrt; - struct net *net = dev_net(dev); int allfrag = 0; - rt = rt6_lookup(net, daddr, saddr, dev->ifindex, 0); + rt = rt6_lookup(net, daddr, saddr, ifindex, 0); if (rt == NULL) return; @@ -1631,6 +1630,27 @@ out: dst_release(&rt->dst); } +void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, + struct net_device *dev, u32 pmtu) +{ + struct net *net = dev_net(dev); + + /* + * RFC 1981 states that a node "MUST reduce the size of the packets it + * is sending along the path" that caused the Packet Too Big message. + * Since it's not possible in the general case to determine which + * interface was used to send the original packet, we update the MTU + * on the interface that will be used to send future packets. We also + * update the MTU on the interface that received the Packet Too Big in + * case the original packet was forced out that interface with + * SO_BINDTODEVICE or similar. This is the next best thing to the + * correct behaviour, which would be to update the MTU on all + * interfaces. + */ + rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0); + rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex); +} + /* * Misc support functions */ -- cgit v1.2.2 From 482964e56e1320cb7952faa1932d8ecf59c4bf75 Mon Sep 17 00:00:00 2001 From: Nagendra Tomar Date: Sat, 2 Oct 2010 23:45:06 +0000 Subject: net: Fix the condition passed to sk_wait_event() This patch fixes the condition (3rd arg) passed to sk_wait_event() in sk_stream_wait_memory(). The incorrect check in sk_stream_wait_memory() causes the following soft lockup in tcp_sendmsg() when the global tcp memory pool has exhausted. >>> snip <<< localhost kernel: BUG: soft lockup - CPU#3 stuck for 11s! [sshd:6429] localhost kernel: CPU 3: localhost kernel: RIP: 0010:[sk_stream_wait_memory+0xcd/0x200] [sk_stream_wait_memory+0xcd/0x200] sk_stream_wait_memory+0xcd/0x200 localhost kernel: localhost kernel: Call Trace: localhost kernel: [sk_stream_wait_memory+0x1b1/0x200] sk_stream_wait_memory+0x1b1/0x200 localhost kernel: [] autoremove_wake_function+0x0/0x40 localhost kernel: [ipv6:tcp_sendmsg+0x6e6/0xe90] tcp_sendmsg+0x6e6/0xce0 localhost kernel: [sock_aio_write+0x126/0x140] sock_aio_write+0x126/0x140 localhost kernel: [xfs:do_sync_write+0xf1/0x130] do_sync_write+0xf1/0x130 localhost kernel: [] autoremove_wake_function+0x0/0x40 localhost kernel: [hrtimer_start+0xe3/0x170] hrtimer_start+0xe3/0x170 localhost kernel: [vfs_write+0x185/0x190] vfs_write+0x185/0x190 localhost kernel: [sys_write+0x50/0x90] sys_write+0x50/0x90 localhost kernel: [system_call+0x7e/0x83] system_call+0x7e/0x83 >>> snip <<< What is happening is, that the sk_wait_event() condition passed from sk_stream_wait_memory() evaluates to true for the case of tcp global memory exhaustion. This is because both sk_stream_memory_free() and vm_wait are true which causes sk_wait_event() to *not* call schedule_timeout(). Hence sk_stream_wait_memory() returns immediately to the caller w/o sleeping. This causes the caller to again try allocation, which again fails and again calls sk_stream_wait_memory(), and so on. [ Bug introduced by commit c1cbe4b7ad0bc4b1d98ea708a3fecb7362aa4088 ("[NET]: Avoid atomic xchg() for non-error case") -DaveM ] Signed-off-by: Nagendra Singh Tomar Signed-off-by: David S. Miller --- net/core/stream.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/core/stream.c b/net/core/stream.c index d959e0f41528..f5df85dcd20b 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -141,10 +141,10 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); sk->sk_write_pending++; - sk_wait_event(sk, ¤t_timeo, !sk->sk_err && - !(sk->sk_shutdown & SEND_SHUTDOWN) && - sk_stream_memory_free(sk) && - vm_wait); + sk_wait_event(sk, ¤t_timeo, sk->sk_err || + (sk->sk_shutdown & SEND_SHUTDOWN) || + (sk_stream_memory_free(sk) && + !vm_wait)); sk->sk_write_pending--; if (vm_wait) { -- cgit v1.2.2 From c5d3557103f8bef81d7a150ab9cc970099cd58a2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 3 Oct 2010 15:37:42 +0000 Subject: Revert "ipv4: Make INET_LRO a bool instead of tristate." This reverts commit e81963b180ac502fda0326edf059b1e29cdef1a2. LRO is now deprecated in favour of GRO, and only a few drivers use it, so it is desirable to build it as a module in distribution kernels. The original change to prevent building it as a module was made in an attempt to avoid the case where some dependents are set to y and some to m, and INET_LRO can be set to m rather than y. However, the Kconfig system will reliably set INET_LRO=y in this case. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- net/ipv4/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 72380a30d1c8..7cd7760144f7 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -413,7 +413,7 @@ config INET_XFRM_MODE_BEET If unsure, say Y. config INET_LRO - bool "Large Receive Offload (ipv4/tcp)" + tristate "Large Receive Offload (ipv4/tcp)" default y ---help--- Support for Large Receive Offload (ipv4/tcp). -- cgit v1.2.2 From 10ccff62bd3de7a64cf98f4c37ec0414b8affd4f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 3 Oct 2010 15:42:05 +0000 Subject: netdev: Depend on INET before selecting INET_LRO Since 'select' ignores dependencies, drivers that select INET_LRO must depend on INET. This fixes the broken configuration reported in . Reported-by: Subrata Modak Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2cc81a54cbf3..5db667c0b371 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2428,7 +2428,7 @@ config UGETH_TX_ON_DEMAND config MV643XX_ETH tristate "Marvell Discovery (643XX) and Orion ethernet support" - depends on MV64X60 || PPC32 || PLAT_ORION + depends on (MV64X60 || PPC32 || PLAT_ORION) && INET select INET_LRO select PHYLIB help @@ -2803,7 +2803,7 @@ config NIU config PASEMI_MAC tristate "PA Semi 1/10Gbit MAC" - depends on PPC_PASEMI && PCI + depends on PPC_PASEMI && PCI && INET select PHYLIB select INET_LRO help -- cgit v1.2.2 From 5b7c84066733c5dfb0e4016d939757b38de189e4 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Thu, 30 Sep 2010 14:29:40 +0000 Subject: ipv4: correct IGMP behavior on v3 query during v2-compatibility mode A recent patch to allow IGMPv2 responses to IGMPv3 queries bypasses length checks for valid query lengths, incorrectly resets the v2_seen timer, and does not support IGMPv1. The following patch responds with a v2 report as required by IGMPv2 while correcting the other problems introduced by the patch. Signed-Off-By: David L Stevens Signed-off-by: David S. Miller --- net/ipv4/igmp.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 1fdcacd36ce7..2a4bb76f2132 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -834,7 +834,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, int mark = 0; - if (len == 8 || IGMP_V2_SEEN(in_dev)) { + if (len == 8) { if (ih->code == 0) { /* Alas, old v1 router presents here. */ @@ -856,6 +856,18 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, igmpv3_clear_delrec(in_dev); } else if (len < 12) { return; /* ignore bogus packet; freed by caller */ + } else if (IGMP_V1_SEEN(in_dev)) { + /* This is a v3 query with v1 queriers present */ + max_delay = IGMP_Query_Response_Interval; + group = 0; + } else if (IGMP_V2_SEEN(in_dev)) { + /* this is a v3 query with v2 queriers present; + * Interpretation of the max_delay code is problematic here. + * A real v2 host would use ih_code directly, while v3 has a + * different encoding. We use the v3 encoding as more likely + * to be intended in a v3 query. + */ + max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE); } else { /* v3 */ if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) return; -- cgit v1.2.2 From d7e0d19aa0fdd22819d35db551bd54c1bcf9c2aa Mon Sep 17 00:00:00 2001 From: Dan Rosenberg Date: Fri, 1 Oct 2010 11:16:58 +0000 Subject: sctp: prevent reading out-of-bounds memory Two user-controlled allocations in SCTP are subsequently dereferenced as sockaddr structs, without checking if the dereferenced struct members fall beyond the end of the allocated chunk. There doesn't appear to be any information leakage here based on how these members are used and additional checking, but it's still worth fixing. [akpm@linux-foundation.org: remove unfashionable newlines, fix gmail tab->space conversion] Signed-off-by: Dan Rosenberg Acked-by: Vlad Yasevich Cc: David Miller Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- net/sctp/socket.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ca44917872d2..fbb70770ad05 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -916,6 +916,11 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, /* Walk through the addrs buffer and count the number of addresses. */ addr_buf = kaddrs; while (walk_size < addrs_size) { + if (walk_size + sizeof(sa_family_t) > addrs_size) { + kfree(kaddrs); + return -EINVAL; + } + sa_addr = (struct sockaddr *)addr_buf; af = sctp_get_af_specific(sa_addr->sa_family); @@ -1002,9 +1007,13 @@ static int __sctp_connect(struct sock* sk, /* Walk through the addrs buffer and count the number of addresses. */ addr_buf = kaddrs; while (walk_size < addrs_size) { + if (walk_size + sizeof(sa_family_t) > addrs_size) { + err = -EINVAL; + goto out_free; + } + sa_addr = (union sctp_addr *)addr_buf; af = sctp_get_af_specific(sa_addr->sa.sa_family); - port = ntohs(sa_addr->v4.sin_port); /* If the address family is not supported or if this address * causes the address buffer to overflow return EINVAL. @@ -1014,6 +1023,8 @@ static int __sctp_connect(struct sock* sk, goto out_free; } + port = ntohs(sa_addr->v4.sin_port); + /* Save current address so we can work with it */ memcpy(&to, sa_addr, af->sockaddr_len); -- cgit v1.2.2 From 51e97a12bef19b7e43199fc153cf9bd5f2140362 Mon Sep 17 00:00:00 2001 From: Dan Rosenberg Date: Fri, 1 Oct 2010 11:51:47 +0000 Subject: sctp: Fix out-of-bounds reading in sctp_asoc_get_hmac() The sctp_asoc_get_hmac() function iterates through a peer's hmac_ids array and attempts to ensure that only a supported hmac entry is returned. The current code fails to do this properly - if the last id in the array is out of range (greater than SCTP_AUTH_HMAC_ID_MAX), the id integer remains set after exiting the loop, and the address of an out-of-bounds entry will be returned and subsequently used in the parent function, causing potentially ugly memory corruption. This patch resets the id integer to 0 on encountering an invalid id so that NULL will be returned after finishing the loop if no valid ids are found. Signed-off-by: Dan Rosenberg Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/auth.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 86366390038a..ddbbf7c81fa1 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -543,16 +543,20 @@ struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc) id = ntohs(hmacs->hmac_ids[i]); /* Check the id is in the supported range */ - if (id > SCTP_AUTH_HMAC_ID_MAX) + if (id > SCTP_AUTH_HMAC_ID_MAX) { + id = 0; continue; + } /* See is we support the id. Supported IDs have name and * length fields set, so that we can allocated and use * them. We can safely just check for name, for without the * name, we can't allocate the TFM. */ - if (!sctp_hmac_list[id].hmac_name) + if (!sctp_hmac_list[id].hmac_name) { + id = 0; continue; + } break; } -- cgit v1.2.2 From ff5ff6060bf880aac233e68dd666cbe9e39ec620 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 26 Sep 2010 16:22:03 -0400 Subject: kconfig: delay symbol direct dependency initialization This fixes the use-after-free and associated crash in kconfig introduced in commit 246cf9c26bf11f2bffbecea6e5bd222eee7b1df8. Signed-off-by: Arnaud Lacombe Acked-by: Catalin Marinas Signed-off-by: Michal Marek --- scripts/kconfig/expr.h | 1 - scripts/kconfig/menu.c | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 6ee2e4fb1481..170459c224a1 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -165,7 +165,6 @@ struct menu { struct symbol *sym; struct property *prompt; struct expr *dep; - struct expr *dir_dep; unsigned int flags; char *help; struct file *file; diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 4fb590247f33..edda8b49619d 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -107,7 +107,6 @@ static struct expr *menu_check_dep(struct expr *e) void menu_add_dep(struct expr *dep) { current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); - current_entry->dir_dep = current_entry->dep; } void menu_set_type(int type) @@ -291,10 +290,6 @@ void menu_finalize(struct menu *parent) for (menu = parent->list; menu; menu = menu->next) menu_finalize(menu); } else if (sym) { - /* ignore inherited dependencies for dir_dep */ - sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep)); - sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr); - basedep = parent->prompt ? parent->prompt->visible.expr : NULL; basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); basedep = expr_eliminate_dups(expr_transform(basedep)); @@ -325,6 +320,8 @@ void menu_finalize(struct menu *parent) parent->next = last_menu->next; last_menu->next = NULL; } + + sym->dir_dep.expr = parent->dep; } for (menu = parent->list; menu; menu = menu->next) { if (sym && sym_is_choice(sym) && -- cgit v1.2.2 From 475d92fc6e72cd123dc5dbb9e70cdb80b0cfdf2d Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 28 Sep 2010 14:02:02 +0100 Subject: ARM: 6416/1: errata: faulty hazard checking in the Store Buffer may lead to data corruption On the r2p0, r2p1 and r2p2 versions of the Cortex-A9, data corruption can occur under very rare conditions due to a store buffer optimisation. This workaround sets a bit in the diagnostic register of the Cortex-A9, disabling the optimisation and preventing the problem from occurring. Acked-by: Catalin Marinas Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/Kconfig | 14 ++++++++++++++ arch/arm/mm/proc-v7.S | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 88c97bc7a6f5..9c26ba7244fb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1101,6 +1101,20 @@ config ARM_ERRATA_720789 invalidated are not, resulting in an incoherency in the system page tables. The workaround changes the TLB flushing routines to invalidate entries regardless of the ASID. + +config ARM_ERRATA_743622 + bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption" + depends on CPU_V7 + help + This option enables the workaround for the 743622 Cortex-A9 + (r2p0..r2p2) erratum. Under very rare conditions, a faulty + optimisation in the Cortex-A9 Store Buffer may lead to data + corruption. This workaround sets a specific bit in the diagnostic + register of the Cortex-A9 which disables the Store Buffer + optimisation, preventing the defect from occurring. This has no + visible impact on the overall performance or power consumption of the + processor. + endmenu source "arch/arm/common/Kconfig" diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 7563ff0141bd..75619c55f137 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -253,6 +253,14 @@ __v7_setup: orreq r10, r10, #1 << 22 @ set bit #22 mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register #endif +#ifdef CONFIG_ARM_ERRATA_743622 + teq r6, #0x20 @ present in r2p0 + teqne r6, #0x21 @ present in r2p1 + teqne r6, #0x22 @ present in r2p2 + mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register + orreq r10, r10, #1 << 6 @ set bit #6 + mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register +#endif 3: mov r10, #0 #ifdef HARVARD_CACHE -- cgit v1.2.2 From 7f58217bb6d39edac68ae0988cdb96a520ad916f Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Thu, 30 Sep 2010 09:02:17 +0100 Subject: ARM: 6419/1: mmu: Fix MT_MEMORY and MT_MEMORY_NONCACHED pte flags The commit f1a2481c0 sets up the default flags for MT_MEMORY and MT_MEMORY_NONCACHED memory types. L_PTE_USER flag is wrongly set as default for these entries so remove it. Also adding the 'L_PTE_WRITE' flag so that these pages become read-write instead of just being read-only [this stops them being exposed to userspace, which is the main concern here --rmk] Reported-by: Catalin Marinas Signed-off-by: Santosh Shilimkar Acked-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6a3a2d0cd6db..e8ed9dc461fe 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -248,7 +248,7 @@ static struct mem_type mem_types[] = { }, [MT_MEMORY] = { .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_USER | L_PTE_EXEC, + L_PTE_WRITE | L_PTE_EXEC, .prot_l1 = PMD_TYPE_TABLE, .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, @@ -259,7 +259,7 @@ static struct mem_type mem_types[] = { }, [MT_MEMORY_NONCACHED] = { .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_USER | L_PTE_EXEC | L_PTE_MT_BUFFERABLE, + L_PTE_WRITE | L_PTE_EXEC | L_PTE_MT_BUFFERABLE, .prot_l1 = PMD_TYPE_TABLE, .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, -- cgit v1.2.2 From ccdf2e1bca8a45eaf89eb142dbed3551886413fe Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 27 Sep 2010 18:12:12 +0100 Subject: ARM: 6412/1: kprobes-decode: add support for MOVW instruction The MOVW instruction moves a 16-bit immediate into the bottom halfword of the destination register. This patch ensures that kprobes leaves the 16-bit immediate intact, rather than assume a 12-bit immediate and mask out the upper 4 bits. Acked-by: Nicolas Pitre Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/kprobes-decode.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c index 8bccbfa693ff..2c1f0050c9c4 100644 --- a/arch/arm/kernel/kprobes-decode.c +++ b/arch/arm/kernel/kprobes-decode.c @@ -1162,11 +1162,12 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) { /* * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx - * Undef : cccc 0011 0x00 xxxx xxxx xxxx xxxx xxxx + * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx * ALU op with S bit and Rd == 15 : * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */ - if ((insn & 0x0f900000) == 0x03200000 || /* MSR & Undef */ + if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */ + (insn & 0x0ff00000) == 0x03400000 || /* Undef */ (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */ return INSN_REJECTED; @@ -1177,7 +1178,7 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) * *S (bit 20) updates condition codes * ADC/SBC/RSC reads the C flag */ - insn &= 0xfff00fff; /* Rn = r0, Rd = r0 */ + insn &= 0xffff0fff; /* Rd = r0 */ asi->insn[0] = insn; asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ emulate_alu_imm_rwflags : emulate_alu_imm_rflags; -- cgit v1.2.2 From eaa71b318c5ed0cd1ac3182a533471dc5edf372d Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 4 Oct 2010 19:28:52 -0300 Subject: Bluetooth: Disallow to change L2CAP_OPTIONS values when connected L2CAP doesn't permit change like MTU, FCS, TxWindow values while the connection is alive, we can only set that before the connection/configuration process. That can lead to bugs in the L2CAP operation. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 44a8fb0d6c29..0b54b7dd8401 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1950,6 +1950,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us switch (optname) { case L2CAP_OPTIONS: + if (sk->sk_state == BT_CONNECTED) { + err = -EINVAL; + break; + } + opts.imtu = l2cap_pi(sk)->imtu; opts.omtu = l2cap_pi(sk)->omtu; opts.flush_to = l2cap_pi(sk)->flush_to; -- cgit v1.2.2 From f6cd378372bff06093d72f978c0150eeed3ea201 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 4 Oct 2010 21:46:11 -0700 Subject: Input: wacom - fix runtime PM related deadlock When runtime PM is enabled by default for input devices, X hangs in wacom open: [] mutex_lock+0x1a/0x40 [] wacom_resume+0x3b/0x90 [wacom] [] usb_resume_interface+0xd2/0x190 [] usb_resume_both+0x6d/0x110 [] usb_runtime_resume+0x24/0x40 [] __pm_runtime_resume+0x26f/0x450 [] __pm_runtime_resume+0x1da/0x450 [] pm_runtime_resume+0x2a/0x50 [] usb_autopm_get_interface+0x26/0x60 [] wacom_open+0x36/0x90 [wacom] wacom_open() takes wacom->lock and calls usb_autopm_get_interface(), which in turn calls wacom_resume() which tries to acquire the lock again. The fix is to call usb_autopm_get_interface() first, before we take the lock. Since we do not do usb_autopm_put_interface() until wacom_close() is called runtime PM is effectively disabled for the driver, however changing it now would risk regressions so the complete fix will have to wait till the next merge window. Reported-by: Jiri Slaby Acked-by: Oliver Neukum Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 42ba3691d908..b35876ee6908 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -103,27 +103,26 @@ static void wacom_sys_irq(struct urb *urb) static int wacom_open(struct input_dev *dev) { struct wacom *wacom = input_get_drvdata(dev); + int retval = 0; - mutex_lock(&wacom->lock); - - wacom->irq->dev = wacom->usbdev; - - if (usb_autopm_get_interface(wacom->intf) < 0) { - mutex_unlock(&wacom->lock); + if (usb_autopm_get_interface(wacom->intf) < 0) return -EIO; - } + + mutex_lock(&wacom->lock); if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { - usb_autopm_put_interface(wacom->intf); - mutex_unlock(&wacom->lock); - return -EIO; + retval = -EIO; + goto out; } wacom->open = true; wacom->intf->needs_remote_wakeup = 1; +out: mutex_unlock(&wacom->lock); - return 0; + if (retval) + usb_autopm_put_interface(wacom->intf); + return retval; } static void wacom_close(struct input_dev *dev) @@ -135,6 +134,8 @@ static void wacom_close(struct input_dev *dev) wacom->open = false; wacom->intf->needs_remote_wakeup = 0; mutex_unlock(&wacom->lock); + + usb_autopm_put_interface(wacom->intf); } static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, -- cgit v1.2.2 From 4e18b3edf71f5d4ad653e3c2ff6560878e965f96 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 4 Oct 2010 02:28:36 +0000 Subject: cls_u32: signedness bug skb_headroom() is unsigned so "skb_headroom(skb) + toff" is also unsigned and can't be less than zero. This test was added in 66d50d25: "u32: negative offset fix" It was supposed to fix a regression. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/sched/cls_u32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 7416a5c73b2a..b0c2a82178af 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -137,7 +137,7 @@ next_knode: int toff = off + key->off + (off2 & key->offmask); __be32 *data, _data; - if (skb_headroom(skb) + toff < 0) + if (skb_headroom(skb) + toff > INT_MAX) goto out; data = skb_header_pointer(skb, toff, 4, &_data); -- cgit v1.2.2 From cdaf9a2f280b25dd2fb1e04da5d3899411766e1b Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 5 Oct 2010 11:29:28 +0100 Subject: ARM: fix section mismatch warnings in Versatile Express WARNING: vmlinux.o(.text+0xbf30): Section mismatch in reference from the function v2m_timer_init() to the function .init.text:sp804_clocksource_init() The function v2m_timer_init() references the function __init sp804_clocksource_init(). This is often because v2m_timer_init lacks a __init annotation or the annotation of sp804_clocksource_init is wrong. WARNING: vmlinux.o(.text+0xbf3c): Section mismatch in reference from the function v2m_timer_init() to the function .init.text:sp804_clockevents_init() The function v2m_timer_init() references the function __init sp804_clockevents_init(). This is often because v2m_timer_init lacks a __init annotation or the annotation of sp804_clockevents_init is wrong. WARNING: vmlinux.o(.text+0xc524): Section mismatch in reference from the function ct_ca9x4_init() to the function .init.text:l2x0_init() The function ct_ca9x4_init() references the function __init l2x0_init(). This is often because ct_ca9x4_init lacks a __init annotation or the annotation of l2x0_init is wrong. WARNING: vmlinux.o(.text+0xc530): Section mismatch in reference from the function ct_ca9x4_init() to the function .init.text:clkdev_add_table() The function ct_ca9x4_init() references the function __init clkdev_add_table(). This is often because ct_ca9x4_init lacks a __init annotation or the annotation of clkdev_add_table is wrong. WARNING: vmlinux.o(.text+0xc578): Section mismatch in reference from the function ct_ca9x4_init() to the (unknown reference) .init.data:(unknown) The function ct_ca9x4_init() references the (unknown reference) __initdata (unknown). This is often because ct_ca9x4_init lacks a __initdata annotation or the annotation of (unknown) is wrong. Fix these by making ct_ca9x4_init() and v2m_timer_init() both __init. Signed-off-by: Russell King --- arch/arm/mach-vexpress/ct-ca9x4.c | 4 ++-- arch/arm/mach-vexpress/v2m.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index efb127022d42..71fb17349520 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -68,7 +68,7 @@ static void __init ct_ca9x4_init_irq(void) } #if 0 -static void ct_ca9x4_timer_init(void) +static void __init ct_ca9x4_timer_init(void) { writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); @@ -222,7 +222,7 @@ static struct platform_device pmu_device = { .resource = pmu_resources, }; -static void ct_ca9x4_init(void) +static void __init ct_ca9x4_init(void) { int i; diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 817f0ad38a0b..7eaa232180a5 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -48,7 +48,7 @@ void __init v2m_map_io(struct map_desc *tile, size_t num) } -static void v2m_timer_init(void) +static void __init v2m_timer_init(void) { writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); -- cgit v1.2.2 From 0fa035e52373386381fcdfbd506e32eac0c662f0 Mon Sep 17 00:00:00 2001 From: Hari Kanigeri Date: Fri, 20 Aug 2010 13:50:18 +0000 Subject: omap: iommu-load cam register before flushing the entry The flush_iotlb_page is not loading the cam register before flushing the cam entry. This causes wrong entry to be flushed out from the TLB, and if the entry happens to be a locked TLB entry it would lead to MMU faults. The fix is to load the cam register with the address to be flushed before flushing the TLB entry. Signed-off-by: Hari Kanigeri Acked-by: Hiroshi DOYU Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/iommu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index a202a2ce6e3d..6cd151b31bc5 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -320,6 +320,7 @@ void flush_iotlb_page(struct iommu *obj, u32 da) if ((start <= da) && (da < start + bytes)) { dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n", __func__, start, da, bytes); + iotlb_load_cr(obj, &cr); iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); } } -- cgit v1.2.2 From 6230d18cc7c4c68b7a38ea73bf5910e7652e5b21 Mon Sep 17 00:00:00 2001 From: minskey guo Date: Fri, 17 Sep 2010 14:02:37 +0800 Subject: seqno mask of THM_ITV register is 16bit The mask of sequence number in THM_ITV register is 16bit width instead of 8bit. Signed-off-by: minskey guo Acked-by: Jesse Barnes Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 9024480a8228..fb317007e3e5 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -230,7 +230,7 @@ #define THM_TC2 0xac #define THM_DTV 0xb0 #define THM_ITV 0xd8 -#define ITV_ME_SEQNO_MASK 0x000f0000 /* ME should update every ~200ms */ +#define ITV_ME_SEQNO_MASK 0x00ff0000 /* ME should update every ~200ms */ #define ITV_ME_SEQNO_SHIFT (16) #define ITV_MCH_TEMP_MASK 0x0000ff00 #define ITV_MCH_TEMP_SHIFT (8) -- cgit v1.2.2 From c21eae4f7c38db0e4693fb4cb24fb42fb83d8c15 Mon Sep 17 00:00:00 2001 From: minskey guo Date: Fri, 17 Sep 2010 14:03:01 +0800 Subject: old_cpu_power is wrongly divided by 65535 in ips_monitor() The variable old_cpu_power is used to save the value of THM_CEC register. In get_cpu_power(), it will be divided by 65535. Signed-off-by: minskey guo Acked-by: Jesse Barnes Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index fb317007e3e5..3c7b25c3cb80 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -948,7 +948,7 @@ static int ips_monitor(void *data) ITV_ME_SEQNO_SHIFT; seqno_timestamp = get_jiffies_64(); - old_cpu_power = thm_readl(THM_CEC) / 65535; + old_cpu_power = thm_readl(THM_CEC); schedule_timeout_interruptible(msecs_to_jiffies(IPS_SAMPLE_PERIOD)); /* Collect an initial average */ -- cgit v1.2.2 From fed522f7ea780d195d5d3e55df95fee520136e17 Mon Sep 17 00:00:00 2001 From: minskey guo Date: Fri, 17 Sep 2010 14:03:15 +0800 Subject: Release symbol on error-handling path of ips_get_i915_syms() In ips_get_i915_syms(), the symbol i915_gpu_busy() is not released when error occurs. Signed-off-by: minskey guo Acked-by: Jesse Barnes Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 3c7b25c3cb80..71dcc410f9d0 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -1390,7 +1390,7 @@ static bool ips_get_i915_syms(struct ips_driver *ips) return true; out_put_busy: - symbol_put(i915_gpu_turbo_disable); + symbol_put(i915_gpu_busy); out_put_lower: symbol_put(i915_gpu_lower); out_put_raise: -- cgit v1.2.2 From a7abda8d721359363d679c5f2de964f29419568c Mon Sep 17 00:00:00 2001 From: minskey guo Date: Fri, 17 Sep 2010 14:03:27 +0800 Subject: NULL pointer might be used in ips_monitor() The patch is to create ips_adjust thread before ips_monitor begins to run because the latter will kthread_stop() or wake up the former via ips->adjust pointer. Without this change, it is possible that ips->adjust is NULL when kthread_stop() or wake_up_process() is called in ips_monitor(). Signed-off-by: minskey guo Acked-by: Jesse Barnes Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 71dcc410f9d0..bfa9c726054a 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -940,7 +940,6 @@ static int ips_monitor(void *data) kfree(mch_samples); kfree(cpu_samples); kfree(mchp_samples); - kthread_stop(ips->adjust); return -ENOMEM; } @@ -1535,19 +1534,24 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) ips_enable_cpu_turbo(ips); ips->cpu_turbo_enabled = true; - /* Set up the work queue and monitor/adjust threads */ - ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor"); - if (IS_ERR(ips->monitor)) { + /* Create thermal adjust thread */ + ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust"); + if (IS_ERR(ips->adjust)) { dev_err(&dev->dev, - "failed to create thermal monitor thread, aborting\n"); + "failed to create thermal adjust thread, aborting\n"); ret = -ENOMEM; goto error_free_irq; + } - ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust"); - if (IS_ERR(ips->adjust)) { + /* + * Set up the work queue and monitor thread. The monitor thread + * will wake up ips_adjust thread. + */ + ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor"); + if (IS_ERR(ips->monitor)) { dev_err(&dev->dev, - "failed to create thermal adjust thread, aborting\n"); + "failed to create thermal monitor thread, aborting\n"); ret = -ENOMEM; goto error_thread_cleanup; } @@ -1566,7 +1570,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) return ret; error_thread_cleanup: - kthread_stop(ips->monitor); + kthread_stop(ips->adjust); error_free_irq: free_irq(ips->dev->irq, ips); error_unmap: -- cgit v1.2.2 From 354aeeb1ca8f82ea133ede21987034addc75057a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 23 Sep 2010 23:49:28 +0200 Subject: IPS driver: don't toggle CPU turbo on unsupported CPUs If the CPU doesn't support turbo, don't try to enable/disable it. http://bugzilla.kernel.org/show_bug.cgi?id=18742 Signed-off-by: Jesse Barnes Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index bfa9c726054a..71d04ef47b8c 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -51,7 +51,6 @@ * TODO: * - handle CPU hotplug * - provide turbo enable/disable api - * - make sure we can write turbo enable/disable reg based on MISC_EN * * Related documents: * - CDI 403777, 403778 - Auburndale EDS vol 1 & 2 @@ -325,6 +324,7 @@ struct ips_driver { bool gpu_preferred; bool poll_turbo_status; bool second_cpu; + bool turbo_toggle_allowed; struct ips_mcp_limits *limits; /* Optional MCH interfaces for if i915 is in use */ @@ -461,7 +461,8 @@ static void ips_enable_cpu_turbo(struct ips_driver *ips) if (ips->__cpu_turbo_on) return; - on_each_cpu(do_enable_cpu_turbo, ips, 1); + if (ips->turbo_toggle_allowed) + on_each_cpu(do_enable_cpu_turbo, ips, 1); ips->__cpu_turbo_on = true; } @@ -498,7 +499,8 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips) if (!ips->__cpu_turbo_on) return; - on_each_cpu(do_disable_cpu_turbo, ips, 1); + if (ips->turbo_toggle_allowed) + on_each_cpu(do_disable_cpu_turbo, ips, 1); ips->__cpu_turbo_on = false; } @@ -1332,8 +1334,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips) * turbo manually or we'll get an illegal MSR access, even though * turbo will still be available. */ - if (!(misc_en & IA32_MISC_TURBO_EN)) - ; /* add turbo MSR write allowed flag if necessary */ + if (misc_en & IA32_MISC_TURBO_EN) + ips->turbo_toggle_allowed = true; + else + ips->turbo_toggle_allowed = false; if (strstr(boot_cpu_data.x86_model_id, "CPU M")) limits = &ips_sv_limits; -- cgit v1.2.2 From eceab272fb895148f6293b5c0644fc2dd36d3aff Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 23 Sep 2010 23:49:29 +0200 Subject: IPS driver: verify BIOS provided limits They're optional. If not present or sane, we should use the CPU defaults. Signed-off-by: Jesse Barnes Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 71d04ef47b8c..c402cc417108 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -664,6 +664,27 @@ static bool mch_exceeded(struct ips_driver *ips) return ret; } +/** + * verify_limits - verify BIOS provided limits + * @ips: IPS structure + * + * BIOS can optionally provide non-default limits for power and temp. Check + * them here and use the defaults if the BIOS values are not provided or + * are otherwise unusable. + */ +static void verify_limits(struct ips_driver *ips) +{ + if (ips->mcp_power_limit < ips->limits->mcp_power_limit || + ips->mcp_power_limit > 35000) + ips->mcp_power_limit = ips->limits->mcp_power_limit; + + if (ips->mcp_temp_limit < ips->limits->core_temp_limit || + ips->mcp_temp_limit < ips->limits->mch_temp_limit || + ips->mcp_temp_limit > 150) + ips->mcp_temp_limit = min(ips->limits->core_temp_limit, + ips->limits->mch_temp_limit); +} + /** * update_turbo_limits - get various limits & settings from regs * @ips: IPS driver struct @@ -688,6 +709,7 @@ static void update_turbo_limits(struct ips_driver *ips) ips->mcp_temp_limit = thm_readw(THM_PTL); ips->mcp_power_limit = thm_readw(THM_MPPC); + verify_limits(ips); /* Ignore BIOS CPU vs GPU pref */ } @@ -1156,6 +1178,7 @@ static irqreturn_t ips_irq_handler(int irq, void *arg) STS_PTL_SHIFT; ips->mcp_power_limit = (tc1 & STS_PPL_MASK) >> STS_PPL_SHIFT; + verify_limits(ips); spin_unlock(&ips->turbo_status_lock); thm_writeb(THM_SEC, SEC_ACK); -- cgit v1.2.2 From a8c096adbd2b55942ff13c8bbc573a7551768003 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Tue, 28 Sep 2010 14:58:15 -0600 Subject: intel_ips: Print MCP limit exceeded values. Print some interesting values when MCP limits are exceeded. Signed-off-by: Tim Gardner Cc: Matthew Garrett Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index c402cc417108..07a1a4aac609 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -600,17 +600,29 @@ static bool mcp_exceeded(struct ips_driver *ips) { unsigned long flags; bool ret = false; + u32 temp_limit; + u32 avg_power; + const char *msg = "MCP limit exceeded: "; spin_lock_irqsave(&ips->turbo_status_lock, flags); - if (ips->mcp_avg_temp > (ips->mcp_temp_limit * 100)) - ret = true; - if (ips->cpu_avg_power + ips->mch_avg_power > ips->mcp_power_limit) + + temp_limit = ips->mcp_temp_limit * 100; + if (ips->mcp_avg_temp > temp_limit) { + dev_info(&ips->dev->dev, + "%sAvg temp %u, limit %u\n", msg, ips->mcp_avg_temp, + temp_limit); ret = true; - spin_unlock_irqrestore(&ips->turbo_status_lock, flags); + } - if (ret) + avg_power = ips->cpu_avg_power + ips->mch_avg_power; + if (avg_power > ips->mcp_power_limit) { dev_info(&ips->dev->dev, - "MCP power or thermal limit exceeded\n"); + "%sAvg power %u, limit %u\n", msg, avg_power, + ips->mcp_power_limit); + ret = true; + } + + spin_unlock_irqrestore(&ips->turbo_status_lock, flags); return ret; } -- cgit v1.2.2 From 070c0ee1ef9f5550cac9247190f0289349f28c01 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 5 Oct 2010 09:48:42 +0100 Subject: intel_ips -- ensure we do not enable gpu turbo mode without driver linkage Both when polling the current turbo status (in poll_turbo_status mode) and when handling thermal events (in ips_irq_handler) the current status of GPU turbo is updated to match the hardware status. However if during driver initialisation we were unable aquire linkage to the i915 driver enabling GPU turbo will lead to an oops on the first attempt to determine GPU busy status. Ensure that we do not enable GPU turbo unless we have driver linkage. BugLink: http://bugs.launchpad.net/bugs/632430 Cc: stable@kernel.org Signed-off-by: Andy Whitcroft Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 07a1a4aac609..76e41dc45f76 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -715,7 +715,8 @@ static void update_turbo_limits(struct ips_driver *ips) u32 hts = thm_readl(THM_HTS); ips->cpu_turbo_enabled = !(hts & HTS_PCTD_DIS); - ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS); + if (ips->gpu_busy) + ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS); ips->core_power_limit = thm_readw(THM_MPCPC); ips->mch_power_limit = thm_readw(THM_MMGPC); ips->mcp_temp_limit = thm_readw(THM_PTL); @@ -1185,7 +1186,8 @@ static irqreturn_t ips_irq_handler(int irq, void *arg) STS_GPL_SHIFT; /* ignore EC CPU vs GPU pref */ ips->cpu_turbo_enabled = !(sts & STS_PCTD_DIS); - ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS); + if (ips->gpu_busy) + ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS); ips->mcp_temp_limit = (sts & STS_PTL_MASK) >> STS_PTL_SHIFT; ips->mcp_power_limit = (tc1 & STS_PPL_MASK) >> -- cgit v1.2.2 From 4fd07ac00d87b942cc8d8f30a27192fea2fc4ab2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 5 Oct 2010 11:26:22 -0700 Subject: IPS driver: apply BIOS provided CPU limit if different from default The BIOS may hand us a lower CPU power limit than the default for a given SKU. We should use it in case the platform isn't designed to dissapate the full TDP of a given part. Signed-off-by: Jesse Barnes Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 76e41dc45f76..50ab1c93e369 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -1391,9 +1391,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips) tdp = turbo_power & TURBO_TDP_MASK; /* Sanity check TDP against CPU */ - if (limits->mcp_power_limit != (tdp / 8) * 1000) { - dev_warn(&ips->dev->dev, "Warning: CPU TDP doesn't match expected value (found %d, expected %d)\n", - tdp / 8, limits->mcp_power_limit / 1000); + if (limits->core_power_limit != (tdp / 8) * 1000) { + dev_info(&ips->dev->dev, "CPU TDP doesn't match expected value (found %d, expected %d)\n", + tdp / 8, limits->core_power_limit / 1000); + limits->core_power_limit = (tdp / 8) * 1000; } out: -- cgit v1.2.2 From 96f3823f537088c13735cfdfbf284436c802352a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 5 Oct 2010 14:50:59 -0400 Subject: [PATCH 2/2] IPS driver: disable CPU turbo The undocumented interface we're using for reading CPU power seems to be overreporting power. Until we figure out how to correct it, disable CPU turbo and power reporting to be safe. This will keep the CPU within default limits and still allow us to increase GPU frequency as needed. Signed-off-by: Jesse Barnes Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 50ab1c93e369..4b3ecdefd6e9 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -715,8 +715,15 @@ static void update_turbo_limits(struct ips_driver *ips) u32 hts = thm_readl(THM_HTS); ips->cpu_turbo_enabled = !(hts & HTS_PCTD_DIS); + /* + * Disable turbo for now, until we can figure out why the power figures + * are wrong + */ + ips->cpu_turbo_enabled = false; + if (ips->gpu_busy) ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS); + ips->core_power_limit = thm_readw(THM_MPCPC); ips->mch_power_limit = thm_readw(THM_MMGPC); ips->mcp_temp_limit = thm_readw(THM_PTL); @@ -895,7 +902,7 @@ static u32 get_cpu_power(struct ips_driver *ips, u32 *last, int period) ret = (ret * 1000) / 65535; *last = val; - return ret; + return 0; } static const u16 temp_decay_factor = 2; @@ -1186,6 +1193,11 @@ static irqreturn_t ips_irq_handler(int irq, void *arg) STS_GPL_SHIFT; /* ignore EC CPU vs GPU pref */ ips->cpu_turbo_enabled = !(sts & STS_PCTD_DIS); + /* + * Disable turbo for now, until we can figure + * out why the power figures are wrong + */ + ips->cpu_turbo_enabled = false; if (ips->gpu_busy) ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS); ips->mcp_temp_limit = (sts & STS_PTL_MASK) >> @@ -1573,8 +1585,8 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) /* Save turbo limits & ratios */ rdmsrl(TURBO_POWER_CURRENT_LIMIT, ips->orig_turbo_limit); - ips_enable_cpu_turbo(ips); - ips->cpu_turbo_enabled = true; + ips_disable_cpu_turbo(ips); + ips->cpu_turbo_enabled = false; /* Create thermal adjust thread */ ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust"); -- cgit v1.2.2 From d24a9da573444ab4aff38af2f4a0da07408ff491 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 5 Oct 2010 14:54:06 -0400 Subject: IPS driver: Fix limit clamping when reducing CPU power Values here are in internal units rather than Watts, so we shouldn't perform any conversion. Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_ips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 4b3ecdefd6e9..c44a5e8b8b82 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -415,7 +415,7 @@ static void ips_cpu_lower(struct ips_driver *ips) new_limit = cur_limit - 8; /* 1W decrease */ /* Clamp to SKU TDP limit */ - if (((new_limit * 10) / 8) < (ips->orig_turbo_limit & TURBO_TDP_MASK)) + if (new_limit < (ips->orig_turbo_limit & TURBO_TDP_MASK)) new_limit = ips->orig_turbo_limit & TURBO_TDP_MASK; thm_writew(THM_MPCPC, (new_limit * 10) / 8); -- cgit v1.2.2 From c4b8c01112a16f3cb8a4bffb11b89f2df079f904 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Tue, 5 Oct 2010 01:16:44 +0000 Subject: ixgbevf.txt: Update ixgbevf documentation Update the documentation for the ixgbevf (ixgbe virtual function driver). Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- Documentation/networking/ixgbevf.txt | 40 +++--------------------------------- 1 file changed, 3 insertions(+), 37 deletions(-) mode change 100755 => 100644 Documentation/networking/ixgbevf.txt diff --git a/Documentation/networking/ixgbevf.txt b/Documentation/networking/ixgbevf.txt old mode 100755 new mode 100644 index 19015de6725f..21dd5d15b6b4 --- a/Documentation/networking/ixgbevf.txt +++ b/Documentation/networking/ixgbevf.txt @@ -1,19 +1,16 @@ Linux* Base Driver for Intel(R) Network Connection ================================================== -November 24, 2009 +Intel Gigabit Linux driver. +Copyright(c) 1999 - 2010 Intel Corporation. Contents ======== -- In This Release - Identifying Your Adapter - Known Issues/Troubleshooting - Support -In This Release -=============== - This file describes the ixgbevf Linux* Base Driver for Intel Network Connection. @@ -33,7 +30,7 @@ Identifying Your Adapter For more information on how to identify your adapter, go to the Adapter & Driver ID Guide at: - http://support.intel.com/support/network/sb/CS-008441.htm + http://support.intel.com/support/go/network/adapter/idguide.htm Known Issues/Troubleshooting ============================ @@ -57,34 +54,3 @@ or the Intel Wired Networking project hosted by Sourceforge at: If an issue is identified with the released source code on the supported kernel with a supported adapter, email the specific information related to the issue to e1000-devel@lists.sf.net - -License -======= - -Intel 10 Gigabit Linux driver. -Copyright(c) 1999 - 2009 Intel Corporation. - -This program is free software; you can redistribute it and/or modify it -under the terms and conditions of the GNU General Public License, -version 2, as published by the Free Software Foundation. - -This program is distributed in the hope it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - -The full GNU General Public License is included in this distribution in -the file called "COPYING". - -Trademarks -========== - -Intel, Itanium, and Pentium are trademarks or registered trademarks of -Intel Corporation or its subsidiaries in the United States and other -countries. - -* Other names and brands may be claimed as the property of others. -- cgit v1.2.2 From 2bff89c3f340776398bfaf6c94404ffcd09f6e77 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Tue, 5 Oct 2010 01:17:05 +0000 Subject: e1000.txt: Update e1000 documentation Updated the e1000 networking driver documentation. Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- Documentation/networking/e1000.txt | 373 ++++++++++--------------------------- 1 file changed, 96 insertions(+), 277 deletions(-) diff --git a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt index 2df71861e578..d9271e74e488 100644 --- a/Documentation/networking/e1000.txt +++ b/Documentation/networking/e1000.txt @@ -1,82 +1,35 @@ Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters =============================================================== -September 26, 2006 - +Intel Gigabit Linux driver. +Copyright(c) 1999 - 2010 Intel Corporation. Contents ======== -- In This Release - Identifying Your Adapter -- Building and Installation - Command Line Parameters - Speed and Duplex Configuration - Additional Configurations -- Known Issues - Support - -In This Release -=============== - -This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family -of Adapters. This driver includes support for Itanium(R)2-based systems. - -For questions related to hardware requirements, refer to the documentation -supplied with your Intel PRO/1000 adapter. All hardware requirements listed -apply to use with Linux. - -The following features are now available in supported kernels: - - Native VLANs - - Channel Bonding (teaming) - - SNMP - -Channel Bonding documentation can be found in the Linux kernel source: -/Documentation/networking/bonding.txt - -The driver information previously displayed in the /proc filesystem is not -supported in this release. Alternatively, you can use ethtool (version 1.6 -or later), lspci, and ifconfig to obtain the same information. - -Instructions on updating ethtool can be found in the section "Additional -Configurations" later in this document. - -NOTE: The Intel(R) 82562v 10/100 Network Connection only provides 10/100 -support. - - Identifying Your Adapter ======================== For more information on how to identify your adapter, go to the Adapter & Driver ID Guide at: - http://support.intel.com/support/network/adapter/pro100/21397.htm + http://support.intel.com/support/go/network/adapter/idguide.htm For the latest Intel network drivers for Linux, refer to the following website. In the search field, enter your adapter name or type, or use the networking link on the left to search for your adapter: - http://downloadfinder.intel.com/scripts-df/support_intel.asp - + http://support.intel.com/support/go/network/adapter/home.htm Command Line Parameters ======================= -If the driver is built as a module, the following optional parameters -are used by entering them on the command line with the modprobe command -using this syntax: - - modprobe e1000 [