Watch
1
Fork
You've already forked kernel_a52xq
0
mirror of https://github.com/a52xq-dev/kernel.git synced 2026-10-18 21:58:11 +07:00

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (342 commits)
  Staging: comedi: fix build errors
  Staging: udlfb: update to version 0.2.3
  Staging: udlfb: fix some sparse warnings.
  Staging: udlfb: clean up checkpatch warnings in udlfb.c
  Staging: udlfb: clean up checkpatch warnings in udlfb.h
  Staging: udlfb: add udlfb driver to build
  Staging: add udlfb driver
  Staging: pata_rdc: remove pointless comments
  Staging: pata_rdc: remove DRIVER macros
  Staging: pata_rdc: remove dbgprintf macro
  Staging: pata_rdc: remove broken flag
  Staging: pata_rdc: fix build warnings
  Staging: pata_rdc: use PCI_DEVICE
  Staging: pata_rdc: remove function prototypes
  Staging: pata_rdc: coding style fixes
  Staging: pata_rdc: convert code to work in 2.6.29
  Staging: pata_rdc: add driver to the build system
  Staging: add pata_rdc driver
  Staging: remove obsolete serqt_usb driver
  Staging: serqt_usb2 add the driver to the build
  ...
This commit is contained in:
Linus Torvalds 2009-06-19 17:48:32 -07:00
commit fb20871a54
658 changed files with 165609 additions and 240517 deletions

View file

@ -5479,6 +5479,7 @@ STAGING SUBSYSTEM
P: Greg Kroah-Hartman
M: gregkh@suse.de
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
L: devel@driverdev.osuosl.org
S: Maintained
F: drivers/staging/

View file

@ -85,6 +85,8 @@ source "drivers/staging/altpciechdma/Kconfig"
source "drivers/staging/rtl8187se/Kconfig"
source "drivers/staging/rtl8192su/Kconfig"
source "drivers/staging/rspiusb/Kconfig"
source "drivers/staging/mimio/Kconfig"
@ -113,11 +115,19 @@ source "drivers/staging/heci/Kconfig"
source "drivers/staging/line6/Kconfig"
source "drivers/staging/serqt_usb/Kconfig"
source "drivers/gpu/drm/radeon/Kconfig"
source "drivers/staging/octeon/Kconfig"
source "drivers/staging/serqt_usb2/Kconfig"
source "drivers/staging/vt6655/Kconfig"
source "drivers/staging/cpc-usb/Kconfig"
source "drivers/staging/pata_rdc/Kconfig"
source "drivers/staging/udlfb/Kconfig"
endif # !STAGING_EXCLUDE_BUILD
endif # STAGING

View file

@ -25,6 +25,7 @@ obj-$(CONFIG_ASUS_OLED) += asus_oled/
obj-$(CONFIG_PANEL) += panel/
obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/
obj-$(CONFIG_RTL8187SE) += rtl8187se/
obj-$(CONFIG_RTL8192SU) += rtl8192su/
obj-$(CONFIG_USB_RSPI) += rspiusb/
obj-$(CONFIG_INPUT_MIMIO) += mimio/
obj-$(CONFIG_TRANZPORT) += frontier/
@ -39,5 +40,9 @@ obj-$(CONFIG_IDE_PHISON) += phison/
obj-$(CONFIG_PLAN9AUTH) += p9auth/
obj-$(CONFIG_HECI) += heci/
obj-$(CONFIG_LINE6_USB) += line6/
obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100) += serqt_usb/
obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/
obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
obj-$(CONFIG_VT6655) += vt6655/
obj-$(CONFIG_USB_CPC) += cpc-usb/
obj-$(CONFIG_RDC_17F3101X) += pata_rdc/
obj-$(CONFIG_FB_UDL) += udlfb/

View file

@ -312,7 +312,6 @@ static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
{
u16 fctl;
int hdrlen;
DECLARE_MAC_BUF(mac);
fctl = le16_to_cpu(hdr->frame_control);
switch (fctl & IEEE80211_FCTL_FTYPE) {
@ -375,13 +374,13 @@ static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
printk("FC=0x%04x DUR=0x%04x",
fctl, le16_to_cpu(hdr->duration_id));
if (hdrlen >= 10)
printk(" A1=%s", print_mac(mac, hdr->addr1));
printk(" A1=%pM", hdr->addr1);
if (hdrlen >= 16)
printk(" A2=%s", print_mac(mac, hdr->addr2));
printk(" A2=%pM", hdr->addr2);
if (hdrlen >= 24)
printk(" A3=%s", print_mac(mac, hdr->addr3));
printk(" A3=%pM", hdr->addr3);
if (hdrlen >= 30)
printk(" A4=%s", print_mac(mac, hdr->addr4));
printk(" A4=%pM", hdr->addr4);
printk("\n");
}

View file

@ -58,15 +58,17 @@ static inline void agnx_interrupt_ack(struct agnx_priv *priv, u32 *reason)
*reason |= AGNX_STAT_TXM;
}
}
/* if (*reason & AGNX_STAT_X) {
#if 0
if (*reason & AGNX_STAT_X) {
reg = ioread32(ctl + AGNX_INT_STAT);
iowrite32(reg, ctl + AGNX_INT_STAT);
/* FIXME reinit interrupt mask *\/
/* FIXME reinit interrupt mask */
reg = 0xc390bf9 & ~IRQ_TX_BEACON;
reg &= ~IRQ_TX_DISABLE;
iowrite32(reg, ctl + AGNX_INT_MASK);
iowrite32(0x800, ctl + AGNX_CIR_BLKCTL);
} */
}
#endif
} /* agnx_interrupt_ack */
static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
@ -150,8 +152,7 @@ static int agnx_get_mac_address(struct agnx_priv *priv)
*((u32 *)(priv->mac_addr + 2)) = cpu_to_le32(reg);
if (!is_valid_ether_addr(priv->mac_addr)) {
DECLARE_MAC_BUF(mbuf);
printk(KERN_WARNING PFX "read mac %s\n", print_mac(mbuf, priv->mac_addr));
printk(KERN_WARNING PFX "read mac %pM\n", priv->mac_addr);
printk(KERN_WARNING PFX "Invalid hwaddr! Using random hwaddr\n");
random_ether_addr(priv->mac_addr);
}
@ -220,7 +221,7 @@ static void agnx_periodic_work_handler(struct work_struct *work)
/* TODO Recalibrate*/
/* calibrate_oscillator(priv); */
/* antenna_calibrate(priv); */
/* agnx_send_packet(priv, 997); /
/* agnx_send_packet(priv, 997); */
/* FIXME */
/* if (debug == 3) */
/* delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
@ -455,47 +456,35 @@ static int __devinit agnx_pci_probe(struct pci_dev *pdev,
{
struct ieee80211_hw *dev;
struct agnx_priv *priv;
u32 mem_addr0, mem_len0;
u32 mem_addr1, mem_len1;
int err;
DECLARE_MAC_BUF(mac);
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR PFX "Can't enable new PCI device\n");
dev_err(&pdev->dev, "can't enable pci device\n");
return err;
}
/* get pci resource */
mem_addr0 = pci_resource_start(pdev, 0);
mem_len0 = pci_resource_len(pdev, 0);
mem_addr1 = pci_resource_start(pdev, 1);
mem_len1 = pci_resource_len(pdev, 1);
printk(KERN_DEBUG PFX "Memaddr0 is %x, length is %x\n", mem_addr0, mem_len0);
printk(KERN_DEBUG PFX "Memaddr1 is %x, length is %x\n", mem_addr1, mem_len1);
err = pci_request_regions(pdev, "agnx-pci");
if (err) {
printk(KERN_ERR PFX "Can't obtain PCI resource\n");
dev_err(&pdev->dev, "can't reserve PCI resources\n");
return err;
}
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_ERR PFX "No suitable DMA available\n");
dev_err(&pdev->dev, "no suitable DMA available\n");
err = -EIO;
goto err_free_reg;
}
pci_set_master(pdev);
printk(KERN_DEBUG PFX "pdev->irq is %d\n", pdev->irq);
dev = ieee80211_alloc_hw(sizeof(*priv), &agnx_ops);
if (!dev) {
printk(KERN_ERR PFX "ieee80211 alloc failed\n");
dev_err(&pdev->dev, "ieee80211 alloc failed\n");
err = -ENOMEM;
goto err_free_reg;
}
/* init priv */
priv = dev->priv;
memset(priv, 0, sizeof(*priv));
priv->mode = NL80211_IFTYPE_MONITOR;
@ -504,17 +493,17 @@ static int __devinit agnx_pci_probe(struct pci_dev *pdev,
spin_lock_init(&priv->lock);
priv->init_status = AGNX_UNINIT;
/* Map mem #1 and #2 */
priv->ctl = pci_iomap(pdev, 0, mem_len0);
/* printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl); */
priv->ctl = pci_iomap(pdev, 0, 0);
/* dev_dbg(&pdev->dev, "MEM1 mapped address is 0x%p\n", priv->ctl); */
if (!priv->ctl) {
printk(KERN_ERR PFX "Can't map device memory\n");
dev_err(&pdev->dev, "can't map device memory\n");
err = -ENOMEM;
goto err_free_dev;
}
priv->data = pci_iomap(pdev, 1, mem_len1);
printk(KERN_DEBUG PFX "MEM2 mapped address is 0x%p\n", priv->data);
priv->data = pci_iomap(pdev, 1, 0);
if (!priv->data) {
printk(KERN_ERR PFX "Can't map device memory\n");
dev_err(&pdev->dev, "can't map device memory\n");
err = -ENOMEM;
goto err_iounmap2;
}
@ -555,15 +544,15 @@ static int __devinit agnx_pci_probe(struct pci_dev *pdev,
err = ieee80211_register_hw(dev);
if (err) {
printk(KERN_ERR PFX "Can't register hardware\n");
dev_err(&pdev->dev, "can't register hardware\n");
goto err_iounmap;
}
agnx_hw_reset(priv);
printk(PFX "%s: hwaddr %s, Rev 0x%02x\n", wiphy_name(dev->wiphy),
print_mac(mac, dev->wiphy->perm_addr), priv->revid);
dev_info(&pdev->dev, "%s: hwaddr %pM, Rev 0x%02x\n",
wiphy_name(dev->wiphy),
dev->wiphy->perm_addr, priv->revid);
return 0;
err_iounmap:

View file

@ -118,7 +118,7 @@ static void mac_address_set(struct agnx_priv *priv)
iowrite32(reg, ctl + AGNX_RXM_MACLO);
}
static void receiver_bssid_set(struct agnx_priv *priv, u8 *bssid)
static void receiver_bssid_set(struct agnx_priv *priv, const u8 *bssid)
{
void __iomem *ctl = priv->ctl;
u32 reg;
@ -954,7 +954,7 @@ int agnx_set_ssid(struct agnx_priv *priv, u8 *ssid, size_t ssid_len)
return 0;
}
void agnx_set_bssid(struct agnx_priv *priv, u8 *bssid)
void agnx_set_bssid(struct agnx_priv *priv, const u8 *bssid)
{
receiver_bssid_set(priv, bssid);
}

View file

@ -401,7 +401,7 @@ u8 read_from_eeprom(struct agnx_priv *priv, u16 address);
void agnx_hw_init(struct agnx_priv *priv);
int agnx_hw_reset(struct agnx_priv *priv);
int agnx_set_ssid(struct agnx_priv *priv, u8 *ssid, size_t ssid_len);
void agnx_set_bssid(struct agnx_priv *priv, u8 *bssid);
void agnx_set_bssid(struct agnx_priv *priv, const u8 *bssid);
void enable_power_saving(struct agnx_priv *priv);
void disable_power_saving(struct agnx_priv *priv);
void calibrate_antenna_period(unsigned long data);

View file

@ -22,7 +22,7 @@ void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
}
void hash_write(struct agnx_priv *priv, u8 *mac_addr, u8 sta_id)
void hash_write(struct agnx_priv *priv, const u8 *mac_addr, u8 sta_id)
{
void __iomem *ctl = priv->ctl;
u32 reghi, reglo;

View file

@ -201,7 +201,7 @@ struct agnx_beacon_hdr {
/* 802.11(abg) beacon */
} __attribute__((__packed__));
void hash_write(struct agnx_priv *priv, u8 *mac_addr, u8 sta_id);
void hash_write(struct agnx_priv *priv, const u8 *mac_addr, u8 sta_id);
void hash_dump(struct agnx_priv *priv, u8 sta_id);
void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id);
void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id);

View file

@ -399,6 +399,7 @@ static inline void ape_chdma_desc_set(struct ape_chdma_desc *desc, dma_addr_t ad
desc->rc_addr_l = cpu_to_le32(pci_dma_l(addr));
}
#if ALTPCIECHDMA_CDEV
/*
* ape_sg_to_chdma_table() - Create a device descriptor table from a scatterlist.
*
@ -456,6 +457,7 @@ static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first,
j++;
return j;
}
#endif
/* compare buffers */
static inline int compare(u32 *p, u32 *q, int len)
@ -540,8 +542,8 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
printk(KERN_DEBUG "Could not allocate coherent DMA buffer.\n");
goto fail;
}
printk(KERN_DEBUG "Allocated cache-coherent DMA buffer (virtual address = 0x%016llx, bus address = 0x%016llx).\n",
(u64)buffer_virt, (u64)buffer_bus);
printk(KERN_DEBUG "Allocated cache-coherent DMA buffer (virtual address = %p, bus address = 0x%016llx).\n",
buffer_virt, (u64)buffer_bus);
/* fill first half of buffer with its virtual address as data */
for (i = 0; i < 4 * PAGE_SIZE; i += 4)
@ -783,7 +785,7 @@ static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
goto err_ape;
}
ape->pci_dev = dev;
dev->dev.driver_data = (void *)ape;
dev_set_drvdata(&dev->dev, ape);
printk(KERN_DEBUG "probe() ape = 0x%p\n", ape);
printk(KERN_DEBUG "sizeof(struct ape_chdma_table) = %d.\n",
@ -801,8 +803,8 @@ static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
goto err_table;
}
printk(KERN_DEBUG "table_virt = 0x%16llx, table_bus = 0x%16llx.\n",
(u64)ape->table_virt, (u64)ape->table_bus);
printk(KERN_DEBUG "table_virt = %p, table_bus = 0x%16llx.\n",
ape->table_virt, (u64)ape->table_bus);
/* enable device */
rc = pci_enable_device(dev);
@ -913,9 +915,11 @@ static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
rc = 0;
printk(KERN_DEBUG "probe() successful.\n");
goto end;
#if ALTPCIECHDMA_CDEV
err_cdev:
/* unmap the BARs */
unmap_bars(ape, dev);
#endif
err_map:
/* free allocated irq */
if (ape->irq_line >= 0)
@ -930,7 +934,7 @@ err_irq:
pci_release_regions(dev);
err_mask:
err_regions:
err_rev:
/*err_rev:*/
/* clean up everything before device enable() */
err_enable:
if (ape->table_virt)
@ -946,19 +950,11 @@ end:
static void __devexit remove(struct pci_dev *dev)
{
struct ape_dev *ape;
struct ape_dev *ape = dev_get_drvdata(&dev->dev);
printk(KERN_DEBUG "remove(0x%p)\n", dev);
if ((dev == 0) || (dev->dev.driver_data == 0)) {
printk(KERN_DEBUG "remove(dev = 0x%p) dev->dev.driver_data = 0x%p\n",
dev, (dev? dev->dev.driver_data: NULL));
return;
}
ape = (struct ape_dev *)dev->dev.driver_data;
printk(KERN_DEBUG "remove(dev = 0x%p) where dev->dev.driver_data = 0x%p\n", dev, ape);
if (ape->pci_dev != dev) {
printk(KERN_DEBUG "dev->dev.driver_data->pci_dev (0x%08lx) != dev (0x%08lx)\n",
(unsigned long)ape->pci_dev, (unsigned long)dev);
}
printk(KERN_DEBUG "remove(dev = 0x%p) where ape = 0x%p\n", dev, ape);
/* remove character device */
#if ALTPCIECHDMA_CDEV
sg_exit(ape);
@ -1151,7 +1147,7 @@ static struct pci_driver pci_driver = {
.name = DRV_NAME,
.id_table = ids,
.probe = probe,
.remove = remove,
.remove = __devexit_p(remove),
/* resume, suspend are optional */
};

View file

@ -6,6 +6,8 @@ config ANDROID
---help---
Enable support for various drivers needed on the Android platform
if ANDROID
config ANDROID_BINDER_IPC
bool "Android Binder IPC Driver"
default n
@ -73,9 +75,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
@ -84,4 +90,6 @@ config ANDROID_LOW_MEMORY_KILLER
---help---
Register processes to be killed when memory is low
endif # if ANDROID
endmenu

View file

@ -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

View file

@ -44,8 +44,8 @@ static struct hlist_head binder_dead_nodes;
static HLIST_HEAD(binder_deferred_list);
static DEFINE_MUTEX(binder_deferred_lock);
static int binder_read_proc_proc(
char *page, char **start, off_t off, int count, int *eof, void *data);
static int binder_read_proc_proc(char *page, char **start, off_t off,
int count, int *eof, void *data);
/* This is only defined in include/asm-arm/sizes.h */
#ifndef SZ_1K
@ -81,12 +81,15 @@ enum {
static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR |
BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;
module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
static int binder_debug_no_lock;
module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
static int binder_stop_on_user_error;
static int binder_set_stop_on_user_error(
const char *val, struct kernel_param *kp)
static int binder_set_stop_on_user_error(const char *val,
struct kernel_param *kp)
{
int ret;
ret = param_set_int(val, kp);
@ -185,13 +188,13 @@ struct binder_node {
int local_strong_refs;
void __user *ptr;
void __user *cookie;
unsigned has_strong_ref : 1;
unsigned pending_strong_ref : 1;
unsigned has_weak_ref : 1;
unsigned pending_weak_ref : 1;
unsigned has_async_transaction : 1;
unsigned accept_fds : 1;
int min_priority : 8;
unsigned has_strong_ref:1;
unsigned pending_strong_ref:1;
unsigned has_weak_ref:1;
unsigned pending_weak_ref:1;
unsigned has_async_transaction:1;
unsigned accept_fds:1;
unsigned min_priority:8;
struct list_head async_todo;
};
@ -221,10 +224,10 @@ struct binder_buffer {
struct list_head entry; /* free and allocated entries by addesss */
struct rb_node rb_node; /* free entry by size or allocated entry */
/* by address */
unsigned free : 1;
unsigned allow_user_free : 1;
unsigned async_transaction : 1;
unsigned debug_id : 29;
unsigned free:1;
unsigned allow_user_free:1;
unsigned async_transaction:1;
unsigned debug_id:29;
struct binder_transaction *transaction;
@ -306,8 +309,8 @@ struct binder_transaction {
struct binder_proc *to_proc;
struct binder_thread *to_thread;
struct binder_transaction *to_parent;
unsigned need_reply : 1;
/*unsigned is_dead : 1;*/ /* not used at the moment */
unsigned need_reply:1;
/* unsigned is_dead:1; */ /* not used at the moment */
struct binder_buffer *buffer;
unsigned int code;
@ -474,8 +477,8 @@ static void binder_set_nice(long nice)
binder_user_error("binder: %d RLIMIT_NICE not set\n", current->pid);
}
static size_t binder_buffer_size(
struct binder_proc *proc, struct binder_buffer *buffer)
static size_t binder_buffer_size(struct binder_proc *proc,
struct binder_buffer *buffer)
{
if (list_is_last(&buffer->entry, &proc->buffers))
return proc->buffer + proc->buffer_size - (void *)buffer->data;
@ -484,8 +487,8 @@ static size_t binder_buffer_size(
struct binder_buffer, entry) - (size_t)buffer->data;
}
static void binder_insert_free_buffer(
struct binder_proc *proc, struct binder_buffer *new_buffer)
static void binder_insert_free_buffer(struct binder_proc *proc,
struct binder_buffer *new_buffer)
{
struct rb_node **p = &proc->free_buffers.rb_node;
struct rb_node *parent = NULL;
@ -517,8 +520,8 @@ static void binder_insert_free_buffer(
rb_insert_color(&new_buffer->rb_node, &proc->free_buffers);
}
static void binder_insert_allocated_buffer(
struct binder_proc *proc, struct binder_buffer *new_buffer)
static void binder_insert_allocated_buffer(struct binder_proc *proc,
struct binder_buffer *new_buffer)
{
struct rb_node **p = &proc->allocated_buffers.rb_node;
struct rb_node *parent = NULL;
@ -542,8 +545,8 @@ static void binder_insert_allocated_buffer(
rb_insert_color(&new_buffer->rb_node, &proc->allocated_buffers);
}
static struct binder_buffer *binder_buffer_lookup(
struct binder_proc *proc, void __user *user_ptr)
static struct binder_buffer *binder_buffer_lookup(struct binder_proc *proc,
void __user *user_ptr)
{
struct rb_node *n = proc->allocated_buffers.rb_node;
struct binder_buffer *buffer;
@ -567,7 +570,8 @@ static struct binder_buffer *binder_buffer_lookup(
}
static int binder_update_page_range(struct binder_proc *proc, int allocate,
void *start, void *end, struct vm_area_struct *vma)
void *start, void *end,
struct vm_area_struct *vma)
{
void *page_addr;
unsigned long user_page_addr;
@ -664,7 +668,8 @@ err_no_vma:
}
static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
size_t data_size, size_t offsets_size, int is_async)
size_t data_size,
size_t offsets_size, int is_async)
{
struct rb_node *n = proc->free_buffers.rb_node;
struct binder_buffer *buffer;
@ -692,8 +697,9 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
if (is_async &&
proc->free_async_space < size + sizeof(struct binder_buffer)) {
if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd f"
"ailed, no async space left\n", proc->pid, size);
printk(KERN_ERR
"binder: %d: binder_alloc_buf size %zd failed, "
"no async space left\n", proc->pid, size);
return NULL;
}
@ -777,8 +783,8 @@ static void *buffer_end_page(struct binder_buffer *buffer)
return (void *)(((uintptr_t)(buffer + 1) - 1) & PAGE_MASK);
}
static void binder_delete_free_buffer(
struct binder_proc *proc, struct binder_buffer *buffer)
static void binder_delete_free_buffer(struct binder_proc *proc,
struct binder_buffer *buffer)
{
struct binder_buffer *prev, *next = NULL;
int free_page_end = 1;
@ -824,8 +830,8 @@ static void binder_delete_free_buffer(
}
}
static void binder_free_buf(
struct binder_proc *proc, struct binder_buffer *buffer)
static void binder_free_buf(struct binder_proc *proc,
struct binder_buffer *buffer)
{
size_t size, buffer_size;
@ -877,8 +883,8 @@ static void binder_free_buf(
binder_insert_free_buffer(proc, buffer);
}
static struct binder_node *
binder_get_node(struct binder_proc *proc, void __user *ptr)
static struct binder_node *binder_get_node(struct binder_proc *proc,
void __user *ptr)
{
struct rb_node *n = proc->nodes.rb_node;
struct binder_node *node;
@ -896,8 +902,9 @@ binder_get_node(struct binder_proc *proc, void __user *ptr)
return NULL;
}
static struct binder_node *
binder_new_node(struct binder_proc *proc, void __user *ptr, void __user *cookie)
static struct binder_node *binder_new_node(struct binder_proc *proc,
void __user *ptr,
void __user *cookie)
{
struct rb_node **p = &proc->nodes.rb_node;
struct rb_node *parent = NULL;
@ -935,9 +942,8 @@ binder_new_node(struct binder_proc *proc, void __user *ptr, void __user *cookie)
return node;
}
static int
binder_inc_node(struct binder_node *node, int strong, int internal,
struct list_head *target_list)
static int binder_inc_node(struct binder_node *node, int strong, int internal,
struct list_head *target_list)
{
if (strong) {
if (internal) {
@ -971,8 +977,7 @@ binder_inc_node(struct binder_node *node, int strong, int internal,
return 0;
}
static int
binder_dec_node(struct binder_node *node, int strong, int internal)
static int binder_dec_node(struct binder_node *node, int strong, int internal)
{
if (strong) {
if (internal)
@ -1014,8 +1019,8 @@ binder_dec_node(struct binder_node *node, int strong, int internal)
}
static struct binder_ref *
binder_get_ref(struct binder_proc *proc, uint32_t desc)
static struct binder_ref *binder_get_ref(struct binder_proc *proc,
uint32_t desc)
{
struct rb_node *n = proc->refs_by_desc.rb_node;
struct binder_ref *ref;
@ -1033,8 +1038,8 @@ binder_get_ref(struct binder_proc *proc, uint32_t desc)
return NULL;
}
static struct binder_ref *
binder_get_ref_for_node(struct binder_proc *proc, struct binder_node *node)
static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
struct binder_node *node)
{
struct rb_node *n;
struct rb_node **p = &proc->refs_by_node.rb_node;
@ -1099,8 +1104,7 @@ binder_get_ref_for_node(struct binder_proc *proc, struct binder_node *node)
return new_ref;
}
static void
binder_delete_ref(struct binder_ref *ref)
static void binder_delete_ref(struct binder_ref *ref)
{
if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS)
printk(KERN_INFO "binder: %d delete ref %d desc %d for "
@ -1125,9 +1129,8 @@ binder_delete_ref(struct binder_ref *ref)
binder_stats.obj_deleted[BINDER_STAT_REF]++;
}
static int
binder_inc_ref(
struct binder_ref *ref, int strong, struct list_head *target_list)
static int binder_inc_ref(struct binder_ref *ref, int strong,
struct list_head *target_list)
{
int ret;
if (strong) {
@ -1149,8 +1152,7 @@ binder_inc_ref(
}
static int
binder_dec_ref(struct binder_ref *ref, int strong)
static int binder_dec_ref(struct binder_ref *ref, int strong)
{
if (strong) {
if (ref->strong == 0) {
@ -1182,9 +1184,8 @@ binder_dec_ref(struct binder_ref *ref, int strong)
return 0;
}
static void
binder_pop_transaction(
struct binder_thread *target_thread, struct binder_transaction *t)
static void binder_pop_transaction(struct binder_thread *target_thread,
struct binder_transaction *t)
{
if (target_thread) {
BUG_ON(target_thread->transaction_stack != t);
@ -1200,8 +1201,8 @@ binder_pop_transaction(
binder_stats.obj_deleted[BINDER_STAT_TRANSACTION]++;
}
static void
binder_send_failed_reply(struct binder_transaction *t, uint32_t error_code)
static void binder_send_failed_reply(struct binder_transaction *t,
uint32_t error_code)
{
struct binder_thread *target_thread;
BUG_ON(t->flags & TF_ONE_WAY);
@ -1253,13 +1254,13 @@ binder_send_failed_reply(struct binder_transaction *t, uint32_t error_code)
}
}
static void
binder_transaction_buffer_release(struct binder_proc *proc,
struct binder_buffer *buffer, size_t *failed_at);
static void binder_transaction_buffer_release(struct binder_proc *proc,
struct binder_buffer *buffer,
size_t *failed_at);
static void
binder_transaction(struct binder_proc *proc, struct binder_thread *thread,
struct binder_transaction_data *tr, int reply)
static void binder_transaction(struct binder_proc *proc,
struct binder_thread *thread,
struct binder_transaction_data *tr, int reply)
{
struct binder_transaction *t;
struct binder_work *tcomplete;
@ -1661,8 +1662,9 @@ err_no_context_mgr_node:
thread->return_error = return_error;
}
static void
binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer *buffer, size_t *failed_at)
static void binder_transaction_buffer_release(struct binder_proc *proc,
struct binder_buffer *buffer,
size_t *failed_at)
{
size_t *offp, *off_end;
int debug_id = buffer->debug_id;
@ -1730,9 +1732,8 @@ binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer
}
}
int
binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
void __user *buffer, int size, signed long *consumed)
int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
void __user *buffer, int size, signed long *consumed)
{
uint32_t cmd;
void __user *ptr = buffer + *consumed;
@ -2104,7 +2105,8 @@ binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
} break;
default:
printk(KERN_ERR "binder: %d:%d unknown command %d\n", proc->pid, thread->pid, cmd);
printk(KERN_ERR "binder: %d:%d unknown command %d\n",
proc->pid, thread->pid, cmd);
return -EINVAL;
}
*consumed = ptr - buffer;
@ -2112,8 +2114,8 @@ binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
return 0;
}
void
binder_stat_br(struct binder_proc *proc, struct binder_thread *thread, uint32_t cmd)
void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread,
uint32_t cmd)
{
if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) {
binder_stats.br[_IOC_NR(cmd)]++;
@ -2122,22 +2124,23 @@ binder_stat_br(struct binder_proc *proc, struct binder_thread *thread, uint32_t
}
}
static int
binder_has_proc_work(struct binder_proc *proc, struct binder_thread *thread)
static int binder_has_proc_work(struct binder_proc *proc,
struct binder_thread *thread)
{
return !list_empty(&proc->todo) || (thread->looper & BINDER_LOOPER_STATE_NEED_RETURN);
return !list_empty(&proc->todo) ||
(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN);
}
static int
binder_has_thread_work(struct binder_thread *thread)
static int binder_has_thread_work(struct binder_thread *thread)
{
return !list_empty(&thread->todo) || thread->return_error != BR_OK ||
(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN);
}
static int
binder_thread_read(struct binder_proc *proc, struct binder_thread *thread,
void __user *buffer, int size, signed long *consumed, int non_block)
static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
void __user *buffer, int size,
signed long *consumed, int non_block)
{
void __user *ptr = buffer + *consumed;
void __user *end = buffer + size;
@ -2152,7 +2155,8 @@ binder_thread_read(struct binder_proc *proc, struct binder_thread *thread,
}
retry:
wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);
wait_for_proc_work = thread->transaction_stack == NULL &&
list_empty(&thread->todo);
if (thread->return_error != BR_OK && ptr < end) {
if (thread->return_error2 != BR_OK) {
@ -2182,7 +2186,8 @@ retry:
"for process work before calling BC_REGISTER_"
"LOOPER or BC_ENTER_LOOPER (state %x)\n",
proc->pid, thread->pid, thread->looper);
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
wait_event_interruptible(binder_user_error_wait,
binder_stop_on_user_error < 2);
}
binder_set_nice(proc->default_priority);
if (non_block) {
@ -2304,8 +2309,10 @@ retry:
case BINDER_WORK_DEAD_BINDER:
case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: {
struct binder_ref_death *death = container_of(w, struct binder_ref_death, work);
struct binder_ref_death *death;
uint32_t cmd;
death = container_of(w, struct binder_ref_death, work);
if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION)
cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE;
else
@ -2362,15 +2369,19 @@ retry:
if (t->from) {
struct task_struct *sender = t->from->proc->tsk;
tr.sender_pid = task_tgid_nr_ns(sender, current->nsproxy->pid_ns);
tr.sender_pid = task_tgid_nr_ns(sender,
current->nsproxy->pid_ns);
} else {
tr.sender_pid = 0;
}
tr.data_size = t->buffer->data_size;
tr.offsets_size = t->buffer->offsets_size;
tr.data.ptr.buffer = (void *)t->buffer->data + proc->user_buffer_offset;
tr.data.ptr.offsets = tr.data.ptr.buffer + ALIGN(t->buffer->data_size, sizeof(void *));
tr.data.ptr.buffer = (void *)t->buffer->data +
proc->user_buffer_offset;
tr.data.ptr.offsets = tr.data.ptr.buffer +
ALIGN(t->buffer->data_size,
sizeof(void *));
if (put_user(cmd, (uint32_t __user *)ptr))
return -EFAULT;
@ -2384,7 +2395,8 @@ retry:
printk(KERN_INFO "binder: %d:%d %s %d %d:%d, cmd %d"
"size %zd-%zd ptr %p-%p\n",
proc->pid, thread->pid,
(cmd == BR_TRANSACTION) ? "BR_TRANSACTION" : "BR_REPLY",
(cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
"BR_REPLY",
t->debug_id, t->from ? t->from->proc->pid : 0,
t->from ? t->from->pid : 0, cmd,
t->buffer->data_size, t->buffer->offsets_size,
@ -2430,7 +2442,9 @@ static void binder_release_work(struct list_head *list)
list_del_init(&w->entry);
switch (w->type) {
case BINDER_WORK_TRANSACTION: {
struct binder_transaction *t = container_of(w, struct binder_transaction, work);
struct binder_transaction *t;
t = container_of(w, struct binder_transaction, work);
if (t->buffer->target_node && !(t->flags & TF_ONE_WAY))
binder_send_failed_reply(t, BR_DEAD_REPLY);
} break;
@ -2480,7 +2494,8 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc)
return thread;
}
static int binder_free_thread(struct binder_proc *proc, struct binder_thread *thread)
static int binder_free_thread(struct binder_proc *proc,
struct binder_thread *thread)
{
struct binder_transaction *t;
struct binder_transaction *send_reply = NULL;
@ -2493,8 +2508,10 @@ static int binder_free_thread(struct binder_proc *proc, struct binder_thread *th
while (t) {
active_transactions++;
if (binder_debug_mask & BINDER_DEBUG_DEAD_TRANSACTION)
printk(KERN_INFO "binder: release %d:%d transaction %d %s, still active\n",
proc->pid, thread->pid, t->debug_id, (t->to_thread == thread) ? "in" : "out");
printk(KERN_INFO "binder: release %d:%d transaction %d "
"%s, still active\n", proc->pid, thread->pid,
t->debug_id,
(t->to_thread == thread) ? "in" : "out");
if (t->to_thread == thread) {
t->to_proc = NULL;
t->to_thread = NULL;
@ -2517,7 +2534,8 @@ static int binder_free_thread(struct binder_proc *proc, struct binder_thread *th
return active_transactions;
}
static unsigned int binder_poll(struct file *filp, struct poll_table_struct *wait)
static unsigned int binder_poll(struct file *filp,
struct poll_table_struct *wait)
{
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread = NULL;
@ -2778,7 +2796,8 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
proc->files = get_files_struct(current);
proc->vma = vma;
/*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/
/*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/
return 0;
err_alloc_small_buf_failed:
@ -2790,7 +2809,8 @@ err_alloc_pages_failed:
err_get_vm_area_failed:
err_already_mapped:
err_bad_arg:
printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
return ret;
}
@ -2799,7 +2819,8 @@ static int binder_open(struct inode *nodp, struct file *filp)
struct binder_proc *proc;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
printk(KERN_INFO "binder_open: %d:%d\n", current->group_leader->pid, current->pid);
printk(KERN_INFO "binder_open: %d:%d\n",
current->group_leader->pid, current->pid);
proc = kzalloc(sizeof(*proc), GFP_KERNEL);
if (proc == NULL)
@ -2821,7 +2842,9 @@ static int binder_open(struct inode *nodp, struct file *filp)
char strbuf[11];
snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
remove_proc_entry(strbuf, binder_proc_dir_entry_proc);
create_proc_read_entry(strbuf, S_IRUGO, binder_proc_dir_entry_proc, binder_read_proc_proc, proc);
create_proc_read_entry(strbuf, S_IRUGO,
binder_proc_dir_entry_proc,
binder_read_proc_proc, proc);
}
return 0;
@ -2925,12 +2948,15 @@ static void binder_deferred_release(struct binder_proc *proc)
}
}
if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER)
printk(KERN_INFO "binder: node %d now dead, refs %d, death %d\n", node->debug_id, incoming_refs, death);
printk(KERN_INFO "binder: node %d now dead, "
"refs %d, death %d\n", node->debug_id,
incoming_refs, death);
}
}
outgoing_refs = 0;
while ((n = rb_first(&proc->refs_by_desc))) {
struct binder_ref *ref = rb_entry(n, struct binder_ref, rb_node_desc);
struct binder_ref *ref = rb_entry(n, struct binder_ref,
rb_node_desc);
outgoing_refs++;
binder_delete_ref(ref);
}
@ -2938,12 +2964,15 @@ static void binder_deferred_release(struct binder_proc *proc)
buffers = 0;
while ((n = rb_first(&proc->allocated_buffers))) {
struct binder_buffer *buffer = rb_entry(n, struct binder_buffer, rb_node);
struct binder_buffer *buffer = rb_entry(n, struct binder_buffer,
rb_node);
t = buffer->transaction;
if (t) {
t->buffer = NULL;
buffer->transaction = NULL;
printk(KERN_ERR "binder: release proc %d, transaction %d, not freed\n", proc->pid, t->debug_id);
printk(KERN_ERR "binder: release proc %d, "
"transaction %d, not freed\n",
proc->pid, t->debug_id);
/*BUG();*/
}
binder_free_buf(proc, buffer);
@ -2957,8 +2986,13 @@ static void binder_deferred_release(struct binder_proc *proc)
int i;
for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) {
if (proc->pages[i]) {
if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
printk(KERN_INFO "binder_release: %d: page %d at %p not freed\n", proc->pid, i, proc->buffer + i * PAGE_SIZE);
if (binder_debug_mask &
BINDER_DEBUG_BUFFER_ALLOC)
printk(KERN_INFO
"binder_release: %d: "
"page %d at %p not freed\n",
proc->pid, i,
proc->buffer + i * PAGE_SIZE);
__free_page(proc->pages[i]);
page_count++;
}
@ -2970,8 +3004,12 @@ static void binder_deferred_release(struct binder_proc *proc)
put_task_struct(proc->tsk);
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
printk(KERN_INFO "binder_release: %d threads %d, nodes %d (ref %d), refs %d, active transactions %d, buffers %d, pages %d\n",
proc->pid, threads, nodes, incoming_refs, outgoing_refs, active_transactions, buffers, page_count);
printk(KERN_INFO
"binder_release: %d threads %d, nodes %d (ref %d), "
"refs %d, active transactions %d, buffers %d, "
"pages %d\n",
proc->pid, threads, nodes, incoming_refs, outgoing_refs,
active_transactions, buffers, page_count);
kfree(proc);
}
@ -2998,9 +3036,11 @@ static void binder_deferred_func(struct work_struct *work)
mutex_unlock(&binder_deferred_lock);
files = NULL;
if (defer & BINDER_DEFERRED_PUT_FILES)
if ((files = proc->files))
if (defer & BINDER_DEFERRED_PUT_FILES) {
files = proc->files;
if (files)
proc->files = NULL;
}
if (defer & BINDER_DEFERRED_FLUSH)
binder_deferred_flush(proc);
@ -3027,10 +3067,14 @@ static void binder_defer_work(struct binder_proc *proc, int defer)
mutex_unlock(&binder_deferred_lock);
}
static char *print_binder_transaction(char *buf, char *end, const char *prefix, struct binder_transaction *t)
static char *print_binder_transaction(char *buf, char *end, const char *prefix,
struct binder_transaction *t)
{
buf += snprintf(buf, end - buf, "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %ld r%d",
prefix, t->debug_id, t, t->from ? t->from->proc->pid : 0,
buf += snprintf(buf, end - buf,
"%s %d: %p from %d:%d to %d:%d code %x "
"flags %x pri %ld r%d",
prefix, t->debug_id, t,
t->from ? t->from->proc->pid : 0,
t->from ? t->from->pid : 0,
t->to_proc ? t->to_proc->pid : 0,
t->to_thread ? t->to_thread->pid : 0,
@ -3053,7 +3097,8 @@ static char *print_binder_transaction(char *buf, char *end, const char *prefix,
return buf;
}
static char *print_binder_buffer(char *buf, char *end, const char *prefix, struct binder_buffer *buffer)
static char *print_binder_buffer(char *buf, char *end, const char *prefix,
struct binder_buffer *buffer)
{
buf += snprintf(buf, end - buf, "%s %d: %p size %zd:%zd %s\n",
prefix, buffer->debug_id, buffer->data,
@ -3063,7 +3108,8 @@ static char *print_binder_buffer(char *buf, char *end, const char *prefix, struc
}
static char *print_binder_work(char *buf, char *end, const char *prefix,
const char *transaction_prefix, struct binder_work *w)
const char *transaction_prefix,
struct binder_work *w)
{
struct binder_node *node;
struct binder_transaction *t;
@ -3080,7 +3126,8 @@ static char *print_binder_work(char *buf, char *end, const char *prefix,
case BINDER_WORK_NODE:
node = container_of(w, struct binder_node, work);
buf += snprintf(buf, end - buf, "%snode work %d: u%p c%p\n",
prefix, node->debug_id, node->ptr, node->cookie);
prefix, node->debug_id, node->ptr,
node->cookie);
break;
case BINDER_WORK_DEAD_BINDER:
buf += snprintf(buf, end - buf, "%shas dead binder\n", prefix);
@ -3101,27 +3148,33 @@ static char *print_binder_work(char *buf, char *end, const char *prefix,
return buf;
}
static char *print_binder_thread(char *buf, char *end, struct binder_thread *thread, int print_always)
static char *print_binder_thread(char *buf, char *end,
struct binder_thread *thread,
int print_always)
{
struct binder_transaction *t;
struct binder_work *w;
char *start_buf = buf;
char *header_buf;
buf += snprintf(buf, end - buf, " thread %d: l %02x\n", thread->pid, thread->looper);
buf += snprintf(buf, end - buf, " thread %d: l %02x\n",
thread->pid, thread->looper);
header_buf = buf;
t = thread->transaction_stack;
while (t) {
if (buf >= end)
break;
if (t->from == thread) {
buf = print_binder_transaction(buf, end, " outgoing transaction", t);
buf = print_binder_transaction(buf, end,
" outgoing transaction", t);
t = t->from_parent;
} else if (t->to_thread == thread) {
buf = print_binder_transaction(buf, end, " incoming transaction", t);
buf = print_binder_transaction(buf, end,
" incoming transaction", t);
t = t->to_parent;
} else {
buf = print_binder_transaction(buf, end, " bad transaction", t);
buf = print_binder_transaction(buf, end,
" bad transaction", t);
t = NULL;
}
}
@ -3142,11 +3195,14 @@ static char *print_binder_node(char *buf, char *end, struct binder_node *node)
struct hlist_node *pos;
struct binder_work *w;
int count;
count = 0;
hlist_for_each_entry(ref, pos, &node->refs, node_entry)
count++;
buf += snprintf(buf, end - buf, " node %d: u%p c%p hs %d hw %d ls %d lw %d is %d iw %d",
buf += snprintf(buf, end - buf,
" node %d: u%p c%p hs %d hw %d ls %d lw %d "
"is %d iw %d",
node->debug_id, node->ptr, node->cookie,
node->has_strong_ref, node->has_weak_ref,
node->local_strong_refs, node->local_weak_refs,
@ -3175,13 +3231,16 @@ static char *print_binder_node(char *buf, char *end, struct binder_node *node)
static char *print_binder_ref(char *buf, char *end, struct binder_ref *ref)
{
buf += snprintf(buf, end - buf, " ref %d: desc %d %snode %d s %d w %d d %p\n",
ref->debug_id, ref->desc, ref->node->proc ? "" : "dead ",
ref->node->debug_id, ref->strong, ref->weak, ref->death);
buf += snprintf(buf, end - buf,
" ref %d: desc %d %snode %d s %d w %d d %p\n",
ref->debug_id, ref->desc,
ref->node->proc ? "" : "dead ", ref->node->debug_id,
ref->strong, ref->weak, ref->death);
return buf;
}
static char *print_binder_proc(char *buf, char *end, struct binder_proc *proc, int print_all)
static char *print_binder_proc(char *buf, char *end,
struct binder_proc *proc, int print_all)
{
struct binder_work *w;
struct rb_node *n;
@ -3191,19 +3250,34 @@ static char *print_binder_proc(char *buf, char *end, struct binder_proc *proc, i
buf += snprintf(buf, end - buf, "proc %d\n", proc->pid);
header_buf = buf;
for (n = rb_first(&proc->threads); n != NULL && buf < end; n = rb_next(n))
buf = print_binder_thread(buf, end, rb_entry(n, struct binder_thread, rb_node), print_all);
for (n = rb_first(&proc->nodes); n != NULL && buf < end; n = rb_next(n)) {
struct binder_node *node = rb_entry(n, struct binder_node, rb_node);
for (n = rb_first(&proc->threads);
n != NULL && buf < end;
n = rb_next(n))
buf = print_binder_thread(buf, end,
rb_entry(n, struct binder_thread,
rb_node), print_all);
for (n = rb_first(&proc->nodes);
n != NULL && buf < end;
n = rb_next(n)) {
struct binder_node *node = rb_entry(n, struct binder_node,
rb_node);
if (print_all || node->has_async_transaction)
buf = print_binder_node(buf, end, node);
}
if (print_all) {
for (n = rb_first(&proc->refs_by_desc); n != NULL && buf < end; n = rb_next(n))
buf = print_binder_ref(buf, end, rb_entry(n, struct binder_ref, rb_node_desc));
for (n = rb_first(&proc->refs_by_desc);
n != NULL && buf < end;
n = rb_next(n))
buf = print_binder_ref(buf, end,
rb_entry(n, struct binder_ref,
rb_node_desc));
}
for (n = rb_first(&proc->allocated_buffers); n != NULL && buf < end; n = rb_next(n))
buf = print_binder_buffer(buf, end, " buffer", rb_entry(n, struct binder_buffer, rb_node));
for (n = rb_first(&proc->allocated_buffers);
n != NULL && buf < end;
n = rb_next(n))
buf = print_binder_buffer(buf, end, " buffer",
rb_entry(n, struct binder_buffer,
rb_node));
list_for_each_entry(w, &proc->todo, entry) {
if (buf >= end)
break;
@ -3213,7 +3287,8 @@ static char *print_binder_proc(char *buf, char *end, struct binder_proc *proc, i
list_for_each_entry(w, &proc->delivered_death, entry) {
if (buf >= end)
break;
buf += snprintf(buf, end - buf, " has delivered dead binder\n");
buf += snprintf(buf, end - buf,
" has delivered dead binder\n");
break;
}
if (!print_all && buf == header_buf)
@ -3272,20 +3347,24 @@ static const char *binder_objstat_strings[] = {
"transaction_complete"
};
static char *print_binder_stats(char *buf, char *end, const char *prefix, struct binder_stats *stats)
static char *print_binder_stats(char *buf, char *end, const char *prefix,
struct binder_stats *stats)
{
int i;
BUILD_BUG_ON(ARRAY_SIZE(stats->bc) != ARRAY_SIZE(binder_command_strings));
BUILD_BUG_ON(ARRAY_SIZE(stats->bc) !=
ARRAY_SIZE(binder_command_strings));
for (i = 0; i < ARRAY_SIZE(stats->bc); i++) {
if (stats->bc[i])
buf += snprintf(buf, end - buf, "%s%s: %d\n", prefix,
binder_command_strings[i], stats->bc[i]);
binder_command_strings[i],
stats->bc[i]);
if (buf >= end)
return buf;
}
BUILD_BUG_ON(ARRAY_SIZE(stats->br) != ARRAY_SIZE(binder_return_strings));
BUILD_BUG_ON(ARRAY_SIZE(stats->br) !=
ARRAY_SIZE(binder_return_strings));
for (i = 0; i < ARRAY_SIZE(stats->br); i++) {
if (stats->br[i])
buf += snprintf(buf, end - buf, "%s%s: %d\n", prefix,
@ -3294,13 +3373,17 @@ static char *print_binder_stats(char *buf, char *end, const char *prefix, struct
return buf;
}
BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != ARRAY_SIZE(binder_objstat_strings));
BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != ARRAY_SIZE(stats->obj_deleted));
BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) !=
ARRAY_SIZE(binder_objstat_strings));
BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) !=
ARRAY_SIZE(stats->obj_deleted));
for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) {
if (stats->obj_created[i] || stats->obj_deleted[i])
buf += snprintf(buf, end - buf, "%s%s: active %d total %d\n", prefix,
buf += snprintf(buf, end - buf,
"%s%s: active %d total %d\n", prefix,
binder_objstat_strings[i],
stats->obj_created[i] - stats->obj_deleted[i],
stats->obj_created[i] -
stats->obj_deleted[i],
stats->obj_created[i]);
if (buf >= end)
return buf;
@ -3308,7 +3391,8 @@ static char *print_binder_stats(char *buf, char *end, const char *prefix, struct
return buf;
}
static char *print_binder_proc_stats(char *buf, char *end, struct binder_proc *proc)
static char *print_binder_proc_stats(char *buf, char *end,
struct binder_proc *proc)
{
struct binder_work *w;
struct rb_node *n;
@ -3340,12 +3424,14 @@ static char *print_binder_proc_stats(char *buf, char *end, struct binder_proc *p
strong = 0;
weak = 0;
for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
struct binder_ref *ref = rb_entry(n, struct binder_ref, rb_node_desc);
struct binder_ref *ref = rb_entry(n, struct binder_ref,
rb_node_desc);
count++;
strong += ref->strong;
weak += ref->weak;
}
buf += snprintf(buf, end - buf, " refs: %d s %d w %d\n", count, strong, weak);
buf += snprintf(buf, end - buf, " refs: %d s %d w %d\n",
count, strong, weak);
if (buf >= end)
return buf;
@ -3376,8 +3462,8 @@ static char *print_binder_proc_stats(char *buf, char *end, struct binder_proc *p
}
static int binder_read_proc_state(
char *page, char **start, off_t off, int count, int *eof, void *data)
static int binder_read_proc_state(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct binder_proc *proc;
struct hlist_node *pos;
@ -3424,8 +3510,8 @@ static int binder_read_proc_state(
return len < count ? len : count;
}
static int binder_read_proc_stats(
char *page, char **start, off_t off, int count, int *eof, void *data)
static int binder_read_proc_stats(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct binder_proc *proc;
struct hlist_node *pos;
@ -3464,8 +3550,8 @@ static int binder_read_proc_stats(
return len < count ? len : count;
}
static int binder_read_proc_transactions(
char *page, char **start, off_t off, int count, int *eof, void *data)
static int binder_read_proc_transactions(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct binder_proc *proc;
struct hlist_node *pos;
@ -3502,8 +3588,8 @@ static int binder_read_proc_transactions(
return len < count ? len : count;
}
static int binder_read_proc_proc(
char *page, char **start, off_t off, int count, int *eof, void *data)
static int binder_read_proc_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct binder_proc *proc = data;
int len = 0;
@ -3533,9 +3619,12 @@ static int binder_read_proc_proc(
return len < count ? len : count;
}
static char *print_binder_transaction_log_entry(char *buf, char *end, struct binder_transaction_log_entry *e)
static char *print_binder_transaction_log_entry(char *buf, char *end,
struct binder_transaction_log_entry *e)
{
buf += snprintf(buf, end - buf, "%d: %s from %d:%d to %d:%d node %d handle %d size %d:%d\n",
buf += snprintf(buf, end - buf,
"%d: %s from %d:%d to %d:%d node %d handle %d "
"size %d:%d\n",
e->debug_id, (e->call_type == 2) ? "reply" :
((e->call_type == 1) ? "async" : "call "), e->from_proc,
e->from_thread, e->to_proc, e->to_thread, e->to_node,
@ -3559,13 +3648,15 @@ static int binder_read_proc_transaction_log(
for (i = log->next; i < ARRAY_SIZE(log->entry); i++) {
if (buf >= end)
break;
buf = print_binder_transaction_log_entry(buf, end, &log->entry[i]);
buf = print_binder_transaction_log_entry(buf, end,
&log->entry[i]);
}
}
for (i = 0; i < log->next; i++) {
if (buf >= end)
break;
buf = print_binder_transaction_log_entry(buf, end, &log->entry[i]);
buf = print_binder_transaction_log_entry(buf, end,
&log->entry[i]);
}
*start = page + off;
@ -3579,7 +3670,7 @@ static int binder_read_proc_transaction_log(
return len < count ? len : count;
}
static struct file_operations binder_fops = {
static const struct file_operations binder_fops = {
.owner = THIS_MODULE,
.poll = binder_poll,
.unlocked_ioctl = binder_ioctl,
@ -3601,14 +3692,35 @@ static int __init binder_init(void)
binder_proc_dir_entry_root = proc_mkdir("binder", NULL);
if (binder_proc_dir_entry_root)
binder_proc_dir_entry_proc = proc_mkdir("proc", binder_proc_dir_entry_root);
binder_proc_dir_entry_proc = proc_mkdir("proc",
binder_proc_dir_entry_root);
ret = misc_register(&binder_miscdev);
if (binder_proc_dir_entry_root) {
create_proc_read_entry("state", S_IRUGO, binder_proc_dir_entry_root, binder_read_proc_state, NULL);
create_proc_read_entry("stats", S_IRUGO, binder_proc_dir_entry_root, binder_read_proc_stats, NULL);
create_proc_read_entry("transactions", S_IRUGO, binder_proc_dir_entry_root, binder_read_proc_transactions, NULL);
create_proc_read_entry("transaction_log", S_IRUGO, binder_proc_dir_entry_root, binder_read_proc_transaction_log, &binder_transaction_log);
create_proc_read_entry("failed_transaction_log", S_IRUGO, binder_proc_dir_entry_root, binder_read_proc_transaction_log, &binder_transaction_log_failed);
create_proc_read_entry("state",
S_IRUGO,
binder_proc_dir_entry_root,
binder_read_proc_state,
NULL);
create_proc_read_entry("stats",
S_IRUGO,
binder_proc_dir_entry_root,
binder_read_proc_stats,
NULL);
create_proc_read_entry("transactions",
S_IRUGO,
binder_proc_dir_entry_root,
binder_read_proc_transactions,
NULL);
create_proc_read_entry("transaction_log",
S_IRUGO,
binder_proc_dir_entry_root,
binder_read_proc_transaction_log,
&binder_transaction_log);
create_proc_read_entry("failed_transaction_log",
S_IRUGO,
binder_proc_dir_entry_root,
binder_read_proc_transaction_log,
&binder_transaction_log_failed);
}
return ret;
}

View file

@ -35,7 +35,7 @@
* mutex 'mutex'.
*/
struct logger_log {
unsigned char * buffer; /* the ring buffer itself */
unsigned char *buffer;/* the ring buffer itself */
struct miscdevice misc; /* misc device representing the log */
wait_queue_head_t wq; /* wait queue for readers */
struct list_head readers; /* this log's readers */
@ -52,7 +52,7 @@ struct logger_log {
* reference counting. The structure is protected by log->mutex.
*/
struct logger_reader {
struct logger_log * log; /* associated log */
struct logger_log *log; /* associated log */
struct list_head list; /* entry in logger_log's list */
size_t r_off; /* current read head offset */
};
@ -74,7 +74,7 @@ struct logger_reader {
* file->logger_log. Thus what file->private_data points at depends on whether
* or not the file was opened for reading. This function hides that dirtiness.
*/
static inline struct logger_log * file_get_log(struct file *file)
static inline struct logger_log *file_get_log(struct file *file)
{
if (file->f_mode & FMODE_READ) {
struct logger_reader *reader = file->private_data;
@ -379,7 +379,7 @@ ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
return ret;
}
static struct logger_log * get_log_from_minor(int);
static struct logger_log *get_log_from_minor(int);
/*
* logger_open - the log's open() file operation
@ -519,7 +519,7 @@ static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return ret;
}
static struct file_operations logger_fops = {
static const struct file_operations logger_fops = {
.owner = THIS_MODULE,
.read = logger_read,
.aio_write = logger_aio_write,
@ -557,7 +557,7 @@ DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024)
DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024)
DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024)
static struct logger_log * get_log_from_minor(int minor)
static struct logger_log *get_log_from_minor(int minor)
{
if (log_main.misc.minor == minor)
return &log_main;

View file

@ -34,18 +34,24 @@ static int lowmem_adj[6] = {
};
static int lowmem_adj_size = 4;
static size_t lowmem_minfree[6] = {
3*512, // 6MB
2*1024, // 8MB
4*1024, // 16MB
16*1024, // 64MB
3 * 512, /* 6MB */
2 * 1024, /* 8MB */
4 * 1024, /* 16MB */
16 * 1024, /* 64MB */
};
static int lowmem_minfree_size = 4;
#define lowmem_print(level, x...) do { if(lowmem_debug_level >= (level)) printk(x); } while(0)
#define lowmem_print(level, x...) \
do { \
if (lowmem_debug_level >= (level)) \
printk(x); \
} while (0)
module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size, S_IRUGO | S_IWUSR);
module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size, S_IRUGO | S_IWUSR);
module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
S_IRUGO | S_IWUSR);
module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
S_IRUGO | S_IWUSR);
module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask)
@ -57,46 +63,77 @@ static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask)
int i;
int min_adj = OOM_ADJUST_MAX + 1;
int selected_tasksize = 0;
int selected_oom_adj;
int array_size = ARRAY_SIZE(lowmem_adj);
int other_free = global_page_state(NR_FREE_PAGES) + global_page_state(NR_FILE_PAGES);
if(lowmem_adj_size < array_size)
int other_free = global_page_state(NR_FREE_PAGES);
int other_file = global_page_state(NR_FILE_PAGES);
if (lowmem_adj_size < array_size)
array_size = lowmem_adj_size;
if(lowmem_minfree_size < array_size)
if (lowmem_minfree_size < array_size)
array_size = lowmem_minfree_size;
for(i = 0; i < array_size; i++) {
if(other_free < lowmem_minfree[i]) {
for (i = 0; i < array_size; i++) {
if (other_free < lowmem_minfree[i] &&
other_file < lowmem_minfree[i]) {
min_adj = lowmem_adj[i];
break;
}
}
if(nr_to_scan > 0)
lowmem_print(3, "lowmem_shrink %d, %x, ofree %d, ma %d\n", nr_to_scan, gfp_mask, other_free, min_adj);
if (nr_to_scan > 0)
lowmem_print(3, "lowmem_shrink %d, %x, ofree %d %d, ma %d\n",
nr_to_scan, gfp_mask, other_free, other_file,
min_adj);
rem = global_page_state(NR_ACTIVE_ANON) +
global_page_state(NR_ACTIVE_FILE) +
global_page_state(NR_INACTIVE_ANON) +
global_page_state(NR_INACTIVE_FILE);
if (nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) {
lowmem_print(5, "lowmem_shrink %d, %x, return %d\n",
nr_to_scan, gfp_mask, rem);
return rem;
}
selected_oom_adj = min_adj;
read_lock(&tasklist_lock);
for_each_process(p) {
if(p->oomkilladj >= 0 && p->mm) {
tasksize = get_mm_rss(p->mm);
if(nr_to_scan > 0 && tasksize > 0 && p->oomkilladj >= min_adj) {
if(selected == NULL ||
p->oomkilladj > selected->oomkilladj ||
(p->oomkilladj == selected->oomkilladj &&
tasksize > selected_tasksize)) {
selected = p;
selected_tasksize = tasksize;
lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n",
p->pid, p->comm, p->oomkilladj, tasksize);
}
}
rem += tasksize;
int oom_adj;
task_lock(p);
if (!p->mm) {
task_unlock(p);
continue;
}
oom_adj = p->oomkilladj;
if (oom_adj < min_adj) {
task_unlock(p);
continue;
}
tasksize = get_mm_rss(p->mm);
task_unlock(p);
if (tasksize <= 0)
continue;
if (selected) {
if (oom_adj < selected_oom_adj)
continue;
if (oom_adj == selected_oom_adj &&
tasksize <= selected_tasksize)
continue;
}
selected = p;
selected_tasksize = tasksize;
selected_oom_adj = oom_adj;
lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n",
p->pid, p->comm, oom_adj, tasksize);
}
if(selected != NULL) {
if (selected) {
lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n",
selected->pid, selected->comm,
selected->oomkilladj, selected_tasksize);
selected->pid, selected->comm,
selected_oom_adj, selected_tasksize);
force_sig(SIGKILL, selected);
rem -= selected_tasksize;
}
lowmem_print(4, "lowmem_shrink %d, %x, return %d\n", nr_to_scan, gfp_mask, rem);
lowmem_print(4, "lowmem_shrink %d, %x, return %d\n",
nr_to_scan, gfp_mask, rem);
read_unlock(&tasklist_lock);
return rem;
}

View file

@ -20,7 +20,7 @@
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <asm/io.h>
#include <linux/io.h>
#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
#include <linux/rslib.h>
@ -225,8 +225,9 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
buffer_size - sizeof(struct ram_console_buffer);
if (ram_console_buffer_size > buffer_size) {
pr_err("ram_console: buffer %p, invalid size %zu, datasize %zu\n",
buffer, buffer_size, ram_console_buffer_size);
pr_err("ram_console: buffer %p, invalid size %zu, "
"datasize %zu\n", buffer, buffer_size,
ram_console_buffer_size);
return 0;
}
@ -365,7 +366,7 @@ static ssize_t ram_console_read_old(struct file *file, char __user *buf,
return count;
}
static struct file_operations ram_console_file_ops = {
static const struct file_operations ram_console_file_ops = {
.owner = THIS_MODULE,
.read = ram_console_read_old,
};

View file

@ -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 platform_device *pdev)
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 platform_device *pdev)
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_driver = {
.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);
}

View file

@ -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;
};

View file

@ -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");

View file

@ -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

Some files were not shown because too many files have changed in this diff Show more