diff --git a/[refs] b/[refs] index 7f78367d3517..d20c8fcb303e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 81b2dbcad86732ffc02bad87aa25c4651199fc77 +refs/heads/master: 93c596f7d611b379302bbdd26f31acdf72f4859a diff --git a/trunk/drivers/ieee1394/sbp2.c b/trunk/drivers/ieee1394/sbp2.c index 16b9d0ad154e..a5ceff287a28 100644 --- a/trunk/drivers/ieee1394/sbp2.c +++ b/trunk/drivers/ieee1394/sbp2.c @@ -1539,15 +1539,13 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, static void sbp2_create_command_orb(struct sbp2_lu *lu, struct sbp2_command_info *cmd, - unchar *scsi_cmd, - unsigned int scsi_use_sg, - unsigned int scsi_request_bufflen, - struct scatterlist *sg, - enum dma_data_direction dma_dir) + struct scsi_cmnd *SCpnt) { struct sbp2_fwhost_info *hi = lu->hi; struct sbp2_command_orb *orb = &cmd->command_orb; u32 orb_direction; + unsigned int scsi_request_bufflen = scsi_bufflen(SCpnt); + enum dma_data_direction dma_dir = SCpnt->sc_data_direction; /* * Set-up our command ORB. @@ -1580,13 +1578,14 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu, orb->data_descriptor_lo = 0x0; orb->misc |= ORB_SET_DIRECTION(1); } else - sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_use_sg, sg, + sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_sg_count(SCpnt), + scsi_sglist(SCpnt), orb_direction, dma_dir); sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb)); - memset(orb->cdb, 0, 12); - memcpy(orb->cdb, scsi_cmd, COMMAND_SIZE(*scsi_cmd)); + memset(orb->cdb, 0, sizeof(orb->cdb)); + memcpy(orb->cdb, SCpnt->cmnd, SCpnt->cmd_len); } static void sbp2_link_orb_command(struct sbp2_lu *lu, @@ -1669,16 +1668,13 @@ static void sbp2_link_orb_command(struct sbp2_lu *lu, static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { - unchar *scsi_cmd = (unchar *)SCpnt->cmnd; struct sbp2_command_info *cmd; cmd = sbp2util_allocate_command_orb(lu, SCpnt, done); if (!cmd) return -EIO; - sbp2_create_command_orb(lu, cmd, scsi_cmd, scsi_sg_count(SCpnt), - scsi_bufflen(SCpnt), scsi_sglist(SCpnt), - SCpnt->sc_data_direction); + sbp2_create_command_orb(lu, cmd, SCpnt); sbp2_link_orb_command(lu, cmd); return 0; diff --git a/trunk/drivers/media/video/bt8xx/bttv-driver.c b/trunk/drivers/media/video/bt8xx/bttv-driver.c index 0165aac533bf..2ca3e9cfb2bb 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-driver.c +++ b/trunk/drivers/media/video/bt8xx/bttv-driver.c @@ -2613,7 +2613,7 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) struct bttv_fh *fh = priv; mutex_lock(&fh->cap.vb_lock); - retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, + retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, V4L2_MEMORY_MMAP); if (retval < 0) { mutex_unlock(&fh->cap.vb_lock); diff --git a/trunk/drivers/media/video/videobuf-core.c b/trunk/drivers/media/video/videobuf-core.c index 0a88c44ace00..982f4463896c 100644 --- a/trunk/drivers/media/video/videobuf-core.c +++ b/trunk/drivers/media/video/videobuf-core.c @@ -331,7 +331,7 @@ int videobuf_mmap_free(struct videobuf_queue *q) } /* Locking: Caller holds q->vb_lock */ -int __videobuf_mmap_setup(struct videobuf_queue *q, +static int __videobuf_mmap_setup(struct videobuf_queue *q, unsigned int bcount, unsigned int bsize, enum v4l2_memory memory) { @@ -1129,7 +1129,6 @@ EXPORT_SYMBOL_GPL(videobuf_read_stream); EXPORT_SYMBOL_GPL(videobuf_read_one); EXPORT_SYMBOL_GPL(videobuf_poll_stream); -EXPORT_SYMBOL_GPL(__videobuf_mmap_setup); EXPORT_SYMBOL_GPL(videobuf_mmap_setup); EXPORT_SYMBOL_GPL(videobuf_mmap_free); EXPORT_SYMBOL_GPL(videobuf_mmap_mapper); diff --git a/trunk/include/media/videobuf-core.h b/trunk/include/media/videobuf-core.h index 874f1340d049..5b39a22533fe 100644 --- a/trunk/include/media/videobuf-core.h +++ b/trunk/include/media/videobuf-core.h @@ -237,9 +237,6 @@ unsigned int videobuf_poll_stream(struct file *file, int videobuf_mmap_setup(struct videobuf_queue *q, unsigned int bcount, unsigned int bsize, enum v4l2_memory memory); -int __videobuf_mmap_setup(struct videobuf_queue *q, - unsigned int bcount, unsigned int bsize, - enum v4l2_memory memory); int videobuf_mmap_free(struct videobuf_queue *q); int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma); diff --git a/trunk/sound/drivers/pcsp/pcsp.c b/trunk/sound/drivers/pcsp/pcsp.c index 1899cf0685bc..54a1f9036c66 100644 --- a/trunk/sound/drivers/pcsp/pcsp.c +++ b/trunk/sound/drivers/pcsp/pcsp.c @@ -96,7 +96,7 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev) return -EINVAL; hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - pcsp_chip.timer.cb_mode = HRTIMER_CB_SOFTIRQ; + pcsp_chip.timer.cb_mode = HRTIMER_CB_IRQSAFE; pcsp_chip.timer.function = pcsp_do_timer; card = snd_card_new(index, id, THIS_MODULE, 0); diff --git a/trunk/sound/drivers/pcsp/pcsp_lib.c b/trunk/sound/drivers/pcsp/pcsp_lib.c index e341f3f83b6a..7ad4a1534b2b 100644 --- a/trunk/sound/drivers/pcsp/pcsp_lib.c +++ b/trunk/sound/drivers/pcsp/pcsp_lib.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "pcsp.h" @@ -19,8 +20,34 @@ MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround " #define DMIX_WANTS_S16 1 +static void pcsp_start_timer(unsigned long dummy) +{ + hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); +} + +/* + * We need the hrtimer_start as a tasklet to avoid + * the nasty locking problem. :( + * The problem: + * - The timer handler is called with the cpu_base->lock + * already held by hrtimer code. + * - snd_pcm_period_elapsed() takes the + * substream->self_group.lock. + * So far so good. + * But the snd_pcsp_trigger() is called with the + * substream->self_group.lock held, and it calls + * hrtimer_start(), which takes the cpu_base->lock. + * You see the problem. We have the code pathes + * which take two locks in a reverse order. This + * can deadlock and the lock validator complains. + * The only solution I could find was to move the + * hrtimer_start() into a tasklet. -stsp + */ +static DECLARE_TASKLET(pcsp_start_timer_tasklet, pcsp_start_timer, 0); + enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) { + unsigned long flags; unsigned char timer_cnt, val; int fmt_size, periods_elapsed; u64 ns; @@ -39,7 +66,9 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) return HRTIMER_RESTART; } - spin_lock_irq(&chip->substream_lock); + /* hrtimer calls us from both hardirq and softirq contexts, + * so irqsave :( */ + spin_lock_irqsave(&chip->substream_lock, flags); /* Takashi Iwai says regarding this extra lock: If the irq handler handles some data on the DMA buffer, it should @@ -110,7 +139,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) chip->period_ptr %= buffer_bytes; } - spin_unlock_irq(&chip->substream_lock); + spin_unlock_irqrestore(&chip->substream_lock, flags); if (!atomic_read(&chip->timer_active)) return HRTIMER_NORESTART; @@ -124,7 +153,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) exit_nr_unlock2: snd_pcm_stream_unlock(substream); exit_nr_unlock1: - spin_unlock_irq(&chip->substream_lock); + spin_unlock_irqrestore(&chip->substream_lock, flags); return HRTIMER_NORESTART; } @@ -145,7 +174,7 @@ static void pcsp_start_playing(struct snd_pcsp *chip) atomic_set(&chip->timer_active, 1); chip->thalf = 0; - hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); + tasklet_schedule(&pcsp_start_timer_tasklet); } static void pcsp_stop_playing(struct snd_pcsp *chip) diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 864b2f598c38..6d4df45e81e0 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -2981,7 +2981,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), - SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), + SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS), SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), @@ -8757,39 +8757,35 @@ static struct hda_input_mux alc262_HP_D7000_capture_source = { }, }; -/* mute/unmute internal speaker according to the hp jacks and mute state */ +/* mute/unmute internal speaker according to the hp jack and mute state */ static void alc262_fujitsu_automute(struct hda_codec *codec, int force) { struct alc_spec *spec = codec->spec; unsigned int mute; if (force || !spec->sense_updated) { - unsigned int present; + unsigned int present_int_hp, present_dock_hp; /* need to execute and sync at first */ snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); - /* check laptop HP jack */ - present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0); - /* need to execute and sync at first */ - snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); - /* check docking HP jack */ - present |= snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0); - if (present & AC_PINSENSE_PRESENCE) - spec->jack_present = 1; - else - spec->jack_present = 0; + present_int_hp = snd_hda_codec_read(codec, 0x14, 0, + AC_VERB_GET_PIN_SENSE, 0); + snd_hda_codec_read(codec, 0x1B, 0, AC_VERB_SET_PIN_SENSE, 0); + present_dock_hp = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0); + spec->jack_present = (present_int_hp & 0x80000000) != 0; + spec->jack_present |= (present_dock_hp & 0x80000000) != 0; spec->sense_updated = 1; } - /* unmute internal speaker only if both HPs are unplugged and - * master switch is on - */ - if (spec->jack_present) - mute = HDA_AMP_MUTE; - else + if (spec->jack_present) { + /* mute internal speaker */ + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); + } else { + /* unmute internal speaker if necessary */ mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); + } } /* unsolicited event for HP jack sensing */ @@ -8801,11 +8797,6 @@ static void alc262_fujitsu_unsol_event(struct hda_codec *codec, alc262_fujitsu_automute(codec, 1); } -static void alc262_fujitsu_init_hook(struct hda_codec *codec) -{ - alc262_fujitsu_automute(codec, 1); -} - /* bind volumes of both NID 0x0c and 0x0d */ static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { .ops = &snd_hda_bind_vol, @@ -9579,7 +9570,6 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_fujitsu_capture_source, .unsol_event = alc262_fujitsu_unsol_event, - .init_hook = alc262_fujitsu_init_hook, }, [ALC262_HP_BPC] = { .mixers = { alc262_HP_BPC_mixer },