diff options
author | Taku Izumi <izumi.taku@jp.fujitsu.com> | 2015-08-21 04:29:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-08-24 17:06:33 -0400 |
commit | 658d439b22924796d00f03282135a356f47cc64e (patch) | |
tree | d03480b8864729f777f10c5d544cccc70da765a1 /drivers/net | |
parent | 4a89ba04ecc6377696e4e26c1abc1cb5764decb9 (diff) |
fjes: Introduce FUJITSU Extended Socket Network Device driver
This patch adds the basic code of FUJITSU Extended Socket
Network Device driver.
When "PNP0C02" is found in ACPI DSDT, it evaluates "_STR"
to check if "PNP0C02" is for Extended Socket device driver
and retrieves ACPI resource information. Then creates
platform_device.
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/Kconfig | 7 | ||||
-rw-r--r-- | drivers/net/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/fjes/Makefile | 30 | ||||
-rw-r--r-- | drivers/net/fjes/fjes.h | 32 | ||||
-rw-r--r-- | drivers/net/fjes/fjes_main.c | 213 |
5 files changed, 284 insertions, 0 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f50373645ab4..770483b31d62 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -413,6 +413,13 @@ config VMXNET3 | |||
413 | To compile this driver as a module, choose M here: the | 413 | To compile this driver as a module, choose M here: the |
414 | module will be called vmxnet3. | 414 | module will be called vmxnet3. |
415 | 415 | ||
416 | config FUJITSU_ES | ||
417 | tristate "FUJITSU Extended Socket Network Device driver" | ||
418 | depends on ACPI | ||
419 | help | ||
420 | This driver provides support for Extended Socket network device | ||
421 | on Extended Partitioning of FUJITSU PRIMEQUEST 2000 E2 series. | ||
422 | |||
416 | source "drivers/net/hyperv/Kconfig" | 423 | source "drivers/net/hyperv/Kconfig" |
417 | 424 | ||
418 | endif # NETDEVICES | 425 | endif # NETDEVICES |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index ca16dd689b36..900b0c5320bb 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -68,3 +68,5 @@ obj-$(CONFIG_USB_NET_DRIVERS) += usb/ | |||
68 | 68 | ||
69 | obj-$(CONFIG_HYPERV_NET) += hyperv/ | 69 | obj-$(CONFIG_HYPERV_NET) += hyperv/ |
70 | obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o | 70 | obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o |
71 | |||
72 | obj-$(CONFIG_FUJITSU_ES) += fjes/ | ||
diff --git a/drivers/net/fjes/Makefile b/drivers/net/fjes/Makefile new file mode 100644 index 000000000000..34bccbafa657 --- /dev/null +++ b/drivers/net/fjes/Makefile | |||
@@ -0,0 +1,30 @@ | |||
1 | ################################################################################ | ||
2 | # | ||
3 | # FUJITSU Extended Socket Network Device driver | ||
4 | # Copyright (c) 2015 FUJITSU LIMITED | ||
5 | # | ||
6 | # This program is free software; you can redistribute it and/or modify it | ||
7 | # under the terms and conditions of the GNU General Public License, | ||
8 | # version 2, as published by the Free Software Foundation. | ||
9 | # | ||
10 | # This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | # more details. | ||
14 | # | ||
15 | # You should have received a copy of the GNU General Public License along with | ||
16 | # this program; if not, see <http://www.gnu.org/licenses/>. | ||
17 | # | ||
18 | # The full GNU General Public License is included in this distribution in | ||
19 | # the file called "COPYING". | ||
20 | # | ||
21 | ################################################################################ | ||
22 | |||
23 | |||
24 | # | ||
25 | # Makefile for the FUJITSU Extended Socket network device driver | ||
26 | # | ||
27 | |||
28 | obj-$(CONFIG_FUJITSU_ES) += fjes.o | ||
29 | |||
30 | fjes-objs := fjes_main.o | ||
diff --git a/drivers/net/fjes/fjes.h b/drivers/net/fjes/fjes.h new file mode 100644 index 000000000000..52eb60b65057 --- /dev/null +++ b/drivers/net/fjes/fjes.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * FUJITSU Extended Socket Network Device driver | ||
3 | * Copyright (c) 2015 FUJITSU LIMITED | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, see <http://www.gnu.org/licenses/>. | ||
16 | * | ||
17 | * The full GNU General Public License is included in this distribution in | ||
18 | * the file called "COPYING". | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef FJES_H_ | ||
23 | #define FJES_H_ | ||
24 | |||
25 | #include <linux/acpi.h> | ||
26 | |||
27 | #define FJES_ACPI_SYMBOL "Extended Socket" | ||
28 | |||
29 | extern char fjes_driver_name[]; | ||
30 | extern char fjes_driver_version[]; | ||
31 | |||
32 | #endif /* FJES_H_ */ | ||
diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c new file mode 100644 index 000000000000..95176667131e --- /dev/null +++ b/drivers/net/fjes/fjes_main.c | |||
@@ -0,0 +1,213 @@ | |||
1 | /* | ||
2 | * FUJITSU Extended Socket Network Device driver | ||
3 | * Copyright (c) 2015 FUJITSU LIMITED | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, see <http://www.gnu.org/licenses/>. | ||
16 | * | ||
17 | * The full GNU General Public License is included in this distribution in | ||
18 | * the file called "COPYING". | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/nls.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | |||
27 | #include "fjes.h" | ||
28 | |||
29 | #define MAJ 1 | ||
30 | #define MIN 0 | ||
31 | #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) | ||
32 | #define DRV_NAME "fjes" | ||
33 | char fjes_driver_name[] = DRV_NAME; | ||
34 | char fjes_driver_version[] = DRV_VERSION; | ||
35 | static const char fjes_driver_string[] = | ||
36 | "FUJITSU Extended Socket Network Device Driver"; | ||
37 | static const char fjes_copyright[] = | ||
38 | "Copyright (c) 2015 FUJITSU LIMITED"; | ||
39 | |||
40 | MODULE_AUTHOR("Taku Izumi <izumi.taku@jp.fujitsu.com>"); | ||
41 | MODULE_DESCRIPTION("FUJITSU Extended Socket Network Device Driver"); | ||
42 | MODULE_LICENSE("GPL"); | ||
43 | MODULE_VERSION(DRV_VERSION); | ||
44 | |||
45 | static int fjes_acpi_add(struct acpi_device *); | ||
46 | static int fjes_acpi_remove(struct acpi_device *); | ||
47 | static acpi_status fjes_get_acpi_resource(struct acpi_resource *, void*); | ||
48 | |||
49 | static int fjes_probe(struct platform_device *); | ||
50 | static int fjes_remove(struct platform_device *); | ||
51 | |||
52 | static const struct acpi_device_id fjes_acpi_ids[] = { | ||
53 | {"PNP0C02", 0}, | ||
54 | {"", 0}, | ||
55 | }; | ||
56 | MODULE_DEVICE_TABLE(acpi, fjes_acpi_ids); | ||
57 | |||
58 | static struct acpi_driver fjes_acpi_driver = { | ||
59 | .name = DRV_NAME, | ||
60 | .class = DRV_NAME, | ||
61 | .owner = THIS_MODULE, | ||
62 | .ids = fjes_acpi_ids, | ||
63 | .ops = { | ||
64 | .add = fjes_acpi_add, | ||
65 | .remove = fjes_acpi_remove, | ||
66 | }, | ||
67 | }; | ||
68 | |||
69 | static struct platform_driver fjes_driver = { | ||
70 | .driver = { | ||
71 | .name = DRV_NAME, | ||
72 | .owner = THIS_MODULE, | ||
73 | }, | ||
74 | .probe = fjes_probe, | ||
75 | .remove = fjes_remove, | ||
76 | }; | ||
77 | |||
78 | static struct resource fjes_resource[] = { | ||
79 | { | ||
80 | .flags = IORESOURCE_MEM, | ||
81 | .start = 0, | ||
82 | .end = 0, | ||
83 | }, | ||
84 | { | ||
85 | .flags = IORESOURCE_IRQ, | ||
86 | .start = 0, | ||
87 | .end = 0, | ||
88 | }, | ||
89 | }; | ||
90 | |||
91 | static int fjes_acpi_add(struct acpi_device *device) | ||
92 | { | ||
93 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; | ||
94 | char str_buf[sizeof(FJES_ACPI_SYMBOL) + 1]; | ||
95 | struct platform_device *plat_dev; | ||
96 | union acpi_object *str; | ||
97 | acpi_status status; | ||
98 | int result; | ||
99 | |||
100 | status = acpi_evaluate_object(device->handle, "_STR", NULL, &buffer); | ||
101 | if (ACPI_FAILURE(status)) | ||
102 | return -ENODEV; | ||
103 | |||
104 | str = buffer.pointer; | ||
105 | result = utf16s_to_utf8s((wchar_t *)str->string.pointer, | ||
106 | str->string.length, UTF16_LITTLE_ENDIAN, | ||
107 | str_buf, sizeof(str_buf) - 1); | ||
108 | str_buf[result] = 0; | ||
109 | |||
110 | if (strncmp(FJES_ACPI_SYMBOL, str_buf, strlen(FJES_ACPI_SYMBOL)) != 0) { | ||
111 | kfree(buffer.pointer); | ||
112 | return -ENODEV; | ||
113 | } | ||
114 | kfree(buffer.pointer); | ||
115 | |||
116 | status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, | ||
117 | fjes_get_acpi_resource, fjes_resource); | ||
118 | if (ACPI_FAILURE(status)) | ||
119 | return -ENODEV; | ||
120 | |||
121 | /* create platform_device */ | ||
122 | plat_dev = platform_device_register_simple(DRV_NAME, 0, fjes_resource, | ||
123 | ARRAY_SIZE(fjes_resource)); | ||
124 | device->driver_data = plat_dev; | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int fjes_acpi_remove(struct acpi_device *device) | ||
130 | { | ||
131 | struct platform_device *plat_dev; | ||
132 | |||
133 | plat_dev = (struct platform_device *)acpi_driver_data(device); | ||
134 | platform_device_unregister(plat_dev); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static acpi_status | ||
140 | fjes_get_acpi_resource(struct acpi_resource *acpi_res, void *data) | ||
141 | { | ||
142 | struct acpi_resource_address32 *addr; | ||
143 | struct acpi_resource_irq *irq; | ||
144 | struct resource *res = data; | ||
145 | |||
146 | switch (acpi_res->type) { | ||
147 | case ACPI_RESOURCE_TYPE_ADDRESS32: | ||
148 | addr = &acpi_res->data.address32; | ||
149 | res[0].start = addr->address.minimum; | ||
150 | res[0].end = addr->address.minimum + | ||
151 | addr->address.address_length - 1; | ||
152 | break; | ||
153 | |||
154 | case ACPI_RESOURCE_TYPE_IRQ: | ||
155 | irq = &acpi_res->data.irq; | ||
156 | if (irq->interrupt_count != 1) | ||
157 | return AE_ERROR; | ||
158 | res[1].start = irq->interrupts[0]; | ||
159 | res[1].end = irq->interrupts[0]; | ||
160 | break; | ||
161 | |||
162 | default: | ||
163 | break; | ||
164 | } | ||
165 | |||
166 | return AE_OK; | ||
167 | } | ||
168 | |||
169 | /* fjes_probe - Device Initialization Routine */ | ||
170 | static int fjes_probe(struct platform_device *plat_dev) | ||
171 | { | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | /* fjes_remove - Device Removal Routine */ | ||
176 | static int fjes_remove(struct platform_device *plat_dev) | ||
177 | { | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | /* fjes_init_module - Driver Registration Routine */ | ||
182 | static int __init fjes_init_module(void) | ||
183 | { | ||
184 | int result; | ||
185 | |||
186 | pr_info("%s - version %s - %s\n", | ||
187 | fjes_driver_string, fjes_driver_version, fjes_copyright); | ||
188 | |||
189 | result = platform_driver_register(&fjes_driver); | ||
190 | if (result < 0) | ||
191 | return result; | ||
192 | |||
193 | result = acpi_bus_register_driver(&fjes_acpi_driver); | ||
194 | if (result < 0) | ||
195 | goto fail_acpi_driver; | ||
196 | |||
197 | return 0; | ||
198 | |||
199 | fail_acpi_driver: | ||
200 | platform_driver_unregister(&fjes_driver); | ||
201 | return result; | ||
202 | } | ||
203 | |||
204 | module_init(fjes_init_module); | ||
205 | |||
206 | /* fjes_exit_module - Driver Exit Cleanup Routine */ | ||
207 | static void __exit fjes_exit_module(void) | ||
208 | { | ||
209 | acpi_bus_unregister_driver(&fjes_acpi_driver); | ||
210 | platform_driver_unregister(&fjes_driver); | ||
211 | } | ||
212 | |||
213 | module_exit(fjes_exit_module); | ||