Re: [patch]full autosuspend and power management support for usbsevseg

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Harrison Metzger <harrisonmetz@xxxxxxxxx>
On Mon, Jul 13, 2009 at 9:45 AM, Oliver Neukum<oliver@xxxxxxxxxx> wrote:> This patch adds to the usbsevseg driver:>> - suspend/resume support> - reset_resume support> - autosuspend using the display's power state to determine idleness>> Signed-off-by: Oliver Neukum <oliver@xxxxxxxxxx>>> Hi,>> Harrison and I have added pm support to the usbsevseg driver.>>        Regards>                Oliver> -->> commit e57549bbabb8462ed30474d5590cd70aff49a75c> Author: Oliver Neukum <oliver@xxxxxxxxxx>> Date:   Mon Jul 13 16:30:37 2009 +0200>>    usb: full power management support for usbsevseg>> diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c> index 28a6a3a..3db2555 100644> --- a/drivers/usb/misc/usbsevseg.c> +++ b/drivers/usb/misc/usbsevseg.c> @@ -38,6 +38,7 @@ static char *display_textmodes[] = {"raw", "hex", "ascii", NULL};>>  struct usb_sevsegdev {>        struct usb_device *udev;> +       struct usb_interface *intf;>>        u8 powered;>        u8 mode_msb;> @@ -46,6 +47,8 @@ struct usb_sevsegdev {>        u8 textmode;>        u8 text[MAXLEN];>        u16 textlength;> +> +       u8 shadow_power; /* for PM */>  };>>  /* sysfs_streq can't replace this completely> @@ -65,6 +68,12 @@ static void update_display_powered(struct usb_sevsegdev *mydev)>  {>        int rc;>> +       if (!mydev->shadow_power && mydev->powered) {> +               rc = usb_autopm_get_interface(mydev->intf);> +               if (rc < 0)> +                       return;> +       }> +>        rc = usb_control_msg(mydev->udev,>                        usb_sndctrlpipe(mydev->udev, 0),>                        0x12,> @@ -76,12 +85,18 @@ static void update_display_powered(struct usb_sevsegdev *mydev)>                        2000);>        if (rc < 0)>                dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc);> +> +       if (mydev->shadow_power && !mydev->powered)> +               usb_autopm_put_interface(mydev->intf);>  }>>  static void update_display_mode(struct usb_sevsegdev *mydev)>  {>        int rc;>> +       if(mydev->shadow_power != 1)> +               return;> +>        rc = usb_control_msg(mydev->udev,>                        usb_sndctrlpipe(mydev->udev, 0),>                        0x12,> @@ -96,14 +111,17 @@ static void update_display_mode(struct usb_sevsegdev *mydev)>                dev_dbg(&mydev->udev->dev, "mode retval = %d\n", rc);>  }>> -static void update_display_visual(struct usb_sevsegdev *mydev)> +static void update_display_visual(struct usb_sevsegdev *mydev, gfp_t mf)>  {>        int rc;>        int i;>        unsigned char *buffer;>        u8 decimals = 0;>> -       buffer = kzalloc(MAXLEN, GFP_KERNEL);> +       if(mydev->shadow_power != 1)> +               return;> +> +       buffer = kzalloc(MAXLEN, mf);>        if (!buffer) {>                dev_err(&mydev->udev->dev, "out of memory\n");>                return;> @@ -163,7 +181,7 @@ static ssize_t set_attr_##name(struct device *dev,          \>        struct usb_sevsegdev *mydev = usb_get_intfdata(intf);   \>                                                                \>        mydev->name = simple_strtoul(buf, NULL, 10);            \> -       update_fcn(mydev); \> +       update_fcn(mydev);                                      \>                                                                \>        return count;                                           \>  }                                                              \> @@ -194,7 +212,7 @@ static ssize_t set_attr_text(struct device *dev,>        if (end > 0)>                memcpy(mydev->text, buf, end);>> -       update_display_visual(mydev);> +       update_display_visual(mydev, GFP_KERNEL);>        return count;>  }>> @@ -242,7 +260,7 @@ static ssize_t set_attr_decimals(struct device *dev,>                if (buf[i] == '1')>                        mydev->decimals[end-1-i] = 1;>> -       update_display_visual(mydev);> +       update_display_visual(mydev, GFP_KERNEL);>>        return count;>  }> @@ -286,7 +304,7 @@ static ssize_t set_attr_textmode(struct device *dev,>        for (i = 0; display_textmodes[i]; i++) {>                if (sysfs_streq(display_textmodes[i], buf)) {>                        mydev->textmode = i;> -                       update_display_visual(mydev);> +                       update_display_visual(mydev, GFP_KERNEL);>                        return count;>                }>        }> @@ -330,6 +348,7 @@ static int sevseg_probe(struct usb_interface *interface,>        }>>        mydev->udev = usb_get_dev(udev);> +       mydev->intf = interface;>        usb_set_intfdata(interface, mydev);>>        /*set defaults */> @@ -364,11 +383,49 @@ static void sevseg_disconnect(struct usb_interface *interface)>        dev_info(&interface->dev, "USB 7 Segment now disconnected\n");>  }>> +static int sevseg_suspend(struct usb_interface *intf, pm_message_t message)> +{> +       struct usb_sevsegdev *mydev;> +> +       mydev = usb_get_intfdata(intf);> +       mydev->shadow_power = 0;> +> +       return 0;> +}> +> +static int sevseg_resume(struct usb_interface *intf)> +{> +       struct usb_sevsegdev *mydev;> +> +       mydev = usb_get_intfdata(intf);> +       mydev->shadow_power = 1;> +       update_display_mode(mydev);> +       update_display_visual(mydev, GFP_NOIO);> +> +       return 0;> +}> +> +static int sevseg_reset_resume(struct usb_interface *intf)> +{> +       struct usb_sevsegdev *mydev;> +> +       mydev = usb_get_intfdata(intf);> +       mydev->shadow_power = 1;> +       update_display_mode(mydev);> +       update_display_visual(mydev, GFP_NOIO);> +> +       return 0;> +}> +>  static struct usb_driver sevseg_driver = {>        .name =         "usbsevseg",>        .probe =        sevseg_probe,>        .disconnect =   sevseg_disconnect,> +       .suspend =      sevseg_suspend,> +       .resume =       sevseg_resume,> +       .reset_resume = sevseg_reset_resume,>        .id_table =     id_table,> +       .supports_autosuspend = 1,>  };>>  static int __init usb_sevseg_init(void)>>��.n��������+%������w��{.n�����{���)��jg��������ݢj����G�������j:+v���w�m������w�������h�����٥


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux