lkml.org 
[lkml]   [2008]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 07/57] ALSA: hda - Add reboot notifier
    2.6.27-stable review patch.  If anyone has any objections, please let us know.

    ------------------
    From: Takashi Iwai <tiwai@suse.de>

    commit 0cbf00980f0fc4cc064a15ab3dfce19b5fae9130 upstream

    The current snd-hda-intel driver seems blocking the power-off on some
    devices like eeepc. Although this is likely a BIOS problem, we can add
    a workaround by disabling IRQ lines before power-off operation.
    This patch adds the reboot notifier to achieve it.

    The detailed problem description is found in bug#11889:
    http://bugme.linux-foundation.org/show_bug.cgi?id=11889

    Tested-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    sound/pci/hda/hda_intel.c | 29 +++++++++++++++++++++++++++++
    1 file changed, 29 insertions(+)

    --- a/sound/pci/hda/hda_intel.c
    +++ b/sound/pci/hda/hda_intel.c
    @@ -45,6 +45,7 @@
    #include <linux/slab.h>
    #include <linux/pci.h>
    #include <linux/mutex.h>
    +#include <linux/reboot.h>
    #include <sound/core.h>
    #include <sound/initval.h>
    #include "hda_codec.h"
    @@ -385,6 +386,9 @@ struct azx {

    /* for pending irqs */
    struct work_struct irq_pending_work;
    +
    + /* reboot notifier (for mysterious hangup problem at power-down) */
    + struct notifier_block reboot_notifier;
    };

    /* driver types */
    @@ -1890,12 +1894,36 @@ static int azx_resume(struct pci_dev *pc


    /*
    + * reboot notifier for hang-up problem at power-down
    + */
    +static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
    +{
    + struct azx *chip = container_of(nb, struct azx, reboot_notifier);
    + azx_stop_chip(chip);
    + return NOTIFY_OK;
    +}
    +
    +static void azx_notifier_register(struct azx *chip)
    +{
    + chip->reboot_notifier.notifier_call = azx_halt;
    + register_reboot_notifier(&chip->reboot_notifier);
    +}
    +
    +static void azx_notifier_unregister(struct azx *chip)
    +{
    + if (chip->reboot_notifier.notifier_call)
    + unregister_reboot_notifier(&chip->reboot_notifier);
    +}
    +
    +/*
    * destructor
    */
    static int azx_free(struct azx *chip)
    {
    int i;

    + azx_notifier_unregister(chip);
    +
    if (chip->initialized) {
    azx_clear_irq_pending(chip);
    for (i = 0; i < chip->num_streams; i++)
    @@ -2250,6 +2278,7 @@ static int __devinit azx_probe(struct pc
    pci_set_drvdata(pci, card);
    chip->running = 1;
    power_down_all_codecs(chip);
    + azx_notifier_register(chip);

    dev++;
    return err;
    --


    \
     
     \ /
      Last update: 2008-11-05 00:41    [W:0.035 / U:30.068 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site