mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge branch 'android-3.10' of https://android.googlesource.com/kernel/common
* android-3.10: (23 commits) proc: uid_cputime: create uids from kuids wakeup: Add last wake up source logging for suspend abort reason. selinux: add SOCK_DIAG_BY_FAMILY to the list of netlink message types selinux/nlmsg: add XFRM_MSG_MAPPING selinux/nlmsg: add XFRM_MSG_MIGRATE selinux/nlmsg: add XFRM_MSG_REPORT selinux/nlmsg: add XFRM_MSG_[NEW|GET]SADINFO selinux/nlmsg: add XFRM_MSG_GETSPDINFO selinux/nlmsg: add XFRM_MSG_NEWSPDINFO SELinux: per-command whitelisting of ioctls security: lsm_audit: add ioctl specific auditing Power: Report suspend times from last_suspend_time arm: crypto: Add optimized SHA-256/224 proc: uid: Adds accounting for the cputimes per uid. USB: gadget: android: Integrate f_midi USB MIDI gadget driver part deux android: base-cfg: disable ALARM_DEV staging: Remove logger and alarm-dev from android Makefile staging: Remove the Android alarm-dev driver staging: Remove the Android logger driver net: ping: fix constness inconsistency in ipv6_chk_addr ...
This commit is contained in:
16
Documentation/ABI/testing/sysfs-kernel-wakeup_reasons
Normal file
16
Documentation/ABI/testing/sysfs-kernel-wakeup_reasons
Normal file
@@ -0,0 +1,16 @@
|
||||
What: /sys/kernel/wakeup_reasons/last_resume_reason
|
||||
Date: February 2014
|
||||
Contact: Ruchi Kandoi <kandoiruchi@google.com>
|
||||
Description:
|
||||
The /sys/kernel/wakeup_reasons/last_resume_reason is
|
||||
used to report wakeup reasons after system exited suspend.
|
||||
|
||||
What: /sys/kernel/wakeup_reasons/last_suspend_time
|
||||
Date: March 2015
|
||||
Contact: jinqian <jinqian@google.com>
|
||||
Description:
|
||||
The /sys/kernel/wakeup_reasons/last_suspend_time is
|
||||
used to report time spent in last suspend cycle. It contains
|
||||
two numbers (in seconds) separated by space. First number is
|
||||
the time spent in suspend and resume processes. Second number
|
||||
is the time spent in sleep state.
|
||||
@@ -6,7 +6,6 @@
|
||||
# CONFIG_OABI_COMPAT is not set
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_ANDROID_INTF_ALARM_DEV=y
|
||||
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
|
||||
CONFIG_ARMV7_COMPAT=y
|
||||
CONFIG_ASHMEM=y
|
||||
|
||||
@@ -6,12 +6,15 @@ obj-$(CONFIG_CRYPTO_AES_ARM) += aes-arm.o
|
||||
obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o
|
||||
obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
|
||||
obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
|
||||
obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
|
||||
obj-$(CONFIG_CRYPTO_SHA512_ARM_NEON) += sha512-arm-neon.o
|
||||
|
||||
aes-arm-y := aes-armv4.o aes_glue.o
|
||||
aes-arm-bs-y := aesbs-core.o aesbs-glue.o
|
||||
sha1-arm-y := sha1-armv4-large.o sha1_glue.o
|
||||
sha1-arm-neon-y := sha1-armv7-neon.o sha1_neon_glue.o
|
||||
sha256-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha256_neon_glue.o
|
||||
sha256-arm-y := sha256-core.o sha256_glue.o $(sha256-arm-neon-y)
|
||||
sha512-arm-neon-y := sha512-armv7-neon.o sha512_neon_glue.o
|
||||
|
||||
quiet_cmd_perl = PERL $@
|
||||
@@ -20,4 +23,7 @@ quiet_cmd_perl = PERL $@
|
||||
$(src)/aesbs-core.S_shipped: $(src)/bsaes-armv7.pl
|
||||
$(call cmd,perl)
|
||||
|
||||
.PRECIOUS: $(obj)/aesbs-core.S
|
||||
$(src)/sha256-core.S_shipped: $(src)/sha256-armv4.pl
|
||||
$(call cmd,perl)
|
||||
|
||||
.PRECIOUS: $(obj)/aesbs-core.S $(obj)/sha256-core.S
|
||||
|
||||
716
arch/arm/crypto/sha256-armv4.pl
Normal file
716
arch/arm/crypto/sha256-armv4.pl
Normal file
File diff suppressed because it is too large
Load Diff
2808
arch/arm/crypto/sha256-core.S_shipped
Normal file
2808
arch/arm/crypto/sha256-core.S_shipped
Normal file
File diff suppressed because it is too large
Load Diff
246
arch/arm/crypto/sha256_glue.c
Normal file
246
arch/arm/crypto/sha256_glue.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Glue code for the SHA256 Secure Hash Algorithm assembly implementation
|
||||
* using optimized ARM assembler and NEON instructions.
|
||||
*
|
||||
* Copyright © 2015 Google Inc.
|
||||
*
|
||||
* This file is based on sha256_ssse3_glue.c:
|
||||
* Copyright (C) 2013 Intel Corporation
|
||||
* Author: Tim Chen <tim.c.chen@linux.intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/cryptohash.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/simd.h>
|
||||
#include <asm/neon.h>
|
||||
#include "sha256_glue.h"
|
||||
|
||||
asmlinkage void sha256_block_data_order(u32 *digest, const void *data,
|
||||
unsigned int num_blks);
|
||||
|
||||
|
||||
int sha256_init(struct shash_desc *desc)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
sctx->state[0] = SHA256_H0;
|
||||
sctx->state[1] = SHA256_H1;
|
||||
sctx->state[2] = SHA256_H2;
|
||||
sctx->state[3] = SHA256_H3;
|
||||
sctx->state[4] = SHA256_H4;
|
||||
sctx->state[5] = SHA256_H5;
|
||||
sctx->state[6] = SHA256_H6;
|
||||
sctx->state[7] = SHA256_H7;
|
||||
sctx->count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sha224_init(struct shash_desc *desc)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
sctx->state[0] = SHA224_H0;
|
||||
sctx->state[1] = SHA224_H1;
|
||||
sctx->state[2] = SHA224_H2;
|
||||
sctx->state[3] = SHA224_H3;
|
||||
sctx->state[4] = SHA224_H4;
|
||||
sctx->state[5] = SHA224_H5;
|
||||
sctx->state[6] = SHA224_H6;
|
||||
sctx->state[7] = SHA224_H7;
|
||||
sctx->count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __sha256_update(struct shash_desc *desc, const u8 *data, unsigned int len,
|
||||
unsigned int partial)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int done = 0;
|
||||
|
||||
sctx->count += len;
|
||||
|
||||
if (partial) {
|
||||
done = SHA256_BLOCK_SIZE - partial;
|
||||
memcpy(sctx->buf + partial, data, done);
|
||||
sha256_block_data_order(sctx->state, sctx->buf, 1);
|
||||
}
|
||||
|
||||
if (len - done >= SHA256_BLOCK_SIZE) {
|
||||
const unsigned int rounds = (len - done) / SHA256_BLOCK_SIZE;
|
||||
|
||||
sha256_block_data_order(sctx->state, data + done, rounds);
|
||||
done += rounds * SHA256_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
memcpy(sctx->buf, data + done, len - done);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sha256_update(struct shash_desc *desc, const u8 *data, unsigned int len)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
|
||||
|
||||
/* Handle the fast case right here */
|
||||
if (partial + len < SHA256_BLOCK_SIZE) {
|
||||
sctx->count += len;
|
||||
memcpy(sctx->buf + partial, data, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return __sha256_update(desc, data, len, partial);
|
||||
}
|
||||
|
||||
/* Add padding and return the message digest. */
|
||||
static int sha256_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int i, index, padlen;
|
||||
__be32 *dst = (__be32 *)out;
|
||||
__be64 bits;
|
||||
static const u8 padding[SHA256_BLOCK_SIZE] = { 0x80, };
|
||||
|
||||
/* save number of bits */
|
||||
bits = cpu_to_be64(sctx->count << 3);
|
||||
|
||||
/* Pad out to 56 mod 64 and append length */
|
||||
index = sctx->count % SHA256_BLOCK_SIZE;
|
||||
padlen = (index < 56) ? (56 - index) : ((SHA256_BLOCK_SIZE+56)-index);
|
||||
|
||||
/* We need to fill a whole block for __sha256_update */
|
||||
if (padlen <= 56) {
|
||||
sctx->count += padlen;
|
||||
memcpy(sctx->buf + index, padding, padlen);
|
||||
} else {
|
||||
__sha256_update(desc, padding, padlen, index);
|
||||
}
|
||||
__sha256_update(desc, (const u8 *)&bits, sizeof(bits), 56);
|
||||
|
||||
/* Store state in digest */
|
||||
for (i = 0; i < 8; i++)
|
||||
dst[i] = cpu_to_be32(sctx->state[i]);
|
||||
|
||||
/* Wipe context */
|
||||
memset(sctx, 0, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha224_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
u8 D[SHA256_DIGEST_SIZE];
|
||||
|
||||
sha256_final(desc, D);
|
||||
|
||||
memcpy(out, D, SHA224_DIGEST_SIZE);
|
||||
memset(D, 0, SHA256_DIGEST_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sha256_export(struct shash_desc *desc, void *out)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
memcpy(out, sctx, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sha256_import(struct shash_desc *desc, const void *in)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
memcpy(sctx, in, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg algs[] = { {
|
||||
.digestsize = SHA256_DIGEST_SIZE,
|
||||
.init = sha256_init,
|
||||
.update = sha256_update,
|
||||
.final = sha256_final,
|
||||
.export = sha256_export,
|
||||
.import = sha256_import,
|
||||
.descsize = sizeof(struct sha256_state),
|
||||
.statesize = sizeof(struct sha256_state),
|
||||
.base = {
|
||||
.cra_name = "sha256",
|
||||
.cra_driver_name = "sha256-asm",
|
||||
.cra_priority = 150,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA256_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
}, {
|
||||
.digestsize = SHA224_DIGEST_SIZE,
|
||||
.init = sha224_init,
|
||||
.update = sha256_update,
|
||||
.final = sha224_final,
|
||||
.export = sha256_export,
|
||||
.import = sha256_import,
|
||||
.descsize = sizeof(struct sha256_state),
|
||||
.statesize = sizeof(struct sha256_state),
|
||||
.base = {
|
||||
.cra_name = "sha224",
|
||||
.cra_driver_name = "sha224-asm",
|
||||
.cra_priority = 150,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA224_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
} };
|
||||
|
||||
static int __init sha256_mod_init(void)
|
||||
{
|
||||
int res = crypto_register_shashes(algs, ARRAY_SIZE(algs));
|
||||
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon()) {
|
||||
res = crypto_register_shashes(sha256_neon_algs,
|
||||
ARRAY_SIZE(sha256_neon_algs));
|
||||
|
||||
if (res < 0)
|
||||
crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void __exit sha256_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
|
||||
|
||||
if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon())
|
||||
crypto_unregister_shashes(sha256_neon_algs,
|
||||
ARRAY_SIZE(sha256_neon_algs));
|
||||
}
|
||||
|
||||
module_init(sha256_mod_init);
|
||||
module_exit(sha256_mod_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm (ARM), including NEON");
|
||||
|
||||
MODULE_ALIAS_CRYPTO("sha256");
|
||||
23
arch/arm/crypto/sha256_glue.h
Normal file
23
arch/arm/crypto/sha256_glue.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef _CRYPTO_SHA256_GLUE_H
|
||||
#define _CRYPTO_SHA256_GLUE_H
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <crypto/sha.h>
|
||||
|
||||
extern struct shash_alg sha256_neon_algs[2];
|
||||
|
||||
extern int sha256_init(struct shash_desc *desc);
|
||||
|
||||
extern int sha224_init(struct shash_desc *desc);
|
||||
|
||||
extern int __sha256_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len, unsigned int partial);
|
||||
|
||||
extern int sha256_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len);
|
||||
|
||||
extern int sha256_export(struct shash_desc *desc, void *out);
|
||||
|
||||
extern int sha256_import(struct shash_desc *desc, const void *in);
|
||||
|
||||
#endif /* _CRYPTO_SHA256_GLUE_H */
|
||||
172
arch/arm/crypto/sha256_neon_glue.c
Normal file
172
arch/arm/crypto/sha256_neon_glue.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Glue code for the SHA256 Secure Hash Algorithm assembly implementation
|
||||
* using NEON instructions.
|
||||
*
|
||||
* Copyright © 2015 Google Inc.
|
||||
*
|
||||
* This file is based on sha512_neon_glue.c:
|
||||
* Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/cryptohash.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/simd.h>
|
||||
#include <asm/neon.h>
|
||||
#include "sha256_glue.h"
|
||||
|
||||
asmlinkage void sha256_block_data_order_neon(u32 *digest, const void *data,
|
||||
unsigned int num_blks);
|
||||
|
||||
|
||||
static int __sha256_neon_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len, unsigned int partial)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int done = 0;
|
||||
|
||||
sctx->count += len;
|
||||
|
||||
if (partial) {
|
||||
done = SHA256_BLOCK_SIZE - partial;
|
||||
memcpy(sctx->buf + partial, data, done);
|
||||
sha256_block_data_order_neon(sctx->state, sctx->buf, 1);
|
||||
}
|
||||
|
||||
if (len - done >= SHA256_BLOCK_SIZE) {
|
||||
const unsigned int rounds = (len - done) / SHA256_BLOCK_SIZE;
|
||||
|
||||
sha256_block_data_order_neon(sctx->state, data + done, rounds);
|
||||
done += rounds * SHA256_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
memcpy(sctx->buf, data + done, len - done);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha256_neon_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
|
||||
int res;
|
||||
|
||||
/* Handle the fast case right here */
|
||||
if (partial + len < SHA256_BLOCK_SIZE) {
|
||||
sctx->count += len;
|
||||
memcpy(sctx->buf + partial, data, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!may_use_simd()) {
|
||||
res = __sha256_update(desc, data, len, partial);
|
||||
} else {
|
||||
kernel_neon_begin();
|
||||
res = __sha256_neon_update(desc, data, len, partial);
|
||||
kernel_neon_end();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Add padding and return the message digest. */
|
||||
static int sha256_neon_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int i, index, padlen;
|
||||
__be32 *dst = (__be32 *)out;
|
||||
__be64 bits;
|
||||
static const u8 padding[SHA256_BLOCK_SIZE] = { 0x80, };
|
||||
|
||||
/* save number of bits */
|
||||
bits = cpu_to_be64(sctx->count << 3);
|
||||
|
||||
/* Pad out to 56 mod 64 and append length */
|
||||
index = sctx->count % SHA256_BLOCK_SIZE;
|
||||
padlen = (index < 56) ? (56 - index) : ((SHA256_BLOCK_SIZE+56)-index);
|
||||
|
||||
if (!may_use_simd()) {
|
||||
sha256_update(desc, padding, padlen);
|
||||
sha256_update(desc, (const u8 *)&bits, sizeof(bits));
|
||||
} else {
|
||||
kernel_neon_begin();
|
||||
/* We need to fill a whole block for __sha256_neon_update() */
|
||||
if (padlen <= 56) {
|
||||
sctx->count += padlen;
|
||||
memcpy(sctx->buf + index, padding, padlen);
|
||||
} else {
|
||||
__sha256_neon_update(desc, padding, padlen, index);
|
||||
}
|
||||
__sha256_neon_update(desc, (const u8 *)&bits,
|
||||
sizeof(bits), 56);
|
||||
kernel_neon_end();
|
||||
}
|
||||
|
||||
/* Store state in digest */
|
||||
for (i = 0; i < 8; i++)
|
||||
dst[i] = cpu_to_be32(sctx->state[i]);
|
||||
|
||||
/* Wipe context */
|
||||
memset(sctx, 0, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha224_neon_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
u8 D[SHA256_DIGEST_SIZE];
|
||||
|
||||
sha256_neon_final(desc, D);
|
||||
|
||||
memcpy(out, D, SHA224_DIGEST_SIZE);
|
||||
memset(D, 0, SHA256_DIGEST_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct shash_alg sha256_neon_algs[] = { {
|
||||
.digestsize = SHA256_DIGEST_SIZE,
|
||||
.init = sha256_init,
|
||||
.update = sha256_neon_update,
|
||||
.final = sha256_neon_final,
|
||||
.export = sha256_export,
|
||||
.import = sha256_import,
|
||||
.descsize = sizeof(struct sha256_state),
|
||||
.statesize = sizeof(struct sha256_state),
|
||||
.base = {
|
||||
.cra_name = "sha256",
|
||||
.cra_driver_name = "sha256-neon",
|
||||
.cra_priority = 250,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA256_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
}, {
|
||||
.digestsize = SHA224_DIGEST_SIZE,
|
||||
.init = sha224_init,
|
||||
.update = sha256_neon_update,
|
||||
.final = sha224_neon_final,
|
||||
.export = sha256_export,
|
||||
.import = sha256_import,
|
||||
.descsize = sizeof(struct sha256_state),
|
||||
.statesize = sizeof(struct sha256_state),
|
||||
.base = {
|
||||
.cra_name = "sha224",
|
||||
.cra_driver_name = "sha224-neon",
|
||||
.cra_priority = 250,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA224_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
} };
|
||||
@@ -556,6 +556,13 @@ config CRYPTO_SHA256
|
||||
This code also includes SHA-224, a 224 bit hash with 112 bits
|
||||
of security against collision attacks.
|
||||
|
||||
config CRYPTO_SHA256_ARM
|
||||
tristate "SHA-224/256 digest algorithm (ARM-asm and NEON)"
|
||||
select CRYPTO_HASH
|
||||
help
|
||||
SHA-256 secure hash standard (DFIPS 180-2) implemented
|
||||
using optimized ARM assembler and NEON, when available.
|
||||
|
||||
config CRYPTO_SHA256_SPARC64
|
||||
tristate "SHA224 and SHA256 digest algorithm (SPARC64)"
|
||||
depends on SPARC64
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/types.h>
|
||||
#include <trace/events/power.h>
|
||||
|
||||
#include "power.h"
|
||||
@@ -661,16 +662,31 @@ EXPORT_SYMBOL_GPL(pm_wakeup_event);
|
||||
|
||||
void pm_get_active_wakeup_sources(char *pending_wakeup_source, size_t max)
|
||||
{
|
||||
struct wakeup_source *ws;
|
||||
struct wakeup_source *ws, *last_active_ws = NULL;
|
||||
int len = 0;
|
||||
bool active = false;
|
||||
|
||||
rcu_read_lock();
|
||||
len += snprintf(pending_wakeup_source, max, "Pending Wakeup Sources: ");
|
||||
list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
|
||||
if (ws->active) {
|
||||
len += snprintf(pending_wakeup_source + len, max,
|
||||
if (!active)
|
||||
len += scnprintf(pending_wakeup_source, max,
|
||||
"Pending Wakeup Sources: ");
|
||||
len += scnprintf(pending_wakeup_source + len, max - len,
|
||||
"%s ", ws->name);
|
||||
active = true;
|
||||
} else if (!active &&
|
||||
(!last_active_ws ||
|
||||
ktime_to_ns(ws->last_time) >
|
||||
ktime_to_ns(last_active_ws->last_time))) {
|
||||
last_active_ws = ws;
|
||||
}
|
||||
}
|
||||
if (!active && last_active_ws) {
|
||||
scnprintf(pending_wakeup_source, max,
|
||||
"Last active Wakeup Source: %s",
|
||||
last_active_ws->name);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm_get_active_wakeup_sources);
|
||||
|
||||
@@ -531,6 +531,12 @@ config SRAM
|
||||
the genalloc API. It is supposed to be used for small on-chip SRAM
|
||||
areas found on many SoCs.
|
||||
|
||||
config UID_CPUTIME
|
||||
tristate "Per-UID cpu time statistics"
|
||||
depends on PROFILING
|
||||
help
|
||||
Per UID based cpu time statistics exported to /proc/uid_cputime
|
||||
|
||||
source "drivers/misc/c2port/Kconfig"
|
||||
source "drivers/misc/eeprom/Kconfig"
|
||||
source "drivers/misc/cb710/Kconfig"
|
||||
|
||||
@@ -54,3 +54,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/
|
||||
obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
|
||||
obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
|
||||
obj-$(CONFIG_SRAM) += sram.o
|
||||
obj-$(CONFIG_UID_CPUTIME) += uid_cputime.o
|
||||
|
||||
237
drivers/misc/uid_cputime.c
Normal file
237
drivers/misc/uid_cputime.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/* drivers/misc/uid_cputime.c
|
||||
*
|
||||
* Copyright (C) 2014 - 2015 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/hashtable.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define UID_HASH_BITS 10
|
||||
DECLARE_HASHTABLE(hash_table, UID_HASH_BITS);
|
||||
|
||||
static DEFINE_MUTEX(uid_lock);
|
||||
static struct proc_dir_entry *parent;
|
||||
|
||||
struct uid_entry {
|
||||
uid_t uid;
|
||||
cputime_t utime;
|
||||
cputime_t stime;
|
||||
cputime_t active_utime;
|
||||
cputime_t active_stime;
|
||||
struct hlist_node hash;
|
||||
};
|
||||
|
||||
static struct uid_entry *find_uid_entry(uid_t uid)
|
||||
{
|
||||
struct uid_entry *uid_entry;
|
||||
hash_for_each_possible(hash_table, uid_entry, hash, uid) {
|
||||
if (uid_entry->uid == uid)
|
||||
return uid_entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct uid_entry *find_or_register_uid(uid_t uid)
|
||||
{
|
||||
struct uid_entry *uid_entry;
|
||||
|
||||
uid_entry = find_uid_entry(uid);
|
||||
if (uid_entry)
|
||||
return uid_entry;
|
||||
|
||||
uid_entry = kzalloc(sizeof(struct uid_entry), GFP_ATOMIC);
|
||||
if (!uid_entry)
|
||||
return NULL;
|
||||
|
||||
uid_entry->uid = uid;
|
||||
|
||||
hash_add(hash_table, &uid_entry->hash, uid);
|
||||
|
||||
return uid_entry;
|
||||
}
|
||||
|
||||
static int uid_stat_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct uid_entry *uid_entry;
|
||||
struct task_struct *task;
|
||||
cputime_t utime;
|
||||
cputime_t stime;
|
||||
unsigned long bkt;
|
||||
|
||||
mutex_lock(&uid_lock);
|
||||
|
||||
hash_for_each(hash_table, bkt, uid_entry, hash) {
|
||||
uid_entry->active_stime = 0;
|
||||
uid_entry->active_utime = 0;
|
||||
}
|
||||
|
||||
read_lock(&tasklist_lock);
|
||||
for_each_process(task) {
|
||||
uid_entry = find_or_register_uid(from_kuid_munged(
|
||||
current_user_ns(), task_uid(task)));
|
||||
if (!uid_entry) {
|
||||
read_unlock(&tasklist_lock);
|
||||
mutex_unlock(&uid_lock);
|
||||
pr_err("%s: failed to find the uid_entry for uid %d\n",
|
||||
__func__, from_kuid_munged(current_user_ns(),
|
||||
task_uid(task)));
|
||||
return -ENOMEM;
|
||||
}
|
||||
task_cputime_adjusted(task, &utime, &stime);
|
||||
uid_entry->active_utime += utime;
|
||||
uid_entry->active_stime += stime;
|
||||
}
|
||||
read_unlock(&tasklist_lock);
|
||||
|
||||
hash_for_each(hash_table, bkt, uid_entry, hash) {
|
||||
cputime_t total_utime = uid_entry->utime +
|
||||
uid_entry->active_utime;
|
||||
cputime_t total_stime = uid_entry->stime +
|
||||
uid_entry->active_stime;
|
||||
seq_printf(m, "%d: %u %u\n", uid_entry->uid,
|
||||
cputime_to_usecs(total_utime),
|
||||
cputime_to_usecs(total_stime));
|
||||
}
|
||||
|
||||
mutex_unlock(&uid_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uid_stat_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, uid_stat_show, PDE_DATA(inode));
|
||||
}
|
||||
|
||||
static const struct file_operations uid_stat_fops = {
|
||||
.open = uid_stat_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int uid_remove_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, NULL, NULL);
|
||||
}
|
||||
|
||||
static ssize_t uid_remove_write(struct file *file,
|
||||
const char __user *buffer, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct uid_entry *uid_entry;
|
||||
struct hlist_node *tmp;
|
||||
char uids[128];
|
||||
char *start_uid, *end_uid = NULL;
|
||||
long int uid_start = 0, uid_end = 0;
|
||||
|
||||
if (count >= sizeof(uids))
|
||||
count = sizeof(uids) - 1;
|
||||
|
||||
if (copy_from_user(uids, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
uids[count] = '\0';
|
||||
end_uid = uids;
|
||||
start_uid = strsep(&end_uid, "-");
|
||||
|
||||
if (!start_uid || !end_uid)
|
||||
return -EINVAL;
|
||||
|
||||
if (kstrtol(start_uid, 10, &uid_start) != 0 ||
|
||||
kstrtol(end_uid, 10, &uid_end) != 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&uid_lock);
|
||||
|
||||
for (; uid_start <= uid_end; uid_start++) {
|
||||
hash_for_each_possible_safe(hash_table, uid_entry, tmp,
|
||||
hash, uid_start) {
|
||||
hash_del(&uid_entry->hash);
|
||||
kfree(uid_entry);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&uid_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations uid_remove_fops = {
|
||||
.open = uid_remove_open,
|
||||
.release = single_release,
|
||||
.write = uid_remove_write,
|
||||
};
|
||||
|
||||
static int process_notifier(struct notifier_block *self,
|
||||
unsigned long cmd, void *v)
|
||||
{
|
||||
struct task_struct *task = v;
|
||||
struct uid_entry *uid_entry;
|
||||
cputime_t utime, stime;
|
||||
uid_t uid;
|
||||
|
||||
if (!task)
|
||||
return NOTIFY_OK;
|
||||
|
||||
mutex_lock(&uid_lock);
|
||||
uid = from_kuid_munged(current_user_ns(), task_uid(task));
|
||||
uid_entry = find_or_register_uid(uid);
|
||||
if (!uid_entry) {
|
||||
pr_err("%s: failed to find uid %d\n", __func__, uid);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
task_cputime_adjusted(task, &utime, &stime);
|
||||
uid_entry->utime += utime;
|
||||
uid_entry->stime += stime;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&uid_lock);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block process_notifier_block = {
|
||||
.notifier_call = process_notifier,
|
||||
};
|
||||
|
||||
static int __init proc_uid_cputime_init(void)
|
||||
{
|
||||
hash_init(hash_table);
|
||||
|
||||
parent = proc_mkdir("uid_cputime", NULL);
|
||||
if (!parent) {
|
||||
pr_err("%s: failed to create proc entry\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
proc_create_data("remove_uid_range", S_IWUGO, parent, &uid_remove_fops,
|
||||
NULL);
|
||||
|
||||
proc_create_data("show_uid_stat", S_IWUGO, parent, &uid_stat_fops,
|
||||
NULL);
|
||||
|
||||
profile_event_register(PROFILE_TASK_EXIT, &process_notifier_block);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
early_initcall(proc_uid_cputime_init);
|
||||
@@ -20,23 +20,6 @@ config ASHMEM
|
||||
It is, in theory, a good memory allocator for low-memory devices,
|
||||
because it can discard shared memory units when under memory pressure.
|
||||
|
||||
config ANDROID_LOGGER
|
||||
tristate "Android log driver"
|
||||
default n
|
||||
---help---
|
||||
This adds support for system-wide logging using four log buffers.
|
||||
|
||||
These are:
|
||||
|
||||
1: main
|
||||
2: events
|
||||
3: radio
|
||||
4: system
|
||||
|
||||
Log reading and writing is performed via normal Linux reads and
|
||||
optimized writes. This optimization avoids logging having too
|
||||
much overhead in the system.
|
||||
|
||||
config ANDROID_TIMED_OUTPUT
|
||||
bool "Timed output class driver"
|
||||
default y
|
||||
@@ -61,15 +44,6 @@ config ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES
|
||||
/sys/module/lowmemorykiller/parameters/adj and convert them
|
||||
to oom_score_adj values.
|
||||
|
||||
config ANDROID_INTF_ALARM_DEV
|
||||
bool "Android alarm driver"
|
||||
depends on RTC_CLASS
|
||||
default n
|
||||
---help---
|
||||
Provides non-wakeup and rtc backed wakeup alarms based on rtc or
|
||||
elapsed realtime, and a non-wakeup alarm on the monotonic clock.
|
||||
Also exports the alarm interface to user-space.
|
||||
|
||||
config SYNC
|
||||
bool "Synchronization framework"
|
||||
default n
|
||||
|
||||
@@ -4,10 +4,8 @@ obj-y += ion/
|
||||
obj-$(CONFIG_FIQ_DEBUGGER) += fiq_debugger/
|
||||
|
||||
obj-$(CONFIG_ASHMEM) += ashmem.o
|
||||
obj-$(CONFIG_ANDROID_LOGGER) += logger.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
|
||||
obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o
|
||||
obj-$(CONFIG_SYNC) += sync.o
|
||||
obj-$(CONFIG_SW_SYNC) += sw_sync.o
|
||||
|
||||
@@ -1,444 +0,0 @@
|
||||
/* drivers/rtc/alarm-dev.c
|
||||
*
|
||||
* Copyright (C) 2007-2009 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/time.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/alarmtimer.h>
|
||||
#include "android_alarm.h"
|
||||
|
||||
#define ANDROID_ALARM_PRINT_INFO (1U << 0)
|
||||
#define ANDROID_ALARM_PRINT_IO (1U << 1)
|
||||
#define ANDROID_ALARM_PRINT_INT (1U << 2)
|
||||
|
||||
static int debug_mask = ANDROID_ALARM_PRINT_INFO;
|
||||
module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
|
||||
|
||||
#define alarm_dbg(debug_level_mask, fmt, ...) \
|
||||
do { \
|
||||
if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) \
|
||||
pr_info(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define ANDROID_ALARM_WAKEUP_MASK ( \
|
||||
ANDROID_ALARM_RTC_WAKEUP_MASK | \
|
||||
ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
|
||||
|
||||
static int alarm_opened;
|
||||
static DEFINE_SPINLOCK(alarm_slock);
|
||||
static struct wakeup_source alarm_wake_lock;
|
||||
static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue);
|
||||
static uint32_t alarm_pending;
|
||||
static uint32_t alarm_enabled;
|
||||
static uint32_t wait_pending;
|
||||
|
||||
struct devalarm {
|
||||
union {
|
||||
struct hrtimer hrt;
|
||||
struct alarm alrm;
|
||||
} u;
|
||||
enum android_alarm_type type;
|
||||
};
|
||||
|
||||
static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT];
|
||||
|
||||
|
||||
static int is_wakeup(enum android_alarm_type type)
|
||||
{
|
||||
return (type == ANDROID_ALARM_RTC_WAKEUP ||
|
||||
type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP);
|
||||
}
|
||||
|
||||
|
||||
static void devalarm_start(struct devalarm *alrm, ktime_t exp)
|
||||
{
|
||||
if (is_wakeup(alrm->type))
|
||||
alarm_start(&alrm->u.alrm, exp);
|
||||
else
|
||||
hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS);
|
||||
}
|
||||
|
||||
|
||||
static int devalarm_try_to_cancel(struct devalarm *alrm)
|
||||
{
|
||||
if (is_wakeup(alrm->type))
|
||||
return alarm_try_to_cancel(&alrm->u.alrm);
|
||||
return hrtimer_try_to_cancel(&alrm->u.hrt);
|
||||
}
|
||||
|
||||
static void devalarm_cancel(struct devalarm *alrm)
|
||||
{
|
||||
if (is_wakeup(alrm->type))
|
||||
alarm_cancel(&alrm->u.alrm);
|
||||
else
|
||||
hrtimer_cancel(&alrm->u.hrt);
|
||||
}
|
||||
|
||||
static void alarm_clear(enum android_alarm_type alarm_type)
|
||||
{
|
||||
uint32_t alarm_type_mask = 1U << alarm_type;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&alarm_slock, flags);
|
||||
alarm_dbg(IO, "alarm %d clear\n", alarm_type);
|
||||
devalarm_try_to_cancel(&alarms[alarm_type]);
|
||||
if (alarm_pending) {
|
||||
alarm_pending &= ~alarm_type_mask;
|
||||
if (!alarm_pending && !wait_pending)
|
||||
__pm_relax(&alarm_wake_lock);
|
||||
}
|
||||
alarm_enabled &= ~alarm_type_mask;
|
||||
spin_unlock_irqrestore(&alarm_slock, flags);
|
||||
|
||||
}
|
||||
|
||||
static void alarm_set(enum android_alarm_type alarm_type,
|
||||
struct timespec *ts)
|
||||
{
|
||||
uint32_t alarm_type_mask = 1U << alarm_type;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&alarm_slock, flags);
|
||||
alarm_dbg(IO, "alarm %d set %ld.%09ld\n",
|
||||
alarm_type, ts->tv_sec, ts->tv_nsec);
|
||||
alarm_enabled |= alarm_type_mask;
|
||||
devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts));
|
||||
spin_unlock_irqrestore(&alarm_slock, flags);
|
||||
}
|
||||
|
||||
static int alarm_wait(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
int rv = 0;
|
||||
|
||||
spin_lock_irqsave(&alarm_slock, flags);
|
||||
alarm_dbg(IO, "alarm wait\n");
|
||||
if (!alarm_pending && wait_pending) {
|
||||
__pm_relax(&alarm_wake_lock);
|
||||
wait_pending = 0;
|
||||
}
|
||||
spin_unlock_irqrestore(&alarm_slock, flags);
|
||||
|
||||
rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
spin_lock_irqsave(&alarm_slock, flags);
|
||||
rv = alarm_pending;
|
||||
wait_pending = 1;
|
||||
alarm_pending = 0;
|
||||
spin_unlock_irqrestore(&alarm_slock, flags);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int alarm_set_rtc(struct timespec *ts)
|
||||
{
|
||||
struct rtc_time new_rtc_tm;
|
||||
struct rtc_device *rtc_dev;
|
||||
unsigned long flags;
|
||||
int rv = 0;
|
||||
|
||||
rtc_time_to_tm(ts->tv_sec, &new_rtc_tm);
|
||||
rtc_dev = alarmtimer_get_rtcdev();
|
||||
rv = do_settimeofday(ts);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
if (rtc_dev)
|
||||
rv = rtc_set_time(rtc_dev, &new_rtc_tm);
|
||||
|
||||
spin_lock_irqsave(&alarm_slock, flags);
|
||||
alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
|
||||
wake_up(&alarm_wait_queue);
|
||||
spin_unlock_irqrestore(&alarm_slock, flags);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int alarm_get_time(enum android_alarm_type alarm_type,
|
||||
struct timespec *ts)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
switch (alarm_type) {
|
||||
case ANDROID_ALARM_RTC_WAKEUP:
|
||||
case ANDROID_ALARM_RTC:
|
||||
getnstimeofday(ts);
|
||||
break;
|
||||
case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
|
||||
case ANDROID_ALARM_ELAPSED_REALTIME:
|
||||
get_monotonic_boottime(ts);
|
||||
break;
|
||||
case ANDROID_ALARM_SYSTEMTIME:
|
||||
ktime_get_ts(ts);
|
||||
break;
|
||||
default:
|
||||
rv = -EINVAL;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static long alarm_do_ioctl(struct file *file, unsigned int cmd,
|
||||
struct timespec *ts)
|
||||
{
|
||||
int rv = 0;
|
||||
unsigned long flags;
|
||||
enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);
|
||||
|
||||
if (alarm_type >= ANDROID_ALARM_TYPE_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) {
|
||||
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
|
||||
return -EPERM;
|
||||
if (file->private_data == NULL &&
|
||||
cmd != ANDROID_ALARM_SET_RTC) {
|
||||
spin_lock_irqsave(&alarm_slock, flags);
|
||||
if (alarm_opened) {
|
||||
spin_unlock_irqrestore(&alarm_slock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
alarm_opened = 1;
|
||||
file->private_data = (void *)1;
|
||||
spin_unlock_irqrestore(&alarm_slock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
switch (ANDROID_ALARM_BASE_CMD(cmd)) {
|
||||
case ANDROID_ALARM_CLEAR(0):
|
||||
alarm_clear(alarm_type);
|
||||
break;
|
||||
case ANDROID_ALARM_SET(0):
|
||||
alarm_set(alarm_type, ts);
|
||||
break;
|
||||
case ANDROID_ALARM_SET_AND_WAIT(0):
|
||||
alarm_set(alarm_type, ts);
|
||||
/* fall though */
|
||||
case ANDROID_ALARM_WAIT:
|
||||
rv = alarm_wait();
|
||||
break;
|
||||
case ANDROID_ALARM_SET_RTC:
|
||||
rv = alarm_set_rtc(ts);
|
||||
break;
|
||||
case ANDROID_ALARM_GET_TIME(0):
|
||||
rv = alarm_get_time(alarm_type, ts);
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = -EINVAL;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
|
||||
struct timespec ts;
|
||||
int rv;
|
||||
|
||||
switch (ANDROID_ALARM_BASE_CMD(cmd)) {
|
||||
case ANDROID_ALARM_SET_AND_WAIT(0):
|
||||
case ANDROID_ALARM_SET(0):
|
||||
case ANDROID_ALARM_SET_RTC:
|
||||
if (copy_from_user(&ts, (void __user *)arg, sizeof(ts)))
|
||||
return -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = alarm_do_ioctl(file, cmd, &ts);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
switch (ANDROID_ALARM_BASE_CMD(cmd)) {
|
||||
case ANDROID_ALARM_GET_TIME(0):
|
||||
if (copy_to_user((void __user *)arg, &ts, sizeof(ts)))
|
||||
return -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
|
||||
struct timespec ts;
|
||||
int rv;
|
||||
|
||||
switch (ANDROID_ALARM_BASE_CMD(cmd)) {
|
||||
case ANDROID_ALARM_SET_AND_WAIT_COMPAT(0):
|
||||
case ANDROID_ALARM_SET_COMPAT(0):
|
||||
case ANDROID_ALARM_SET_RTC_COMPAT:
|
||||
if (compat_get_timespec(&ts, (void __user *)arg))
|
||||
return -EFAULT;
|
||||
/* fall through */
|
||||
case ANDROID_ALARM_GET_TIME_COMPAT(0):
|
||||
cmd = ANDROID_ALARM_COMPAT_TO_NORM(cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
rv = alarm_do_ioctl(file, cmd, &ts);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
switch (ANDROID_ALARM_BASE_CMD(cmd)) {
|
||||
case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */
|
||||
if (compat_put_timespec(&ts, (void __user *)arg))
|
||||
return -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int alarm_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alarm_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&alarm_slock, flags);
|
||||
if (file->private_data) {
|
||||
for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
|
||||
uint32_t alarm_type_mask = 1U << i;
|
||||
|
||||
if (alarm_enabled & alarm_type_mask) {
|
||||
alarm_dbg(INFO,
|
||||
"%s: clear alarm, pending %d\n",
|
||||
__func__,
|
||||
!!(alarm_pending & alarm_type_mask));
|
||||
alarm_enabled &= ~alarm_type_mask;
|
||||
}
|
||||
spin_unlock_irqrestore(&alarm_slock, flags);
|
||||
devalarm_cancel(&alarms[i]);
|
||||
spin_lock_irqsave(&alarm_slock, flags);
|
||||
}
|
||||
if (alarm_pending | wait_pending) {
|
||||
if (alarm_pending)
|
||||
alarm_dbg(INFO, "%s: clear pending alarms %x\n",
|
||||
__func__, alarm_pending);
|
||||
__pm_relax(&alarm_wake_lock);
|
||||
wait_pending = 0;
|
||||
alarm_pending = 0;
|
||||
}
|
||||
alarm_opened = 0;
|
||||
}
|
||||
spin_unlock_irqrestore(&alarm_slock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void devalarm_triggered(struct devalarm *alarm)
|
||||
{
|
||||
unsigned long flags;
|
||||
uint32_t alarm_type_mask = 1U << alarm->type;
|
||||
|
||||
alarm_dbg(INT, "%s: type %d\n", __func__, alarm->type);
|
||||
spin_lock_irqsave(&alarm_slock, flags);
|
||||
if (alarm_enabled & alarm_type_mask) {
|
||||
__pm_wakeup_event(&alarm_wake_lock, 5000); /* 5secs */
|
||||
alarm_enabled &= ~alarm_type_mask;
|
||||
alarm_pending |= alarm_type_mask;
|
||||
wake_up(&alarm_wait_queue);
|
||||
}
|
||||
spin_unlock_irqrestore(&alarm_slock, flags);
|
||||
}
|
||||
|
||||
|
||||
static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt)
|
||||
{
|
||||
struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt);
|
||||
|
||||
devalarm_triggered(devalrm);
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
static enum alarmtimer_restart devalarm_alarmhandler(struct alarm *alrm,
|
||||
ktime_t now)
|
||||
{
|
||||
struct devalarm *devalrm = container_of(alrm, struct devalarm, u.alrm);
|
||||
|
||||
devalarm_triggered(devalrm);
|
||||
return ALARMTIMER_NORESTART;
|
||||
}
|
||||
|
||||
|
||||
static const struct file_operations alarm_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.unlocked_ioctl = alarm_ioctl,
|
||||
.open = alarm_open,
|
||||
.release = alarm_release,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = alarm_compat_ioctl,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct miscdevice alarm_device = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "alarm",
|
||||
.fops = &alarm_fops,
|
||||
};
|
||||
|
||||
static int __init alarm_dev_init(void)
|
||||
{
|
||||
int err;
|
||||
int i;
|
||||
|
||||
err = misc_register(&alarm_device);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm,
|
||||
ALARM_REALTIME, devalarm_alarmhandler);
|
||||
hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt,
|
||||
CLOCK_REALTIME, HRTIMER_MODE_ABS);
|
||||
alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm,
|
||||
ALARM_BOOTTIME, devalarm_alarmhandler);
|
||||
hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt,
|
||||
CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
|
||||
hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt,
|
||||
CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
|
||||
|
||||
for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
|
||||
alarms[i].type = i;
|
||||
if (!is_wakeup(i))
|
||||
alarms[i].u.hrt.function = devalarm_hrthandler;
|
||||
}
|
||||
|
||||
wakeup_source_init(&alarm_wake_lock, "alarm");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alarm_dev_exit(void)
|
||||
{
|
||||
misc_deregister(&alarm_device);
|
||||
wakeup_source_trash(&alarm_wake_lock);
|
||||
}
|
||||
|
||||
module_init(alarm_dev_init);
|
||||
module_exit(alarm_dev_exit);
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/* include/linux/android_alarm.h
|
||||
*
|
||||
* Copyright (C) 2006-2007 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_ANDROID_ALARM_H
|
||||
#define _LINUX_ANDROID_ALARM_H
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#include "uapi/android_alarm.h"
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define ANDROID_ALARM_SET_COMPAT(type) ALARM_IOW(2, type, \
|
||||
struct compat_timespec)
|
||||
#define ANDROID_ALARM_SET_AND_WAIT_COMPAT(type) ALARM_IOW(3, type, \
|
||||
struct compat_timespec)
|
||||
#define ANDROID_ALARM_GET_TIME_COMPAT(type) ALARM_IOW(4, type, \
|
||||
struct compat_timespec)
|
||||
#define ANDROID_ALARM_SET_RTC_COMPAT _IOW('a', 5, \
|
||||
struct compat_timespec)
|
||||
#define ANDROID_ALARM_IOCTL_NR(cmd) (_IOC_NR(cmd) & ((1<<4)-1))
|
||||
#define ANDROID_ALARM_COMPAT_TO_NORM(cmd) \
|
||||
ALARM_IOW(ANDROID_ALARM_IOCTL_NR(cmd), \
|
||||
ANDROID_ALARM_IOCTL_TO_TYPE(cmd), \
|
||||
struct timespec)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,89 +0,0 @@
|
||||
/* include/linux/logger.h
|
||||
*
|
||||
* Copyright (C) 2007-2008 Google, Inc.
|
||||
* Author: Robert Love <rlove@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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_LOGGER_H
|
||||
#define _LINUX_LOGGER_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
/**
|
||||
* struct user_logger_entry_compat - defines a single entry that is given to a logger
|
||||
* @len: The length of the payload
|
||||
* @__pad: Two bytes of padding that appear to be required
|
||||
* @pid: The generating process' process ID
|
||||
* @tid: The generating process' thread ID
|
||||
* @sec: The number of seconds that have elapsed since the Epoch
|
||||
* @nsec: The number of nanoseconds that have elapsed since @sec
|
||||
* @msg: The message that is to be logged
|
||||
*
|
||||
* The userspace structure for version 1 of the logger_entry ABI.
|
||||
* This structure is returned to userspace unless the caller requests
|
||||
* an upgrade to a newer ABI version.
|
||||
*/
|
||||
struct user_logger_entry_compat {
|
||||
__u16 len;
|
||||
__u16 __pad;
|
||||
__s32 pid;
|
||||
__s32 tid;
|
||||
__s32 sec;
|
||||
__s32 nsec;
|
||||
char msg[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct logger_entry - defines a single entry that is given to a logger
|
||||
* @len: The length of the payload
|
||||
* @hdr_size: sizeof(struct logger_entry_v2)
|
||||
* @pid: The generating process' process ID
|
||||
* @tid: The generating process' thread ID
|
||||
* @sec: The number of seconds that have elapsed since the Epoch
|
||||
* @nsec: The number of nanoseconds that have elapsed since @sec
|
||||
* @euid: Effective UID of logger
|
||||
* @msg: The message that is to be logged
|
||||
*
|
||||
* The structure for version 2 of the logger_entry ABI.
|
||||
* This structure is returned to userspace if ioctl(LOGGER_SET_VERSION)
|
||||
* is called with version >= 2
|
||||
*/
|
||||
struct logger_entry {
|
||||
__u16 len;
|
||||
__u16 hdr_size;
|
||||
__s32 pid;
|
||||
__s32 tid;
|
||||
__s32 sec;
|
||||
__s32 nsec;
|
||||
kuid_t euid;
|
||||
char msg[0];
|
||||
};
|
||||
|
||||
#define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */
|
||||
#define LOGGER_LOG_EVENTS "log_events" /* system/hardware events */
|
||||
#define LOGGER_LOG_SYSTEM "log_system" /* system/framework messages */
|
||||
#define LOGGER_LOG_MAIN "log_main" /* everything else */
|
||||
|
||||
#define LOGGER_ENTRY_MAX_PAYLOAD 4076
|
||||
|
||||
#define __LOGGERIO 0xAE
|
||||
|
||||
#define LOGGER_GET_LOG_BUF_SIZE _IO(__LOGGERIO, 1) /* size of log */
|
||||
#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */
|
||||
#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */
|
||||
#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */
|
||||
#define LOGGER_GET_VERSION _IO(__LOGGERIO, 5) /* abi version */
|
||||
#define LOGGER_SET_VERSION _IO(__LOGGERIO, 6) /* abi version */
|
||||
|
||||
#endif /* _LINUX_LOGGER_H */
|
||||
@@ -1,62 +0,0 @@
|
||||
/* drivers/staging/android/uapi/android_alarm.h
|
||||
*
|
||||
* Copyright (C) 2006-2007 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 _UAPI_LINUX_ANDROID_ALARM_H
|
||||
#define _UAPI_LINUX_ANDROID_ALARM_H
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
enum android_alarm_type {
|
||||
/* return code bit numbers or set alarm arg */
|
||||
ANDROID_ALARM_RTC_WAKEUP,
|
||||
ANDROID_ALARM_RTC,
|
||||
ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
|
||||
ANDROID_ALARM_ELAPSED_REALTIME,
|
||||
ANDROID_ALARM_SYSTEMTIME,
|
||||
|
||||
ANDROID_ALARM_TYPE_COUNT,
|
||||
|
||||
/* return code bit numbers */
|
||||
/* ANDROID_ALARM_TIME_CHANGE = 16 */
|
||||
};
|
||||
|
||||
enum android_alarm_return_flags {
|
||||
ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP,
|
||||
ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC,
|
||||
ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK =
|
||||
1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
|
||||
ANDROID_ALARM_ELAPSED_REALTIME_MASK =
|
||||
1U << ANDROID_ALARM_ELAPSED_REALTIME,
|
||||
ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
|
||||
ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
|
||||
};
|
||||
|
||||
/* Disable alarm */
|
||||
#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4))
|
||||
|
||||
/* Ack last alarm and wait for next */
|
||||
#define ANDROID_ALARM_WAIT _IO('a', 1)
|
||||
|
||||
#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size)
|
||||
/* Set alarm */
|
||||
#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec)
|
||||
#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec)
|
||||
#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec)
|
||||
#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec)
|
||||
#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0)))
|
||||
#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4)
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user