xref: /linux/drivers/gpio/gpio-virtio.c (revision 3a29355a22c0275fe864100794fee58a73175d93)
1*3a29355aSViresh Kumar // SPDX-License-Identifier: GPL-2.0+
2*3a29355aSViresh Kumar /*
3*3a29355aSViresh Kumar  * GPIO driver for virtio-based virtual GPIO controllers
4*3a29355aSViresh Kumar  *
5*3a29355aSViresh Kumar  * Copyright (C) 2021 metux IT consult
6*3a29355aSViresh Kumar  * Enrico Weigelt, metux IT consult <info@metux.net>
7*3a29355aSViresh Kumar  *
8*3a29355aSViresh Kumar  * Copyright (C) 2021 Linaro.
9*3a29355aSViresh Kumar  * Viresh Kumar <viresh.kumar@linaro.org>
10*3a29355aSViresh Kumar  */
11*3a29355aSViresh Kumar 
12*3a29355aSViresh Kumar #include <linux/completion.h>
13*3a29355aSViresh Kumar #include <linux/err.h>
14*3a29355aSViresh Kumar #include <linux/gpio/driver.h>
15*3a29355aSViresh Kumar #include <linux/io.h>
16*3a29355aSViresh Kumar #include <linux/kernel.h>
17*3a29355aSViresh Kumar #include <linux/module.h>
18*3a29355aSViresh Kumar #include <linux/mutex.h>
19*3a29355aSViresh Kumar #include <linux/virtio_config.h>
20*3a29355aSViresh Kumar #include <uapi/linux/virtio_gpio.h>
21*3a29355aSViresh Kumar #include <uapi/linux/virtio_ids.h>
22*3a29355aSViresh Kumar 
23*3a29355aSViresh Kumar struct virtio_gpio_line {
24*3a29355aSViresh Kumar 	struct mutex lock; /* Protects line operation */
25*3a29355aSViresh Kumar 	struct completion completion;
26*3a29355aSViresh Kumar 	struct virtio_gpio_request req ____cacheline_aligned;
27*3a29355aSViresh Kumar 	struct virtio_gpio_response res ____cacheline_aligned;
28*3a29355aSViresh Kumar 	unsigned int rxlen;
29*3a29355aSViresh Kumar };
30*3a29355aSViresh Kumar 
31*3a29355aSViresh Kumar struct virtio_gpio {
32*3a29355aSViresh Kumar 	struct virtio_device *vdev;
33*3a29355aSViresh Kumar 	struct mutex lock; /* Protects virtqueue operation */
34*3a29355aSViresh Kumar 	struct gpio_chip gc;
35*3a29355aSViresh Kumar 	struct virtio_gpio_config config;
36*3a29355aSViresh Kumar 	struct virtio_gpio_line *lines;
37*3a29355aSViresh Kumar 	struct virtqueue *request_vq;
38*3a29355aSViresh Kumar };
39*3a29355aSViresh Kumar 
40*3a29355aSViresh Kumar static int _virtio_gpio_req(struct virtio_gpio *vgpio, u16 type, u16 gpio,
41*3a29355aSViresh Kumar 			    u8 txvalue, u8 *rxvalue, void *response, u32 rxlen)
42*3a29355aSViresh Kumar {
43*3a29355aSViresh Kumar 	struct virtio_gpio_line *line = &vgpio->lines[gpio];
44*3a29355aSViresh Kumar 	struct virtio_gpio_request *req = &line->req;
45*3a29355aSViresh Kumar 	struct virtio_gpio_response *res = response;
46*3a29355aSViresh Kumar 	struct scatterlist *sgs[2], req_sg, res_sg;
47*3a29355aSViresh Kumar 	struct device *dev = &vgpio->vdev->dev;
48*3a29355aSViresh Kumar 	int ret;
49*3a29355aSViresh Kumar 
50*3a29355aSViresh Kumar 	/*
51*3a29355aSViresh Kumar 	 * Prevent concurrent requests for the same line since we have
52*3a29355aSViresh Kumar 	 * pre-allocated request/response buffers for each GPIO line. Moreover
53*3a29355aSViresh Kumar 	 * Linux always accesses a GPIO line sequentially, so this locking shall
54*3a29355aSViresh Kumar 	 * always go through without any delays.
55*3a29355aSViresh Kumar 	 */
56*3a29355aSViresh Kumar 	mutex_lock(&line->lock);
57*3a29355aSViresh Kumar 
58*3a29355aSViresh Kumar 	req->type = cpu_to_le16(type);
59*3a29355aSViresh Kumar 	req->gpio = cpu_to_le16(gpio);
60*3a29355aSViresh Kumar 	req->value = txvalue;
61*3a29355aSViresh Kumar 
62*3a29355aSViresh Kumar 	sg_init_one(&req_sg, req, sizeof(*req));
63*3a29355aSViresh Kumar 	sg_init_one(&res_sg, res, rxlen);
64*3a29355aSViresh Kumar 	sgs[0] = &req_sg;
65*3a29355aSViresh Kumar 	sgs[1] = &res_sg;
66*3a29355aSViresh Kumar 
67*3a29355aSViresh Kumar 	line->rxlen = 0;
68*3a29355aSViresh Kumar 	reinit_completion(&line->completion);
69*3a29355aSViresh Kumar 
70*3a29355aSViresh Kumar 	/*
71*3a29355aSViresh Kumar 	 * Virtqueue callers need to ensure they don't call its APIs with other
72*3a29355aSViresh Kumar 	 * virtqueue operations at the same time.
73*3a29355aSViresh Kumar 	 */
74*3a29355aSViresh Kumar 	mutex_lock(&vgpio->lock);
75*3a29355aSViresh Kumar 	ret = virtqueue_add_sgs(vgpio->request_vq, sgs, 1, 1, line, GFP_KERNEL);
76*3a29355aSViresh Kumar 	if (ret) {
77*3a29355aSViresh Kumar 		dev_err(dev, "failed to add request to vq\n");
78*3a29355aSViresh Kumar 		mutex_unlock(&vgpio->lock);
79*3a29355aSViresh Kumar 		goto out;
80*3a29355aSViresh Kumar 	}
81*3a29355aSViresh Kumar 
82*3a29355aSViresh Kumar 	virtqueue_kick(vgpio->request_vq);
83*3a29355aSViresh Kumar 	mutex_unlock(&vgpio->lock);
84*3a29355aSViresh Kumar 
85*3a29355aSViresh Kumar 	if (!wait_for_completion_timeout(&line->completion, HZ)) {
86*3a29355aSViresh Kumar 		dev_err(dev, "GPIO operation timed out\n");
87*3a29355aSViresh Kumar 		ret = -ETIMEDOUT;
88*3a29355aSViresh Kumar 		goto out;
89*3a29355aSViresh Kumar 	}
90*3a29355aSViresh Kumar 
91*3a29355aSViresh Kumar 	if (unlikely(res->status != VIRTIO_GPIO_STATUS_OK)) {
92*3a29355aSViresh Kumar 		dev_err(dev, "GPIO request failed: %d\n", gpio);
93*3a29355aSViresh Kumar 		ret = -EINVAL;
94*3a29355aSViresh Kumar 		goto out;
95*3a29355aSViresh Kumar 	}
96*3a29355aSViresh Kumar 
97*3a29355aSViresh Kumar 	if (unlikely(line->rxlen != rxlen)) {
98*3a29355aSViresh Kumar 		dev_err(dev, "GPIO operation returned incorrect len (%u : %u)\n",
99*3a29355aSViresh Kumar 			rxlen, line->rxlen);
100*3a29355aSViresh Kumar 		ret = -EINVAL;
101*3a29355aSViresh Kumar 		goto out;
102*3a29355aSViresh Kumar 	}
103*3a29355aSViresh Kumar 
104*3a29355aSViresh Kumar 	if (rxvalue)
105*3a29355aSViresh Kumar 		*rxvalue = res->value;
106*3a29355aSViresh Kumar 
107*3a29355aSViresh Kumar out:
108*3a29355aSViresh Kumar 	mutex_unlock(&line->lock);
109*3a29355aSViresh Kumar 	return ret;
110*3a29355aSViresh Kumar }
111*3a29355aSViresh Kumar 
112*3a29355aSViresh Kumar static int virtio_gpio_req(struct virtio_gpio *vgpio, u16 type, u16 gpio,
113*3a29355aSViresh Kumar 			   u8 txvalue, u8 *rxvalue)
114*3a29355aSViresh Kumar {
115*3a29355aSViresh Kumar 	struct virtio_gpio_line *line = &vgpio->lines[gpio];
116*3a29355aSViresh Kumar 	struct virtio_gpio_response *res = &line->res;
117*3a29355aSViresh Kumar 
118*3a29355aSViresh Kumar 	return _virtio_gpio_req(vgpio, type, gpio, txvalue, rxvalue, res,
119*3a29355aSViresh Kumar 				sizeof(*res));
120*3a29355aSViresh Kumar }
121*3a29355aSViresh Kumar 
122*3a29355aSViresh Kumar static void virtio_gpio_free(struct gpio_chip *gc, unsigned int gpio)
123*3a29355aSViresh Kumar {
124*3a29355aSViresh Kumar 	struct virtio_gpio *vgpio = gpiochip_get_data(gc);
125*3a29355aSViresh Kumar 
126*3a29355aSViresh Kumar 	virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_SET_DIRECTION, gpio,
127*3a29355aSViresh Kumar 			VIRTIO_GPIO_DIRECTION_NONE, NULL);
128*3a29355aSViresh Kumar }
129*3a29355aSViresh Kumar 
130*3a29355aSViresh Kumar static int virtio_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)
131*3a29355aSViresh Kumar {
132*3a29355aSViresh Kumar 	struct virtio_gpio *vgpio = gpiochip_get_data(gc);
133*3a29355aSViresh Kumar 	u8 direction;
134*3a29355aSViresh Kumar 	int ret;
135*3a29355aSViresh Kumar 
136*3a29355aSViresh Kumar 	ret = virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_GET_DIRECTION, gpio, 0,
137*3a29355aSViresh Kumar 			      &direction);
138*3a29355aSViresh Kumar 	if (ret)
139*3a29355aSViresh Kumar 		return ret;
140*3a29355aSViresh Kumar 
141*3a29355aSViresh Kumar 	switch (direction) {
142*3a29355aSViresh Kumar 	case VIRTIO_GPIO_DIRECTION_IN:
143*3a29355aSViresh Kumar 		return GPIO_LINE_DIRECTION_IN;
144*3a29355aSViresh Kumar 	case VIRTIO_GPIO_DIRECTION_OUT:
145*3a29355aSViresh Kumar 		return GPIO_LINE_DIRECTION_OUT;
146*3a29355aSViresh Kumar 	default:
147*3a29355aSViresh Kumar 		return -EINVAL;
148*3a29355aSViresh Kumar 	}
149*3a29355aSViresh Kumar }
150*3a29355aSViresh Kumar 
151*3a29355aSViresh Kumar static int virtio_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio)
152*3a29355aSViresh Kumar {
153*3a29355aSViresh Kumar 	struct virtio_gpio *vgpio = gpiochip_get_data(gc);
154*3a29355aSViresh Kumar 
155*3a29355aSViresh Kumar 	return virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_SET_DIRECTION, gpio,
156*3a29355aSViresh Kumar 			       VIRTIO_GPIO_DIRECTION_IN, NULL);
157*3a29355aSViresh Kumar }
158*3a29355aSViresh Kumar 
159*3a29355aSViresh Kumar static int virtio_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio,
160*3a29355aSViresh Kumar 					int value)
161*3a29355aSViresh Kumar {
162*3a29355aSViresh Kumar 	struct virtio_gpio *vgpio = gpiochip_get_data(gc);
163*3a29355aSViresh Kumar 	int ret;
164*3a29355aSViresh Kumar 
165*3a29355aSViresh Kumar 	ret = virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_SET_VALUE, gpio, value, NULL);
166*3a29355aSViresh Kumar 	if (ret)
167*3a29355aSViresh Kumar 		return ret;
168*3a29355aSViresh Kumar 
169*3a29355aSViresh Kumar 	return virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_SET_DIRECTION, gpio,
170*3a29355aSViresh Kumar 			       VIRTIO_GPIO_DIRECTION_OUT, NULL);
171*3a29355aSViresh Kumar }
172*3a29355aSViresh Kumar 
173*3a29355aSViresh Kumar static int virtio_gpio_get(struct gpio_chip *gc, unsigned int gpio)
174*3a29355aSViresh Kumar {
175*3a29355aSViresh Kumar 	struct virtio_gpio *vgpio = gpiochip_get_data(gc);
176*3a29355aSViresh Kumar 	u8 value;
177*3a29355aSViresh Kumar 	int ret;
178*3a29355aSViresh Kumar 
179*3a29355aSViresh Kumar 	ret = virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_GET_VALUE, gpio, 0, &value);
180*3a29355aSViresh Kumar 	return ret ? ret : value;
181*3a29355aSViresh Kumar }
182*3a29355aSViresh Kumar 
183*3a29355aSViresh Kumar static void virtio_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value)
184*3a29355aSViresh Kumar {
185*3a29355aSViresh Kumar 	struct virtio_gpio *vgpio = gpiochip_get_data(gc);
186*3a29355aSViresh Kumar 
187*3a29355aSViresh Kumar 	virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_SET_VALUE, gpio, value, NULL);
188*3a29355aSViresh Kumar }
189*3a29355aSViresh Kumar 
190*3a29355aSViresh Kumar static void virtio_gpio_request_vq(struct virtqueue *vq)
191*3a29355aSViresh Kumar {
192*3a29355aSViresh Kumar 	struct virtio_gpio_line *line;
193*3a29355aSViresh Kumar 	unsigned int len;
194*3a29355aSViresh Kumar 
195*3a29355aSViresh Kumar 	do {
196*3a29355aSViresh Kumar 		line = virtqueue_get_buf(vq, &len);
197*3a29355aSViresh Kumar 		if (!line)
198*3a29355aSViresh Kumar 			return;
199*3a29355aSViresh Kumar 
200*3a29355aSViresh Kumar 		line->rxlen = len;
201*3a29355aSViresh Kumar 		complete(&line->completion);
202*3a29355aSViresh Kumar 	} while (1);
203*3a29355aSViresh Kumar }
204*3a29355aSViresh Kumar 
205*3a29355aSViresh Kumar static void virtio_gpio_free_vqs(struct virtio_device *vdev)
206*3a29355aSViresh Kumar {
207*3a29355aSViresh Kumar 	vdev->config->reset(vdev);
208*3a29355aSViresh Kumar 	vdev->config->del_vqs(vdev);
209*3a29355aSViresh Kumar }
210*3a29355aSViresh Kumar 
211*3a29355aSViresh Kumar static int virtio_gpio_alloc_vqs(struct virtio_gpio *vgpio,
212*3a29355aSViresh Kumar 				 struct virtio_device *vdev)
213*3a29355aSViresh Kumar {
214*3a29355aSViresh Kumar 	const char * const names[] = { "requestq" };
215*3a29355aSViresh Kumar 	vq_callback_t *cbs[] = {
216*3a29355aSViresh Kumar 		virtio_gpio_request_vq,
217*3a29355aSViresh Kumar 	};
218*3a29355aSViresh Kumar 	struct virtqueue *vqs[1] = { NULL };
219*3a29355aSViresh Kumar 	int ret;
220*3a29355aSViresh Kumar 
221*3a29355aSViresh Kumar 	ret = virtio_find_vqs(vdev, 1, vqs, cbs, names, NULL);
222*3a29355aSViresh Kumar 	if (ret) {
223*3a29355aSViresh Kumar 		dev_err(&vdev->dev, "failed to find vqs: %d\n", ret);
224*3a29355aSViresh Kumar 		return ret;
225*3a29355aSViresh Kumar 	}
226*3a29355aSViresh Kumar 
227*3a29355aSViresh Kumar 	if (!vqs[0]) {
228*3a29355aSViresh Kumar 		dev_err(&vdev->dev, "failed to find requestq vq\n");
229*3a29355aSViresh Kumar 		return -ENODEV;
230*3a29355aSViresh Kumar 	}
231*3a29355aSViresh Kumar 	vgpio->request_vq = vqs[0];
232*3a29355aSViresh Kumar 
233*3a29355aSViresh Kumar 	return 0;
234*3a29355aSViresh Kumar }
235*3a29355aSViresh Kumar 
236*3a29355aSViresh Kumar static const char **virtio_gpio_get_names(struct virtio_gpio *vgpio)
237*3a29355aSViresh Kumar {
238*3a29355aSViresh Kumar 	struct virtio_gpio_config *config = &vgpio->config;
239*3a29355aSViresh Kumar 	struct virtio_gpio_response_get_names *res;
240*3a29355aSViresh Kumar 	struct device *dev = &vgpio->vdev->dev;
241*3a29355aSViresh Kumar 	u8 *gpio_names, *str;
242*3a29355aSViresh Kumar 	const char **names;
243*3a29355aSViresh Kumar 	int i, ret, len;
244*3a29355aSViresh Kumar 
245*3a29355aSViresh Kumar 	if (!config->gpio_names_size)
246*3a29355aSViresh Kumar 		return NULL;
247*3a29355aSViresh Kumar 
248*3a29355aSViresh Kumar 	len = sizeof(*res) + config->gpio_names_size;
249*3a29355aSViresh Kumar 	res = devm_kzalloc(dev, len, GFP_KERNEL);
250*3a29355aSViresh Kumar 	if (!res)
251*3a29355aSViresh Kumar 		return NULL;
252*3a29355aSViresh Kumar 	gpio_names = res->value;
253*3a29355aSViresh Kumar 
254*3a29355aSViresh Kumar 	ret = _virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_GET_NAMES, 0, 0, NULL,
255*3a29355aSViresh Kumar 			       res, len);
256*3a29355aSViresh Kumar 	if (ret) {
257*3a29355aSViresh Kumar 		dev_err(dev, "Failed to get GPIO names: %d\n", ret);
258*3a29355aSViresh Kumar 		return NULL;
259*3a29355aSViresh Kumar 	}
260*3a29355aSViresh Kumar 
261*3a29355aSViresh Kumar 	names = devm_kcalloc(dev, config->ngpio, sizeof(*names), GFP_KERNEL);
262*3a29355aSViresh Kumar 	if (!names)
263*3a29355aSViresh Kumar 		return NULL;
264*3a29355aSViresh Kumar 
265*3a29355aSViresh Kumar 	/* NULL terminate the string instead of checking it */
266*3a29355aSViresh Kumar 	gpio_names[config->gpio_names_size - 1] = '\0';
267*3a29355aSViresh Kumar 
268*3a29355aSViresh Kumar 	for (i = 0, str = gpio_names; i < config->ngpio; i++) {
269*3a29355aSViresh Kumar 		names[i] = str;
270*3a29355aSViresh Kumar 		str += strlen(str) + 1; /* zero-length strings are allowed */
271*3a29355aSViresh Kumar 
272*3a29355aSViresh Kumar 		if (str > gpio_names + config->gpio_names_size) {
273*3a29355aSViresh Kumar 			dev_err(dev, "gpio_names block is too short (%d)\n", i);
274*3a29355aSViresh Kumar 			return NULL;
275*3a29355aSViresh Kumar 		}
276*3a29355aSViresh Kumar 	}
277*3a29355aSViresh Kumar 
278*3a29355aSViresh Kumar 	return names;
279*3a29355aSViresh Kumar }
280*3a29355aSViresh Kumar 
281*3a29355aSViresh Kumar static int virtio_gpio_probe(struct virtio_device *vdev)
282*3a29355aSViresh Kumar {
283*3a29355aSViresh Kumar 	struct virtio_gpio_config *config;
284*3a29355aSViresh Kumar 	struct device *dev = &vdev->dev;
285*3a29355aSViresh Kumar 	struct virtio_gpio *vgpio;
286*3a29355aSViresh Kumar 	int ret, i;
287*3a29355aSViresh Kumar 
288*3a29355aSViresh Kumar 	vgpio = devm_kzalloc(dev, sizeof(*vgpio), GFP_KERNEL);
289*3a29355aSViresh Kumar 	if (!vgpio)
290*3a29355aSViresh Kumar 		return -ENOMEM;
291*3a29355aSViresh Kumar 
292*3a29355aSViresh Kumar 	config = &vgpio->config;
293*3a29355aSViresh Kumar 
294*3a29355aSViresh Kumar 	/* Read configuration */
295*3a29355aSViresh Kumar 	virtio_cread_bytes(vdev, 0, config, sizeof(*config));
296*3a29355aSViresh Kumar 	config->gpio_names_size = le32_to_cpu(config->gpio_names_size);
297*3a29355aSViresh Kumar 	config->ngpio = le16_to_cpu(config->ngpio);
298*3a29355aSViresh Kumar 	if (!config->ngpio) {
299*3a29355aSViresh Kumar 		dev_err(dev, "Number of GPIOs can't be zero\n");
300*3a29355aSViresh Kumar 		return -EINVAL;
301*3a29355aSViresh Kumar 	}
302*3a29355aSViresh Kumar 
303*3a29355aSViresh Kumar 	vgpio->lines = devm_kcalloc(dev, config->ngpio, sizeof(*vgpio->lines), GFP_KERNEL);
304*3a29355aSViresh Kumar 	if (!vgpio->lines)
305*3a29355aSViresh Kumar 		return -ENOMEM;
306*3a29355aSViresh Kumar 
307*3a29355aSViresh Kumar 	for (i = 0; i < config->ngpio; i++) {
308*3a29355aSViresh Kumar 		mutex_init(&vgpio->lines[i].lock);
309*3a29355aSViresh Kumar 		init_completion(&vgpio->lines[i].completion);
310*3a29355aSViresh Kumar 	}
311*3a29355aSViresh Kumar 
312*3a29355aSViresh Kumar 	mutex_init(&vgpio->lock);
313*3a29355aSViresh Kumar 	vdev->priv = vgpio;
314*3a29355aSViresh Kumar 
315*3a29355aSViresh Kumar 	vgpio->vdev			= vdev;
316*3a29355aSViresh Kumar 	vgpio->gc.free			= virtio_gpio_free;
317*3a29355aSViresh Kumar 	vgpio->gc.get_direction		= virtio_gpio_get_direction;
318*3a29355aSViresh Kumar 	vgpio->gc.direction_input	= virtio_gpio_direction_input;
319*3a29355aSViresh Kumar 	vgpio->gc.direction_output	= virtio_gpio_direction_output;
320*3a29355aSViresh Kumar 	vgpio->gc.get			= virtio_gpio_get;
321*3a29355aSViresh Kumar 	vgpio->gc.set			= virtio_gpio_set;
322*3a29355aSViresh Kumar 	vgpio->gc.ngpio			= config->ngpio;
323*3a29355aSViresh Kumar 	vgpio->gc.base			= -1; /* Allocate base dynamically */
324*3a29355aSViresh Kumar 	vgpio->gc.label			= dev_name(dev);
325*3a29355aSViresh Kumar 	vgpio->gc.parent		= dev;
326*3a29355aSViresh Kumar 	vgpio->gc.owner			= THIS_MODULE;
327*3a29355aSViresh Kumar 	vgpio->gc.can_sleep		= true;
328*3a29355aSViresh Kumar 
329*3a29355aSViresh Kumar 	ret = virtio_gpio_alloc_vqs(vgpio, vdev);
330*3a29355aSViresh Kumar 	if (ret)
331*3a29355aSViresh Kumar 		return ret;
332*3a29355aSViresh Kumar 
333*3a29355aSViresh Kumar 	/* Mark the device ready to perform operations from within probe() */
334*3a29355aSViresh Kumar 	virtio_device_ready(vdev);
335*3a29355aSViresh Kumar 
336*3a29355aSViresh Kumar 	vgpio->gc.names = virtio_gpio_get_names(vgpio);
337*3a29355aSViresh Kumar 
338*3a29355aSViresh Kumar 	ret = gpiochip_add_data(&vgpio->gc, vgpio);
339*3a29355aSViresh Kumar 	if (ret) {
340*3a29355aSViresh Kumar 		virtio_gpio_free_vqs(vdev);
341*3a29355aSViresh Kumar 		dev_err(dev, "Failed to add virtio-gpio controller\n");
342*3a29355aSViresh Kumar 	}
343*3a29355aSViresh Kumar 
344*3a29355aSViresh Kumar 	return ret;
345*3a29355aSViresh Kumar }
346*3a29355aSViresh Kumar 
347*3a29355aSViresh Kumar static void virtio_gpio_remove(struct virtio_device *vdev)
348*3a29355aSViresh Kumar {
349*3a29355aSViresh Kumar 	struct virtio_gpio *vgpio = vdev->priv;
350*3a29355aSViresh Kumar 
351*3a29355aSViresh Kumar 	gpiochip_remove(&vgpio->gc);
352*3a29355aSViresh Kumar 	virtio_gpio_free_vqs(vdev);
353*3a29355aSViresh Kumar }
354*3a29355aSViresh Kumar 
355*3a29355aSViresh Kumar static const struct virtio_device_id id_table[] = {
356*3a29355aSViresh Kumar 	{ VIRTIO_ID_GPIO, VIRTIO_DEV_ANY_ID },
357*3a29355aSViresh Kumar 	{},
358*3a29355aSViresh Kumar };
359*3a29355aSViresh Kumar MODULE_DEVICE_TABLE(virtio, id_table);
360*3a29355aSViresh Kumar 
361*3a29355aSViresh Kumar static struct virtio_driver virtio_gpio_driver = {
362*3a29355aSViresh Kumar 	.id_table		= id_table,
363*3a29355aSViresh Kumar 	.probe			= virtio_gpio_probe,
364*3a29355aSViresh Kumar 	.remove			= virtio_gpio_remove,
365*3a29355aSViresh Kumar 	.driver			= {
366*3a29355aSViresh Kumar 		.name		= KBUILD_MODNAME,
367*3a29355aSViresh Kumar 		.owner		= THIS_MODULE,
368*3a29355aSViresh Kumar 	},
369*3a29355aSViresh Kumar };
370*3a29355aSViresh Kumar module_virtio_driver(virtio_gpio_driver);
371*3a29355aSViresh Kumar 
372*3a29355aSViresh Kumar MODULE_AUTHOR("Enrico Weigelt, metux IT consult <info@metux.net>");
373*3a29355aSViresh Kumar MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
374*3a29355aSViresh Kumar MODULE_DESCRIPTION("VirtIO GPIO driver");
375*3a29355aSViresh Kumar MODULE_LICENSE("GPL");
376