aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/goldfish/patches-2.6.30/0054-timed_gpio-Separate-timed_output-class-into-a-separ.patch
blob: 16f1350f5995c25eca15a86fabeb7efcb6a4f7a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#ifndef _SHA1_H
#define _SHA1_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef _STD_TYPES
#define _STD_TYPES

#define uchar   unsigned char
#define uint    unsigned int
#define ulong   unsigned long int

#endif

typedef struct
{
    ulong total[2];
    ulong state[5];
    uchar buffer[64];
}
sha1_context;

/*
 * Core SHA-1 functions
 */
void sha1_starts( sha1_context *ctx );
void sha1_update( sha1_context *ctx, uchar *input, uint length );
void sha1_finish( sha1_context *ctx, uchar digest[20] );

/*
 * Output SHA-1(file contents), returns 0 if successful.
 */
int sha1_file( char *filename, uchar digest[20] );

/*
 * Output SHA-1(buf)
 */
void sha1_csum( uchar *buf, uint buflen, uchar digest[20] );

/*
 * Output HMAC-SHA-1(key,buf)
 */
void sha1_hmac( uchar *key, uint keylen, uchar *buf, uint buflen,
                uchar digest[20] );

/*
 * Checkup routine
 */
int sha1_self_test( void );

#ifdef __cplusplus
}
#endif

#endif /* sha1.h */
42 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
From e4c9c5d7d6d5deb124083678fe5d839d3133f60a Mon Sep 17 00:00:00 2001
From: Mike Lockwood <lockwood@android.com>
Date: Mon, 12 Jan 2009 13:25:05 -0500
Subject: [PATCH 054/134] timed_gpio: Separate timed_output class into a separate driver.
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Mike Lockwood <lockwood@android.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 drivers/staging/android/Kconfig        |    6 ++-
 drivers/staging/android/Makefile       |    1 +
 drivers/staging/android/timed_gpio.c   |   98 +++++++++++--------------
 drivers/staging/android/timed_gpio.h   |    4 +-
 drivers/staging/android/timed_output.c |  121 ++++++++++++++++++++++++++++++++
 drivers/staging/android/timed_output.h |   37 ++++++++++
 6 files changed, 210 insertions(+), 57 deletions(-)
 create mode 100644 drivers/staging/android/timed_output.c
 create mode 100644 drivers/staging/android/timed_output.h

--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -73,9 +73,13 @@ config ANDROID_RAM_CONSOLE_EARLY_SIZE
 	default 0
 	depends on ANDROID_RAM_CONSOLE_EARLY_INIT
 
+config ANDROID_TIMED_OUTPUT
+	bool "Timed output class driver"
+	default y
+
 config ANDROID_TIMED_GPIO
 	tristate "Android timed gpio driver"
-	depends on GENERIC_GPIO
+	depends on GENERIC_GPIO && ANDROID_TIMED_OUTPUT
 	default n
 
 config ANDROID_LOW_MEMORY_KILLER
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_ANDROID_BINDER_IPC)	+= binder.o
 obj-$(CONFIG_ANDROID_LOGGER)		+= logger.o
 obj-$(CONFIG_ANDROID_RAM_CONSOLE)	+= ram_console.o
+obj-$(CONFIG_ANDROID_TIMED_OUTPUT)	+= timed_output.o
 obj-$(CONFIG_ANDROID_TIMED_GPIO)	+= timed_gpio.o
 obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)	+= lowmemorykiller.o
--- a/drivers/staging/android/timed_gpio.c
+++ b/drivers/staging/android/timed_gpio.c
@@ -20,13 +20,12 @@
 #include <linux/err.h>
 #include <linux/gpio.h>
 
+#include "timed_output.h"
 #include "timed_gpio.h"
 
 
-static struct class *timed_gpio_class;
-
 struct timed_gpio_data {
-	struct device *dev;
+	struct timed_output_dev dev;
 	struct hrtimer timer;
 	spinlock_t lock;
 	unsigned 	gpio;
@@ -36,70 +35,62 @@ struct timed_gpio_data {
 
 static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)
 {
-	struct timed_gpio_data *gpio_data = container_of(timer, struct timed_gpio_data, timer);
+	struct timed_gpio_data *data =
+		container_of(timer, struct timed_gpio_data, timer);
 
-	gpio_direction_output(gpio_data->gpio, gpio_data->active_low ? 1 : 0);
+	gpio_direction_output(data->gpio, data->active_low ? 1 : 0);
 	return HRTIMER_NORESTART;
 }
 
-static ssize_t gpio_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+static int gpio_get_time(struct timed_output_dev *dev)
 {
-	struct timed_gpio_data *gpio_data = dev_get_drvdata(dev);
-	int remaining;
+	struct timed_gpio_data	*data =
+		container_of(dev, struct timed_gpio_data, dev);
 
-	if (hrtimer_active(&gpio_data->timer)) {
-		ktime_t r = hrtimer_get_remaining(&gpio_data->timer);
+	if (hrtimer_active(&data->timer)) {
+		ktime_t r = hrtimer_get_remaining(&data->timer);
 		struct timeval t = ktime_to_timeval(r);
-		remaining = t.tv_sec * 1000 + t.tv_usec / 1000;
+		return t.tv_sec * 1000 + t.tv_usec / 1000;
 	} else
-		remaining = 0;
-
-	return sprintf(buf, "%d\n", remaining);
+		return 0;
 }
 
-static ssize_t gpio_enable_store(
-		struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t size)
+static void gpio_enable(struct timed_output_dev *dev, int value)
 {
-	struct timed_gpio_data *gpio_data = dev_get_drvdata(dev);
-	int value;
+	struct timed_gpio_data	*data =
+		container_of(dev, struct timed_gpio_data, dev);
 	unsigned long	flags;
 
-	sscanf(buf, "%d", &value);
-
-	spin_lock_irqsave(&gpio_data->lock, flags);
+	spin_lock_irqsave(&data->lock, flags);
 
 	/* cancel previous timer and set GPIO according to value */
-	hrtimer_cancel(&gpio_data->timer);
-	gpio_direction_output(gpio_data->gpio, gpio_data->active_low ? !value : !!value);
+	hrtimer_cancel(&data->timer);
+	gpio_direction_output(data->gpio, data->active_low ? !value : !!value);
 
 	if (value > 0) {
-		if (value > gpio_data->max_timeout)
-			value = gpio_data->max_timeout;
+		if (value > data->max_timeout)
+			value = data->max_timeout;
 
-		hrtimer_start(&gpio_data->timer,
-						ktime_set(value / 1000, (value % 1000) * 1000000),
-						HRTIMER_MODE_REL);
+		hrtimer_start(&data->timer,
+			ktime_set(value / 1000, (value % 1000) * 1000000),
+			HRTIMER_MODE_REL);
 	}
 
-	spin_unlock_irqrestore(&gpio_data->lock, flags);
-
-	return size;
+	spin_unlock_irqrestore(&data->lock, flags);
 }
 
-static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, gpio_enable_show, gpio_enable_store);
-
 static int timed_gpio_probe(struct platform_device *pdev)
 {
 	struct timed_gpio_platform_data *pdata = pdev->dev.platform_data;
 	struct timed_gpio *cur_gpio;
 	struct timed_gpio_data *gpio_data, *gpio_dat;
-	int i, ret = 0;
+	int i, j, ret = 0;
 
 	if (!pdata)
 		return -EBUSY;
 
-	gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios, GFP_KERNEL);
+	gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios,
+			GFP_KERNEL);
 	if (!gpio_data)
 		return -ENOMEM;
 
@@ -107,23 +98,26 @@ static int timed_gpio_probe(struct platf
 		cur_gpio = &pdata->gpios[i];
 		gpio_dat = &gpio_data[i];
 
-		hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+		hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC,
+				HRTIMER_MODE_REL);
 		gpio_dat->timer.function = gpio_timer_func;
 		spin_lock_init(&gpio_dat->lock);
 
+		gpio_dat->dev.name = cur_gpio->name;
+		gpio_dat->dev.get_time = gpio_get_time;
+		gpio_dat->dev.enable = gpio_enable;
+		ret = timed_output_dev_register(&gpio_dat->dev);
+		if (ret < 0) {
+			for (j = 0; j < i; j++)
+				timed_output_dev_unregister(&gpio_data[i].dev);
+			kfree(gpio_data);
+			return ret;
+		}
+
 		gpio_dat->gpio = cur_gpio->gpio;
 		gpio_dat->max_timeout = cur_gpio->max_timeout;
 		gpio_dat->active_low = cur_gpio->active_low;
 		gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low);
-
-		gpio_dat->dev = device_create(timed_gpio_class, &pdev->dev, 0, "%s", cur_gpio->name);
-		if (unlikely(IS_ERR(gpio_dat->dev)))
-			return PTR_ERR(gpio_dat->dev);
-
-		dev_set_drvdata(gpio_dat->dev, gpio_dat);
-		ret = device_create_file(gpio_dat->dev, &dev_attr_enable);
-		if (ret)
-			return ret;
 	}
 
 	platform_set_drvdata(pdev, gpio_data);
@@ -137,10 +131,8 @@ static int timed_gpio_remove(struct plat
 	struct timed_gpio_data *gpio_data = platform_get_drvdata(pdev);
 	int i;
 
-	for (i = 0; i < pdata->num_gpios; i++) {
-		device_remove_file(gpio_data[i].dev, &dev_attr_enable);
-		device_unregister(gpio_data[i].dev);
-	}
+	for (i = 0; i < pdata->num_gpios; i++)
+		timed_output_dev_unregister(&gpio_data[i].dev);
 
 	kfree(gpio_data);
 
@@ -151,22 +143,18 @@ static struct platform_driver timed_gpio
 	.probe		= timed_gpio_probe,
 	.remove		= timed_gpio_remove,
 	.driver		= {
-		.name		= "timed-gpio",
+		.name		= TIMED_GPIO_NAME,
 		.owner		= THIS_MODULE,
 	},
 };
 
 static int __init timed_gpio_init(void)
 {
-	timed_gpio_class = class_create(THIS_MODULE, "timed_output");
-	if (IS_ERR(timed_gpio_class))
-		return PTR_ERR(timed_gpio_class);
 	return platform_driver_register(&timed_gpio_driver);
 }
 
 static void __exit timed_gpio_exit(void)
 {
-	class_destroy(timed_gpio_class);
 	platform_driver_unregister(&timed_gpio_driver);
 }
 
--- a/drivers/staging/android/timed_gpio.h
+++ b/drivers/staging/android/timed_gpio.h
@@ -16,10 +16,12 @@
 #ifndef _LINUX_TIMED_GPIO_H
 #define _LINUX_TIMED_GPIO_H
 
+#define TIMED_GPIO_NAME "timed-gpio"
+
 struct timed_gpio {
 	const char *name;
 	unsigned 	gpio;
-	int     max_timeout;
+	int		max_timeout;
 	u8 		active_low;
 };
 
--- /dev/null
+++ b/drivers/staging/android/timed_output.c
@@ -0,0 +1,121 @@
+/* drivers/misc/timed_output.c
+ *
+ * Copyright (C) 2009 Google, Inc.
+ * Author: Mike Lockwood <lockwood@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+
+#include "timed_output.h"
+
+static struct class *timed_output_class;
+static atomic_t device_count;
+
+static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct timed_output_dev *tdev = dev_get_drvdata(dev);
+	int remaining = tdev->get_time(tdev);
+
+	return sprintf(buf, "%d\n", remaining);
+}
+
+static ssize_t enable_store(
+		struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t size)
+{
+	struct timed_output_dev *tdev = dev_get_drvdata(dev);
+	int value;
+
+	sscanf(buf, "%d", &value);
+	tdev->enable(tdev, value);
+
+	return size;
+}
+
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
+
+static int create_timed_output_class(void)
+{
+	if (!timed_output_class) {
+		timed_output_class = class_create(THIS_MODULE, "timed_output");
+		if (IS_ERR(timed_output_class))
+			return PTR_ERR(timed_output_class);
+		atomic_set(&device_count, 0);
+	}
+
+	return 0;
+}
+
+int timed_output_dev_register(struct timed_output_dev *tdev)
+{
+	int ret;
+
+	if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time)
+		return -EINVAL;
+
+	ret = create_timed_output_class();
+	if (ret < 0)
+		return ret;
+
+	tdev->index = atomic_inc_return(&device_count);
+	tdev->dev = device_create(timed_output_class, NULL,
+		MKDEV(0, tdev->index), NULL, tdev->name);
+	if (IS_ERR(tdev->dev))
+		return PTR_ERR(tdev->dev);
+
+	ret = device_create_file(tdev->dev, &dev_attr_enable);
+	if (ret < 0)
+		goto err_create_file;
+
+	dev_set_drvdata(tdev->dev, tdev);
+	tdev->state = 0;
+	return 0;
+
+err_create_file:
+	device_destroy(timed_output_class, MKDEV(0, tdev->index));
+	printk(KERN_ERR "timed_output: Failed to register driver %s\n",
+			tdev->name);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(timed_output_dev_register);
+
+void timed_output_dev_unregister(struct timed_output_dev *tdev)
+{
+	device_remove_file(tdev->dev, &dev_attr_enable);
+	device_destroy(timed_output_class, MKDEV(0, tdev->index));
+	dev_set_drvdata(tdev->dev, NULL);
+}
+EXPORT_SYMBOL_GPL(timed_output_dev_unregister);
+
+static int __init timed_output_init(void)
+{
+	return create_timed_output_class();
+}
+
+static void __exit timed_output_exit(void)
+{
+	class_destroy(timed_output_class);
+}
+
+module_init(timed_output_init);
+module_exit(timed_output_exit);
+
+MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
+MODULE_DESCRIPTION("timed output class driver");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ b/drivers/staging/android/timed_output.h
@@ -0,0 +1,37 @@
+/* include/linux/timed_output.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+*/
+
+#ifndef _LINUX_TIMED_OUTPUT_H
+#define _LINUX_TIMED_OUTPUT_H
+
+struct timed_output_dev {
+	const char	*name;
+
+	/* enable the output and set the timer */
+	void	(*enable)(struct timed_output_dev *sdev, int timeout);
+
+	/* returns the current number of milliseconds remaining on the timer */
+	int		(*get_time)(struct timed_output_dev *sdev);
+
+	/* private data */
+	struct device	*dev;
+	int		index;
+	int		state;
+};
+
+extern int timed_output_dev_register(struct timed_output_dev *dev);
+extern void timed_output_dev_unregister(struct timed_output_dev *dev);
+
+#endif