aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fjes
diff options
context:
space:
mode:
authorTaku Izumi <izumi.taku@jp.fujitsu.com>2015-08-21 04:29:17 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-24 17:06:33 -0400
commit658d439b22924796d00f03282135a356f47cc64e (patch)
treed03480b8864729f777f10c5d544cccc70da765a1 /drivers/net/fjes
parent4a89ba04ecc6377696e4e26c1abc1cb5764decb9 (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/fjes')
-rw-r--r--drivers/net/fjes/Makefile30
-rw-r--r--drivers/net/fjes/fjes.h32
-rw-r--r--drivers/net/fjes/fjes_main.c213
3 files changed, 275 insertions, 0 deletions
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
28obj-$(CONFIG_FUJITSU_ES) += fjes.o
29
30fjes-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
29extern char fjes_driver_name[];
30extern 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"
33char fjes_driver_name[] = DRV_NAME;
34char fjes_driver_version[] = DRV_VERSION;
35static const char fjes_driver_string[] =
36 "FUJITSU Extended Socket Network Device Driver";
37static const char fjes_copyright[] =
38 "Copyright (c) 2015 FUJITSU LIMITED";
39
40MODULE_AUTHOR("Taku Izumi <izumi.taku@jp.fujitsu.com>");
41MODULE_DESCRIPTION("FUJITSU Extended Socket Network Device Driver");
42MODULE_LICENSE("GPL");
43MODULE_VERSION(DRV_VERSION);
44
45static int fjes_acpi_add(struct acpi_device *);
46static int fjes_acpi_remove(struct acpi_device *);
47static acpi_status fjes_get_acpi_resource(struct acpi_resource *, void*);
48
49static int fjes_probe(struct platform_device *);
50static int fjes_remove(struct platform_device *);
51
52static const struct acpi_device_id fjes_acpi_ids[] = {
53 {"PNP0C02", 0},
54 {"", 0},
55};
56MODULE_DEVICE_TABLE(acpi, fjes_acpi_ids);
57
58static 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
69static 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
78static 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
91static 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
129static 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
139static acpi_status
140fjes_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 */
170static int fjes_probe(struct platform_device *plat_dev)
171{
172 return 0;
173}
174
175/* fjes_remove - Device Removal Routine */
176static int fjes_remove(struct platform_device *plat_dev)
177{
178 return 0;
179}
180
181/* fjes_init_module - Driver Registration Routine */
182static 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
199fail_acpi_driver:
200 platform_driver_unregister(&fjes_driver);
201 return result;
202}
203
204module_init(fjes_init_module);
205
206/* fjes_exit_module - Driver Exit Cleanup Routine */
207static void __exit fjes_exit_module(void)
208{
209 acpi_bus_unregister_driver(&fjes_acpi_driver);
210 platform_driver_unregister(&fjes_driver);
211}
212
213module_exit(fjes_exit_module);