aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/misc/usbsevseg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/misc/usbsevseg.c')
-rw-r--r--drivers/usb/misc/usbsevseg.c50
1 files changed, 21 insertions, 29 deletions
diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c
index 3db255537e7..1fe6b73c22f 100644
--- a/drivers/usb/misc/usbsevseg.c
+++ b/drivers/usb/misc/usbsevseg.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/string.h>
@@ -24,10 +23,10 @@
#define VENDOR_ID 0x0fc5
#define PRODUCT_ID 0x1227
-#define MAXLEN 6
+#define MAXLEN 8
/* table of devices that work with this driver */
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
{ USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
{ },
};
@@ -49,6 +48,7 @@ struct usb_sevsegdev {
u16 textlength;
u8 shadow_power; /* for PM */
+ u8 has_interface_pm;
};
/* sysfs_streq can't replace this completely
@@ -56,7 +56,7 @@ struct usb_sevsegdev {
* if str commands are used, we would assume the end of string
* so mem commands are used.
*/
-inline size_t my_memlen(const char *buf, size_t count)
+static inline size_t my_memlen(const char *buf, size_t count)
{
if (count > 0 && buf[count-1] == '\n')
return count - 1;
@@ -68,12 +68,16 @@ static void update_display_powered(struct usb_sevsegdev *mydev)
{
int rc;
- if (!mydev->shadow_power && mydev->powered) {
+ if (mydev->powered && !mydev->has_interface_pm) {
rc = usb_autopm_get_interface(mydev->intf);
if (rc < 0)
return;
+ mydev->has_interface_pm = 1;
}
+ if (mydev->shadow_power != 1)
+ return;
+
rc = usb_control_msg(mydev->udev,
usb_sndctrlpipe(mydev->udev, 0),
0x12,
@@ -86,8 +90,10 @@ static void update_display_powered(struct usb_sevsegdev *mydev)
if (rc < 0)
dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc);
- if (mydev->shadow_power && !mydev->powered)
+ if (!mydev->powered && mydev->has_interface_pm) {
usb_autopm_put_interface(mydev->intf);
+ mydev->has_interface_pm = 0;
+ }
}
static void update_display_mode(struct usb_sevsegdev *mydev)
@@ -185,7 +191,7 @@ static ssize_t set_attr_##name(struct device *dev, \
\
return count; \
} \
-static DEVICE_ATTR(name, S_IWUGO | S_IRUGO, show_attr_##name, set_attr_##name);
+static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_attr_##name, set_attr_##name);
static ssize_t show_attr_text(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -216,7 +222,7 @@ static ssize_t set_attr_text(struct device *dev,
return count;
}
-static DEVICE_ATTR(text, S_IWUGO | S_IRUGO, show_attr_text, set_attr_text);
+static DEVICE_ATTR(text, S_IRUGO | S_IWUSR, show_attr_text, set_attr_text);
static ssize_t show_attr_decimals(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -265,8 +271,7 @@ static ssize_t set_attr_decimals(struct device *dev,
return count;
}
-static DEVICE_ATTR(decimals, S_IWUGO | S_IRUGO,
- show_attr_decimals, set_attr_decimals);
+static DEVICE_ATTR(decimals, S_IRUGO | S_IWUSR, show_attr_decimals, set_attr_decimals);
static ssize_t show_attr_textmode(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -312,8 +317,7 @@ static ssize_t set_attr_textmode(struct device *dev,
return -EINVAL;
}
-static DEVICE_ATTR(textmode, S_IWUGO | S_IRUGO,
- show_attr_textmode, set_attr_textmode);
+static DEVICE_ATTR(textmode, S_IRUGO | S_IWUSR, show_attr_textmode, set_attr_textmode);
MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered);
@@ -351,6 +355,10 @@ static int sevseg_probe(struct usb_interface *interface,
mydev->intf = interface;
usb_set_intfdata(interface, mydev);
+ /* PM */
+ mydev->shadow_power = 1; /* currently active */
+ mydev->has_interface_pm = 0; /* have not issued autopm_get */
+
/*set defaults */
mydev->textmode = 0x02; /* ascii mode */
mydev->mode_msb = 0x06; /* 6 characters */
@@ -428,23 +436,7 @@ static struct usb_driver sevseg_driver = {
.supports_autosuspend = 1,
};
-static int __init usb_sevseg_init(void)
-{
- int rc = 0;
-
- rc = usb_register(&sevseg_driver);
- if (rc)
- err("usb_register failed. Error number %d", rc);
- return rc;
-}
-
-static void __exit usb_sevseg_exit(void)
-{
- usb_deregister(&sevseg_driver);
-}
-
-module_init(usb_sevseg_init);
-module_exit(usb_sevseg_exit);
+module_usb_driver(sevseg_driver);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);