From 15c88fad4b7dca6b66cebe53c641593b95432fec Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sat, 15 Jan 2011 21:58:57 -0300 Subject: [media] DM04/QQBOX memcpy to const char fix Driver Version v1.75 Kernel oops appears in 2.6.37-rc8 in lme_firmware_switch because of a memcpy to a const char. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/lmedm04.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index 9eea4188303b..46ccd01a7696 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c @@ -659,7 +659,7 @@ static int lme2510_download_firmware(struct usb_device *dev, } /* Default firmware for LME2510C */ -const char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw"; +char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw"; static void lme_coldreset(struct usb_device *dev) { @@ -1006,7 +1006,7 @@ static struct dvb_usb_device_properties lme2510c_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = DEVICE_SPECIFIC, .download_firmware = lme2510_download_firmware, - .firmware = lme_firmware, + .firmware = (const char *)&lme_firmware, .size_of_priv = sizeof(struct lme2510_state), .num_adapters = 1, .adapter = { @@ -1109,5 +1109,5 @@ module_exit(lme2510_module_exit); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); -MODULE_VERSION("1.74"); +MODULE_VERSION("1.75"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 0552774d0670692f37a8d94374ed16fd9f676dbf Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Sun, 16 Jan 2011 16:22:20 -0300 Subject: [media] Fix double free of video_device in mem2mem_testdev video_device is already being freed in video_device.release callback on release. Signed-off-by: Pawel Osciak Reported-by: Roland Kletzing Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mem2mem_testdev.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index c179041d91f8..e7e717800ee2 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c @@ -1011,7 +1011,6 @@ 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.3 From 752eb7ae5075506fb6ac96a901b0e5b3e459f001 Mon Sep 17 00:00:00 2001 From: sensoray-dev Date: Wed, 19 Jan 2011 17:41:45 -0300 Subject: [media] s2255drv: firmware re-loading changes Change for firmware re-loading and updated firmware versions. Signed-off-by: Dean Anderson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s2255drv.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index b63f8cafa671..561909b65ce6 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -57,7 +57,7 @@ #include #define S2255_MAJOR_VERSION 1 -#define S2255_MINOR_VERSION 20 +#define S2255_MINOR_VERSION 21 #define S2255_RELEASE 0 #define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ S2255_MINOR_VERSION, \ @@ -312,9 +312,9 @@ struct s2255_fh { }; /* current cypress EEPROM firmware version */ -#define S2255_CUR_USB_FWVER ((3 << 8) | 6) +#define S2255_CUR_USB_FWVER ((3 << 8) | 11) /* current DSP FW version */ -#define S2255_CUR_DSP_FWVER 8 +#define S2255_CUR_DSP_FWVER 10102 /* Need DSP version 5+ for video status feature */ #define S2255_MIN_DSP_STATUS 5 #define S2255_MIN_DSP_COLORFILTER 8 @@ -492,9 +492,11 @@ static void planar422p_to_yuv_packed(const unsigned char *in, static void s2255_reset_dsppower(struct s2255_dev *dev) { - s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b0b, NULL, 0, 1); + s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b01, NULL, 0, 1); msleep(10); s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1); + msleep(600); + s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1); return; } -- cgit v1.2.3 From 83587839d648e2a9b5edb5b9d4d9118ead56f22d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jan 2011 18:16:50 -0300 Subject: [media] ir-raw: Properly initialize the IR event (BZ#27202) Changeset 4651918a4afdd49bdea21d2f919b189ef17a6399 changed the way events are stored. However, it forgot to fix ir_raw_event_store_edge() to work with the new way. Due to that, the decoders will likely do bad things. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-raw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 73230ff93b8a..01f258a2a57a 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c @@ -112,7 +112,7 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) { ktime_t now; s64 delta; /* ns */ - struct ir_raw_event ev; + DEFINE_IR_RAW_EVENT(ev); int rc = 0; if (!dev->raw) @@ -125,7 +125,6 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) * being called for the first time, note that delta can't * possibly be negative. */ - ev.duration = 0; if (delta > IR_MAX_DURATION || !dev->raw->last_type) type |= IR_START_EVENT; else -- cgit v1.2.3 From 54ebb8b83f2be99413261c8ba8238b390159a026 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 23 Jan 2011 19:12:27 -0300 Subject: [media] au0828: fix VBI handling when in V4L2 streaming mode au0828: fix VBI handling when in V4L2 streaming mode It turns up V4L2 streaming mode (a.k.a mmap) was broken for VBI streaming. This was causing libzvbi to fall back to V4L1 capture mode, and is a blatent violation of the V4L2 specification. Make the implementation work properly in this mode. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/au0828/au0828-video.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index e41e4ad5cc40..9c475c600fc9 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c @@ -1758,7 +1758,12 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (rc < 0) return rc; - return videobuf_reqbufs(&fh->vb_vidq, rb); + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + rc = videobuf_reqbufs(&fh->vb_vidq, rb); + else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) + rc = videobuf_reqbufs(&fh->vb_vbiq, rb); + + return rc; } static int vidioc_querybuf(struct file *file, void *priv, @@ -1772,7 +1777,12 @@ static int vidioc_querybuf(struct file *file, void *priv, if (rc < 0) return rc; - return videobuf_querybuf(&fh->vb_vidq, b); + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + rc = videobuf_querybuf(&fh->vb_vidq, b); + else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) + rc = videobuf_querybuf(&fh->vb_vbiq, b); + + return rc; } static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) @@ -1785,7 +1795,12 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) if (rc < 0) return rc; - return videobuf_qbuf(&fh->vb_vidq, b); + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + rc = videobuf_qbuf(&fh->vb_vidq, b); + else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) + rc = videobuf_qbuf(&fh->vb_vbiq, b); + + return rc; } static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) @@ -1806,7 +1821,12 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) dev->greenscreen_detected = 0; } - return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + rc = videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); + else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) + rc = videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags & O_NONBLOCK); + + return rc; } static struct v4l2_file_operations au0828_v4l_fops = { -- cgit v1.2.3 From 8d9bd9002dc8c3a05e11c5f40d95d06e15e83f71 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 23 Feb 2011 02:30:28 +0300 Subject: ARM: pxa/colibri: don't register pxa2xx-pcmcia nodes on non-colibri platforms PXA supports multi-machine kernels since long ago. However a kernel compiled with support for colibri and any other PXA machine and with PCMCIA enabled will barf at runtime about duplicate registration of pxa2xx-pcmcia device. Fix that. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Eric Miao --- drivers/pcmcia/pxa2xx_colibri.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index c3f72192af66..a52039564e74 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c @@ -181,6 +181,9 @@ static int __init colibri_pcmcia_init(void) { int ret; + if (!machine_is_colibri() && !machine_is_colibri320()) + return -ENODEV; + colibri_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); if (!colibri_pcmcia_device) return -ENOMEM; -- cgit v1.2.3 From 0a91be40ed67ca72a81cfd842d5c2604ff1a54a4 Mon Sep 17 00:00:00 2001 From: Antti Seppälä Date: Sun, 13 Feb 2011 07:29:15 -0300 Subject: [media] Fix sysfs rc protocol lookup for rc-5-sz MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the current matching rules the lookup for rc protocol named rc-5-sz matches with "rc-5" before finding "rc-5-sz". Thus one is able to never enable/disable the rc-5-sz protocol via sysfs. Fix the lookup to require an exact match which allows the manipulation of sz protocol. Signed-off-by: Antti Seppälä Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 72be8a02118c..e5b29a4c691e 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -844,7 +844,7 @@ static ssize_t store_protocols(struct device *device, count++; } else { for (i = 0; i < ARRAY_SIZE(proto_names); i++) { - if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) { + if (!strcasecmp(tmp, proto_names[i].name)) { tmp += strlen(proto_names[i].name); mask = proto_names[i].type; break; -- cgit v1.2.3 From e192a7cf0effe7680264a5bc35c0ad1bdcdc921c Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Fri, 14 Jan 2011 13:58:59 -0300 Subject: [media] DiB7000M: add pid filtering This patch adds the pid filtering for the dib7000M demod. It also corrects the pid filtering for the dib7700 based board. It should prevent an oops, when using dib7700p based board. References: https://bugzilla.novell.com/show_bug.cgi?id=644807 Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Tested-by: Pavel SKARKA Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 21 +++++++++++++++++++-- drivers/media/dvb/frontends/dib7000m.c | 19 +++++++++++++++++++ drivers/media/dvb/frontends/dib7000m.h | 15 +++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index defd83964ce2..193cdb77b76a 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -870,6 +870,23 @@ static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap) return 0; } +static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index, + u16 pid, int onoff) +{ + struct dib0700_state *st = adapter->dev->priv; + if (st->is_dib7000pc) + return dib7000p_pid_filter(adapter->fe, index, pid, onoff); + return dib7000m_pid_filter(adapter->fe, index, pid, onoff); +} + +static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) +{ + struct dib0700_state *st = adapter->dev->priv; + if (st->is_dib7000pc) + return dib7000p_pid_filter_ctrl(adapter->fe, onoff); + return dib7000m_pid_filter_ctrl(adapter->fe, onoff); +} + static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { return dib7000p_pid_filter(adapter->fe, index, pid, onoff); @@ -1875,8 +1892,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { { .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, - .pid_filter = stk70x0p_pid_filter, - .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .pid_filter = stk7700p_pid_filter, + .pid_filter_ctrl = stk7700p_pid_filter_ctrl, .frontend_attach = stk7700p_frontend_attach, .tuner_attach = stk7700p_tuner_attach, diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c index c7f5ccf54aa5..289a79837f24 100644 --- a/drivers/media/dvb/frontends/dib7000m.c +++ b/drivers/media/dvb/frontends/dib7000m.c @@ -1285,6 +1285,25 @@ struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum di } EXPORT_SYMBOL(dib7000m_get_i2c_master); +int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) +{ + struct dib7000m_state *state = fe->demodulator_priv; + u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef; + val |= (onoff & 0x1) << 4; + dprintk("PID filter enabled %d", onoff); + return dib7000m_write_word(state, 294 + state->reg_offs, val); +} +EXPORT_SYMBOL(dib7000m_pid_filter_ctrl); + +int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) +{ + struct dib7000m_state *state = fe->demodulator_priv; + dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff); + return dib7000m_write_word(state, 300 + state->reg_offs + id, + onoff ? (1 << 13) | pid : 0); +} +EXPORT_SYMBOL(dib7000m_pid_filter); + #if 0 /* used with some prototype boards */ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h index 113819ce9f0d..81fcf2241c64 100644 --- a/drivers/media/dvb/frontends/dib7000m.h +++ b/drivers/media/dvb/frontends/dib7000m.h @@ -46,6 +46,8 @@ extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, extern struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); +extern int dib7000m_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); +extern int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff); #else static inline struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, @@ -63,6 +65,19 @@ struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod, printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } +static inline int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, + u16 pid, u8 onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, + uint8_t onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} #endif /* TODO -- cgit v1.2.3 From 67914b5c400d6c213f9e56d7547a2038ab5c06f4 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 13 Feb 2011 21:52:50 -0300 Subject: [media] cx23885: Revert "Check for slave nack on all transactions" This reverts commit 44835f197bf1e3f57464f23dfb239fef06cf89be. With the CX23885 hardware I2C master, checking for I2C slave ACK/NAK is not valid when the I2C_EXTEND or I2C_NOSTOP bits are set. Revert the commit that checks for I2C slave ACK/NAK on all transactions, so that XC5000 tuners work with the CX23885 again. Thanks go to Mark Zimmerman for reporting and bisecting this problem. Bisected-by: Mark Zimmerman Reported-by: Mark Zimmerman Signed-off-by: Andy Walls Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-i2c.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index ed3d8f55029b..1007f80bd7c1 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c @@ -122,10 +122,6 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, if (!i2c_wait_done(i2c_adap)) goto eio; - if (!i2c_slave_did_ack(i2c_adap)) { - retval = -ENXIO; - goto err; - } if (i2c_debug) { printk(" addr << 1, msg->buf[0]); if (!(ctrl & I2C_NOSTOP)) @@ -209,10 +205,6 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, if (!i2c_wait_done(i2c_adap)) goto eio; - if (cnt == 0 && !i2c_slave_did_ack(i2c_adap)) { - retval = -ENXIO; - goto err; - } msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; if (i2c_debug) { dprintk(1, " %02x", msg->buf[cnt]); -- cgit v1.2.3 From 593110d143f85d1aca227685edd571f137388b24 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 13 Feb 2011 22:01:38 -0300 Subject: [media] cx23885: Remove unused 'err:' labels to quiet compiler warning The previous revert-commit, that affected cx23885-i2c.c, left some unused labels that the compiler griped about. Clean them up. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-i2c.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index 1007f80bd7c1..307ff543c254 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c @@ -154,7 +154,6 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, eio: retval = -EIO; - err: if (i2c_debug) printk(KERN_ERR " ERR: %d\n", retval); return retval; @@ -216,7 +215,6 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, eio: retval = -EIO; - err: if (i2c_debug) printk(KERN_ERR " ERR: %d\n", retval); return retval; -- cgit v1.2.3 From 1e6406b8f0dc1ae7d7c39c9e1ac6ca78e016ebfb Mon Sep 17 00:00:00 2001 From: Sven Barth Date: Sun, 13 Feb 2011 22:09:43 -0300 Subject: [media] cx25840: fix probing of cx2583x chips Fix the probing of cx2583x chips, because two controls were clustered that are not created for these chips. This regression was introduced in 2.6.36. Signed-off-by: Sven Barth Signed-off-by: Andy Walls Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 6fc09dd41b9d..35796e035247 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -2015,7 +2015,8 @@ static int cx25840_probe(struct i2c_client *client, kfree(state); return err; } - v4l2_ctrl_cluster(2, &state->volume); + if (!is_cx2583x(state)) + v4l2_ctrl_cluster(2, &state->volume); v4l2_ctrl_handler_setup(&state->hdl); if (client->dev.platform_data) { -- cgit v1.2.3 From d213ad08362909ab50fbd6568fcc9fd568268d29 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 26 Feb 2011 01:56:34 -0300 Subject: [media] ivtv: Fix corrective action taken upon DMA ERR interrupt to avoid hang After upgrading the kernel from stock Ubuntu 7.10 to 10.04, with no hardware changes, I started getting the dreaded DMA TIMEOUT errors, followed by inability to encode until the machine was rebooted. I came across a post from Andy in March (http://www.gossamer-threads.com/lists/ivtv/users/40943#40943) where he speculates that perhaps the corrective actions being taken after a DMA ERROR are not sufficient to recover the situation. After some testing I suspect that this is indeed the case, and that in fact the corrective action may be what hangs the card's DMA engine, rather than the original error. Specifically these DMA ERROR IRQs seem to present with two different values in the IVTV_REG_DMASTATUS register: 0x11 and 0x13. The current corrective action is to clear that status register back to 0x01 or 0x03, and then issue the next DMA request. In the case of a 0x13 this seems to result in a minor glitch in the encoded stream due to the failed transfer that was not retried, but otherwise things continue OK. In the case of a 0x11 the card's DMA write engine is never heard from again, and a DMA TIMEOUT follows shortly after. 0x11 is the killer. I suspect that the two cases need to be handled differently. The difference is in bit 1 (0x02), which is set when the error is about to be successfully recovered, and clear when things are about to go bad. Bit 1 of DMASTATUS is described differently in different places either as a positive "write finished", or an inverted "write busy". If we take the first definition, then when an error arises with state 0x11, it means that the write did not complete. It makes sense to start a new transfer, as in the current code. But if we take the second definition, then 0x11 means "an error but the write engine is still busy". Trying to feed it a new transfer in this situation might not be a good idea. As an experiment, I added code to ignore the DMA ERROR IRQ if DMASTATUS is 0x11. I.e., don't start a new transfer, don't clear our flags, etc. The hope was that the card would complete the transfer and issue a ENC DMA COMPLETE, either successfully or with an error condition there. However the card still hung. The only remaining corrective action being taken with a 0x11 status was then the write back to the status register to clear the error, i.e. DMASTATUS = DMASTATUS & ~3. This would have the effect of clearing the error bit 4, while leaving the lower bits indicating DMA write busy. Strangely enough, removing this write to the status register solved the problem! If the DMA ERROR IRQ with DMASTATUS=0x11 is completely ignored, with no corrective action at all, then the card will complete the transfer and issue a new IRQ. If the status register is written to when it has the value 0x11, then the DMA engine hangs. Perhaps it's illegal to write to DMASTATUS while the read or write busy bit is set? At any rate, it appears that the current corrective action is indeed making things worse rather than better. I put together a patch that modifies ivtv_irq_dma_err to do the following: - Don't write back to IVTV_REG_DMASTATUS. - If write-busy is asserted, leave the card alone. Just extend the timeout slightly. - If write-busy is de-asserted, retry the current transfer. This has completely fixed my DMA TIMEOUT woes. DMA ERR events still occur, but now they seem to be correctly handled. 0x11 events no longer hang the card, and 0x13 events no longer result in a glitch in the stream, as the failed transfer is retried. I'm happy. I've inlined the patch below in case it is of interest. As described above, I have a theory about why it works (based on a different interpretation of bit 1 of DMASTATUS), but I can't guarantee that my theory is correct. There may be another explanation, or it may be a fluke. Maybe ignoring that IRQ entirely would be equally effective? Maybe the status register read/writeback sequence is race condition if the card changes it in the mean time? Also as I am using a PVR-150 only, I have not been able to test it on other cards, which may be especially relevant for 350s that support concurrent decoding. Hopefully the patch does not break the DMA READ path. Mike [awalls@md.metrocast.net: Modified patch to add a verbose comment, make minor brace reformats, and clear the error flags in the IVTV_REG_DMASTATUS iff both read and write DMA were not in progress. Mike's conjecture about a race condition with the writeback is correct; it can confuse the DMA engine.] [Comment and analysis from the ML post by Michael ] Signed-off-by: Andy Walls Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-irq.c | 58 ++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 9b4faf009196..9c29e964d400 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c @@ -628,22 +628,66 @@ static void ivtv_irq_enc_pio_complete(struct ivtv *itv) static void ivtv_irq_dma_err(struct ivtv *itv) { u32 data[CX2341X_MBOX_MAX_DATA]; + u32 status; del_timer(&itv->dma_timer); + ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data); + status = read_reg(IVTV_REG_DMASTATUS); IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1], - read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream); - write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); + status, itv->cur_dma_stream); + /* + * We do *not* write back to the IVTV_REG_DMASTATUS register to + * clear the error status, if either the encoder write (0x02) or + * decoder read (0x01) bus master DMA operation do not indicate + * completed. We can race with the DMA engine, which may have + * transitioned to completed status *after* we read the register. + * Setting a IVTV_REG_DMASTATUS flag back to "busy" status, after the + * DMA engine has completed, will cause the DMA engine to stop working. + */ + status &= 0x3; + if (status == 0x3) + write_reg(status, IVTV_REG_DMASTATUS); + if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) { struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream]; - /* retry */ - if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) + if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { + /* retry */ + /* + * FIXME - handle cases of DMA error similar to + * encoder below, except conditioned on status & 0x1 + */ ivtv_dma_dec_start(s); - else - ivtv_dma_enc_start(s); - return; + return; + } else { + if ((status & 0x2) == 0) { + /* + * CX2341x Bus Master DMA write is ongoing. + * Reset the timer and let it complete. + */ + itv->dma_timer.expires = + jiffies + msecs_to_jiffies(600); + add_timer(&itv->dma_timer); + return; + } + + if (itv->dma_retries < 3) { + /* + * CX2341x Bus Master DMA write has ended. + * Retry the write, starting with the first + * xfer segment. Just retrying the current + * segment is not sufficient. + */ + s->sg_processed = 0; + itv->dma_retries++; + ivtv_dma_enc_start_xfer(s); + return; + } + /* Too many retries, give up on this one */ + } + } if (test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { ivtv_udma_start(itv); -- cgit v1.2.3 From e3bfeabbf5ba5da7f6cc5d53a83cb7765220c619 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sat, 26 Feb 2011 02:44:38 -0300 Subject: [media] cx18: Add support for Hauppauge HVR-1600 models with s5h1411 The newest variants of the HVR-1600 have an s5h1411/tda18271 for the digital frontend. Add support for these boards. Thanks to Hauppauge Computer Works for providing sample hardware. [awalls@md.metrocast.net: Changed an additional log message to clarify for the end user that the driver is defaulting to an original HVR-1600 for unknown model numbers.] Signed-off-by: Devin Heitmueller Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 50 +++++++++++++++++++++++++++++++++- drivers/media/video/cx18/cx18-driver.c | 25 +++++++++++++++-- drivers/media/video/cx18/cx18-driver.h | 3 +- drivers/media/video/cx18/cx18-dvb.c | 38 ++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 87177733cf92..68ad1963f421 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -95,6 +95,53 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { .i2c = &cx18_i2c_std, }; +static const struct cx18_card cx18_card_hvr1600_s5h1411 = { + .type = CX18_CARD_HVR_1600_S5H1411, + .name = "Hauppauge HVR-1600", + .comment = "Simultaneous Digital and Analog TV capture supported\n", + .v4l2_capabilities = CX18_CAP_ENCODER, + .hw_audio_ctrl = CX18_HW_418_AV, + .hw_muxer = CX18_HW_CS5345, + .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER | + CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL | + CX18_HW_Z8F0811_IR_HAUP, + .video_inputs = { + { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, + { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, + { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, + { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, + }, + .audio_inputs = { + { CX18_CARD_INPUT_AUD_TUNER, + CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, + { CX18_CARD_INPUT_LINE_IN1, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 }, + { CX18_CARD_INPUT_LINE_IN2, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 }, + }, + .radio_input = { CX18_CARD_INPUT_AUD_TUNER, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 }, + .ddr = { + /* ESMT M13S128324A-5B memory */ + .chip_config = 0x003, + .refresh = 0x30c, + .timing1 = 0x44220e82, + .timing2 = 0x08, + .tune_lane = 0, + .initial_emrs = 0, + }, + .gpio_init.initial_value = 0x3001, + .gpio_init.direction = 0x3001, + .gpio_i2c_slave_reset = { + .active_lo_mask = 0x3001, + .msecs_asserted = 10, + .msecs_recovery = 40, + .ir_reset_mask = 0x0001, + }, + .i2c = &cx18_i2c_std, +}; + static const struct cx18_card cx18_card_hvr1600_samsung = { .type = CX18_CARD_HVR_1600_SAMSUNG, .name = "Hauppauge HVR-1600 (Preproduction)", @@ -523,7 +570,8 @@ static const struct cx18_card *cx18_card_list[] = { &cx18_card_toshiba_qosmio_dvbt, &cx18_card_leadtek_pvr2100, &cx18_card_leadtek_dvr3100h, - &cx18_card_gotview_dvd3 + &cx18_card_gotview_dvd3, + &cx18_card_hvr1600_s5h1411 }; const struct cx18_card *cx18_get_card(u16 index) diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 944af8adbe0c..b1c3cbd92743 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -157,6 +157,7 @@ MODULE_PARM_DESC(cardtype, "\t\t\t 7 = Leadtek WinFast PVR2100\n" "\t\t\t 8 = Leadtek WinFast DVR3100 H\n" "\t\t\t 9 = GoTView PCI DVD3 Hybrid\n" + "\t\t\t 10 = Hauppauge HVR 1600 (S5H1411)\n" "\t\t\t 0 = Autodetect (default)\n" "\t\t\t-1 = Ignore this card\n\t\t"); MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); @@ -337,6 +338,7 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) switch (cx->card->type) { case CX18_CARD_HVR_1600_ESMT: case CX18_CARD_HVR_1600_SAMSUNG: + case CX18_CARD_HVR_1600_S5H1411: tveeprom_hauppauge_analog(&c, tv, eedata); break; case CX18_CARD_YUAN_MPC718: @@ -365,7 +367,25 @@ static void cx18_process_eeprom(struct cx18 *cx) from the model number. Use the cardtype module option if you have one of these preproduction models. */ switch (tv.model) { - case 74000 ... 74999: + case 74301: /* Retail models */ + case 74321: + case 74351: /* OEM models */ + case 74361: + /* Digital side is s5h1411/tda18271 */ + cx->card = cx18_get_card(CX18_CARD_HVR_1600_S5H1411); + break; + case 74021: /* Retail models */ + case 74031: + case 74041: + case 74141: + case 74541: /* OEM models */ + case 74551: + case 74591: + case 74651: + case 74691: + case 74751: + case 74891: + /* Digital side is s5h1409/mxl5005s */ cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; case 0x718: @@ -377,7 +397,8 @@ static void cx18_process_eeprom(struct cx18 *cx) CX18_ERR("Invalid EEPROM\n"); return; default: - CX18_ERR("Unknown model %d, defaulting to HVR-1600\n", tv.model); + CX18_ERR("Unknown model %d, defaulting to original HVR-1600 " + "(cardtype=1)\n", tv.model); cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; } diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 306caac6d3fc..f736679d2517 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -85,7 +85,8 @@ #define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ #define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */ #define CX18_CARD_GOTVIEW_PCI_DVD3 8 /* GoTView PCI DVD3 Hybrid */ -#define CX18_CARD_LAST 8 +#define CX18_CARD_HVR_1600_S5H1411 9 /* Hauppauge HVR 1600 s5h1411/tda18271*/ +#define CX18_CARD_LAST 9 #define CX18_ENC_STREAM_TYPE_MPG 0 #define CX18_ENC_STREAM_TYPE_TS 1 diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index f0381d62518d..f41922bd4020 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c @@ -29,6 +29,8 @@ #include "cx18-gpio.h" #include "s5h1409.h" #include "mxl5005s.h" +#include "s5h1411.h" +#include "tda18271.h" #include "zl10353.h" #include @@ -76,6 +78,32 @@ static struct s5h1409_config hauppauge_hvr1600_config = { .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE }; +/* + * CX18_CARD_HVR_1600_S5H1411 + */ +static struct s5h1411_config hcw_s5h1411_config = { + .output_mode = S5H1411_SERIAL_OUTPUT, + .gpio = S5H1411_GPIO_OFF, + .vsb_if = S5H1411_IF_44000, + .qam_if = S5H1411_IF_4000, + .inversion = S5H1411_INVERSION_ON, + .status_mode = S5H1411_DEMODLOCKING, + .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, +}; + +static struct tda18271_std_map hauppauge_tda18271_std_map = { + .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, + .if_lvl = 6, .rfagc_top = 0x37 }, + .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, + .if_lvl = 6, .rfagc_top = 0x37 }, +}; + +static struct tda18271_config hauppauge_tda18271_config = { + .std_map = &hauppauge_tda18271_std_map, + .gate = TDA18271_GATE_DIGITAL, + .output_opt = TDA18271_OUTPUT_LT_OFF, +}; + /* * CX18_CARD_LEADTEK_DVR3100H */ @@ -244,6 +272,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) switch (cx->card->type) { case CX18_CARD_HVR_1600_ESMT: case CX18_CARD_HVR_1600_SAMSUNG: + case CX18_CARD_HVR_1600_S5H1411: v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL); v |= 0x00400000; /* Serial Mode */ v |= 0x00002000; /* Data Length - Byte */ @@ -455,6 +484,15 @@ static int dvb_register(struct cx18_stream *stream) ret = 0; } break; + case CX18_CARD_HVR_1600_S5H1411: + dvb->fe = dvb_attach(s5h1411_attach, + &hcw_s5h1411_config, + &cx->i2c_adap[0]); + if (dvb->fe != NULL) + dvb_attach(tda18271_attach, dvb->fe, + 0x60, &cx->i2c_adap[0], + &hauppauge_tda18271_config); + break; case CX18_CARD_LEADTEK_DVR3100H: dvb->fe = dvb_attach(zl10353_attach, &leadtek_dvr3100h_demod, -- cgit v1.2.3 From 3198ed161c9be9bbd15bb2e9c22561248cac6e6a Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 1 Mar 2011 12:38:02 -0300 Subject: [media] nuvoton-cir: fix wake from suspend The CIR Wake FIFO is 67 bytes long, but the stock remote appears to only populate 65 of them. Limit comparison to 65 bytes, and wake from suspend works a whole lot better (it wasn't working at all for most folks). Fix based on comparison with the old lirc_wb677 driver from Nuvoton, debugging and testing done by Dave Treacy by way of the lirc mailing list. Reported-by: Dave Treacy Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/nuvoton-cir.c | 5 +++-- drivers/media/rc/nuvoton-cir.h | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 273d9d674792..d4d64492a057 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -385,8 +385,9 @@ static void nvt_cir_regs_init(struct nvt_dev *nvt) static void nvt_cir_wake_regs_init(struct nvt_dev *nvt) { - /* set number of bytes needed for wake key comparison (default 67) */ - nvt_cir_wake_reg_write(nvt, CIR_WAKE_FIFO_LEN, CIR_WAKE_FIFO_CMP_DEEP); + /* set number of bytes needed for wake from s3 (default 65) */ + nvt_cir_wake_reg_write(nvt, CIR_WAKE_FIFO_CMP_BYTES, + CIR_WAKE_FIFO_CMP_DEEP); /* set tolerance/variance allowed per byte during wake compare */ nvt_cir_wake_reg_write(nvt, CIR_WAKE_CMP_TOLERANCE, diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 1df82351cb03..048135eea702 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -305,8 +305,11 @@ struct nvt_dev { #define CIR_WAKE_IRFIFOSTS_RX_EMPTY 0x20 #define CIR_WAKE_IRFIFOSTS_RX_FULL 0x10 -/* CIR Wake FIFO buffer is 67 bytes long */ -#define CIR_WAKE_FIFO_LEN 67 +/* + * The CIR Wake FIFO buffer is 67 bytes long, but the stock remote wakes + * the system comparing only 65 bytes (fails with this set to 67) + */ +#define CIR_WAKE_FIFO_CMP_BYTES 65 /* CIR Wake byte comparison tolerance */ #define CIR_WAKE_CMP_TOLERANCE 5 -- cgit v1.2.3 From a6994eb0a706bf36bcb3b5f7e439c5b76c31cfe5 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 1 Mar 2011 12:38:28 -0300 Subject: [media] mceusb: don't claim multifunction device non-IR parts There's a Realtek combo card reader and IR receiver device with multiple usb interfaces on it. The mceusb driver is incorrectly grabbing all of them. This change should make it bind to only interface 2 (patch based on lsusb output on the linux-media list from Lucian Muresan). Tested regression-free with the six mceusb devices I have myself. Reported-by: Patrick Boettcher Reported-by: Lucian Muresan Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mceusb.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 6df0a4980645..e4f8eac7f717 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -148,6 +148,7 @@ enum mceusb_model_type { MCE_GEN2_TX_INV, POLARIS_EVK, CX_HYBRID_TV, + MULTIFUNCTION, }; struct mceusb_model { @@ -155,9 +156,10 @@ struct mceusb_model { u32 mce_gen2:1; u32 mce_gen3:1; u32 tx_mask_normal:1; - u32 is_polaris:1; u32 no_tx:1; + int ir_intfnum; + const char *rc_map; /* Allow specify a per-board map */ const char *name; /* per-board name */ }; @@ -179,7 +181,6 @@ static const struct mceusb_model mceusb_model[] = { .tx_mask_normal = 1, }, [POLARIS_EVK] = { - .is_polaris = 1, /* * In fact, the EVK is shipped without * remotes, but we should have something handy, @@ -189,10 +190,13 @@ static const struct mceusb_model mceusb_model[] = { .name = "Conexant Hybrid TV (cx231xx) MCE IR", }, [CX_HYBRID_TV] = { - .is_polaris = 1, .no_tx = 1, /* tx isn't wired up at all */ .name = "Conexant Hybrid TV (cx231xx) MCE IR", }, + [MULTIFUNCTION] = { + .mce_gen2 = 1, + .ir_intfnum = 2, + }, }; static struct usb_device_id mceusb_dev_table[] = { @@ -216,8 +220,9 @@ static struct usb_device_id mceusb_dev_table[] = { { 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) }, + /* Realtek MCE IR Receiver and card reader */ + { USB_DEVICE(VENDOR_REALTEK, 0x0161), + .driver_info = MULTIFUNCTION }, /* SMK/Toshiba G83C0004D410 */ { USB_DEVICE(VENDOR_SMK, 0x031d), .driver_info = MCE_GEN2_TX_INV }, @@ -1101,7 +1106,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, bool is_gen3; bool is_microsoft_gen1; bool tx_mask_normal; - bool is_polaris; + int ir_intfnum; dev_dbg(&intf->dev, "%s called\n", __func__); @@ -1110,13 +1115,11 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, is_gen3 = mceusb_model[model].mce_gen3; is_microsoft_gen1 = mceusb_model[model].mce_gen1; tx_mask_normal = mceusb_model[model].tx_mask_normal; - is_polaris = mceusb_model[model].is_polaris; + ir_intfnum = mceusb_model[model].ir_intfnum; - if (is_polaris) { - /* Interface 0 is IR */ - if (idesc->desc.bInterfaceNumber) - return -ENODEV; - } + /* There are multi-function devices with non-IR interfaces */ + if (idesc->desc.bInterfaceNumber != ir_intfnum) + return -ENODEV; /* step through the endpoints to find first bulk in and out endpoint */ for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { -- cgit v1.2.3 From 89a8969afa300c202066c23cc5cc9e42eb81967c Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 1 Mar 2011 12:38:48 -0300 Subject: [media] tda829x: fix regression in probe functions In commit 567aba0b7997dad5fe3fb4aeb174ee9018df8c5b, the probe address for tda8290_probe and tda8295_probe was hard-coded to 0x4b, which is the default i2c address for those devices, but its possible for the device to be at an alternate address, 0x42, which is the case for the HVR-1950. If we probe the wrong address, probe fails and we have a non-working device. We have the actual address passed into the function by way of i2c_props, we just need to use it. Also fix up some copy/paste comment issues and streamline debug spew a touch. Verified to restore my HVR-1950 to full working order. Special thanks to Ken Bass for reporting the issue in the first place, and to both he and Gary Buhrmaster for aiding in debugging and analysis of the problem. Reported-by: Ken Bass Tested-by: Jarod Wilson Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda8290.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c index bc6a67768af1..8c4852114eeb 100644 --- a/drivers/media/common/tuners/tda8290.c +++ b/drivers/media/common/tuners/tda8290.c @@ -658,13 +658,13 @@ static int tda8290_probe(struct tuner_i2c_props *i2c_props) #define TDA8290_ID 0x89 u8 reg = 0x1f, id; struct i2c_msg msg_read[] = { - { .addr = 0x4b, .flags = 0, .len = 1, .buf = ® }, - { .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id }, + { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = ® }, + { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id }, }; /* detect tda8290 */ if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) { - printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n", + printk(KERN_WARNING "%s: couldn't read register 0x%02x\n", __func__, reg); return -ENODEV; } @@ -685,13 +685,13 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props) #define TDA8295C2_ID 0x8b u8 reg = 0x2f, id; struct i2c_msg msg_read[] = { - { .addr = 0x4b, .flags = 0, .len = 1, .buf = ® }, - { .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id }, + { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = ® }, + { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id }, }; - /* detect tda8290 */ + /* detect tda8295 */ if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) { - printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n", + printk(KERN_WARNING "%s: couldn't read register 0x%02x\n", __func__, reg); return -ENODEV; } -- cgit v1.2.3 From a4e36e60a6f62db6282e718cc228bde1a4e31eba Mon Sep 17 00:00:00 2001 From: "Arnaud Patard (Rtp)" Date: Mon, 28 Feb 2011 10:15:59 -0300 Subject: [media] mantis_pci: remove asm/pgtable.h include mantis_pci.c is including asm/pgtable.h and it's leading to a build failure on arm. It has been noticed here : https://buildd.debian.org/fetch.cgi?pkg=linux-2.6&arch=armel&ver=2.6.38~rc6-1~experimental.1&stamp=1298430952&file=log&as=raw As this header doesn't seem to be used, I'm removing it. I've build tested it with arm and x86. Signed-off-by: Arnaud Patard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/mantis/mantis_pci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/dvb/mantis/mantis_pci.c index 59feeb84aec7..10a432a79d00 100644 --- a/drivers/media/dvb/mantis/mantis_pci.c +++ b/drivers/media/dvb/mantis/mantis_pci.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 0c0db0355bc070b4c623622248d3f577642536b9 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 3 Mar 2011 17:56:05 +0100 Subject: [S390] xpram: remove __initdata attribute from module parameters The module parameter 'devs' and 'sizes' are marked as __initdata. The memory for the parameters are freed after module_init completed. This can lead to kernel crashes in param_free_charp. Remove the __initdata attribute to fix the problem. Signed-off-by: Martin Schwidefsky --- drivers/s390/block/xpram.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index c881a14fa5dd..1f6a4d894e73 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -62,8 +62,8 @@ static int xpram_devs; /* * Parameter parsing functions. */ -static int __initdata devs = XPRAM_DEVS; -static char __initdata *sizes[XPRAM_MAX_DEVS]; +static int devs = XPRAM_DEVS; +static char *sizes[XPRAM_MAX_DEVS]; module_param(devs, int, 0); module_param_array(sizes, charp, NULL, 0); -- cgit v1.2.3 From b652277b09d3d030cb074cc6a98ba80b34244c03 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Mar 2011 17:56:06 +0100 Subject: [S390] keyboard: integer underflow bug The "ct" variable should be an unsigned int. Both struct kbdiacrs ->kb_cnt and struct kbd_data ->accent_table_size are unsigned ints. Making it signed causes a problem in KBDIACRUC because the user could set the signed bit and cause a buffer overflow. Cc: Signed-off-by: Dan Carpenter Signed-off-by: Martin Schwidefsky --- drivers/s390/char/keyboard.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 8cd58e412b5e..5ad44daef73b 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -460,7 +460,8 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp; - int ct, perm; + unsigned int ct; + int perm; argp = (void __user *)arg; -- cgit v1.2.3 From 0c2bd9b24e73287aa4ee87844c847205e0da8a9b Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 3 Mar 2011 17:56:07 +0100 Subject: [S390] tape: deadlock on system work queue The 34xx and 3590 tape driver uses the system work queue to defer work from the interrupt function to process context, e.g. a medium sense after an unsolicited interrupt. The tape commands started by the work handler need to be asynchronous, otherwise a deadlock on the system work queue can occur. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tape.h | 8 +++++ drivers/s390/char/tape_34xx.c | 59 ++++++++++++++++++++---------- drivers/s390/char/tape_3590.c | 83 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 116 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 7a242f073632..267b54e8ff5a 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -280,6 +280,14 @@ tape_do_io_free(struct tape_device *device, struct tape_request *request) return rc; } +static inline void +tape_do_io_async_free(struct tape_device *device, struct tape_request *request) +{ + request->callback = (void *) tape_free_request; + request->callback_data = NULL; + tape_do_io_async(device, request); +} + extern int tape_oper_handler(int irq, int status); extern void tape_noper_handler(int irq, int status); extern int tape_open(struct tape_device *); diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index c17f35b6136a..c26511171ffe 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -53,23 +53,11 @@ static void tape_34xx_delete_sbid_from(struct tape_device *, int); * Medium sense for 34xx tapes. There is no 'real' medium sense call. * So we just do a normal sense. */ -static int -tape_34xx_medium_sense(struct tape_device *device) +static void __tape_34xx_medium_sense(struct tape_request *request) { - struct tape_request *request; - unsigned char *sense; - int rc; - - request = tape_alloc_request(1, 32); - if (IS_ERR(request)) { - DBF_EXCEPTION(6, "MSEN fail\n"); - return PTR_ERR(request); - } - - request->op = TO_MSEN; - tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + struct tape_device *device = request->device; + unsigned char *sense; - rc = tape_do_io_interruptible(device, request); if (request->rc == 0) { sense = request->cpdata; @@ -88,15 +76,47 @@ tape_34xx_medium_sense(struct tape_device *device) device->tape_generic_status |= GMT_WR_PROT(~0); else device->tape_generic_status &= ~GMT_WR_PROT(~0); - } else { + } else DBF_EVENT(4, "tape_34xx: medium sense failed with rc=%d\n", request->rc); - } tape_free_request(request); +} + +static int tape_34xx_medium_sense(struct tape_device *device) +{ + struct tape_request *request; + int rc; + + request = tape_alloc_request(1, 32); + if (IS_ERR(request)) { + DBF_EXCEPTION(6, "MSEN fail\n"); + return PTR_ERR(request); + } + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + rc = tape_do_io_interruptible(device, request); + __tape_34xx_medium_sense(request); return rc; } +static void tape_34xx_medium_sense_async(struct tape_device *device) +{ + struct tape_request *request; + + request = tape_alloc_request(1, 32); + if (IS_ERR(request)) { + DBF_EXCEPTION(6, "MSEN fail\n"); + return; + } + + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + request->callback = (void *) __tape_34xx_medium_sense; + request->callback_data = NULL; + tape_do_io_async(device, request); +} + struct tape_34xx_work { struct tape_device *device; enum tape_op op; @@ -109,6 +129,9 @@ struct tape_34xx_work { * is inserted but cannot call tape_do_io* from an interrupt context. * Maybe that's useful for other actions we want to start from the * interrupt handler. + * Note: the work handler is called by the system work queue. The tape + * commands started by the handler need to be asynchrounous, otherwise + * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq). */ static void tape_34xx_work_handler(struct work_struct *work) @@ -119,7 +142,7 @@ tape_34xx_work_handler(struct work_struct *work) switch(p->op) { case TO_MSEN: - tape_34xx_medium_sense(device); + tape_34xx_medium_sense_async(device); break; default: DBF_EVENT(3, "T34XX: internal error: unknown work\n"); diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index fbe361fcd2c0..de2e99e0a71b 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -329,17 +329,17 @@ out: /* * Enable encryption */ -static int tape_3592_enable_crypt(struct tape_device *device) +static struct tape_request *__tape_3592_enable_crypt(struct tape_device *device) { struct tape_request *request; char *data; DBF_EVENT(6, "tape_3592_enable_crypt\n"); if (!crypt_supported(device)) - return -ENOSYS; + return ERR_PTR(-ENOSYS); request = tape_alloc_request(2, 72); if (IS_ERR(request)) - return PTR_ERR(request); + return request; data = request->cpdata; memset(data,0,72); @@ -354,23 +354,42 @@ static int tape_3592_enable_crypt(struct tape_device *device) request->op = TO_CRYPT_ON; tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); + return request; +} + +static int tape_3592_enable_crypt(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_enable_crypt(device); + if (IS_ERR(request)) + return PTR_ERR(request); return tape_do_io_free(device, request); } +static void tape_3592_enable_crypt_async(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_enable_crypt(device); + if (!IS_ERR(request)) + tape_do_io_async_free(device, request); +} + /* * Disable encryption */ -static int tape_3592_disable_crypt(struct tape_device *device) +static struct tape_request *__tape_3592_disable_crypt(struct tape_device *device) { struct tape_request *request; char *data; DBF_EVENT(6, "tape_3592_disable_crypt\n"); if (!crypt_supported(device)) - return -ENOSYS; + return ERR_PTR(-ENOSYS); request = tape_alloc_request(2, 72); if (IS_ERR(request)) - return PTR_ERR(request); + return request; data = request->cpdata; memset(data,0,72); @@ -383,9 +402,28 @@ static int tape_3592_disable_crypt(struct tape_device *device) tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); + return request; +} + +static int tape_3592_disable_crypt(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_disable_crypt(device); + if (IS_ERR(request)) + return PTR_ERR(request); return tape_do_io_free(device, request); } +static void tape_3592_disable_crypt_async(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_disable_crypt(device); + if (!IS_ERR(request)) + tape_do_io_async_free(device, request); +} + /* * IOCTL: Set encryption status */ @@ -457,8 +495,7 @@ tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg) /* * SENSE Medium: Get Sense data about medium state */ -static int -tape_3590_sense_medium(struct tape_device *device) +static int tape_3590_sense_medium(struct tape_device *device) { struct tape_request *request; @@ -470,6 +507,18 @@ tape_3590_sense_medium(struct tape_device *device) return tape_do_io_free(device, request); } +static void tape_3590_sense_medium_async(struct tape_device *device) +{ + struct tape_request *request; + + request = tape_alloc_request(1, 128); + if (IS_ERR(request)) + return; + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, MEDIUM_SENSE, 128, request->cpdata); + tape_do_io_async_free(device, request); +} + /* * MTTELL: Tell block. Return the number of block relative to current file. */ @@ -546,15 +595,14 @@ tape_3590_read_opposite(struct tape_device *device, * 2. The attention msg is written to the "read subsystem data" buffer. * In this case we probably should print it to the console. */ -static int -tape_3590_read_attmsg(struct tape_device *device) +static void tape_3590_read_attmsg_async(struct tape_device *device) { struct tape_request *request; char *buf; request = tape_alloc_request(3, 4096); if (IS_ERR(request)) - return PTR_ERR(request); + return; request->op = TO_READ_ATTMSG; buf = request->cpdata; buf[0] = PREP_RD_SS_DATA; @@ -562,12 +610,15 @@ tape_3590_read_attmsg(struct tape_device *device) tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf); tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12); tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); - return tape_do_io_free(device, request); + tape_do_io_async_free(device, request); } /* * These functions are used to schedule follow-up actions from within an * interrupt context (like unsolicited interrupts). + * Note: the work handler is called by the system work queue. The tape + * commands started by the handler need to be asynchrounous, otherwise + * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq). */ struct work_handler_data { struct tape_device *device; @@ -583,16 +634,16 @@ tape_3590_work_handler(struct work_struct *work) switch (p->op) { case TO_MSEN: - tape_3590_sense_medium(p->device); + tape_3590_sense_medium_async(p->device); break; case TO_READ_ATTMSG: - tape_3590_read_attmsg(p->device); + tape_3590_read_attmsg_async(p->device); break; case TO_CRYPT_ON: - tape_3592_enable_crypt(p->device); + tape_3592_enable_crypt_async(p->device); break; case TO_CRYPT_OFF: - tape_3592_disable_crypt(p->device); + tape_3592_disable_crypt_async(p->device); break; default: DBF_EVENT(3, "T3590: work handler undefined for " -- cgit v1.2.3 From 73412c3854c877e5f37ad944ee8977addde4d35a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Mar 2011 09:58:36 +1000 Subject: drm/nouveau: allocate kernel's notifier object at end of block The nv30/nv40 3d driver is about to start using DMA_FENCE from the 3D object which, it turns out, doesn't like its DMA object to not be aligned to a 4KiB boundary. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_dma.c | 3 ++- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 ++- drivers/gpu/drm/nouveau/nouveau_notifier.c | 11 +++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 65699bfaaaea..b368ed74aad7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -83,7 +83,8 @@ nouveau_dma_init(struct nouveau_channel *chan) return ret; /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ - ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); + ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfd0, 0x1000, + &chan->m2mf_ntfy); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9821fcacc3d2..982d70b12722 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -852,7 +852,8 @@ extern const struct ttm_mem_type_manager_func nouveau_vram_manager; extern int nouveau_notifier_init_channel(struct nouveau_channel *); extern void nouveau_notifier_takedown_channel(struct nouveau_channel *); extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, - int cout, uint32_t *offset); + int cout, uint32_t start, uint32_t end, + uint32_t *offset); extern int nouveau_notifier_offset(struct nouveau_gpuobj *, uint32_t *); extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data, struct drm_file *); diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index fe29d604b820..5ea167623a82 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c @@ -96,7 +96,8 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev, int nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, - int size, uint32_t *b_offset) + int size, uint32_t start, uint32_t end, + uint32_t *b_offset) { struct drm_device *dev = chan->dev; struct nouveau_gpuobj *nobj = NULL; @@ -104,9 +105,10 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, uint32_t offset; int target, ret; - mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0); + mem = drm_mm_search_free_in_range(&chan->notifier_heap, size, 0, + start, end, 0); if (mem) - mem = drm_mm_get_block(mem, size, 0); + mem = drm_mm_get_block_range(mem, size, 0, start, end); if (!mem) { NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); return -ENOMEM; @@ -177,7 +179,8 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, if (IS_ERR(chan)) return PTR_ERR(chan); - ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); + ret = nouveau_notifier_alloc(chan, na->handle, na->size, 0, 0x1000, + &na->offset); nouveau_channel_put(&chan); return ret; } -- cgit v1.2.3 From 2ec38a0359e227c01080dcd670a0368c61ccd9ce Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 4 Mar 2011 17:36:19 -0800 Subject: drivers/rtc/rtc-s3c.c: fix prototype for s3c_rtc_setaie() Fix s3c_rtc_setaie() prototype to eliminate the following compile warning: drivers/rtc/rtc-s3c.c:383: warning: initialization from incompatible pointer type (akpm: the rtc_class_ops.alarm_irq_enable() handler is being passed two arguments where it expects just one, presumably with undesired effects) Signed-off-by: Axel Lin Cc: Alessandro Zummo Cc: Ben Dooks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s3c.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index cf953ecbfca9..b80fa2882408 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -77,18 +77,20 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id) } /* Update control registers */ -static void s3c_rtc_setaie(int to) +static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) { unsigned int tmp; - pr_debug("%s: aie=%d\n", __func__, to); + pr_debug("%s: aie=%d\n", __func__, enabled); tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; - if (to) + if (enabled) tmp |= S3C2410_RTCALM_ALMEN; writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); + + return 0; } static int s3c_rtc_setpie(struct device *dev, int enabled) @@ -308,7 +310,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) writeb(alrm_en, base + S3C2410_RTCALM); - s3c_rtc_setaie(alrm->enabled); + s3c_rtc_setaie(dev, alrm->enabled); return 0; } @@ -440,7 +442,7 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) rtc_device_unregister(rtc); s3c_rtc_setpie(&dev->dev, 0); - s3c_rtc_setaie(0); + s3c_rtc_setaie(&dev->dev, 0); clk_disable(rtc_clk); clk_put(rtc_clk); -- cgit v1.2.3 From 97e419a082461f8a3a0818834eb88ad41219a1da Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 4 Mar 2011 17:36:22 -0800 Subject: drivers/misc/bmp085.c: add MODULE_DEVICE_TABLE The device table is required to load modules based on modaliases. Signed-off-by: Axel Lin Cc: Shubhrajyoti D Cc: Christoph Mair Cc: Jonathan Cameron Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/bmp085.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c index 63ee4c1a5315..b6e1c9a6679e 100644 --- a/drivers/misc/bmp085.c +++ b/drivers/misc/bmp085.c @@ -449,6 +449,7 @@ static const struct i2c_device_id bmp085_id[] = { { "bmp085", 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, bmp085_id); static struct i2c_driver bmp085_driver = { .driver = { -- cgit v1.2.3 From 95b90afec301f050f72740e8696f7cce8a37db5a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 4 Mar 2011 17:36:23 -0800 Subject: pps: make pps_gen_parport depend on BROKEN This driver causes hard lockups, when the active clock soure is jiffies. The reason is that it loops with interrupts disabled waiting for a timestamp to be reached by polling getnstimeofday(). Though with a jiffies clocksource, when that code runs on the same CPU which is responsible for updating jiffies, then we loop in circles for ever simply because the timer interrupt cannot update jiffies. So both UP and SMP can be affected. There is no easy fix for that problem so make it depend on BROKEN for now. Signed-off-by: Thomas Gleixner Cc: Alexander Gordeev Cc: Rodolfo Giometti Cc: john stultz Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pps/generators/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pps/generators/Kconfig b/drivers/pps/generators/Kconfig index f3a73dd77660..e4c4f3dc0728 100644 --- a/drivers/pps/generators/Kconfig +++ b/drivers/pps/generators/Kconfig @@ -6,7 +6,7 @@ comment "PPS generators support" config PPS_GENERATOR_PARPORT tristate "Parallel port PPS signal generator" - depends on PARPORT + depends on PARPORT && BROKEN help If you say yes here you get support for a PPS signal generator which utilizes STROBE pin of a parallel port to send PPS signals. It uses -- cgit v1.2.3 From 9dab51daef2e4a0d18d7824e23fcb64a2a86481d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 4 Mar 2011 17:36:27 -0800 Subject: drivers/video/backlight/ltv350qv.c: fix a memory leak Signed-off-by: Axel Lin Cc: Haavard Skinnemoen Cc: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/ltv350qv.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index 8010aaeb5adb..dd0e84a9bd2f 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c @@ -239,11 +239,15 @@ static int __devinit ltv350qv_probe(struct spi_device *spi) lcd->spi = spi; lcd->power = FB_BLANK_POWERDOWN; lcd->buffer = kzalloc(8, GFP_KERNEL); + if (!lcd->buffer) { + ret = -ENOMEM; + goto out_free_lcd; + } ld = lcd_device_register("ltv350qv", &spi->dev, lcd, <v_ops); if (IS_ERR(ld)) { ret = PTR_ERR(ld); - goto out_free_lcd; + goto out_free_buffer; } lcd->ld = ld; @@ -257,6 +261,8 @@ static int __devinit ltv350qv_probe(struct spi_device *spi) out_unregister: lcd_device_unregister(ld); +out_free_buffer: + kfree(lcd->buffer); out_free_lcd: kfree(lcd); return ret; @@ -268,6 +274,7 @@ static int __devexit ltv350qv_remove(struct spi_device *spi) ltv350qv_power(lcd, FB_BLANK_POWERDOWN); lcd_device_unregister(lcd->ld); + kfree(lcd->buffer); kfree(lcd); return 0; -- cgit v1.2.3 From 0ee537abbd10a9abf11e1c22ee32a68e8c12ed4a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Mar 2011 09:03:16 +0000 Subject: Revert "drm/i915: fix corruptions on i8xx due to relaxed fencing" This reverts commit c2e0eb167070a6e9dcb49c84c13c79a30d672431. As it turns out, userspace already depends upon being able to enable tiling on existing bo which it promises to be large enough for its purposes i.e. it will not access beyond the end of the last full-tile row. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=35016 Reported-and-tested-by: Kamal Mostafa Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_tiling.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 79a04fde69b5..22a32b9932c5 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -184,7 +184,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) static bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) { - int tile_width, tile_height; + int tile_width; /* Linear is always fine */ if (tiling_mode == I915_TILING_NONE) @@ -215,20 +215,6 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) } } - if (IS_GEN2(dev) || - (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) - tile_height = 32; - else - tile_height = 8; - /* i8xx is strange: It has 2 interleaved rows of tiles, so needs an even - * number of tile rows. */ - if (IS_GEN2(dev)) - tile_height *= 2; - - /* Size needs to be aligned to a full tile row */ - if (size & (tile_height * stride - 1)) - return false; - /* 965+ just needs multiples of tile width */ if (INTEL_INFO(dev)->gen >= 4) { if (stride & (tile_width - 1)) -- cgit v1.2.3 From 91355834646328e7edc6bd25176ae44bcd7386c7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Mar 2011 19:22:40 +0000 Subject: drm/i915: Do not overflow the MMADDR write FIFO Whilst the GT is powered down (rc6), writes to MMADDR are placed in a FIFO by the System Agent. This is a limited resource, only 64 entries, of which 20 are reserved for Display and PCH writes, and so we must take care not to queue up too many writes. To avoid this, there is counter which we can poll to ensure there are sufficient free entries in the fifo. "Issuing a write to a full FIFO is not supported; at worst it could result in corruption or a system hang." Reported-and-Tested-by: Matt Turner Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34056 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.c | 14 ++++++++++++-- drivers/gpu/drm/i915/i915_drv.h | 20 +++++++++++++++----- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_display.c | 8 ++++---- drivers/gpu/drm/i915/intel_ringbuffer.h | 13 +++++++------ 6 files changed, 42 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3601466c5502..4ff9b6cc973f 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -865,7 +865,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) int max_freq; /* RPSTAT1 is in the GT power well */ - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); seq_printf(m, "RPSTAT1: 0x%08x\n", I915_READ(GEN6_RPSTAT1)); @@ -888,7 +888,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", max_freq * 100); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } else { seq_printf(m, "no P-state info available\n"); } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0ad533f06af9..37d672a116db 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -254,7 +254,7 @@ void intel_detect_pch (struct drm_device *dev) } } -void __gen6_force_wake_get(struct drm_i915_private *dev_priv) +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) { int count; @@ -270,12 +270,22 @@ void __gen6_force_wake_get(struct drm_i915_private *dev_priv) udelay(10); } -void __gen6_force_wake_put(struct drm_i915_private *dev_priv) +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE, 0); POSTING_READ(FORCEWAKE); } +void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) +{ + int loop = 500; + u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); + while (fifo < 20 && loop--) { + udelay(10); + fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); + } +} + static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 65dfe81d0035..549c046b4ecc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1353,22 +1353,32 @@ __i915_write(64, q) * must be set to prevent GT core from power down and stale values being * returned. */ -void __gen6_force_wake_get(struct drm_i915_private *dev_priv); -void __gen6_force_wake_put (struct drm_i915_private *dev_priv); -static inline u32 i915_safe_read(struct drm_i915_private *dev_priv, u32 reg) +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); +void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); + +static inline u32 i915_gt_read(struct drm_i915_private *dev_priv, u32 reg) { u32 val; if (dev_priv->info->gen >= 6) { - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); val = I915_READ(reg); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } else val = I915_READ(reg); return val; } +static inline void i915_gt_write(struct drm_i915_private *dev_priv, + u32 reg, u32 val) +{ + if (dev_priv->info->gen >= 6) + __gen6_gt_wait_for_fifo(dev_priv); + I915_WRITE(reg, val); +} + static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 729d4233b763..3e6f486f4605 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3261,6 +3261,8 @@ #define FORCEWAKE 0xA18C #define FORCEWAKE_ACK 0x130090 +#define GT_FIFO_FREE_ENTRIES 0x120008 + #define GEN6_RPNSWREQ 0xA008 #define GEN6_TURBO_DISABLE (1<<31) #define GEN6_FREQUENCY(x) ((x)<<25) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e79b25bbee6c..49fb54fd9a18 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1219,7 +1219,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev) u32 blt_ecoskpd; /* Make sure blitter notifies FBC of writes */ - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD); blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY << GEN6_BLITTER_LOCK_SHIFT; @@ -1230,7 +1230,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev) GEN6_BLITTER_LOCK_SHIFT); I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); POSTING_READ(GEN6_BLITTER_ECOSKPD); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) @@ -6282,7 +6282,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) * userspace... */ I915_WRITE(GEN6_RC_STATE, 0); - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); /* disable the counters and set deterministic thresholds */ I915_WRITE(GEN6_RC_CONTROL, 0); @@ -6380,7 +6380,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) /* enable all PM interrupts */ I915_WRITE(GEN6_PMINTRMSK, 0); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } void intel_enable_clock_gating(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 6d6fde85a636..34306865a5df 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -14,22 +14,23 @@ struct intel_hw_status_page { struct drm_i915_gem_object *obj; }; -#define I915_RING_READ(reg) i915_safe_read(dev_priv, reg) +#define I915_RING_READ(reg) i915_gt_read(dev_priv, reg) +#define I915_RING_WRITE(reg, val) i915_gt_write(dev_priv, reg, val) #define I915_READ_TAIL(ring) I915_RING_READ(RING_TAIL((ring)->mmio_base)) -#define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL((ring)->mmio_base), val) +#define I915_WRITE_TAIL(ring, val) I915_RING_WRITE(RING_TAIL((ring)->mmio_base), val) #define I915_READ_START(ring) I915_RING_READ(RING_START((ring)->mmio_base)) -#define I915_WRITE_START(ring, val) I915_WRITE(RING_START((ring)->mmio_base), val) +#define I915_WRITE_START(ring, val) I915_RING_WRITE(RING_START((ring)->mmio_base), val) #define I915_READ_HEAD(ring) I915_RING_READ(RING_HEAD((ring)->mmio_base)) -#define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD((ring)->mmio_base), val) +#define I915_WRITE_HEAD(ring, val) I915_RING_WRITE(RING_HEAD((ring)->mmio_base), val) #define I915_READ_CTL(ring) I915_RING_READ(RING_CTL((ring)->mmio_base)) -#define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL((ring)->mmio_base), val) +#define I915_WRITE_CTL(ring, val) I915_RING_WRITE(RING_CTL((ring)->mmio_base), val) -#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) #define I915_READ_IMR(ring) I915_RING_READ(RING_IMR((ring)->mmio_base)) +#define I915_WRITE_IMR(ring, val) I915_RING_WRITE(RING_IMR((ring)->mmio_base), val) #define I915_READ_NOPID(ring) I915_RING_READ(RING_NOPID((ring)->mmio_base)) #define I915_READ_SYNC_0(ring) I915_RING_READ(RING_SYNC_0((ring)->mmio_base)) -- cgit v1.2.3 From d7a62cd0332115d4c7c4689abea0d889a30d8349 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Fri, 4 Mar 2011 14:04:33 +1030 Subject: virtio: console: Don't access vqs if device was unplugged If a virtio-console device gets unplugged while a port is open, a subsequent close() call on the port accesses vqs to free up buffers. This can lead to a crash. The buffers are already freed up as a result of the call to unplug_ports() from virtcons_remove(). The fix is to simply not access vq information if port->portdev is NULL. Reported-by: juzhang CC: stable@kernel.org Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds --- drivers/char/virtio_console.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 490393186338..84b164d1eb2b 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -388,6 +388,10 @@ static void discard_port_data(struct port *port) unsigned int len; int ret; + if (!port->portdev) { + /* Device has been unplugged. vqs are already gone. */ + return; + } vq = port->in_vq; if (port->inbuf) buf = port->inbuf; @@ -470,6 +474,10 @@ static void reclaim_consumed_buffers(struct port *port) void *buf; unsigned int len; + if (!port->portdev) { + /* Device has been unplugged. vqs are already gone. */ + return; + } while ((buf = virtqueue_get_buf(port->out_vq, &len))) { kfree(buf); port->outvq_full = false; -- cgit v1.2.3 From c4154f25c85a44c8ff331c3d28e8d9d2f710a553 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 6 Mar 2011 10:49:25 +0000 Subject: bnx2x: fix non-pmf device load flow Remove port MAX BW configuration from non-pmf functions, which caused reconfigure of HW according to 10G (fake) link. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 032ae184b605..469ca60195c4 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2092,8 +2092,9 @@ static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type) bnx2x_calc_vn_weight_sum(bp); /* calculate and set min-max rate for each vn */ - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, vn); + if (bp->port.pmf) + for (vn = VN_0; vn < E1HVN_MAX; vn++) + bnx2x_init_vn_minmax(bp, vn); /* always enable rate shaping and fairness */ bp->cmng.flags.cmng_enables |= -- cgit v1.2.3 From 9fdc3e9566b3ae691aefc3aa7b8dca6cac32c95e Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 6 Mar 2011 10:49:15 +0000 Subject: bnx2x: fix link notification Report link to OS and other PFs after HW is fully reconfigured according to new link parameters. (Affected only Multi Function modes). Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 469ca60195c4..aa032339e321 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2163,13 +2163,6 @@ static void bnx2x_link_attn(struct bnx2x *bp) bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); } - /* indicate link status only if link status actually changed */ - if (prev_link_status != bp->link_vars.link_status) - bnx2x_link_report(bp); - - if (IS_MF(bp)) - bnx2x_link_sync_notify(bp); - if (bp->link_vars.link_up && bp->link_vars.line_speed) { int cmng_fns = bnx2x_get_cmng_fns_mode(bp); @@ -2181,6 +2174,13 @@ static void bnx2x_link_attn(struct bnx2x *bp) DP(NETIF_MSG_IFUP, "single function mode without fairness\n"); } + + if (IS_MF(bp)) + bnx2x_link_sync_notify(bp); + + /* indicate link status only if link status actually changed */ + if (prev_link_status != bp->link_vars.link_status) + bnx2x_link_report(bp); } void bnx2x__link_status_update(struct bnx2x *bp) -- cgit v1.2.3 From e3835b99333eb3ac7222f6fc0af5cae46074ac49 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 6 Mar 2011 10:50:44 +0000 Subject: bnx2x: (NPAR) prevent HW access in D3 state Changing speed setting in NPAR requires HW access, this patch delays the access to D0 state when performed in D3. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 1 + drivers/net/bnx2x/bnx2x_cmn.c | 22 ++++++++++++++++++++++ drivers/net/bnx2x/bnx2x_cmn.h | 9 +++++++++ drivers/net/bnx2x/bnx2x_ethtool.c | 18 ++++++++---------- 4 files changed, 40 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 7897d114b290..2ac4e3c597fa 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1211,6 +1211,7 @@ struct bnx2x { /* DCBX Negotation results */ struct dcbx_features dcbx_local_feat; u32 dcbx_error; + u32 pending_max; }; /** diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 93798129061b..a71b32940533 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -996,6 +996,23 @@ void bnx2x_free_skbs(struct bnx2x *bp) bnx2x_free_rx_skbs(bp); } +void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value) +{ + /* load old values */ + u32 mf_cfg = bp->mf_config[BP_VN(bp)]; + + if (value != bnx2x_extract_max_cfg(bp, mf_cfg)) { + /* leave all but MAX value */ + mf_cfg &= ~FUNC_MF_CFG_MAX_BW_MASK; + + /* set new MAX value */ + mf_cfg |= (value << FUNC_MF_CFG_MAX_BW_SHIFT) + & FUNC_MF_CFG_MAX_BW_MASK; + + bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, mf_cfg); + } +} + static void bnx2x_free_msix_irqs(struct bnx2x *bp) { int i, offset = 1; @@ -1464,6 +1481,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bnx2x_set_eth_mac(bp, 1); + if (bp->pending_max) { + bnx2x_update_max_mf_config(bp, bp->pending_max); + bp->pending_max = 0; + } + if (bp->port.pmf) bnx2x_initial_phy_init(bp, load_mode); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 326ba44b3ded..85ea7f26b51f 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -341,6 +341,15 @@ void bnx2x_dcbx_init(struct bnx2x *bp); */ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); +/** + * Updates MAX part of MF configuration in HW + * (if required) + * + * @param bp + * @param value + */ +void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value); + /* dev_close main block */ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index ef2919987a10..7e92f9d0dcfd 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) speed |= (cmd->speed_hi << 16); if (IS_MF_SI(bp)) { - u32 param = 0, part; + u32 part; u32 line_speed = bp->link_vars.line_speed; /* use 10G if no link detected */ @@ -251,24 +251,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) REQ_BC_VER_4_SET_MF_BW); return -EINVAL; } + part = (speed * 100) / line_speed; + if (line_speed < speed || !part) { BNX2X_DEV_INFO("Speed setting should be in a range " "from 1%% to 100%% " "of actual line speed\n"); return -EINVAL; } - /* load old values */ - param = bp->mf_config[BP_VN(bp)]; - /* leave only MIN value */ - param &= FUNC_MF_CFG_MIN_BW_MASK; - - /* set new MAX value */ - param |= (part << FUNC_MF_CFG_MAX_BW_SHIFT) - & FUNC_MF_CFG_MAX_BW_MASK; + if (bp->state != BNX2X_STATE_OPEN) + /* store value for following "load" */ + bp->pending_max = part; + else + bnx2x_update_max_mf_config(bp, part); - bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); return 0; } -- cgit v1.2.3 From 9b3de1ef1ba0aa1129a9f857f07a6a97d954c6fd Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 6 Mar 2011 10:51:37 +0000 Subject: bnx2x: fix MaxBW configuration Increase resolution of MaxBW algorithm to suit Min Bandwidth configuration. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 2ac4e3c597fa..8849699c66c4 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1617,8 +1617,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, /* CMNG constants, as derived from system spec calculations */ /* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */ #define DEF_MIN_RATE 100 -/* resolution of the rate shaping timer - 100 usec */ -#define RS_PERIODIC_TIMEOUT_USEC 100 +/* resolution of the rate shaping timer - 400 usec */ +#define RS_PERIODIC_TIMEOUT_USEC 400 /* number of bytes in single QM arbitration cycle - * coefficient for calculating the fairness timer */ #define QM_ARB_BYTES 160000 -- cgit v1.2.3 From 120bdaa47cdd1ca37ce938c888bb08e33e6181a8 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Fri, 4 Mar 2011 19:02:24 +0530 Subject: i2c-omap: Program I2C_WE on OMAP4 to enable i2c wakeup For the I2C module to be wakeup capable, programming I2C_WE register (which was skipped for OMAP4430) is needed even on OMAP4. This fixes i2c controller timeouts which were seen recently with the static dependency being cleared between MPU and L4PER clockdomains. Signed-off-by: Rajendra Nayak [ben-linux@fluff.org: re-flowed description] Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-omap.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 829a2a1029f7..58a58c7eaa17 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -378,9 +378,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev->westate = OMAP_I2C_WE_ALL; - if (dev->rev < OMAP_I2C_REV_ON_4430) - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, - dev->westate); + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); } } omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); -- cgit v1.2.3 From a1656b9090f7008d2941c314f5a64724bea2ae37 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Mar 2011 18:48:03 +0000 Subject: drm/i915: Disable GPU semaphores by default Andi Kleen narrowed his GPU hangs on his Sugar Bay (SNB desktop) rev 09 down to the use of GPU semaphores, and we already know that they appear broken up to Huron River (mobile) rev 08. (I'm optimistic that disabling GPU semaphores is simply hiding another bug by the latency and side-effects of the additional device interaction it introduces...) However, use of semaphores is a massive performance improvement... Only as long as the system remains stable. Enable at your peril. Reported-by: Andi Kleen Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=33921 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.c | 3 +++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 37d672a116db..22ec066adae6 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -46,6 +46,9 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); unsigned int i915_powersave = 1; module_param_named(powersave, i915_powersave, int, 0600); +unsigned int i915_semaphores = 0; +module_param_named(semaphores, i915_semaphores, int, 0600); + unsigned int i915_enable_rc6 = 0; module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 549c046b4ecc..d023b9b33d60 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -956,6 +956,7 @@ extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; extern unsigned int i915_fbpercrtc; extern unsigned int i915_powersave; +extern unsigned int i915_semaphores; extern unsigned int i915_lvds_downclock; extern unsigned int i915_panel_use_ssc; extern unsigned int i915_enable_rc6; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index d2f445e825f2..50ab1614571c 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -772,8 +772,8 @@ i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, if (from == NULL || to == from) return 0; - /* XXX gpu semaphores are currently causing hard hangs on SNB mobile */ - if (INTEL_INFO(obj->base.dev)->gen < 6 || IS_MOBILE(obj->base.dev)) + /* XXX gpu semaphores are implicated in various hard hangs on SNB */ + if (INTEL_INFO(obj->base.dev)->gen < 6 || !i915_semaphores) return i915_gem_object_wait_rendering(obj, true); idx = intel_ring_sync_index(from, to); -- cgit v1.2.3 From 467cffba85791cdfce38c124d75bd578f4bb8625 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 7 Mar 2011 10:42:03 +0000 Subject: drm/i915: Rebind the buffer if its alignment constraints changes with tiling Early gen3 and gen2 chipset do not have the relaxed per-surface tiling constraints of the later chipsets, so we need to check that the GTT alignment is correct for the new tiling. If it is not, we need to rebind. Reported-by: Daniel Vetter Reviewed-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_gem_tiling.c | 21 +++++++++++++++++---- 3 files changed, 21 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d023b9b33d60..456f40484838 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1178,6 +1178,9 @@ void i915_gem_detach_phys_object(struct drm_device *dev, void i915_gem_free_all_phys_object(struct drm_device *dev); void i915_gem_release(struct drm_device *dev, struct drm_file *file); +uint32_t +i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj); + /* i915_gem_gtt.c */ void i915_gem_restore_gtt_mappings(struct drm_device *dev); int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cf4f74c7c6fb..36e66cc5225e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1398,7 +1398,7 @@ i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj) * Return the required GTT alignment for an object, only taking into account * unfenced tiled surface requirements. */ -static uint32_t +uint32_t i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) { struct drm_device *dev = obj->base.dev; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 22a32b9932c5..d64843e18df2 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -349,14 +349,27 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, (obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end && i915_gem_object_fence_ok(obj, args->tiling_mode)); - obj->tiling_changed = true; - obj->tiling_mode = args->tiling_mode; - obj->stride = args->stride; + /* Rebind if we need a change of alignment */ + if (!obj->map_and_fenceable) { + u32 unfenced_alignment = + i915_gem_get_unfenced_gtt_alignment(obj); + if (obj->gtt_offset & (unfenced_alignment - 1)) + ret = i915_gem_object_unbind(obj); + } + + if (ret == 0) { + obj->tiling_changed = true; + obj->tiling_mode = args->tiling_mode; + obj->stride = args->stride; + } } + /* we have to maintain this existing ABI... */ + args->stride = obj->stride; + args->tiling_mode = obj->tiling_mode; drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); - return 0; + return ret; } /** -- cgit v1.2.3 From f277e65e7a2d360189f760baca42f3ca2f62dd7a Mon Sep 17 00:00:00 2001 From: Göran Weinholt Date: Wed, 2 Mar 2011 04:07:21 +0000 Subject: net/smsc911x.c: Set the VLAN1 register to fix VLAN MTU problem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The smsc911x driver would drop frames longer than 1518 bytes, which is a problem for networks with VLAN tagging. The VLAN1 tag register is used to increase the legal frame size to 1522 when a VLAN tag is identified. Signed-off-by: Göran Weinholt Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 64bfdae5956f..d70bde95460b 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1178,6 +1178,11 @@ static int smsc911x_open(struct net_device *dev) smsc911x_reg_write(pdata, HW_CFG, 0x00050000); smsc911x_reg_write(pdata, AFC_CFG, 0x006E3740); + /* Increase the legal frame size of VLAN tagged frames to 1522 bytes */ + spin_lock_irq(&pdata->mac_lock); + smsc911x_mac_write(pdata, VLAN1, ETH_P_8021Q); + spin_unlock_irq(&pdata->mac_lock); + /* Make sure EEPROM has finished loading before setting GPIO_CFG */ timeout = 50; while ((smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) && -- cgit v1.2.3 From ef1b287169cd3d1e428c8ed8222e0bbf733d5dbb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Mar 2011 17:18:03 +1000 Subject: drm/nouveau: fix regression causing ttm to not be able to evict vram TTM assumes an error condition from man->func->get_node() means that something went horribly wrong, and causes it to bail. The driver is supposed to return 0, and leave mm_node == NULL to signal that it couldn't allocate any memory. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_mem.c | 6 ++++-- drivers/gpu/drm/nouveau/nouveau_mm.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 26347b7cd872..b0fb9bdcddb7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -725,8 +725,10 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, ret = vram->get(dev, mem->num_pages << PAGE_SHIFT, mem->page_alignment << PAGE_SHIFT, size_nc, (nvbo->tile_flags >> 8) & 0xff, &node); - if (ret) - return ret; + if (ret) { + mem->mm_node = NULL; + return (ret == -ENOSPC) ? 0 : ret; + } node->page_shift = 12; if (nvbo->vma.node) diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.c b/drivers/gpu/drm/nouveau/nouveau_mm.c index 8844b50c3e54..7609756b6faf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mm.c +++ b/drivers/gpu/drm/nouveau/nouveau_mm.c @@ -123,7 +123,7 @@ nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc, return 0; } - return -ENOMEM; + return -ENOSPC; } int -- cgit v1.2.3 From 6f70a4c3d19e8e8e1047a4dbf0ca910fed39f619 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Mar 2011 17:18:04 +1000 Subject: drm/nv50-nvc0: prevent multiple vm/bar flushes occuring simultanenously The per-vm mutex doesn't prevent this completely, a flush coming from the BAR VM could potentially happen at the same time as one for the channel VM. Not to mention that if/when we get per-client/channel VM, this will happen far more frequently. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nv50_instmem.c | 8 ++++++++ drivers/gpu/drm/nouveau/nv50_vm.c | 4 ++++ 2 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index ea0041810ae3..e57caa2a00e3 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -403,16 +403,24 @@ nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj) void nv50_instmem_flush(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + + spin_lock(&dev_priv->ramin_lock); nv_wr32(dev, 0x00330c, 0x00000001); if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) NV_ERROR(dev, "PRAMIN flush timeout\n"); + spin_unlock(&dev_priv->ramin_lock); } void nv84_instmem_flush(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + + spin_lock(&dev_priv->ramin_lock); nv_wr32(dev, 0x070000, 0x00000001); if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) NV_ERROR(dev, "PRAMIN flush timeout\n"); + spin_unlock(&dev_priv->ramin_lock); } diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index 459ff08241e5..6144156f255a 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c @@ -169,7 +169,11 @@ nv50_vm_flush(struct nouveau_vm *vm) void nv50_vm_flush_engine(struct drm_device *dev, int engine) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + + spin_lock(&dev_priv->ramin_lock); nv_wr32(dev, 0x100c80, (engine << 16) | 1); if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); + spin_unlock(&dev_priv->ramin_lock); } -- cgit v1.2.3 From 34497913f2936fd43c86b007da7224bb8e77fd15 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Thu, 3 Mar 2011 17:40:10 -0500 Subject: mmc: sdio: Allow sdio operations in other threads during sdio_add_func() This fixes a bug introduced by 807e8e40673d ("mmc: Fix sd/sdio/mmc initialization frequency retries") that prevented SDIO drivers from performing SDIO commands in their probe routines -- the above patch called mmc_claim_host() before sdio_add_func(), which causes a deadlock if an external SDIO driver calls sdio_claim_host(). Fix tested on an OLPC XO-1.75 with libertas on SDIO. Signed-off-by: Dmitry Shmidt Reviewed-and-Tested-by: Chris Ball Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 5c4a54d9b6a4..ebc62ad4cc56 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -792,7 +792,6 @@ int mmc_attach_sdio(struct mmc_host *host) */ mmc_release_host(host); err = mmc_add_card(host->card); - mmc_claim_host(host); if (err) goto remove_added; @@ -805,12 +804,12 @@ int mmc_attach_sdio(struct mmc_host *host) goto remove_added; } + mmc_claim_host(host); return 0; remove_added: /* Remove without lock if the device has been added. */ - mmc_release_host(host); mmc_sdio_remove(host); mmc_claim_host(host); remove: -- cgit v1.2.3 From 062ac622e03a8be5f894555ece540d63a54ae8bd Mon Sep 17 00:00:00 2001 From: roel Date: Mon, 7 Mar 2011 18:00:34 +0100 Subject: drm: index i shadowed in 2nd loop Index i was already used in thhe first loop Signed-off-by: Roel Kluin Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 6977a1ce9d98..f73ef4390db6 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -672,7 +672,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) struct drm_crtc_helper_funcs *crtc_funcs; u16 *red, *green, *blue, *transp; struct drm_crtc *crtc; - int i, rc = 0; + int i, j, rc = 0; int start; for (i = 0; i < fb_helper->crtc_count; i++) { @@ -685,7 +685,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) transp = cmap->transp; start = cmap->start; - for (i = 0; i < cmap->len; i++) { + for (j = 0; j < cmap->len; j++) { u16 hred, hgreen, hblue, htransp = 0xffff; hred = *red++; -- cgit v1.2.3 From ce3c869283739379134e1a90c37dd1a30b5f31b7 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Fri, 4 Mar 2011 13:49:41 +0000 Subject: drivers/net/macvtap: fix error check 'len' is unsigned of type size_t and can't be negative. Signed-off-by: Nicolas Kaiser Acked-by: Arnd Bergmann Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 5933621ac3ff..fc27a9926d9e 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -528,8 +528,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, vnet_hdr_len = q->vnet_hdr_sz; err = -EINVAL; - if ((len -= vnet_hdr_len) < 0) + if (len < vnet_hdr_len) goto err; + len -= vnet_hdr_len; err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0, sizeof(vnet_hdr)); -- cgit v1.2.3 From 16d79d7dc98e56d4700054b9b785a92102d8998c Mon Sep 17 00:00:00 2001 From: Nils Carlson Date: Thu, 3 Mar 2011 22:09:11 +0000 Subject: bonding 802.3ad: Fix the state machine locking v2 Changes since v1: * Clarify an unclear comment * Move a (possible) name change to a separate patch The ad_rx_machine, ad_periodic_machine and ad_port_selection_logic functions all inspect and alter common fields within the port structure. Previous to this patch, only the ad_rx_machines were mutexed, and the periodic and port_selection could run unmutexed against an ad_rx_machine trigged by an arriving LACPDU. This patch remedies the situation by protecting all the state machines from concurrency. This is accomplished by locking around all the state machines for a given port, which are executed at regular intervals; and the ad_rx_machine when handling an incoming LACPDU. Signed-off-by: Nils Carlson Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 1024ae158227..de30c8d6301e 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -1025,9 +1025,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) { rx_states_t last_state; - // Lock to prevent 2 instances of this function to run simultaneously(rx interrupt and periodic machine callback) - __get_rx_machine_lock(port); - // keep current State Machine state to compare later if it was changed last_state = port->sm_rx_state; @@ -1133,7 +1130,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) pr_err("%s: An illegal loopback occurred on adapter (%s).\n" "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", port->slave->dev->master->name, port->slave->dev->name); - __release_rx_machine_lock(port); return; } __update_selected(lacpdu, port); @@ -1153,7 +1149,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) break; } } - __release_rx_machine_lock(port); } /** @@ -2155,6 +2150,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work) goto re_arm; } + /* Lock around state machines to protect data accessed + * by all (e.g., port->sm_vars). ad_rx_machine may run + * concurrently due to incoming LACPDU. + */ + __get_rx_machine_lock(port); + ad_rx_machine(NULL, port); ad_periodic_machine(port); ad_port_selection_logic(port); @@ -2164,6 +2165,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) // turn off the BEGIN bit, since we already handled it if (port->sm_vars & AD_PORT_BEGIN) port->sm_vars &= ~AD_PORT_BEGIN; + + __release_rx_machine_lock(port); } re_arm: @@ -2200,7 +2203,10 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u case AD_TYPE_LACPDU: pr_debug("Received LACPDU on port %d\n", port->actor_port_number); + /* Protect against concurrent state machines */ + __get_rx_machine_lock(port); ad_rx_machine(lacpdu, port); + __release_rx_machine_lock(port); break; case AD_TYPE_MARKER: -- cgit v1.2.3 From 9ac3524a948cab48137a8b40a4fa8ae1092b0a24 Mon Sep 17 00:00:00 2001 From: Nils Carlson Date: Thu, 3 Mar 2011 22:09:12 +0000 Subject: bonding 802.3ad: Rename rx_machine_lock to state_machine_lock Rename the rx_machine_lock to state_machine_lock as this makes more sense in light of it now protecting all the state machines against concurrency. Signed-off-by: Nils Carlson Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 24 ++++++++++++------------ drivers/net/bonding/bond_3ad.h | 3 ++- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index de30c8d6301e..a5d5d0b5b155 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -281,23 +281,23 @@ static inline int __check_agg_selection_timer(struct port *port) } /** - * __get_rx_machine_lock - lock the port's RX machine + * __get_state_machine_lock - lock the port's state machines * @port: the port we're looking at * */ -static inline void __get_rx_machine_lock(struct port *port) +static inline void __get_state_machine_lock(struct port *port) { - spin_lock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); + spin_lock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); } /** - * __release_rx_machine_lock - unlock the port's RX machine + * __release_state_machine_lock - unlock the port's state machines * @port: the port we're looking at * */ -static inline void __release_rx_machine_lock(struct port *port) +static inline void __release_state_machine_lock(struct port *port) { - spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); + spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); } /** @@ -388,14 +388,14 @@ static u8 __get_duplex(struct port *port) } /** - * __initialize_port_locks - initialize a port's RX machine spinlock + * __initialize_port_locks - initialize a port's STATE machine spinlock * @port: the port we're looking at * */ static inline void __initialize_port_locks(struct port *port) { // make sure it isn't called twice - spin_lock_init(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); + spin_lock_init(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); } //conversions @@ -2154,7 +2154,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) * by all (e.g., port->sm_vars). ad_rx_machine may run * concurrently due to incoming LACPDU. */ - __get_rx_machine_lock(port); + __get_state_machine_lock(port); ad_rx_machine(NULL, port); ad_periodic_machine(port); @@ -2166,7 +2166,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) if (port->sm_vars & AD_PORT_BEGIN) port->sm_vars &= ~AD_PORT_BEGIN; - __release_rx_machine_lock(port); + __release_state_machine_lock(port); } re_arm: @@ -2204,9 +2204,9 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u pr_debug("Received LACPDU on port %d\n", port->actor_port_number); /* Protect against concurrent state machines */ - __get_rx_machine_lock(port); + __get_state_machine_lock(port); ad_rx_machine(lacpdu, port); - __release_rx_machine_lock(port); + __release_state_machine_lock(port); break; case AD_TYPE_MARKER: diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 2c46a154f2c6..b28baff70864 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h @@ -264,7 +264,8 @@ struct ad_bond_info { struct ad_slave_info { struct aggregator aggregator; // 802.3ad aggregator structure struct port port; // 802.3ad port structure - spinlock_t rx_machine_lock; // To avoid race condition between callback and receive interrupt + spinlock_t state_machine_lock; /* mutex state machines vs. + incoming LACPDU */ u16 id; }; -- cgit v1.2.3 From bad3babace2ee4d1763b4016a662a5c660ab92e9 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Tue, 8 Mar 2011 23:32:02 +0200 Subject: mmc: fix CONFIG_MMC_UNSAFE_RESUME regression 30201e7f3 ("mmc: skip detection of nonremovable cards on rescan") allowed skipping detection of nonremovable cards on mmc_rescan(). The intention was to only skip detection of hardwired cards that cannot be removed, so make sure this is indeed the case by directly checking for (lack of) MMC_CAP_NONREMOVABLE, instead of using mmc_card_is_removable(), which is overloaded with CONFIG_MMC_UNSAFE_RESUME semantics. The user-visible symptom of the bug this patch fixes is that no "mmc: card XXXX removed" message appears in dmesg when a card is removed and CONFIG_MMC_UNSAFE_RESUME=y. Reported-and-tested-by: Dmitry Shmidt Reported-and-tested-by: Maxim Levitsky Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 6625c057be05..150b5f3cd401 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1529,7 +1529,7 @@ void mmc_rescan(struct work_struct *work) * still present */ if (host->bus_ops && host->bus_ops->detect && !host->bus_dead - && mmc_card_is_removable(host)) + && !(host->caps & MMC_CAP_NONREMOVABLE)) host->bus_ops->detect(host); /* -- cgit v1.2.3 From c60c9c71ade23351d9cd9d1ef96ad007eb4a15ab Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 7 Mar 2011 00:09:40 +0000 Subject: r6040: fix multicast operations The original code does not work well when the number of mulitcast address to handle is greater than MCAST_MAX. It only enable promiscous mode instead of multicast hash table mode, so the hash table function will not be activated and all multicast frames will be recieved in this condition. This patch fixes the following issues with the r6040 NIC operating in multicast: 1) When the IFF_ALLMULTI flag is set, we should write 0xffff to the NIC hash table registers to make it process multicast traffic. 2) When the number of multicast address to handle is smaller than MCAST_MAX, we should use the NIC multicast registers MID1_{L,M,H}. 3) The hashing of the address was not correct, due to an invalid substraction (15 - (crc & 0x0f)) instead of (crc & 0x0f) and an incorrect crc algorithm (ether_crc_le) instead of (ether_crc). 4) If necessary, we should set HASH_EN flag in MCR0 to enable multicast hash table function. Reported-by: Marc Leclerc Tested-by: Marc Leclerc Signed-off-by: Shawn Lin Signed-off-by: Albert Chen Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 111 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 27e6f6d43cac..7965ae42eae4 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -69,6 +69,8 @@ /* MAC registers */ #define MCR0 0x00 /* Control register 0 */ +#define MCR0_PROMISC 0x0020 /* Promiscuous mode */ +#define MCR0_HASH_EN 0x0100 /* Enable multicast hash table function */ #define MCR1 0x04 /* Control register 1 */ #define MAC_RST 0x0001 /* Reset the MAC */ #define MBCR 0x08 /* Bus control */ @@ -851,77 +853,92 @@ static void r6040_multicast_list(struct net_device *dev) { struct r6040_private *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; - u16 *adrp; - u16 reg; unsigned long flags; struct netdev_hw_addr *ha; int i; + u16 *adrp; + u16 hash_table[4] = { 0 }; + + spin_lock_irqsave(&lp->lock, flags); - /* MAC Address */ + /* Keep our MAC Address */ adrp = (u16 *)dev->dev_addr; iowrite16(adrp[0], ioaddr + MID_0L); iowrite16(adrp[1], ioaddr + MID_0M); iowrite16(adrp[2], ioaddr + MID_0H); - /* Promiscous Mode */ - spin_lock_irqsave(&lp->lock, flags); - /* Clear AMCP & PROM bits */ - reg = ioread16(ioaddr) & ~0x0120; - if (dev->flags & IFF_PROMISC) { - reg |= 0x0020; - lp->mcr0 |= 0x0020; - } - /* Too many multicast addresses - * accept all traffic */ - else if ((netdev_mc_count(dev) > MCAST_MAX) || - (dev->flags & IFF_ALLMULTI)) - reg |= 0x0020; + lp->mcr0 = ioread16(ioaddr + MCR0) & ~(MCR0_PROMISC | MCR0_HASH_EN); - iowrite16(reg, ioaddr); - spin_unlock_irqrestore(&lp->lock, flags); + /* Promiscuous mode */ + if (dev->flags & IFF_PROMISC) + lp->mcr0 |= MCR0_PROMISC; - /* Build the hash table */ - if (netdev_mc_count(dev) > MCAST_MAX) { - u16 hash_table[4]; - u32 crc; + /* Enable multicast hash table function to + * receive all multicast packets. */ + else if (dev->flags & IFF_ALLMULTI) { + lp->mcr0 |= MCR0_HASH_EN; - for (i = 0; i < 4; i++) - hash_table[i] = 0; + for (i = 0; i < MCAST_MAX ; i++) { + iowrite16(0, ioaddr + MID_1L + 8 * i); + iowrite16(0, ioaddr + MID_1M + 8 * i); + iowrite16(0, ioaddr + MID_1H + 8 * i); + } + for (i = 0; i < 4; i++) + hash_table[i] = 0xffff; + } + /* Use internal multicast address registers if the number of + * multicast addresses is not greater than MCAST_MAX. */ + else if (netdev_mc_count(dev) <= MCAST_MAX) { + i = 0; netdev_for_each_mc_addr(ha, dev) { - char *addrs = ha->addr; + u16 *adrp = (u16 *) ha->addr; + iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); + iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); + iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); + i++; + } + while (i < MCAST_MAX) { + iowrite16(0, ioaddr + MID_1L + 8 * i); + iowrite16(0, ioaddr + MID_1M + 8 * i); + iowrite16(0, ioaddr + MID_1H + 8 * i); + i++; + } + } + /* Otherwise, Enable multicast hash table function. */ + else { + u32 crc; - if (!(*addrs & 1)) - continue; + lp->mcr0 |= MCR0_HASH_EN; + + for (i = 0; i < MCAST_MAX ; i++) { + iowrite16(0, ioaddr + MID_1L + 8 * i); + iowrite16(0, ioaddr + MID_1M + 8 * i); + iowrite16(0, ioaddr + MID_1H + 8 * i); + } - crc = ether_crc_le(6, addrs); + /* Build multicast hash table */ + netdev_for_each_mc_addr(ha, dev) { + u8 *addrs = ha->addr; + + crc = ether_crc(ETH_ALEN, addrs); crc >>= 26; - hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); + hash_table[crc >> 4] |= 1 << (crc & 0xf); } - /* Fill the MAC hash tables with their values */ + } + + iowrite16(lp->mcr0, ioaddr + MCR0); + + /* Fill the MAC hash tables with their values */ + if (lp->mcr0 && MCR0_HASH_EN) { iowrite16(hash_table[0], ioaddr + MAR0); iowrite16(hash_table[1], ioaddr + MAR1); iowrite16(hash_table[2], ioaddr + MAR2); iowrite16(hash_table[3], ioaddr + MAR3); } - /* Multicast Address 1~4 case */ - i = 0; - netdev_for_each_mc_addr(ha, dev) { - if (i >= MCAST_MAX) - break; - adrp = (u16 *) ha->addr; - iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); - iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); - iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); - i++; - } - while (i < MCAST_MAX) { - iowrite16(0xffff, ioaddr + MID_1L + 8 * i); - iowrite16(0xffff, ioaddr + MID_1M + 8 * i); - iowrite16(0xffff, ioaddr + MID_1H + 8 * i); - i++; - } + + spin_unlock_irqrestore(&lp->lock, flags); } static void netdev_get_drvinfo(struct net_device *dev, -- cgit v1.2.3 From 86f99fffffc631b8fa03d07219dc0c67bb65893d Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 7 Mar 2011 00:09:42 +0000 Subject: r6040: bump to version 0.27 and date 23Feb2011 Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 7965ae42eae4..e3ebd90ae651 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -49,8 +49,8 @@ #include #define DRV_NAME "r6040" -#define DRV_VERSION "0.26" -#define DRV_RELDATE "30May2010" +#define DRV_VERSION "0.27" +#define DRV_RELDATE "23Feb2011" /* PHY CHIP Address */ #define PHY1_ADDR 1 /* For MAC1 */ -- cgit v1.2.3 From 12c383238d675f41e8ecdb8278bfa30c9f2781d4 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 28 Feb 2011 13:52:32 -0700 Subject: i2c-ocores: Fix pointer type mismatch error ocores_i2c_of_probe needs to use a const __be32 type for handing device tree property values. This patch fixed the following build warning: CC drivers/i2c/busses/i2c-ocores.o drivers/i2c/busses/i2c-ocores.c: In function 'ocores_i2c_of_probe': drivers/i2c/busses/i2c-ocores.c:254: warning: assignment discards qualifiers from pointer target type drivers/i2c/busses/i2c-ocores.c:261: warning: assignment discards qualifiers from pointer target type Signed-off-by: Grant Likely Cc: Peter Korsgaard Cc: Ben Dooks Cc: linux-i2c@vger.kernel.org Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-ocores.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index ef3bcb1ce864..61653f079671 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -249,7 +249,7 @@ static struct i2c_adapter ocores_adapter = { static int ocores_i2c_of_probe(struct platform_device* pdev, struct ocores_i2c* i2c) { - __be32* val; + const __be32* val; val = of_get_property(pdev->dev.of_node, "regstep", NULL); if (!val) { -- cgit v1.2.3 From 6dbc2f35ab457770d121d119788fc89c79124734 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Feb 2011 11:11:35 +0100 Subject: i2c-eg20t: include slab.h for memory allocations Fixes (with v2.6.38-rc3/parisc/parisc-allmodconfig): src/drivers/i2c/busses/i2c-eg20t.c:720: error: implicit declaration of function 'kzalloc' src/drivers/i2c/busses/i2c-eg20t.c:790: error: implicit declaration of function 'kfree' Reported-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang Cc: Tomoya MORINAGA Cc: Ben Dooks Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-eg20t.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 2e067dd2ee51..50ea1f43bdc1 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c @@ -29,6 +29,7 @@ #include #include #include +#include #define PCH_EVENT_SET 0 /* I2C Interrupt Event Set Status */ #define PCH_EVENT_NONE 1 /* I2C Interrupt Event Clear Status */ -- cgit v1.2.3 From d406577526a611e6be1f6b1cfeaf094dd95fa439 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 28 Feb 2011 10:16:29 +0100 Subject: watchdog: sbc_fitpc2_wdt, fix crash on systems without DMI_BOARD_NAME Some systems don't provide DMI_BOARD_NAME in their DMI tables. Avoid crash in such situations in fitpc2_wdt_init. The fix is to check if the dmi_get_system_info return value is NULL. The oops: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] strstr+0x26/0xa0 PGD 3966e067 PUD 39605067 PMD 0 Oops: 0000 [#1] SMP last sysfs file: /sys/devices/system/cpu/cpu1/cache/index2/shared_cpu_map CPU 1 Modules linked in: ... Pid: 1748, comm: modprobe Not tainted 2.6.37-22-default #1 /Bochs RIP: 0010:[] [] strstr+0x26/0xa0 RSP: 0018:ffff88003ad73f18 EFLAGS: 00010206 RAX: 0000000000000000 RBX: 00000000ffffffed RCX: 00000000ffffffff RDX: ffffffffa003f4cc RSI: ffffffffa003f4c2 RDI: 0000000000000000 ... CR2: 0000000000000000 CR3: 000000003b7ac000 CR4: 00000000000006e0 ... Process modprobe (pid: 1748, threadinfo ffff88003ad72000, task ffff88002e6365c0) Stack: ... Call Trace: [] fitpc2_wdt_init+0x1f/0x13c [sbc_fitpc2_wdt] [] do_one_initcall+0x3a/0x170 ... Code: f3 c3 0f 1f 00 80 3e 00 53 48 89 f8 74 1b 48 89 f2 0f 1f 40 00 48 83 c2 01 80 3a 00 75 f7 49 89 d0 48 89 f8 49 29 f0 75 02 5b c3 <80> 3f 00 74 0e 0f 1f 44 00 00 48 83 c0 01 80 38 00 75 f7 49 89 Signed-off-by: Jiri Slaby Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sbc_fitpc2_wdt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c index c7d67e9a7465..79906255eeb6 100644 --- a/drivers/watchdog/sbc_fitpc2_wdt.c +++ b/drivers/watchdog/sbc_fitpc2_wdt.c @@ -201,11 +201,14 @@ static struct miscdevice fitpc2_wdt_miscdev = { static int __init fitpc2_wdt_init(void) { int err; + const char *brd_name; - if (!strstr(dmi_get_system_info(DMI_BOARD_NAME), "SBC-FITPC2")) + brd_name = dmi_get_system_info(DMI_BOARD_NAME); + + if (!brd_name || !strstr(brd_name, "SBC-FITPC2")) return -ENODEV; - pr_info("%s found\n", dmi_get_system_info(DMI_BOARD_NAME)); + pr_info("%s found\n", brd_name); if (!request_region(COMMAND_PORT, 1, WATCHDOG_NAME)) { pr_err("I/O address 0x%04x already in use\n", COMMAND_PORT); -- cgit v1.2.3 From ba3820ade317ee36e496b9b40d2ec3987dd4aef0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 10 Mar 2011 14:02:12 +0100 Subject: drm/i915: Revive combination mode for backlight control This reverts commit 951f3512dba5bd44cda3e5ee22b4b522e4bb09fb drm/i915: Do not handle backlight combination mode specially since this commit introduced other regressions due to untouched LBPC register, e.g. the backlight dimmed after resume. In addition to the revert, this patch includes a fix for the original issue (weird backlight levels) by removing the wrong bit shift for computing the current backlight level. Also, including typo fixes (lpbc -> lbpc). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34524 Acked-by: Indan Zupancic Reviewed-by: Keith Packard Reviewed-by: Jesse Barnes Cc: Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_reg.h | 10 ++++++++++ drivers/gpu/drm/i915/intel_panel.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3e6f486f4605..2abe240dae58 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1553,7 +1553,17 @@ /* Backlight control */ #define BLC_PWM_CTL 0x61254 +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) #define BLC_PWM_CTL2 0x61250 /* 965+ only */ +#define BLM_COMBINATION_MODE (1 << 30) +/* + * This is the most significant 15 bits of the number of backlight cycles in a + * complete cycle of the modulated backlight control. + * + * The actual value is this field multiplied by two. + */ +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) /* * This is the number of cycles out of the backlight modulation cycle for which * the backlight is on. diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index d860abeda70f..f8f86e57df22 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -30,6 +30,8 @@ #include "intel_drv.h" +#define PCI_LBPC 0xf4 /* legacy/combination backlight modes */ + void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode) @@ -110,6 +112,19 @@ done: dev_priv->pch_pf_size = (width << 16) | height; } +static int is_backlight_combination_mode(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (INTEL_INFO(dev)->gen >= 4) + return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE; + + if (IS_GEN2(dev)) + return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE; + + return 0; +} + static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) { u32 val; @@ -166,6 +181,9 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev) if (INTEL_INFO(dev)->gen < 4) max &= ~1; } + + if (is_backlight_combination_mode(dev)) + max *= 0xff; } DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); @@ -183,6 +201,14 @@ u32 intel_panel_get_backlight(struct drm_device *dev) val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; if (IS_PINEVIEW(dev)) val >>= 1; + + if (is_backlight_combination_mode(dev)){ + u8 lbpc; + + val &= ~1; + pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); + val *= lbpc; + } } DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); @@ -205,6 +231,16 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level) if (HAS_PCH_SPLIT(dev)) return intel_pch_panel_set_backlight(dev, level); + + if (is_backlight_combination_mode(dev)){ + u32 max = intel_panel_get_max_backlight(dev); + u8 lbpc; + + lbpc = level * 0xfe / max + 1; + level /= lbpc; + pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc); + } + tmp = I915_READ(BLC_PWM_CTL); if (IS_PINEVIEW(dev)) { tmp &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1); -- cgit v1.2.3 From 4c418ba9695a24917a1fcfa48f7db3fd76337eb7 Mon Sep 17 00:00:00 2001 From: "Doe, YiCheng" Date: Thu, 10 Mar 2011 14:00:21 -0600 Subject: ipmi: Fix IPMI errors due to timing problems This patch fixes an issue in OpenIPMI module where sometimes an ABORT command is sent after sending an IPMI request to BMC causing the IPMI request to fail. Signed-off-by: YiCheng Doe Signed-off-by: Corey Minyard Acked-by: Tom Mingarelli Tested-by: Andy Cress Tested-by: Mika Lansirine Tested-by: Brian De Wolf Cc: Jean Michel Audet Cc: Jozef Sudelsky Acked-by: Matthew Garrett Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 7855f9f45b8e..62787e30d508 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -900,6 +900,14 @@ static void sender(void *send_info, printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec); #endif + /* + * last_timeout_jiffies is updated here to avoid + * smi_timeout() handler passing very large time_diff + * value to smi_event_handler() that causes + * the send command to abort. + */ + smi_info->last_timeout_jiffies = jiffies; + mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES); if (smi_info->thread) -- cgit v1.2.3