-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 42591 b: refs/heads/master c: 9f5e8ee h: refs/heads/master i: 42589: 573ba4c 42587: 8b871dc 42583: adb0c8c 42575: 9a7b295 42559: 1c865ae v: v3
- Loading branch information
Paul Mundt
committed
Dec 6, 2006
1 parent
a43ae1e
commit 884998a
Showing
6 changed files
with
179 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 99a596f93be10001c50894bcab69e458a49a3b8c | ||
refs/heads/master: 9f5e8eee5cfe1328660c71812d87c2a67bda389f |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
menu "Additional SuperH Device Drivers" | ||
|
||
config PUSH_SWITCH | ||
tristate "Push switch support" | ||
help | ||
This enables support for the push switch framework, a simple | ||
framework that allows for sysfs driven switch status reporting. | ||
|
||
endmenu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/* | ||
* Generic push-switch framework | ||
* | ||
* Copyright (C) 2006 Paul Mundt | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file "COPYING" in the main directory of this archive | ||
* for more details. | ||
*/ | ||
#include <linux/init.h> | ||
#include <linux/module.h> | ||
#include <linux/interrupt.h> | ||
#include <linux/platform_device.h> | ||
#include <asm/push-switch.h> | ||
|
||
#define DRV_NAME "push-switch" | ||
#define DRV_VERSION "0.1.0" | ||
|
||
static ssize_t switch_show(struct device *dev, | ||
struct device_attribute *attr, | ||
char *buf) | ||
{ | ||
struct push_switch_platform_info *psw_info = dev->platform_data; | ||
return sprintf(buf, "%s\n", psw_info->name); | ||
} | ||
static DEVICE_ATTR(switch, S_IRUGO, switch_show, NULL); | ||
|
||
static void switch_timer(unsigned long data) | ||
{ | ||
struct push_switch *psw = (struct push_switch *)data; | ||
|
||
schedule_work(&psw->work); | ||
} | ||
|
||
static void switch_work_handler(void *data) | ||
{ | ||
struct platform_device *pdev = data; | ||
struct push_switch *psw = platform_get_drvdata(pdev); | ||
|
||
psw->state = 0; | ||
|
||
kobject_uevent(&pdev->dev.kobj, KOBJ_CHANGE); | ||
} | ||
|
||
static int switch_drv_probe(struct platform_device *pdev) | ||
{ | ||
struct push_switch_platform_info *psw_info; | ||
struct push_switch *psw; | ||
int ret, irq; | ||
|
||
psw = kzalloc(sizeof(struct push_switch), GFP_KERNEL); | ||
if (unlikely(!psw)) | ||
return -ENOMEM; | ||
|
||
irq = platform_get_irq(pdev, 0); | ||
if (unlikely(irq < 0)) { | ||
ret = -ENODEV; | ||
goto err; | ||
} | ||
|
||
psw_info = pdev->dev.platform_data; | ||
BUG_ON(!psw_info); | ||
|
||
ret = request_irq(irq, psw_info->irq_handler, | ||
IRQF_DISABLED | psw_info->irq_flags, | ||
psw_info->name ? psw_info->name : DRV_NAME, pdev); | ||
if (unlikely(ret < 0)) | ||
goto err; | ||
|
||
if (psw_info->name) { | ||
ret = device_create_file(&pdev->dev, &dev_attr_switch); | ||
if (unlikely(ret)) { | ||
dev_err(&pdev->dev, "Failed creating device attrs\n"); | ||
ret = -EINVAL; | ||
goto err_irq; | ||
} | ||
} | ||
|
||
INIT_WORK(&psw->work, switch_work_handler, pdev); | ||
init_timer(&psw->debounce); | ||
|
||
psw->debounce.function = switch_timer; | ||
psw->debounce.data = (unsigned long)psw; | ||
|
||
platform_set_drvdata(pdev, psw); | ||
|
||
return 0; | ||
|
||
err_irq: | ||
free_irq(irq, pdev); | ||
err: | ||
kfree(psw); | ||
return ret; | ||
} | ||
|
||
static int switch_drv_remove(struct platform_device *pdev) | ||
{ | ||
struct push_switch *psw = platform_get_drvdata(pdev); | ||
struct push_switch_platform_info *psw_info = pdev->dev.platform_data; | ||
int irq = platform_get_irq(pdev, 0); | ||
|
||
if (psw_info->name) | ||
device_remove_file(&pdev->dev, &dev_attr_switch); | ||
|
||
platform_set_drvdata(pdev, NULL); | ||
flush_scheduled_work(); | ||
del_timer_sync(&psw->debounce); | ||
free_irq(irq, pdev); | ||
|
||
kfree(psw); | ||
|
||
return 0; | ||
} | ||
|
||
static struct platform_driver switch_driver = { | ||
.probe = switch_drv_probe, | ||
.remove = switch_drv_remove, | ||
.driver = { | ||
.name = DRV_NAME, | ||
}, | ||
}; | ||
|
||
static int __init switch_init(void) | ||
{ | ||
printk(KERN_NOTICE DRV_NAME ": version %s loaded\n", DRV_VERSION); | ||
return platform_driver_register(&switch_driver); | ||
} | ||
|
||
static void __exit switch_exit(void) | ||
{ | ||
platform_driver_unregister(&switch_driver); | ||
} | ||
module_init(switch_init); | ||
module_exit(switch_exit); | ||
|
||
MODULE_VERSION(DRV_VERSION); | ||
MODULE_AUTHOR("Paul Mundt"); | ||
MODULE_LICENSE("GPLv2"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#ifndef __ASM_SH_PUSH_SWITCH_H | ||
#define __ASM_SH_PUSH_SWITCH_H | ||
|
||
#include <linux/timer.h> | ||
#include <linux/interrupt.h> | ||
#include <linux/workqueue.h> | ||
|
||
struct push_switch { | ||
/* switch state */ | ||
unsigned int state:1; | ||
/* debounce timer */ | ||
struct timer_list debounce; | ||
/* workqueue */ | ||
struct work_struct work; | ||
}; | ||
|
||
struct push_switch_platform_info { | ||
/* IRQ handler */ | ||
irqreturn_t (*irq_handler)(int irq, void *data); | ||
/* Special IRQ flags */ | ||
unsigned int irq_flags; | ||
/* Bit location of switch */ | ||
unsigned int bit; | ||
/* Symbolic switch name */ | ||
const char *name; | ||
}; | ||
|
||
#endif /* __ASM_SH_PUSH_SWITCH_H */ |