fe5959fc021b387a7de72d39dd95a216e728738b
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / usb / core / port.c
1 /*
2  * usb port device code
3  *
4  * Copyright (C) 2012 Intel Corp
5  *
6  * Author: Lan Tianyu <tianyu.lan@intel.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * for more details.
16  *
17  */
18
19 #include <linux/slab.h>
20
21 #include "hub.h"
22
23 static const struct attribute_group *port_dev_group[];
24
25 static ssize_t show_port_connect_type(struct device *dev,
26         struct device_attribute *attr, char *buf)
27 {
28         struct usb_port *port_dev = to_usb_port(dev);
29         char *result;
30
31         switch (port_dev->connect_type) {
32         case USB_PORT_CONNECT_TYPE_HOT_PLUG:
33                 result = "hotplug";
34                 break;
35         case USB_PORT_CONNECT_TYPE_HARD_WIRED:
36                 result = "hardwired";
37                 break;
38         case USB_PORT_NOT_USED:
39                 result = "not used";
40                 break;
41         default:
42                 result = "unknown";
43                 break;
44         }
45
46         return sprintf(buf, "%s\n", result);
47 }
48 static DEVICE_ATTR(connect_type, S_IRUGO, show_port_connect_type,
49                 NULL);
50
51 static struct attribute *port_dev_attrs[] = {
52         &dev_attr_connect_type.attr,
53         NULL,
54 };
55
56 static struct attribute_group port_dev_attr_grp = {
57         .attrs = port_dev_attrs,
58 };
59
60 static const struct attribute_group *port_dev_group[] = {
61         &port_dev_attr_grp,
62         NULL,
63 };
64
65 static void usb_port_device_release(struct device *dev)
66 {
67         struct usb_port *port_dev = to_usb_port(dev);
68
69         kfree(port_dev);
70 }
71
72 struct device_type usb_port_device_type = {
73         .name =         "usb_port",
74         .release =      usb_port_device_release,
75 };
76
77 int usb_hub_create_port_device(struct usb_hub *hub, int port1)
78 {
79         struct usb_port *port_dev = NULL;
80         int retval;
81
82         port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
83         if (!port_dev) {
84                 retval = -ENOMEM;
85                 goto exit;
86         }
87
88         hub->ports[port1 - 1] = port_dev;
89         port_dev->dev.parent = hub->intfdev;
90         port_dev->dev.groups = port_dev_group;
91         port_dev->dev.type = &usb_port_device_type;
92         dev_set_name(&port_dev->dev, "port%d", port1);
93
94         retval = device_register(&port_dev->dev);
95         if (retval)
96                 goto error_register;
97
98         return 0;
99
100 error_register:
101         put_device(&port_dev->dev);
102 exit:
103         return retval;
104 }
105
106 void usb_hub_remove_port_device(struct usb_hub *hub,
107                                        int port1)
108 {
109         device_unregister(&hub->ports[port1 - 1]->dev);
110 }
111