From e24f90390a9b03007533441b84e82b0f3876263c Mon Sep 17 00:00:00 2001 From: Zhang Wei Date: Tue, 13 May 2008 14:44:59 -0700 Subject: [PATCH] --- yaml --- r: 97044 b: refs/heads/master c: 76b0c788e6033c514f2a75171b04c73c68d28e8d h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/MAINTAINERS | 8 ++-- trunk/arch/x86/pci/common.c | 8 ++-- trunk/drivers/firewire/fw-cdev.c | 14 ------ trunk/drivers/ieee1394/sbp2.c | 20 ++++---- trunk/drivers/media/video/bt8xx/bttv-driver.c | 2 +- trunk/drivers/media/video/videobuf-core.c | 3 +- trunk/include/media/videobuf-core.h | 3 -- trunk/sound/drivers/pcsp/pcsp.c | 2 +- trunk/sound/drivers/pcsp/pcsp_lib.c | 37 ++++++++++++-- trunk/sound/pci/hda/patch_realtek.c | 48 ++++++++----------- 11 files changed, 77 insertions(+), 70 deletions(-) diff --git a/[refs] b/[refs] index ad565344f8aa..6e8141b5058a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 737b0fbf448306975267509e6c6a074885ddb43c +refs/heads/master: 76b0c788e6033c514f2a75171b04c73c68d28e8d diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 461c2790e29e..7fd9c430aea4 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1646,8 +1646,10 @@ W: http://linux-fbdev.sourceforge.net/ S: Maintained FREESCALE DMA DRIVER -P; Zhang Wei -M: wei.zhang@freescale.com +P: Li Yang +M: leoli@freescale.com +P: Zhang Wei +M: zw@zh-kernel.org L: linuxppc-embedded@ozlabs.org L: linux-kernel@vger.kernel.org S: Maintained @@ -3143,7 +3145,7 @@ PCI ERROR RECOVERY P: Linas Vepstas M: linas@austin.ibm.com L: linux-kernel@vger.kernel.org -L: linux-pci@vger.kernel.org +L: linux-pci@atrey.karlin.mff.cuni.cz S: Supported PCI SUBSYSTEM diff --git a/trunk/arch/x86/pci/common.c b/trunk/arch/x86/pci/common.c index 6e64aaf00d1d..8545c8a9d107 100644 --- a/trunk/arch/x86/pci/common.c +++ b/trunk/arch/x86/pci/common.c @@ -302,18 +302,18 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { }, { .callback = set_bf_sort, - .ident = "HP ProLiant DL360", + .ident = "HP ProLiant DL385 G2", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL360"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL385 G2"), }, }, { .callback = set_bf_sort, - .ident = "HP ProLiant DL380", + .ident = "HP ProLiant DL585 G2", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL380"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"), }, }, #ifdef __i386__ diff --git a/trunk/drivers/firewire/fw-cdev.c b/trunk/drivers/firewire/fw-cdev.c index dda14015e873..4a541921a14a 100644 --- a/trunk/drivers/firewire/fw-cdev.c +++ b/trunk/drivers/firewire/fw-cdev.c @@ -113,11 +113,6 @@ static int fw_device_op_open(struct inode *inode, struct file *file) if (device == NULL) return -ENODEV; - if (fw_device_is_shutdown(device)) { - fw_device_put(device); - return -ENODEV; - } - client = kzalloc(sizeof(*client), GFP_KERNEL); if (client == NULL) { fw_device_put(device); @@ -906,9 +901,6 @@ fw_device_op_ioctl(struct file *file, { struct client *client = file->private_data; - if (fw_device_is_shutdown(client->device)) - return -ENODEV; - return dispatch_ioctl(client, cmd, (void __user *) arg); } @@ -919,9 +911,6 @@ fw_device_op_compat_ioctl(struct file *file, { struct client *client = file->private_data; - if (fw_device_is_shutdown(client->device)) - return -ENODEV; - return dispatch_ioctl(client, cmd, compat_ptr(arg)); } #endif @@ -933,9 +922,6 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma) unsigned long size; int page_count, retval; - if (fw_device_is_shutdown(client->device)) - return -ENODEV; - /* FIXME: We could support multiple buffers, but we don't. */ if (client->buffer.pages != NULL) return -EBUSY; diff --git a/trunk/drivers/ieee1394/sbp2.c b/trunk/drivers/ieee1394/sbp2.c index a5ceff287a28..16b9d0ad154e 100644 --- a/trunk/drivers/ieee1394/sbp2.c +++ b/trunk/drivers/ieee1394/sbp2.c @@ -1539,13 +1539,15 @@ 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, - struct scsi_cmnd *SCpnt) + unchar *scsi_cmd, + unsigned int scsi_use_sg, + unsigned int scsi_request_bufflen, + struct scatterlist *sg, + enum dma_data_direction dma_dir) { 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. @@ -1578,14 +1580,13 @@ 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_sg_count(SCpnt), - scsi_sglist(SCpnt), + sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_use_sg, sg, orb_direction, dma_dir); sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb)); - memset(orb->cdb, 0, sizeof(orb->cdb)); - memcpy(orb->cdb, SCpnt->cmnd, SCpnt->cmd_len); + memset(orb->cdb, 0, 12); + memcpy(orb->cdb, scsi_cmd, COMMAND_SIZE(*scsi_cmd)); } static void sbp2_link_orb_command(struct sbp2_lu *lu, @@ -1668,13 +1669,16 @@ 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, SCpnt); + sbp2_create_command_orb(lu, cmd, scsi_cmd, scsi_sg_count(SCpnt), + scsi_bufflen(SCpnt), scsi_sglist(SCpnt), + SCpnt->sc_data_direction); 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 },