16cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg/* drivers/input/misc/gpio_event.c 26cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * 36cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * Copyright (C) 2007 Google, Inc. 46cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * 56cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * This software is licensed under the terms of the GNU General Public 66cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * License version 2, as published by the Free Software Foundation, and 76cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * may be copied, distributed, and modified under those terms. 86cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * 96cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * This program is distributed in the hope that it will be useful, 106cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * but WITHOUT ANY WARRANTY; without even the implied warranty of 116cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 126cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * GNU General Public License for more details. 136cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg * 146cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg */ 156cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 166cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg#include <linux/module.h> 176cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg#include <linux/input.h> 186cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg#include <linux/gpio_event.h> 196cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg#include <linux/hrtimer.h> 206cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg#include <linux/platform_device.h> 216cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg#include <linux/slab.h> 226cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 236cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågstruct gpio_event { 246cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg struct gpio_event_input_devs *input_devs; 256cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg const struct gpio_event_platform_data *info; 266cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg void *state[0]; 276cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg}; 286cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 296cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågstatic int gpio_input_event( 306cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg struct input_dev *dev, unsigned int type, unsigned int code, int value) 316cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg{ 326cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int i; 336cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int devnr; 346cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int ret = 0; 356cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int tmp_ret; 366cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg struct gpio_event_info **ii; 376cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg struct gpio_event *ip = input_get_drvdata(dev); 386cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 396cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg for (devnr = 0; devnr < ip->input_devs->count; devnr++) 406cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (ip->input_devs->dev[devnr] == dev) 416cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg break; 426cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (devnr == ip->input_devs->count) { 436cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg pr_err("gpio_input_event: unknown device %p\n", dev); 446cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg return -EIO; 456cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 466cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 476cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) { 486cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if ((*ii)->event) { 496cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg tmp_ret = (*ii)->event(ip->input_devs, *ii, 506cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg &ip->state[i], 516cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg devnr, type, code, value); 526cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (tmp_ret) 536cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ret = tmp_ret; 546cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 556cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 566cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg return ret; 576cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg} 586cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 596cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågstatic int gpio_event_call_all_func(struct gpio_event *ip, int func) 606cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg{ 616cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int i; 626cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int ret; 636cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg struct gpio_event_info **ii; 646cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 656cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) { 666cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ii = ip->info->info; 676cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg for (i = 0; i < ip->info->info_count; i++, ii++) { 686cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if ((*ii)->func == NULL) { 696cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ret = -ENODEV; 706cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg pr_err("gpio_event_probe: Incomplete pdata, " 716cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg "no function\n"); 726cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg goto err_no_func; 736cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 746cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (func == GPIO_EVENT_FUNC_RESUME && (*ii)->no_suspend) 756cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg continue; 766cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ret = (*ii)->func(ip->input_devs, *ii, &ip->state[i], 776cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg func); 786cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (ret) { 796cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg pr_err("gpio_event_probe: function failed\n"); 806cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg goto err_func_failed; 816cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 826cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 836cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg return 0; 846cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 856cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 866cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ret = 0; 876cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg i = ip->info->info_count; 886cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ii = ip->info->info + i; 896cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg while (i > 0) { 906cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg i--; 916cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ii--; 926cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if ((func & ~1) == GPIO_EVENT_FUNC_SUSPEND && (*ii)->no_suspend) 936cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg continue; 946cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg (*ii)->func(ip->input_devs, *ii, &ip->state[i], func & ~1); 956cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågerr_func_failed: 966cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågerr_no_func: 976cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ; 986cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 996cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg return ret; 1006cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg} 1016cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 102f811f7f66c3ca0047fbbfae747cb09433bd64824Colin Crossstatic void __maybe_unused gpio_event_suspend(struct gpio_event *ip) 1036cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg{ 1046cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND); 105f811f7f66c3ca0047fbbfae747cb09433bd64824Colin Cross if (ip->info->power) 106f811f7f66c3ca0047fbbfae747cb09433bd64824Colin Cross ip->info->power(ip->info, 0); 1076cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg} 1086cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 109f811f7f66c3ca0047fbbfae747cb09433bd64824Colin Crossstatic void __maybe_unused gpio_event_resume(struct gpio_event *ip) 1106cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg{ 111f811f7f66c3ca0047fbbfae747cb09433bd64824Colin Cross if (ip->info->power) 112f811f7f66c3ca0047fbbfae747cb09433bd64824Colin Cross ip->info->power(ip->info, 1); 1136cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME); 1146cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg} 1156cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 1166cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågstatic int gpio_event_probe(struct platform_device *pdev) 1176cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg{ 1186cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int err; 1196cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg struct gpio_event *ip; 1206cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg struct gpio_event_platform_data *event_info; 1216cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int dev_count = 1; 1226cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int i; 1236cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int registered = 0; 1246cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 1256cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg event_info = pdev->dev.platform_data; 1266cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (event_info == NULL) { 1276cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg pr_err("gpio_event_probe: No pdata\n"); 1286cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg return -ENODEV; 1296cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 1306cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if ((!event_info->name && !event_info->names[0]) || 1316cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg !event_info->info || !event_info->info_count) { 1326cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg pr_err("gpio_event_probe: Incomplete pdata\n"); 1336cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg return -ENODEV; 1346cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 1356cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (!event_info->name) 1366cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg while (event_info->names[dev_count]) 1376cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg dev_count++; 1386cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ip = kzalloc(sizeof(*ip) + 1396cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg sizeof(ip->state[0]) * event_info->info_count + 1406cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg sizeof(*ip->input_devs) + 1416cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg sizeof(ip->input_devs->dev[0]) * dev_count, GFP_KERNEL); 1426cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (ip == NULL) { 1436cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg err = -ENOMEM; 1446cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg pr_err("gpio_event_probe: Failed to allocate private data\n"); 1456cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg goto err_kp_alloc_failed; 1466cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 1476cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ip->input_devs = (void*)&ip->state[event_info->info_count]; 1486cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg platform_set_drvdata(pdev, ip); 1496cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 1506cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg for (i = 0; i < dev_count; i++) { 1516cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg struct input_dev *input_dev = input_allocate_device(); 1526cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (input_dev == NULL) { 1536cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg err = -ENOMEM; 1546cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg pr_err("gpio_event_probe: " 1556cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg "Failed to allocate input device\n"); 1566cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg goto err_input_dev_alloc_failed; 1576cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 1586cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg input_set_drvdata(input_dev, ip); 1596cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg input_dev->name = event_info->name ? 1606cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg event_info->name : event_info->names[i]; 1616cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg input_dev->event = gpio_input_event; 1626cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ip->input_devs->dev[i] = input_dev; 1636cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 1646cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ip->input_devs->count = dev_count; 1656cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ip->info = event_info; 166f811f7f66c3ca0047fbbfae747cb09433bd64824Colin Cross if (event_info->power) 1676cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ip->info->power(ip->info, 1); 1686cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 1696cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT); 1706cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (err) 1716cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg goto err_call_all_func_failed; 1726cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 1736cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg for (i = 0; i < dev_count; i++) { 1746cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg err = input_register_device(ip->input_devs->dev[i]); 1756cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg if (err) { 1766cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg pr_err("gpio_event_probe: Unable to register %s " 1776cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg "input device\n", ip->input_devs->dev[i]->name); 1786cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg goto err_input_register_device_failed; 1796cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 1806cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg registered++; 1816cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 1826cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 1836cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg return 0; 1846cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 1856cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågerr_input_register_device_failed: 1866cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT); 1876cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågerr_call_all_func_failed: 188f811f7f66c3ca0047fbbfae747cb09433bd64824Colin Cross if (event_info->power) 1896cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ip->info->power(ip->info, 0); 1906cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg for (i = 0; i < registered; i++) 1916cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg input_unregister_device(ip->input_devs->dev[i]); 1926cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg for (i = dev_count - 1; i >= registered; i--) { 1936cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg input_free_device(ip->input_devs->dev[i]); 1946cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågerr_input_dev_alloc_failed: 1956cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ; 1966cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg } 1976cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg kfree(ip); 1986cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågerr_kp_alloc_failed: 1996cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg return err; 2006cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg} 2016cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 2026cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågstatic int gpio_event_remove(struct platform_device *pdev) 2036cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg{ 2046cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg struct gpio_event *ip = platform_get_drvdata(pdev); 2056cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg int i; 2066cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 2076cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT); 208f811f7f66c3ca0047fbbfae747cb09433bd64824Colin Cross if (ip->info->power) 2096cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg ip->info->power(ip->info, 0); 2106cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg for (i = 0; i < ip->input_devs->count; i++) 2116cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg input_unregister_device(ip->input_devs->dev[i]); 2126cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg kfree(ip); 2136cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg return 0; 2146cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg} 2156cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 2166cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågstatic struct platform_driver gpio_event_driver = { 2176cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg .probe = gpio_event_probe, 2186cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg .remove = gpio_event_remove, 2196cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg .driver = { 2206cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg .name = GPIO_EVENT_DEV_NAME, 2216cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg }, 2226cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg}; 2236cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 2246cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågstatic int __devinit gpio_event_init(void) 2256cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg{ 2266cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg return platform_driver_register(&gpio_event_driver); 2276cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg} 2286cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 2296cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågstatic void __exit gpio_event_exit(void) 2306cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg{ 2316cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg platform_driver_unregister(&gpio_event_driver); 2326cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg} 2336cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 2346cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågmodule_init(gpio_event_init); 2356cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevågmodule_exit(gpio_event_exit); 2366cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 2376cf80c7fbf27523037b2306322c60cc97a23814cArve HjønnevågMODULE_DESCRIPTION("GPIO Event Driver"); 2386cf80c7fbf27523037b2306322c60cc97a23814cArve HjønnevågMODULE_LICENSE("GPL"); 2396cf80c7fbf27523037b2306322c60cc97a23814cArve Hjønnevåg 240