Commit 092f4c56 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'akpm' (Andrew's incoming - part two)

Says Andrew:

 "60 patches.  That's good enough for -rc1 I guess.  I have quite a lot
  of detritus to be rechecked, work through maintainers, etc.

 - most of the remains of MM
 - rtc
 - various misc
 - cgroups
 - memcg
 - cpusets
 - procfs
 - ipc
 - rapidio
 - sysctl
 - pps
 - w1
 - drivers/misc
 - aio"

* akpm: (60 commits)
  memcg: replace ss->id_lock with a rwlock
  aio: allocate kiocbs in batches
  drivers/misc/vmw_balloon.c: fix typo in code comment
  drivers/misc/vmw_balloon.c: determine page allocation flag can_sleep outside loop
  w1: disable irqs in critical section
  drivers/w1/w1_int.c: multiple masters used same init_name
  drivers/power/ds2780_battery.c: fix deadlock upon insertion and removal
  drivers/power/ds2780_battery.c: add a nolock function to w1 interface
  drivers/power/ds2780_battery.c: create central point for calling w1 interface
  w1: ds2760 and ds2780, use ida for id and ida_simple_get() to get it
  pps gpio client: add missing dependency
  pps: new client driver using GPIO
  pps: default echo function
  include/linux/dma-mapping.h: add dma_zalloc_coherent()
  sysctl: make CONFIG_SYSCTL_SYSCALL default to n
  sysctl: add support for poll()
  RapidIO: documentation update
  drivers/net/rionet.c: fix ethernet address macros for LE platforms
  RapidIO: fix potential null deref in rio_setup_device()
  RapidIO: add mport driver for Tsi721 bridge
  ...
parents 80c28616 c1e2ee2d
...@@ -50,6 +50,13 @@ specify the GFP_ flags (see kmalloc) for the allocation (the ...@@ -50,6 +50,13 @@ specify the GFP_ flags (see kmalloc) for the allocation (the
implementation may choose to ignore flags that affect the location of implementation may choose to ignore flags that affect the location of
the returned memory, like GFP_DMA). the returned memory, like GFP_DMA).
void *
dma_zalloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
Wraps dma_alloc_coherent() and also zeroes the returned memory if the
allocation attempt succeeded.
void void
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_handle) dma_addr_t dma_handle)
......
...@@ -418,7 +418,6 @@ total_unevictable - sum of all children's "unevictable" ...@@ -418,7 +418,6 @@ total_unevictable - sum of all children's "unevictable"
# The following additional stats are dependent on CONFIG_DEBUG_VM. # The following additional stats are dependent on CONFIG_DEBUG_VM.
inactive_ratio - VM internal parameter. (see mm/page_alloc.c)
recent_rotated_anon - VM internal parameter. (see mm/vmscan.c) recent_rotated_anon - VM internal parameter. (see mm/vmscan.c)
recent_rotated_file - VM internal parameter. (see mm/vmscan.c) recent_rotated_file - VM internal parameter. (see mm/vmscan.c)
recent_scanned_anon - VM internal parameter. (see mm/vmscan.c) recent_scanned_anon - VM internal parameter. (see mm/vmscan.c)
......
...@@ -133,41 +133,6 @@ Who: Pavel Machek <pavel@ucw.cz> ...@@ -133,41 +133,6 @@ Who: Pavel Machek <pavel@ucw.cz>
--------------------------- ---------------------------
What: sys_sysctl
When: September 2010
Option: CONFIG_SYSCTL_SYSCALL
Why: The same information is available in a more convenient from
/proc/sys, and none of the sysctl variables appear to be
important performance wise.
Binary sysctls are a long standing source of subtle kernel
bugs and security issues.
When I looked several months ago all I could find after
searching several distributions were 5 user space programs and
glibc (which falls back to /proc/sys) using this syscall.
The man page for sysctl(2) documents it as unusable for user
space programs.
sysctl(2) is not generally ABI compatible to a 32bit user
space application on a 64bit and a 32bit kernel.
For the last several months the policy has been no new binary
sysctls and no one has put forward an argument to use them.
Binary sysctls issues seem to keep happening appearing so
properly deprecating them (with a warning to user space) and a
2 year grace warning period will mean eventually we can kill
them and end the pain.
In the mean time individual binary sysctls can be dealt with
in a piecewise fashion.
Who: Eric Biederman <ebiederm@xmission.com>
---------------------------
What: /proc/<pid>/oom_adj What: /proc/<pid>/oom_adj
When: August 2012 When: August 2012
Why: /proc/<pid>/oom_adj allows userspace to influence the oom killer's Why: /proc/<pid>/oom_adj allows userspace to influence the oom killer's
......
...@@ -144,7 +144,7 @@ and the default device ID in order to access the device on the active port. ...@@ -144,7 +144,7 @@ and the default device ID in order to access the device on the active port.
After the host has completed enumeration of the entire network it releases After the host has completed enumeration of the entire network it releases
devices by clearing device ID locks (calls rio_clear_locks()). For each endpoint devices by clearing device ID locks (calls rio_clear_locks()). For each endpoint
in the system, it sets the Master Enable bit in the Port General Control CSR in the system, it sets the Discovered bit in the Port General Control CSR
to indicate that enumeration is completed and agents are allowed to execute to indicate that enumeration is completed and agents are allowed to execute
passive discovery of the network. passive discovery of the network.
......
RapidIO subsystem mport driver for IDT Tsi721 PCI Express-to-SRIO bridge.
=========================================================================
I. Overview
This driver implements all currently defined RapidIO mport callback functions.
It supports maintenance read and write operations, inbound and outbound RapidIO
doorbells, inbound maintenance port-writes and RapidIO messaging.
To generate SRIO maintenance transactions this driver uses one of Tsi721 DMA
channels. This mechanism provides access to larger range of hop counts and
destination IDs without need for changes in outbound window translation.
RapidIO messaging support uses dedicated messaging channels for each mailbox.
For inbound messages this driver uses destination ID matching to forward messages
into the corresponding message queue. Messaging callbacks are implemented to be
fully compatible with RIONET driver (Ethernet over RapidIO messaging services).
II. Known problems
None.
III. To do
Add DMA data transfers (non-messaging).
Add inbound region (SRIO-to-PCIe) mapping.
IV. Version History
1.0.0 - Initial driver release.
V. License
-----------------------------------------------
Copyright(c) 2011 Integrated Device Technology, Inc. All rights reserved.
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.
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.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
...@@ -16,16 +16,6 @@ ...@@ -16,16 +16,6 @@
#ifdef __HAVE_ARCH_PTE_SPECIAL #ifdef __HAVE_ARCH_PTE_SPECIAL
static inline void get_huge_page_tail(struct page *page)
{
/*
* __split_huge_page_refcount() cannot run
* from under us.
*/
VM_BUG_ON(atomic_read(&page->_count) < 0);
atomic_inc(&page->_count);
}
/* /*
* The performance critical leaf functions are made noinline otherwise gcc * The performance critical leaf functions are made noinline otherwise gcc
* inlines everything into a single function which results in too much * inlines everything into a single function which results in too much
...@@ -57,8 +47,6 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, ...@@ -57,8 +47,6 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
put_page(page); put_page(page);
return 0; return 0;
} }
if (PageTail(page))
get_huge_page_tail(page);
pages[*nr] = page; pages[*nr] = page;
(*nr)++; (*nr)++;
......
...@@ -390,7 +390,7 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add ...@@ -390,7 +390,7 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add
{ {
unsigned long mask; unsigned long mask;
unsigned long pte_end; unsigned long pte_end;
struct page *head, *page; struct page *head, *page, *tail;
pte_t pte; pte_t pte;
int refs; int refs;
...@@ -413,6 +413,7 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add ...@@ -413,6 +413,7 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add
head = pte_page(pte); head = pte_page(pte);
page = head + ((addr & (sz-1)) >> PAGE_SHIFT); page = head + ((addr & (sz-1)) >> PAGE_SHIFT);
tail = page;
do { do {
VM_BUG_ON(compound_head(page) != head); VM_BUG_ON(compound_head(page) != head);
pages[*nr] = page; pages[*nr] = page;
...@@ -428,10 +429,20 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add ...@@ -428,10 +429,20 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add
if (unlikely(pte_val(pte) != pte_val(*ptep))) { if (unlikely(pte_val(pte) != pte_val(*ptep))) {
/* Could be optimized better */ /* Could be optimized better */
while (*nr) { *nr -= refs;
put_page(page); while (refs--)
(*nr)--; put_page(head);
} return 0;
}
/*
* Any tail page need their mapcount reference taken before we
* return.
*/
while (refs--) {
if (PageTail(tail))
get_huge_page_tail(tail);
tail++;
} }
return 1; return 1;
......
...@@ -1608,6 +1608,7 @@ int fsl_rio_setup(struct platform_device *dev) ...@@ -1608,6 +1608,7 @@ int fsl_rio_setup(struct platform_device *dev)
return 0; return 0;
err: err:
iounmap(priv->regs_win); iounmap(priv->regs_win);
release_resource(&port->iores);
err_res: err_res:
kfree(priv); kfree(priv);
err_priv: err_priv:
......
...@@ -52,7 +52,7 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, ...@@ -52,7 +52,7 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr) unsigned long end, int write, struct page **pages, int *nr)
{ {
unsigned long mask, result; unsigned long mask, result;
struct page *head, *page; struct page *head, *page, *tail;
int refs; int refs;
result = write ? 0 : _SEGMENT_ENTRY_RO; result = write ? 0 : _SEGMENT_ENTRY_RO;
...@@ -64,6 +64,7 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, ...@@ -64,6 +64,7 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
refs = 0; refs = 0;
head = pmd_page(pmd); head = pmd_page(pmd);
page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT); page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
tail = page;
do { do {
VM_BUG_ON(compound_head(page) != head); VM_BUG_ON(compound_head(page) != head);
pages[*nr] = page; pages[*nr] = page;
...@@ -81,6 +82,17 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, ...@@ -81,6 +82,17 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
*nr -= refs; *nr -= refs;
while (refs--) while (refs--)
put_page(head); put_page(head);
return 0;
}
/*
* Any tail page need their mapcount reference taken before we
* return.
*/
while (refs--) {
if (PageTail(tail))
get_huge_page_tail(tail);
tail++;
} }
return 1; return 1;
......
...@@ -56,6 +56,8 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, ...@@ -56,6 +56,8 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
put_page(head); put_page(head);
return 0; return 0;
} }
if (head != page)
get_huge_page_tail(page);
pages[*nr] = page; pages[*nr] = page;
(*nr)++; (*nr)++;
......
...@@ -108,16 +108,6 @@ static inline void get_head_page_multiple(struct page *page, int nr) ...@@ -108,16 +108,6 @@ static inline void get_head_page_multiple(struct page *page, int nr)
SetPageReferenced(page); SetPageReferenced(page);
} }
static inline void get_huge_page_tail(struct page *page)
{
/*
* __split_huge_page_refcount() cannot run
* from under us.
*/
VM_BUG_ON(atomic_read(&page->_count) < 0);
atomic_inc(&page->_count);
}
static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr) unsigned long end, int write, struct page **pages, int *nr)
{ {
......
...@@ -151,7 +151,7 @@ MODULE_LICENSE("GPL"); ...@@ -151,7 +151,7 @@ MODULE_LICENSE("GPL");
struct vmballoon_stats { struct vmballoon_stats {
unsigned int timer; unsigned int timer;
/* allocation statustics */ /* allocation statistics */
unsigned int alloc; unsigned int alloc;
unsigned int alloc_fail; unsigned int alloc_fail;
unsigned int sleep_alloc; unsigned int sleep_alloc;
...@@ -412,6 +412,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep) ...@@ -412,6 +412,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
gfp_t flags; gfp_t flags;
unsigned int hv_status; unsigned int hv_status;
bool locked = false; bool locked = false;
flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
do { do {
if (!can_sleep) if (!can_sleep)
...@@ -419,7 +420,6 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep) ...@@ -419,7 +420,6 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
else else
STATS_INC(b->stats.sleep_alloc); STATS_INC(b->stats.sleep_alloc);
flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
page = alloc_page(flags); page = alloc_page(flags);
if (!page) { if (!page) {
if (!can_sleep) if (!can_sleep)
......
...@@ -88,8 +88,8 @@ static struct rio_dev **rionet_active; ...@@ -88,8 +88,8 @@ static struct rio_dev **rionet_active;
#define dev_rionet_capable(dev) \ #define dev_rionet_capable(dev) \
is_rionet_capable(dev->src_ops, dev->dst_ops) is_rionet_capable(dev->src_ops, dev->dst_ops)
#define RIONET_MAC_MATCH(x) (*(u32 *)x == 0x00010001) #define RIONET_MAC_MATCH(x) (!memcmp((x), "\00\01\00\01", 4))
#define RIONET_GET_DESTID(x) (*(u16 *)(x + 4)) #define RIONET_GET_DESTID(x) ((*((u8 *)x + 4) << 8) | *((u8 *)x + 5))
static int rionet_rx_clean(struct net_device *ndev) static int rionet_rx_clean(struct net_device *ndev)
{ {
......
...@@ -39,6 +39,7 @@ struct ds2780_device_info { ...@@ -39,6 +39,7 @@ struct ds2780_device_info {
struct device *dev; struct device *dev;
struct power_supply bat; struct power_supply bat;
struct device *w1_dev; struct device *w1_dev;
struct task_struct *mutex_holder;
}; };
enum current_types { enum current_types {
...@@ -49,8 +50,8 @@ enum current_types { ...@@ -49,8 +50,8 @@ enum current_types {
static const char model[] = "DS2780"; static const char model[] = "DS2780";
static const char manufacturer[] = "Maxim/Dallas"; static const char manufacturer[] = "Maxim/Dallas";
static inline struct ds2780_device_info *to_ds2780_device_info( static inline struct ds2780_device_info *
struct power_supply *psy) to_ds2780_device_info(struct power_supply *psy)
{ {
return container_of(psy, struct ds2780_device_info, bat); return container_of(psy, struct ds2780_device_info, bat);
} }
...@@ -60,17 +61,28 @@ static inline struct power_supply *to_power_supply(struct device *dev) ...@@ -60,17 +61,28 @@ static inline struct power_supply *to_power_supply(struct device *dev)
return dev_get_drvdata(dev); return dev_get_drvdata(dev);
} }
static inline int ds2780_read8(struct device *dev, u8 *val, int addr) static inline int ds2780_battery_io(struct ds2780_device_info *dev_info,
char *buf, int addr, size_t count, int io)
{ {
return w1_ds2780_io(dev, val, addr, sizeof(u8), 0); if (dev_info->mutex_holder == current)
return w1_ds2780_io_nolock(dev_info->w1_dev, buf, addr, count, io);
else
return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io);
}
static inline int ds2780_read8(struct ds2780_device_info *dev_info, u8 *val,
int addr)
{
return ds2780_battery_io(dev_info, val, addr, sizeof(u8), 0);
} }
static int ds2780_read16(struct device *dev, s16 *val, int addr) static int ds2780_read16(struct ds2780_device_info *dev_info, s16 *val,
int addr)
{ {
int ret; int ret;
u8 raw[2]; u8 raw[2];
ret = w1_ds2780_io(dev, raw, addr, sizeof(u8) * 2, 0); ret = ds2780_battery_io(dev_info, raw, addr, sizeof(raw), 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -79,16 +91,16 @@ static int ds2780_read16(struct device *dev, s16 *val, int addr) ...@@ -79,16 +91,16 @@ static int ds2780_read16(struct device *dev, s16 *val, int addr)
return 0; return 0;
} }
static inline int ds2780_read_block(struct device *dev, u8 *val, int addr, static inline int ds2780_read_block(struct ds2780_device_info *dev_info,
size_t count) u8 *val, int addr, size_t count)
{ {
return w1_ds2780_io(dev, val, addr, count, 0); return ds2780_battery_io(dev_info, val, addr, count, 0);
} }
static inline int ds2780_write(struct device *dev, u8 *val, int addr, static inline int ds2780_write(struct ds2780_device_info *dev_info, u8 *val,
size_t count) int addr, size_t count)
{ {
return w1_ds2780_io(dev, val, addr, count, 1); return ds2780_battery_io(dev_info, val, addr, count, 1);
} }
static inline int ds2780_store_eeprom(struct device *dev, int addr) static inline int ds2780_store_eeprom(struct device *dev, int addr)
...@@ -122,7 +134,7 @@ static int ds2780_set_sense_register(struct ds2780_device_info *dev_info, ...@@ -122,7 +134,7 @@ static int ds2780_set_sense_register(struct ds2780_device_info *dev_info,
{ {
int ret; int ret;
ret = ds2780_write(dev_info->w1_dev, &conductance, ret = ds2780_write(dev_info, &conductance,
DS2780_RSNSP_REG, sizeof(u8)); DS2780_RSNSP_REG, sizeof(u8));
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -134,7 +146,7 @@ static int ds2780_set_sense_register(struct ds2780_device_info *dev_info, ...@@ -134,7 +146,7 @@ static int ds2780_set_sense_register(struct ds2780_device_info *dev_info,
static int ds2780_get_rsgain_register(struct ds2780_device_info *dev_info, static int ds2780_get_rsgain_register(struct ds2780_device_info *dev_info,
u16 *rsgain) u16 *rsgain)
{ {
return ds2780_read16(dev_info->w1_dev, rsgain, DS2780_RSGAIN_MSB_REG); return ds2780_read16(dev_info, rsgain, DS2780_RSGAIN_MSB_REG);
} }
/* Set RSGAIN value from 0 to 1.999 in steps of 0.001 */ /* Set RSGAIN value from 0 to 1.999 in steps of 0.001 */
...@@ -144,8 +156,8 @@ static int ds2780_set_rsgain_register(struct ds2780_device_info *dev_info, ...@@ -144,8 +156,8 @@ static int ds2780_set_rsgain_register(struct ds2780_device_info *dev_info,
int ret; int ret;
u8 raw[] = {rsgain >> 8, rsgain & 0xFF}; u8 raw[] = {rsgain >> 8, rsgain & 0xFF};
ret = ds2780_write(dev_info->w1_dev, raw, ret = ds2780_write(dev_info, raw,
DS2780_RSGAIN_MSB_REG, sizeof(u8) * 2); DS2780_RSGAIN_MSB_REG, sizeof(raw));
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -167,7 +179,7 @@ static int ds2780_get_voltage(struct ds2780_device_info *dev_info, ...@@ -167,7 +179,7 @@ static int ds2780_get_voltage(struct ds2780_device_info *dev_info,
* Bits 2 - 0 of the voltage value are in bits 7 - 5 of the * Bits 2 - 0 of the voltage value are in bits 7 - 5 of the
* voltage LSB register * voltage LSB register
*/ */
ret = ds2780_read16(dev_info->w1_dev, &voltage_raw, ret = ds2780_read16(dev_info, &voltage_raw,
DS2780_VOLT_MSB_REG); DS2780_VOLT_MSB_REG);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -196,7 +208,7 @@ static int ds2780_get_temperature(struct ds2780_device_info *dev_info, ...@@ -196,7 +208,7 @@ static int ds2780_get_temperature(struct ds2780_device_info *dev_info,
* Bits 2 - 0 of the temperature value are in bits 7 - 5 of the * Bits 2 - 0 of the temperature value are in bits 7 - 5 of the
* temperature LSB register * temperature LSB register
*/ */
ret = ds2780_read16(dev_info->w1_dev, &temperature_raw, ret = ds2780_read16(dev_info, &temperature_raw,
DS2780_TEMP_MSB_REG); DS2780_TEMP_MSB_REG);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -222,13 +234,13 @@ static int ds2780_get_current(struct ds2780_device_info *dev_info, ...@@ -222,13 +234,13 @@ static int ds2780_get_current(struct ds2780_device_info *dev_info,
* The units of measurement for current are dependent on the value of * The units of measurement for current are dependent on the value of
* the sense resistor. * the sense resistor.
*/ */
ret = ds2780_read8(dev_info->w1_dev, &sense_res_raw, DS2780_RSNSP_REG); ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (sense_res_raw == 0) { if (sense_res_raw == 0) {
dev_err(dev_info->dev, "sense resistor value is 0\n"); dev_err(dev_info->dev, "sense resistor value is 0\n");
return -ENXIO; return -EINVAL;
} }
sense_res = 1000 / sense_res_raw; sense_res = 1000 / sense_res_raw;
...@@ -248,7 +260,7 @@ static int ds2780_get_current(struct ds2780_device_info *dev_info, ...@@ -248,7 +260,7 @@ static int ds2780_get_current(struct ds2780_device_info *dev_info,
* Bits 7 - 0 of the current value are in bits 7 - 0 of the current * Bits 7 - 0 of the current value are in bits 7 - 0 of the current
* LSB register * LSB register
*/ */
ret = ds2780_read16(dev_info->w1_dev, &current_raw, reg_msb); ret = ds2780_read16(dev_info, &current_raw, reg_msb);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -267,7 +279,7 @@ static int ds2780_get_accumulated_current(struct ds2780_device_info *dev_info, ...@@ -267,7 +279,7 @@ static int ds2780_get_accumulated_current(struct ds2780_device_info *dev_info,
* The units of measurement for accumulated current are dependent on * The units of measurement for accumulated current are dependent on
* the value of the sense resistor. * the value of the sense resistor.
*/ */
ret = ds2780_read8(dev_info->w1_dev, &sense_res_raw, DS2780_RSNSP_REG); ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -285,7 +297,7 @@ static int ds2780_get_accumulated_current(struct ds2780_device_info *dev_info, ...@@ -285,7 +297,7 @@ static int ds2780_get_accumulated_current(struct ds2780_device_info *dev_info,
* Bits 7 - 0 of the ACR value are in bits 7 - 0 of the ACR * Bits 7 - 0 of the ACR value are in bits 7 - 0 of the ACR
* LSB register * LSB register
*/ */
ret = ds2780_read16(dev_info->w1_dev, &current_raw, DS2780_ACR_MSB_REG); ret = ds2780_read16(dev_info, &current_raw, DS2780_ACR_MSB_REG);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -299,7 +311,7 @@ static int ds2780_get_capacity(struct ds2780_device_info *dev_info, ...@@ -299,7 +311,7 @@ static int ds2780_get_capacity(struct ds2780_device_info *dev_info,
int ret; int ret;
u8 raw; u8 raw;
ret = ds2780_read8(dev_info->w1_dev, &raw, DS2780_RARC_REG); ret = ds2780_read8(dev_info, &raw, DS2780_RARC_REG);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -345,7 +357,7 @@ static int ds2780_get_charge_now(struct ds2780_device_info *dev_info, ...@@ -345,7 +357,7 @@ static int ds2780_get_charge_now(struct ds2780_device_info *dev_info,
* Bits 7 - 0 of the RAAC value are in bits 7 - 0 of the RAAC * Bits 7 - 0 of the RAAC value are in bits 7 - 0 of the RAAC
* LSB register * LSB register
*/ */
ret = ds2780_read16(dev_info->w1_dev, &charge_raw, DS2780_RAAC_MSB_REG); ret = ds2780_read16(dev_info, &charge_raw, DS2780_RAAC_MSB_REG);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -356,7 +368,7 @@ static int ds2780_get_charge_now(struct ds2780_device_info *dev_info, ...@@ -356,7 +368,7 @@ static int ds2780_get_charge_now(struct ds2780_device_info *dev_info,
static int ds2780_get_control_register(struct ds2780_device_info *dev_info, static int ds2780_get_control_register(struct ds2780_device_info *dev_info,
u8 *control_reg) u8 *control_reg)
{ {
return ds2780_read8(dev_info->w1_dev, control_reg, DS2780_CONTROL_REG); return ds2780_read8(dev_info, control_reg, DS2780_CONTROL_REG);
} }
static int ds2780_set_control_register(struct ds2780_device_info *dev_info, static int ds2780_set_control_register(struct ds2780_device_info *dev_info,
...@@ -364,7 +376,7 @@ static int ds2780_set_control_register(struct ds2780_device_info *dev_info, ...@@ -364,7 +376,7 @@ static int ds2780_set_control_register(struct ds2780_device_info *dev_info,
{ {
int ret; int ret;
ret = ds2780_write(dev_info->w1_dev, &control_reg, ret = ds2780_write(dev_info, &control_reg,
DS2780_CONTROL_REG, sizeof(u8)); DS2780_CONTROL_REG, sizeof(u8));
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -503,7 +515,7 @@ static ssize_t ds2780_get_sense_resistor_value(struct device *dev, ...@@ -503,7 +515,7 @@ static ssize_t ds2780_get_sense_resistor_value(struct device *dev,
struct power_supply *psy = to_power_supply(dev); struct power_supply *psy = to_power_supply(dev);
struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
ret = ds2780_read8(dev_info->w1_dev, &sense_resistor, DS2780_RSNSP_REG); ret = ds2780_read8(dev_info, &sense_resistor, DS2780_RSNSP_REG);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -584,7 +596,7 @@ static ssize_t ds2780_get_pio_pin(struct device *dev, ...@@ -584,7 +596,7 @@ static ssize_t ds2780_get_pio_pin(struct device *dev,
struct power_supply *psy = to_power_supply(dev); struct power_supply *psy = to_power_supply(dev);
struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
ret = ds2780_read8(dev_info->w1_dev, &sfr, DS2780_SFR_REG); ret = ds2780_read8(dev_info, &sfr, DS2780_SFR_REG);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -611,7 +623,7 @@ static ssize_t ds2780_set_pio_pin(struct device *dev, ...@@ -611,7 +623,7 @@ static ssize_t ds2780_set_pio_pin(struct device *dev,
return -EINVAL; return -EINVAL;
} }
ret = ds2780_write(dev_info->w1_dev, &new_setting, ret = ds2780_write(dev_info, &new_setting,
DS2780_SFR_REG, sizeof(u8)); DS2780_SFR_REG, sizeof(u8));
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -632,7 +644,7 @@ static ssize_t ds2780_read_param_eeprom_bin(struct file *filp, ...@@ -632,7 +644,7 @@ static ssize_t ds2780_read_param_eeprom_bin(struct file *filp,
DS2780_EEPROM_BLOCK1_END - DS2780_EEPROM_BLOCK1_END -
DS2780_EEPROM_BLOCK1_START + 1 - off); DS2780_EEPROM_BLOCK1_START + 1 - off);
return ds2780_read_block(dev_info->w1_dev, buf, return ds2780_read_block(dev_info, buf,
DS2780_EEPROM_BLOCK1_START + off, count); DS2780_EEPROM_BLOCK1_START + off, count);
} }
...@@ -650,7 +662,7 @@ static ssize_t ds2780_write_param_eeprom_bin(struct file *filp, ...@@ -650,7 +662,7 @@ static ssize_t ds2780_write_param_eeprom_bin(struct file *filp,
DS2780_EEPROM_BLOCK1_END - DS2780_EEPROM_BLOCK1_END -
DS2780_EEPROM_BLOCK1_START + 1 - off); DS2780_EEPROM_BLOCK1_START + 1 - off);
ret = ds2780_write(dev_info->w1_dev, buf, ret = ds2780_write(dev_info, buf,
DS2780_EEPROM_BLOCK1_START + off, count); DS2780_EEPROM_BLOCK1_START + off, count);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -685,9 +697,8 @@ static ssize_t ds2780_read_user_eeprom_bin(struct file *filp, ...@@ -685,9 +697,8 @@ static ssize_t ds2780_read_user_eeprom_bin(struct file *filp,
DS2780_EEPROM_BLOCK0_END - DS2780_EEPROM_BLOCK0_END -
DS2780_EEPROM_BLOCK0_START + 1 - off); DS2780_EEPROM_BLOCK0_START + 1 - off);
return ds2780_read_block(dev_info->w1_dev, buf, return ds2780_read_block(dev_info, buf,
DS2780_EEPROM_BLOCK0_START + off, count); DS2780_EEPROM_BLOCK0_START + off, count);
} }
static ssize_t ds2780_write_user_eeprom_bin(struct file *filp, static ssize_t ds2780_write_user_eeprom_bin(struct file *filp,
...@@ -704,7 +715,7 @@ static ssize_t ds2780_write_user_eeprom_bin(struct file *filp, ...@@ -704,7 +715,7 @@ static ssize_t ds2780_write_user_eeprom_bin(struct file *filp,
DS2780_EEPROM_BLOCK0_END - DS2780_EEPROM_BLOCK0_END -
DS2780_EEPROM_BLOCK0_START + 1 - off); DS2780_EEPROM_BLOCK0_START + 1 - off);
ret = ds2780_write(dev_info->w1_dev, buf, ret = ds2780_write(dev_info, buf,
DS2780_EEPROM_BLOCK0_START + off, count); DS2780_EEPROM_BLOCK0_START + off, count);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -768,6 +779,7 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev) ...@@ -768,6 +779,7 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev)
dev_info->bat.properties = ds2780_battery_props; dev_info->bat.properties = ds2780_battery_props;
dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props); dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props);
dev_info->bat.get_property = ds2780_battery_get_property; dev_info->bat.get_property = ds2780_battery_get_property;
dev_info->mutex_holder = current;
ret = power_supply_register(&pdev->dev, &dev_info->bat); ret = power_supply_register(&pdev->dev, &dev_info->bat);
if (ret) { if (ret) {
...@@ -797,6 +809,8 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev) ...@@ -797,6 +809,8 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev)
goto fail_remove_bin_file; goto fail_remove_bin_file;
} }
dev_info->mutex_holder = NULL;
return 0; return 0;
fail_remove_bin_file: fail_remove_bin_file:
...@@ -816,6 +830,8 @@ static int __devexit ds2780_battery_remove(struct platform_device *pdev) ...@@ -816,6 +830,8 @@ static int __devexit ds2780_battery_remove(struct platform_device *pdev)
{ {
struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); struct ds2780_device_info *dev_info = platform_get_drvdata(pdev);
dev_info->mutex_holder = current;
/* remove attributes */ /* remove attributes */
sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);
......
...@@ -29,4 +29,13 @@ config PPS_CLIENT_PARPORT ...@@ -29,4 +29,13 @@ config PPS_CLIENT_PARPORT
If you say yes here you get support for a PPS source connected If you say yes here you get support for a PPS source connected
with the interrupt pin of your parallel port. with the interrupt pin of your parallel port.
config PPS_CLIENT_GPIO
tristate "PPS client using GPIO"
depends on PPS && GENERIC_HARDIRQS
help
If you say yes here you get support for a PPS source using
GPIO. To be useful you must also register a platform device
specifying the GPIO pin and other options, usually in your board
setup.
endif endif
...@@ -5,5 +5,6 @@ ...@@ -5,5 +5,6 @@
obj-$(CONFIG_PPS_CLIENT_KTIMER) += pps-ktimer.o obj-$(CONFIG_PPS_CLIENT_KTIMER) += pps-ktimer.o
obj-$(CONFIG_PPS_CLIENT_LDISC) += pps-ldisc.o obj-$(CONFIG_PPS_CLIENT_LDISC) += pps-ldisc.o
obj-$(CONFIG_PPS_CLIENT_PARPORT) += pps_parport.o obj-$(CONFIG_PPS_CLIENT_PARPORT) += pps_parport.o
obj-$(CONFIG_PPS_CLIENT_GPIO) += pps-gpio.o
ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG
/*
* pps-gpio.c -- PPS client driver using GPIO
*
*
* Copyright (C) 2010 Ricardo Martins <rasm@fe.up.pt>
* Copyright (C) 2011 James Nuss <jamesnuss@nanometrics.ca>
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define PPS_GPIO_NAME "pps-gpio"
#define pr_fmt(fmt) PPS_GPIO_NAME ": " fmt
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/pps_kernel.h>
#include <linux/pps-gpio.h>
#include <linux/gpio.h>
#include <linux/list.h>
/* Info for each registered platform device */
struct pps_gpio_device_data {
int irq; /* IRQ used as PPS source */
struct pps_device *pps; /* PPS source device */
struct pps_source_info info; /* PPS source information */
const struct pps_gpio_platform_data *pdata;
};
/*
* Report the PPS event
*/
static irqreturn_t pps_gpio_irq_handler(int irq, void *data)
{
const struct pps_gpio_device_data *info;
struct pps_event_time ts;
int rising_edge;
/* Get the time stamp first */
pps_get_ts(&ts);
info = data;
rising_edge = gpio_get_value(info->pdata->gpio_pin);
if ((rising_edge && !info->pdata->assert_falling_edge) ||
(!rising_edge && info->pdata->assert_falling_edge))
pps_event(info->pps, &ts, PPS_CAPTUREASSERT, NULL);
else if (info->pdata->capture_clear &&
((rising_edge && info->pdata->assert_falling_edge) ||
(!rising_edge && !info->pdata->assert_falling_edge)))
pps_event(info->pps, &ts, PPS_CAPTURECLEAR, NULL);
return IRQ_HANDLED;
}
static int pps_gpio_setup(struct platform_device *pdev)
{
int ret;
const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data;
ret = gpio_request(pdata->gpio_pin, pdata->gpio_label);
if (ret) {
pr_warning("failed to request GPIO %u\n", pdata->gpio_pin);
return -EINVAL;
}
ret = gpio_direction_input(pdata->gpio_pin);
if (ret) {
pr_warning("failed to set pin direction\n");
gpio_free(pdata->gpio_pin);
return -EINVAL;
}
return 0;
}
static unsigned long
get_irqf_trigger_flags(const struct pps_gpio_platform_data *pdata)
{
unsigned long flags = pdata->assert_falling_edge ?
IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
if (pdata->capture_clear) {
flags |= ((flags & IRQF_TRIGGER_RISING) ?
IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING);
}
return flags;
}
static int pps_gpio_probe(struct platform_device *pdev)
{
struct pps_gpio_device_data *data;
int irq;
int ret;
int err;
int pps_default_params;
const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data;
/* GPIO setup */
ret = pps_gpio_setup(pdev);
if (ret)
return -EINVAL;
/* IRQ setup */
irq = gpio_to_irq(pdata->gpio_pin);
if (irq < 0) {
pr_err("failed to map GPIO to IRQ: %d\n", irq);
err = -EINVAL;
goto return_error;
}
/* allocate space for device info */
data = kzalloc(sizeof(struct pps_gpio_device_data), GFP_KERNEL);
if (data == NULL) {
err = -ENOMEM;
goto return_error;
}
/* initialize PPS specific parts of the bookkeeping data structure. */
data->info.mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT |
PPS_ECHOASSERT | PPS_CANWAIT | PPS_TSFMT_TSPEC;
if (pdata->capture_clear)
data->info.mode |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR |
PPS_ECHOCLEAR;
data->info.owner = THIS_MODULE;
snprintf(data->info.name, PPS_MAX_NAME_LEN - 1, "%s.%d",
pdev->name, pdev->id);
/* register PPS source */
pps_default_params = PPS_CAPTUREASSERT | PPS_OFFSETASSERT;
if (pdata->capture_clear)
pps_default_params |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR;
data->pps = pps_register_source(&data->info, pps_default_params);
if (data->pps == NULL) {
kfree(data);
pr_err("failed to register IRQ %d as PPS source\n", irq);
err = -EINVAL;
goto return_error;
}
data->irq = irq;
data->pdata = pdata;
/* register IRQ interrupt handler */
ret = request_irq(irq, pps_gpio_irq_handler,
get_irqf_trigger_flags(pdata), data->info.name, data);
if (ret) {
pps_unregister_source(data->pps);
kfree(data);
pr_err("failed to acquire IRQ %d\n", irq);
err = -EINVAL;
goto return_error;
}
platform_set_drvdata(pdev, data);
dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n", irq);
return 0;
return_error:
gpio_free(pdata->gpio_pin);
return err;
}
static int pps_gpio_remove(struct platform_device *pdev)
{
struct pps_gpio_device_data *data = platform_get_drvdata(pdev);
const struct pps_gpio_platform_data *pdata = data->pdata;
platform_set_drvdata(pdev, NULL);
free_irq(data->irq, data);
gpio_free(pdata->gpio_pin);
pps_unregister_source(data->pps);
pr_info("removed IRQ %d as PPS source\n", data->irq);
kfree(data);
return 0;
}
static struct platform_driver pps_gpio_driver = {
.probe = pps_gpio_probe,
.remove = __devexit_p(pps_gpio_remove),
.driver = {
.name = PPS_GPIO_NAME,
.owner = THIS_MODULE
},
};
static int __init pps_gpio_init(void)
{
int ret = platform_driver_register(&pps_gpio_driver);
if (ret < 0)
pr_err("failed to register platform driver\n");
return ret;
}
static void __exit pps_gpio_exit(void)
{
platform_driver_unregister(&pps_gpio_driver);
pr_debug("unregistered platform driver\n");
}
module_init(pps_gpio_init);
module_exit(pps_gpio_exit);
MODULE_AUTHOR("Ricardo Martins <rasm@fe.up.pt>");
MODULE_AUTHOR("James Nuss <jamesnuss@nanometrics.ca>");
MODULE_DESCRIPTION("Use GPIO pin as PPS source");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0.0");
...@@ -51,17 +51,6 @@ static void pps_ktimer_event(unsigned long ptr) ...@@ -51,17 +51,6 @@ static void pps_ktimer_event(unsigned long ptr)
mod_timer(&ktimer, jiffies + HZ); mod_timer(&ktimer, jiffies + HZ);
} }
/*
* The echo function
*/
static void pps_ktimer_echo(struct pps_device *pps, int event, void *data)
{
dev_info(pps->dev, "echo %s %s\n",
event & PPS_CAPTUREASSERT ? "assert" : "",
event & PPS_CAPTURECLEAR ? "clear" : "");
}
/* /*
* The PPS info struct * The PPS info struct
*/ */
...@@ -72,7 +61,6 @@ static struct pps_source_info pps_ktimer_info = { ...@@ -72,7 +61,6 @@ static struct pps_source_info pps_ktimer_info = {
.mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | .mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT |
PPS_ECHOASSERT | PPS_ECHOASSERT |
PPS_CANWAIT | PPS_TSFMT_TSPEC, PPS_CANWAIT | PPS_TSFMT_TSPEC,
.echo = pps_ktimer_echo,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
......
...@@ -133,14 +133,6 @@ static void parport_irq(void *handle) ...@@ -133,14 +133,6 @@ static void parport_irq(void *handle)
return; return;
} }
/* the PPS echo function */
static void pps_echo(struct pps_device *pps, int event, void *data)
{
dev_info(pps->dev, "echo %s %s\n",
event & PPS_CAPTUREASSERT ? "assert" : "",
event & PPS_CAPTURECLEAR ? "clear" : "");
}
static void parport_attach(struct parport *port) static void parport_attach(struct parport *port)
{ {
struct pps_client_pp *device; struct pps_client_pp *device;
...@@ -151,7 +143,6 @@ static void parport_attach(struct parport *port) ...@@ -151,7 +143,6 @@ static void parport_attach(struct parport *port)
PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \ PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \
PPS_ECHOASSERT | PPS_ECHOCLEAR | \ PPS_ECHOASSERT | PPS_ECHOCLEAR | \
PPS_CANWAIT | PPS_TSFMT_TSPEC, PPS_CANWAIT | PPS_TSFMT_TSPEC,
.echo = pps_echo,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.dev = NULL .dev = NULL
}; };
......
...@@ -52,6 +52,14 @@ static void pps_add_offset(struct pps_ktime *ts, struct pps_ktime *offset) ...@@ -52,6 +52,14 @@ static void pps_add_offset(struct pps_ktime *ts, struct pps_ktime *offset)
ts->sec += offset->sec; ts->sec += offset->sec;
} }
static void pps_echo_client_default(struct pps_device *pps, int event,
void *data)
{
dev_info(pps->dev, "echo %s %s\n",
event & PPS_CAPTUREASSERT ? "assert" : "",
event & PPS_CAPTURECLEAR ? "clear" : "");
}
/* /*
* Exported functions * Exported functions
*/ */
...@@ -80,13 +88,6 @@ struct pps_device *pps_register_source(struct pps_source_info *info, ...@@ -80,13 +88,6 @@ struct pps_device *pps_register_source(struct pps_source_info *info,
err = -EINVAL; err = -EINVAL;
goto pps_register_source_exit; goto pps_register_source_exit;
} }
if ((info->mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)) != 0 &&
info->echo == NULL) {
pr_err("%s: echo function is not defined\n",
info->name);
err = -EINVAL;
goto pps_register_source_exit;
}
if ((info->mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) { if ((info->mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) {
pr_err("%s: unspecified time format\n", pr_err("%s: unspecified time format\n",
info->name); info->name);
...@@ -108,6 +109,11 @@ struct pps_device *pps_register_source(struct pps_source_info *info, ...@@ -108,6 +109,11 @@ struct pps_device *pps_register_source(struct pps_source_info *info,
pps->params.mode = default_params; pps->params.mode = default_params;
pps->info = *info; pps->info = *info;
/* check for default echo function */
if ((pps->info.mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)) &&
pps->info.echo == NULL)
pps->info.echo = pps_echo_client_default;
init_waitqueue_head(&pps->queue); init_waitqueue_head(&pps->queue);
spin_lock_init(&pps->lock); spin_lock_init(&pps->lock);
......
# #
# RapidIO configuration # RapidIO configuration
# #
source "drivers/rapidio/devices/Kconfig"
config RAPIDIO_DISC_TIMEOUT config RAPIDIO_DISC_TIMEOUT
int "Discovery timeout duration (seconds)" int "Discovery timeout duration (seconds)"
depends on RAPIDIO depends on RAPIDIO
...@@ -20,8 +22,6 @@ config RAPIDIO_ENABLE_RX_TX_PORTS ...@@ -20,8 +22,6 @@ config RAPIDIO_ENABLE_RX_TX_PORTS
ports for Input/Output direction to allow other traffic ports for Input/Output direction to allow other traffic
than Maintenance transfers. than Maintenance transfers.
source "drivers/rapidio/switches/Kconfig"
config RAPIDIO_DEBUG config RAPIDIO_DEBUG
bool "RapidIO subsystem debug messages" bool "RapidIO subsystem debug messages"
depends on RAPIDIO depends on RAPIDIO
...@@ -32,3 +32,5 @@ config RAPIDIO_DEBUG ...@@ -32,3 +32,5 @@ config RAPIDIO_DEBUG
going on. going on.
If you are unsure about this, say N here. If you are unsure about this, say N here.
source "drivers/rapidio/switches/Kconfig"
...@@ -4,5 +4,6 @@ ...@@ -4,5 +4,6 @@
obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o
obj-$(CONFIG_RAPIDIO) += switches/ obj-$(CONFIG_RAPIDIO) += switches/
obj-$(CONFIG_RAPIDIO) += devices/
subdir-ccflags-$(CONFIG_RAPIDIO_DEBUG) := -DDEBUG subdir-ccflags-$(CONFIG_RAPIDIO_DEBUG) := -DDEBUG
#
# RapidIO master port configuration
#
config RAPIDIO_TSI721
bool "IDT Tsi721 PCI Express SRIO Controller support"
depends on RAPIDIO && PCIEPORTBUS
default "n"
---help---
Include support for IDT Tsi721 PCI Express Serial RapidIO controller.
#
# Makefile for RapidIO devices
#
obj-$(CONFIG_RAPIDIO_TSI721) += tsi721.o
This diff is collapsed.
This diff is collapsed.
...@@ -516,7 +516,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, ...@@ -516,7 +516,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
return rdev; return rdev;
cleanup: cleanup:
if (rio_is_switch(rdev)) if (rswitch)
kfree(rswitch->route_table); kfree(rswitch->route_table);
kfree(rdev); kfree(rdev);
...@@ -923,7 +923,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, ...@@ -923,7 +923,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
* rio_enum_complete- Tests if enumeration of a network is complete * rio_enum_complete- Tests if enumeration of a network is complete
* @port: Master port to send transaction * @port: Master port to send transaction
* *
* Tests the Component Tag CSR for non-zero value (enumeration * Tests the PGCCSR discovered bit for non-zero value (enumeration
* complete flag). Return %1 if enumeration is complete or %0 if * complete flag). Return %1 if enumeration is complete or %0 if
* enumeration is incomplete. * enumeration is incomplete.
*/ */
...@@ -933,7 +933,7 @@ static int rio_enum_complete(struct rio_mport *port) ...@@ -933,7 +933,7 @@ static int rio_enum_complete(struct rio_mport *port)
rio_local_read_config_32(port, port->phys_efptr + RIO_PORT_GEN_CTL_CSR, rio_local_read_config_32(port, port->phys_efptr + RIO_PORT_GEN_CTL_CSR,
&regval); &regval);
return (regval & RIO_PORT_GEN_MASTER) ? 1 : 0; return (regval & RIO_PORT_GEN_DISCOVERED) ? 1 : 0;
} }
/** /**
......
...@@ -21,16 +21,13 @@ ...@@ -21,16 +21,13 @@
#include "rtc-core.h" #include "rtc-core.h"
static DEFINE_IDR(rtc_idr); static DEFINE_IDA(rtc_ida);
static DEFINE_MUTEX(idr_lock);
struct class *rtc_class; struct class *rtc_class;
static void rtc_device_release(struct device *dev) static void rtc_device_release(struct device *dev)
{ {
struct rtc_device *rtc = to_rtc_device(dev); struct rtc_device *rtc = to_rtc_device(dev);
mutex_lock(&idr_lock); ida_simple_remove(&rtc_ida, rtc->id);
idr_remove(&rtc_idr, rtc->id);
mutex_unlock(&idr_lock);
kfree(rtc); kfree(rtc);
} }
...@@ -146,25 +143,16 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, ...@@ -146,25 +143,16 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
struct rtc_wkalrm alrm; struct rtc_wkalrm alrm;
int id, err; int id, err;
if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL);
err = -ENOMEM; if (id < 0) {
err = id;
goto exit; goto exit;
} }
mutex_lock(&idr_lock);
err = idr_get_new(&rtc_idr, NULL, &id);
mutex_unlock(&idr_lock);
if (err < 0)
goto exit;
id = id & MAX_ID_MASK;
rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL); rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);
if (rtc == NULL) { if (rtc == NULL) {
err = -ENOMEM; err = -ENOMEM;
goto exit_idr; goto exit_ida;
} }
rtc->id = id; rtc->id = id;
...@@ -222,10 +210,8 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, ...@@ -222,10 +210,8 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
exit_kfree: exit_kfree:
kfree(rtc); kfree(rtc);
exit_idr: exit_ida:
mutex_lock(&idr_lock); ida_simple_remove(&rtc_ida, id);
idr_remove(&rtc_idr, id);
mutex_unlock(&idr_lock);
exit: exit:
dev_err(dev, "rtc core: unable to register %s, err = %d\n", dev_err(dev, "rtc core: unable to register %s, err = %d\n",
...@@ -276,7 +262,7 @@ static void __exit rtc_exit(void) ...@@ -276,7 +262,7 @@ static void __exit rtc_exit(void)
{ {
rtc_dev_exit(); rtc_dev_exit();
class_destroy(rtc_class); class_destroy(rtc_class);
idr_destroy(&rtc_idr); ida_destroy(&rtc_ida);
} }
subsys_initcall(rtc_init); subsys_initcall(rtc_init);
......
...@@ -34,6 +34,7 @@ enum ds_type { ...@@ -34,6 +34,7 @@ enum ds_type {
ds_1388, ds_1388,
ds_3231, ds_3231,
m41t00, m41t00,
mcp7941x,
rx_8025, rx_8025,
// rs5c372 too? different address... // rs5c372 too? different address...
}; };
...@@ -43,6 +44,7 @@ enum ds_type { ...@@ -43,6 +44,7 @@ enum ds_type {
#define DS1307_REG_SECS 0x00 /* 00-59 */ #define DS1307_REG_SECS 0x00 /* 00-59 */
# define DS1307_BIT_CH 0x80 # define DS1307_BIT_CH 0x80
# define DS1340_BIT_nEOSC 0x80 # define DS1340_BIT_nEOSC 0x80
# define MCP7941X_BIT_ST 0x80
#define DS1307_REG_MIN 0x01 /* 00-59 */ #define DS1307_REG_MIN 0x01 /* 00-59 */
#define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */ #define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */
# define DS1307_BIT_12HR 0x40 /* in REG_HOUR */ # define DS1307_BIT_12HR 0x40 /* in REG_HOUR */
...@@ -50,6 +52,7 @@ enum ds_type { ...@@ -50,6 +52,7 @@ enum ds_type {
# define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */ # define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */
# define DS1340_BIT_CENTURY 0x40 /* in REG_HOUR */ # define DS1340_BIT_CENTURY 0x40 /* in REG_HOUR */
#define DS1307_REG_WDAY 0x03 /* 01-07 */ #define DS1307_REG_WDAY 0x03 /* 01-07 */
# define MCP7941X_BIT_VBATEN 0x08
#define DS1307_REG_MDAY 0x04 /* 01-31 */ #define DS1307_REG_MDAY 0x04 /* 01-31 */
#define DS1307_REG_MONTH 0x05 /* 01-12 */ #define DS1307_REG_MONTH 0x05 /* 01-12 */
# define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */ # define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */
...@@ -137,6 +140,8 @@ static const struct chip_desc chips[] = { ...@@ -137,6 +140,8 @@ static const struct chip_desc chips[] = {
}, },
[m41t00] = { [m41t00] = {
}, },
[mcp7941x] = {
},
[rx_8025] = { [rx_8025] = {
}, }; }, };
...@@ -149,6 +154,7 @@ static const struct i2c_device_id ds1307_id[] = { ...@@ -149,6 +154,7 @@ static const struct i2c_device_id ds1307_id[] = {
{ "ds1340", ds_1340 }, { "ds1340", ds_1340 },
{ "ds3231", ds_3231 }, { "ds3231", ds_3231 },
{ "m41t00", m41t00 }, { "m41t00", m41t00 },
{ "mcp7941x", mcp7941x },
{ "pt7c4338", ds_1307 }, { "pt7c4338", ds_1307 },
{ "rx8025", rx_8025 }, { "rx8025", rx_8025 },
{ } { }
...@@ -365,6 +371,10 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) ...@@ -365,6 +371,10 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN
| DS1340_BIT_CENTURY; | DS1340_BIT_CENTURY;
break; break;
case mcp7941x:
buf[DS1307_REG_SECS] |= MCP7941X_BIT_ST;
buf[DS1307_REG_WDAY] |= MCP7941X_BIT_VBATEN;
break;
default: default:
break; break;
} }
...@@ -808,6 +818,23 @@ static int __devinit ds1307_probe(struct i2c_client *client, ...@@ -808,6 +818,23 @@ static int __devinit ds1307_probe(struct i2c_client *client,
i2c_smbus_write_byte_data(client, DS1340_REG_FLAG, 0); i2c_smbus_write_byte_data(client, DS1340_REG_FLAG, 0);
dev_warn(&client->dev, "SET TIME!\n"); dev_warn(&client->dev, "SET TIME!\n");
} }
break;
case mcp7941x:
/* make sure that the backup battery is enabled */
if (!(ds1307->regs[DS1307_REG_WDAY] & MCP7941X_BIT_VBATEN)) {
i2c_smbus_write_byte_data(client, DS1307_REG_WDAY,
ds1307->regs[DS1307_REG_WDAY]
| MCP7941X_BIT_VBATEN);
}
/* clock halted? turn it on, so clock can tick. */
if (!(tmp & MCP7941X_BIT_ST)) {
i2c_smbus_write_byte_data(client, DS1307_REG_SECS,
MCP7941X_BIT_ST);
dev_warn(&client->dev, "SET TIME!\n");
goto read_rtc;
}
break; break;
case rx_8025: case rx_8025:
case ds_1337: case ds_1337:
......
...@@ -309,7 +309,7 @@ static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev) ...@@ -309,7 +309,7 @@ static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int __devinit mc13xxx_rtc_probe(struct platform_device *pdev) static int __init mc13xxx_rtc_probe(struct platform_device *pdev)
{ {
int ret; int ret;
struct mc13xxx_rtc *priv; struct mc13xxx_rtc *priv;
...@@ -378,7 +378,7 @@ static int __devinit mc13xxx_rtc_probe(struct platform_device *pdev) ...@@ -378,7 +378,7 @@ static int __devinit mc13xxx_rtc_probe(struct platform_device *pdev)
return ret; return ret;
} }
static int __devexit mc13xxx_rtc_remove(struct platform_device *pdev) static int __exit mc13xxx_rtc_remove(struct platform_device *pdev)
{ {
struct mc13xxx_rtc *priv = platform_get_drvdata(pdev); struct mc13xxx_rtc *priv = platform_get_drvdata(pdev);
...@@ -410,7 +410,7 @@ const struct platform_device_id mc13xxx_rtc_idtable[] = { ...@@ -410,7 +410,7 @@ const struct platform_device_id mc13xxx_rtc_idtable[] = {
static struct platform_driver mc13xxx_rtc_driver = { static struct platform_driver mc13xxx_rtc_driver = {
.id_table = mc13xxx_rtc_idtable, .id_table = mc13xxx_rtc_idtable,
.remove = __devexit_p(mc13xxx_rtc_remove), .remove = __exit_p(mc13xxx_rtc_remove),
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -114,43 +114,7 @@ static struct bin_attribute w1_ds2760_bin_attr = { ...@@ -114,43 +114,7 @@ static struct bin_attribute w1_ds2760_bin_attr = {
.read = w1_ds2760_read_bin, .read = w1_ds2760_read_bin,
}; };
static DEFINE_IDR(bat_idr); static DEFINE_IDA(bat_ida);
static DEFINE_MUTEX(bat_idr_lock);
static int new_bat_id(void)
{
int ret;
while (1) {
int id;
ret = idr_pre_get(&bat_idr, GFP_KERNEL);
if (ret == 0)
return -ENOMEM;
mutex_lock(&bat_idr_lock);
ret = idr_get_new(&bat_idr, NULL, &id);
mutex_unlock(&bat_idr_lock);
if (ret == 0) {
ret = id & MAX_ID_MASK;
break;
} else if (ret == -EAGAIN) {
continue;
} else {
break;
}
}
return ret;
}
static void release_bat_id(int id)
{
mutex_lock(&bat_idr_lock);
idr_remove(&bat_idr, id);
mutex_unlock(&bat_idr_lock);
}
static int w1_ds2760_add_slave(struct w1_slave *sl) static int w1_ds2760_add_slave(struct w1_slave *sl)
{ {
...@@ -158,7 +122,7 @@ static int w1_ds2760_add_slave(struct w1_slave *sl) ...@@ -158,7 +122,7 @@ static int w1_ds2760_add_slave(struct w1_slave *sl)
int id; int id;
struct platform_device *pdev; struct platform_device *pdev;
id = new_bat_id(); id = ida_simple_get(&bat_ida, 0, 0, GFP_KERNEL);
if (id < 0) { if (id < 0) {
ret = id; ret = id;
goto noid; goto noid;
...@@ -187,7 +151,7 @@ static int w1_ds2760_add_slave(struct w1_slave *sl) ...@@ -187,7 +151,7 @@ static int w1_ds2760_add_slave(struct w1_slave *sl)
pdev_add_failed: pdev_add_failed:
platform_device_unregister(pdev); platform_device_unregister(pdev);
pdev_alloc_failed: pdev_alloc_failed:
release_bat_id(id); ida_simple_remove(&bat_ida, id);
noid: noid:
success: success:
return ret; return ret;
...@@ -199,7 +163,7 @@ static void w1_ds2760_remove_slave(struct w1_slave *sl) ...@@ -199,7 +163,7 @@ static void w1_ds2760_remove_slave(struct w1_slave *sl)
int id = pdev->id; int id = pdev->id;
platform_device_unregister(pdev); platform_device_unregister(pdev);
release_bat_id(id); ida_simple_remove(&bat_ida, id);
sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr); sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
} }
...@@ -217,14 +181,14 @@ static int __init w1_ds2760_init(void) ...@@ -217,14 +181,14 @@ static int __init w1_ds2760_init(void)
{ {
printk(KERN_INFO "1-Wire driver for the DS2760 battery monitor " printk(KERN_INFO "1-Wire driver for the DS2760 battery monitor "
" chip - (c) 2004-2005, Szabolcs Gyurko\n"); " chip - (c) 2004-2005, Szabolcs Gyurko\n");
idr_init(&bat_idr); ida_init(&bat_ida);
return w1_register_family(&w1_ds2760_family); return w1_register_family(&w1_ds2760_family);
} }
static void __exit w1_ds2760_exit(void) static void __exit w1_ds2760_exit(void)
{ {
w1_unregister_family(&w1_ds2760_family); w1_unregister_family(&w1_ds2760_family);
idr_destroy(&bat_idr); ida_destroy(&bat_ida);
} }
EXPORT_SYMBOL(w1_ds2760_read); EXPORT_SYMBOL(w1_ds2760_read);
......
...@@ -26,20 +26,14 @@ ...@@ -26,20 +26,14 @@
#include "../w1_family.h" #include "../w1_family.h"
#include "w1_ds2780.h" #include "w1_ds2780.h"
int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count, static int w1_ds2780_do_io(struct device *dev, char *buf, int addr,
int io) size_t count, int io)
{ {
struct w1_slave *sl = container_of(dev, struct w1_slave, dev); struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
if (!dev) if (addr > DS2780_DATA_SIZE || addr < 0)
return -ENODEV; return 0;
mutex_lock(&sl->master->mutex);
if (addr > DS2780_DATA_SIZE || addr < 0) {
count = 0;
goto out;
}
count = min_t(int, count, DS2780_DATA_SIZE - addr); count = min_t(int, count, DS2780_DATA_SIZE - addr);
if (w1_reset_select_slave(sl) == 0) { if (w1_reset_select_slave(sl) == 0) {
...@@ -47,7 +41,6 @@ int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count, ...@@ -47,7 +41,6 @@ int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count,
w1_write_8(sl->master, W1_DS2780_WRITE_DATA); w1_write_8(sl->master, W1_DS2780_WRITE_DATA);
w1_write_8(sl->master, addr); w1_write_8(sl->master, addr);
w1_write_block(sl->master, buf, count); w1_write_block(sl->master, buf, count);
/* XXX w1_write_block returns void, not n_written */
} else { } else {
w1_write_8(sl->master, W1_DS2780_READ_DATA); w1_write_8(sl->master, W1_DS2780_READ_DATA);
w1_write_8(sl->master, addr); w1_write_8(sl->master, addr);
...@@ -55,13 +48,42 @@ int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count, ...@@ -55,13 +48,42 @@ int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count,
} }
} }
out: return count;
}
int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count,
int io)
{
struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
int ret;
if (!dev)
return -ENODEV;
mutex_lock(&sl->master->mutex);
ret = w1_ds2780_do_io(dev, buf, addr, count, io);
mutex_unlock(&sl->master->mutex); mutex_unlock(&sl->master->mutex);
return count; return ret;
} }
EXPORT_SYMBOL(w1_ds2780_io); EXPORT_SYMBOL(w1_ds2780_io);
int w1_ds2780_io_nolock(struct device *dev, char *buf, int addr, size_t count,
int io)
{
int ret;
if (!dev)
return -ENODEV;
ret = w1_ds2780_do_io(dev, buf, addr, count, io);
return ret;
}
EXPORT_SYMBOL(w1_ds2780_io_nolock);
int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd) int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd)
{ {
struct w1_slave *sl = container_of(dev, struct w1_slave, dev); struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
...@@ -99,43 +121,7 @@ static struct bin_attribute w1_ds2780_bin_attr = { ...@@ -99,43 +121,7 @@ static struct bin_attribute w1_ds2780_bin_attr = {
.read = w1_ds2780_read_bin, .read = w1_ds2780_read_bin,
}; };
static DEFINE_IDR(bat_idr); static DEFINE_IDA(bat_ida);
static DEFINE_MUTEX(bat_idr_lock);
static int new_bat_id(void)
{
int ret;
while (1) {
int id;
ret = idr_pre_get(&bat_idr, GFP_KERNEL);
if (ret == 0)
return -ENOMEM;
mutex_lock(&bat_idr_lock);
ret = idr_get_new(&bat_idr, NULL, &id);
mutex_unlock(&bat_idr_lock);
if (ret == 0) {
ret = id & MAX_ID_MASK;
break;
} else if (ret == -EAGAIN) {
continue;
} else {
break;
}
}
return ret;
}
static void release_bat_id(int id)
{
mutex_lock(&bat_idr_lock);
idr_remove(&bat_idr, id);
mutex_unlock(&bat_idr_lock);
}
static int w1_ds2780_add_slave(struct w1_slave *sl) static int w1_ds2780_add_slave(struct w1_slave *sl)
{ {
...@@ -143,7 +129,7 @@ static int w1_ds2780_add_slave(struct w1_slave *sl) ...@@ -143,7 +129,7 @@ static int w1_ds2780_add_slave(struct w1_slave *sl)
int id; int id;
struct platform_device *pdev; struct platform_device *pdev;
id = new_bat_id(); id = ida_simple_get(&bat_ida, 0, 0, GFP_KERNEL);
if (id < 0) { if (id < 0) {
ret = id; ret = id;
goto noid; goto noid;
...@@ -172,7 +158,7 @@ static int w1_ds2780_add_slave(struct w1_slave *sl) ...@@ -172,7 +158,7 @@ static int w1_ds2780_add_slave(struct w1_slave *sl)
pdev_add_failed: pdev_add_failed:
platform_device_unregister(pdev); platform_device_unregister(pdev);
pdev_alloc_failed: pdev_alloc_failed:
release_bat_id(id); ida_simple_remove(&bat_ida, id);
noid: noid:
return ret; return ret;
} }
...@@ -183,7 +169,7 @@ static void w1_ds2780_remove_slave(struct w1_slave *sl) ...@@ -183,7 +169,7 @@ static void w1_ds2780_remove_slave(struct w1_slave *sl)
int id = pdev->id; int id = pdev->id;
platform_device_unregister(pdev); platform_device_unregister(pdev);
release_bat_id(id); ida_simple_remove(&bat_ida, id);
sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2780_bin_attr); sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2780_bin_attr);
} }
...@@ -199,14 +185,14 @@ static struct w1_family w1_ds2780_family = { ...@@ -199,14 +185,14 @@ static struct w1_family w1_ds2780_family = {
static int __init w1_ds2780_init(void) static int __init w1_ds2780_init(void)
{ {
idr_init(&bat_idr); ida_init(&bat_ida);
return w1_register_family(&w1_ds2780_family); return w1_register_family(&w1_ds2780_family);
} }
static void __exit w1_ds2780_exit(void) static void __exit w1_ds2780_exit(void)
{ {
w1_unregister_family(&w1_ds2780_family); w1_unregister_family(&w1_ds2780_family);
idr_destroy(&bat_idr); ida_destroy(&bat_ida);
} }
module_init(w1_ds2780_init); module_init(w1_ds2780_init);
......
...@@ -124,6 +124,8 @@ ...@@ -124,6 +124,8 @@
extern int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count, extern int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count,
int io); int io);
extern int w1_ds2780_io_nolock(struct device *dev, char *buf, int addr,
size_t count, int io);
extern int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd); extern int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd);
#endif /* !_W1_DS2780_H */ #endif /* !_W1_DS2780_H */
...@@ -78,6 +78,7 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, ...@@ -78,6 +78,7 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
memcpy(&dev->dev, device, sizeof(struct device)); memcpy(&dev->dev, device, sizeof(struct device));
dev_set_name(&dev->dev, "w1_bus_master%u", dev->id); dev_set_name(&dev->dev, "w1_bus_master%u", dev->id);
snprintf(dev->name, sizeof(dev->name), "w1_bus_master%u", dev->id); snprintf(dev->name, sizeof(dev->name), "w1_bus_master%u", dev->id);
dev->dev.init_name = dev->name;
dev->driver = driver; dev->driver = driver;
......
...@@ -158,13 +158,18 @@ EXPORT_SYMBOL_GPL(w1_write_8); ...@@ -158,13 +158,18 @@ EXPORT_SYMBOL_GPL(w1_write_8);
static u8 w1_read_bit(struct w1_master *dev) static u8 w1_read_bit(struct w1_master *dev)
{ {
int result; int result;
unsigned long flags;
/* sample timing is critical here */
local_irq_save(flags);
dev->bus_master->write_bit(dev->bus_master->data, 0); dev->bus_master->write_bit(dev->bus_master->data, 0);
w1_delay(6); w1_delay(6);
dev->bus_master->write_bit(dev->bus_master->data, 1); dev->bus_master->write_bit(dev->bus_master->data, 1);
w1_delay(9); w1_delay(9);
result = dev->bus_master->read_bit(dev->bus_master->data); result = dev->bus_master->read_bit(dev->bus_master->data);
local_irq_restore(flags);
w1_delay(55); w1_delay(55);
return result & 0x1; return result & 0x1;
......
...@@ -440,8 +440,6 @@ void exit_aio(struct mm_struct *mm) ...@@ -440,8 +440,6 @@ void exit_aio(struct mm_struct *mm)
static struct kiocb *__aio_get_req(struct kioctx *ctx) static struct kiocb *__aio_get_req(struct kioctx *ctx)
{ {
struct kiocb *req = NULL; struct kiocb *req = NULL;
struct aio_ring *ring;
int okay = 0;
req = kmem_cache_alloc(kiocb_cachep, GFP_KERNEL); req = kmem_cache_alloc(kiocb_cachep, GFP_KERNEL);
if (unlikely(!req)) if (unlikely(!req))
...@@ -459,39 +457,114 @@ static struct kiocb *__aio_get_req(struct kioctx *ctx) ...@@ -459,39 +457,114 @@ static struct kiocb *__aio_get_req(struct kioctx *ctx)
INIT_LIST_HEAD(&req->ki_run_list); INIT_LIST_HEAD(&req->ki_run_list);
req->ki_eventfd = NULL; req->ki_eventfd = NULL;
/* Check if the completion queue has enough free space to return req;
* accept an event from this io. }
*/
/*
* struct kiocb's are allocated in batches to reduce the number of
* times the ctx lock is acquired and released.
*/
#define KIOCB_BATCH_SIZE 32L
struct kiocb_batch {
struct list_head head;
long count; /* number of requests left to allocate */
};
static void kiocb_batch_init(struct kiocb_batch *batch, long total)
{
INIT_LIST_HEAD(&batch->head);
batch->count = total;
}
static void kiocb_batch_free(struct kiocb_batch *batch)
{
struct kiocb *req, *n;
list_for_each_entry_safe(req, n, &batch->head, ki_batch) {
list_del(&req->ki_batch);
kmem_cache_free(kiocb_cachep, req);
}
}
/*
* Allocate a batch of kiocbs. This avoids taking and dropping the
* context lock a lot during setup.
*/
static int kiocb_batch_refill(struct kioctx *ctx, struct kiocb_batch *batch)
{
unsigned short allocated, to_alloc;
long avail;
bool called_fput = false;
struct kiocb *req, *n;
struct aio_ring *ring;
to_alloc = min(batch->count, KIOCB_BATCH_SIZE);
for (allocated = 0; allocated < to_alloc; allocated++) {
req = __aio_get_req(ctx);
if (!req)
/* allocation failed, go with what we've got */
break;
list_add(&req->ki_batch, &batch->head);
}
if (allocated == 0)
goto out;
retry:
spin_lock_irq(&ctx->ctx_lock); spin_lock_irq(&ctx->ctx_lock);
ring = kmap_atomic(ctx->ring_info.ring_pages[0], KM_USER0); ring = kmap_atomic(ctx->ring_info.ring_pages[0]);
if (ctx->reqs_active < aio_ring_avail(&ctx->ring_info, ring)) {
avail = aio_ring_avail(&ctx->ring_info, ring) - ctx->reqs_active;
BUG_ON(avail < 0);
if (avail == 0 && !called_fput) {
/*
* Handle a potential starvation case. It is possible that
* we hold the last reference on a struct file, causing us
* to delay the final fput to non-irq context. In this case,
* ctx->reqs_active is artificially high. Calling the fput
* routine here may free up a slot in the event completion
* ring, allowing this allocation to succeed.
*/
kunmap_atomic(ring);
spin_unlock_irq(&ctx->ctx_lock);
aio_fput_routine(NULL);
called_fput = true;
goto retry;
}
if (avail < allocated) {
/* Trim back the number of requests. */
list_for_each_entry_safe(req, n, &batch->head, ki_batch) {
list_del(&req->ki_batch);
kmem_cache_free(kiocb_cachep, req);
if (--allocated <= avail)
break;
}
}
batch->count -= allocated;
list_for_each_entry(req, &batch->head, ki_batch) {
list_add(&req->ki_list, &ctx->active_reqs); list_add(&req->ki_list, &ctx->active_reqs);
ctx->reqs_active++; ctx->reqs_active++;
okay = 1;
} }
kunmap_atomic(ring, KM_USER0);
spin_unlock_irq(&ctx->ctx_lock);
if (!okay) { kunmap_atomic(ring);
kmem_cache_free(kiocb_cachep, req); spin_unlock_irq(&ctx->ctx_lock);
req = NULL;
}
return req; out:
return allocated;
} }
static inline struct kiocb *aio_get_req(struct kioctx *ctx) static inline struct kiocb *aio_get_req(struct kioctx *ctx,
struct kiocb_batch *batch)
{ {
struct kiocb *req; struct kiocb *req;
/* Handle a potential starvation case -- should be exceedingly rare as
* requests will be stuck on fput_head only if the aio_fput_routine is if (list_empty(&batch->head))
* delayed and the requests were the last user of the struct file. if (kiocb_batch_refill(ctx, batch) == 0)
*/ return NULL;
req = __aio_get_req(ctx); req = list_first_entry(&batch->head, struct kiocb, ki_batch);
if (unlikely(NULL == req)) { list_del(&req->ki_batch);
aio_fput_routine(NULL);
req = __aio_get_req(ctx);
}
return req; return req;
} }
...@@ -1515,7 +1588,8 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat) ...@@ -1515,7 +1588,8 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
} }
static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
struct iocb *iocb, bool compat) struct iocb *iocb, struct kiocb_batch *batch,
bool compat)
{ {
struct kiocb *req; struct kiocb *req;
struct file *file; struct file *file;
...@@ -1541,7 +1615,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, ...@@ -1541,7 +1615,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
if (unlikely(!file)) if (unlikely(!file))
return -EBADF; return -EBADF;
req = aio_get_req(ctx); /* returns with 2 references to req */ req = aio_get_req(ctx, batch); /* returns with 2 references to req */
if (unlikely(!req)) { if (unlikely(!req)) {
fput(file); fput(file);
return -EAGAIN; return -EAGAIN;
...@@ -1621,8 +1695,9 @@ long do_io_submit(aio_context_t ctx_id, long nr, ...@@ -1621,8 +1695,9 @@ long do_io_submit(aio_context_t ctx_id, long nr,
{ {
struct kioctx *ctx; struct kioctx *ctx;
long ret = 0; long ret = 0;
int i; int i = 0;
struct blk_plug plug; struct blk_plug plug;
struct kiocb_batch batch;
if (unlikely(nr < 0)) if (unlikely(nr < 0))
return -EINVAL; return -EINVAL;
...@@ -1639,6 +1714,8 @@ long do_io_submit(aio_context_t ctx_id, long nr, ...@@ -1639,6 +1714,8 @@ long do_io_submit(aio_context_t ctx_id, long nr,
return -EINVAL; return -EINVAL;
} }
kiocb_batch_init(&batch, nr);
blk_start_plug(&plug); blk_start_plug(&plug);
/* /*
...@@ -1659,12 +1736,13 @@ long do_io_submit(aio_context_t ctx_id, long nr, ...@@ -1659,12 +1736,13 @@ long do_io_submit(aio_context_t ctx_id, long nr,
break; break;
} }
ret = io_submit_one(ctx, user_iocb, &tmp, compat); ret = io_submit_one(ctx, user_iocb, &tmp, &batch, compat);
if (ret) if (ret)
break; break;
} }
blk_finish_plug(&plug); blk_finish_plug(&plug);
kiocb_batch_free(&batch);
put_ioctx(ctx); put_ioctx(ctx);
return i ? i : ret; return i ? i : ret;
} }
......
...@@ -795,7 +795,16 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -795,7 +795,16 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
* might try to exec. This is because the brk will * might try to exec. This is because the brk will
* follow the loader, and is not movable. */ * follow the loader, and is not movable. */
#if defined(CONFIG_X86) || defined(CONFIG_ARM) #if defined(CONFIG_X86) || defined(CONFIG_ARM)
load_bias = 0; /* Memory randomization might have been switched off
* in runtime via sysctl.
* If that is the case, retain the original non-zero
* load_bias value in order to establish proper
* non-randomized mappings.
*/
if (current->flags & PF_RANDOMIZE)
load_bias = 0;
else
load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
#else #else
load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
#endif #endif
......
...@@ -46,11 +46,26 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke ...@@ -46,11 +46,26 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
case HFS_EXT_CNID: case HFS_EXT_CNID:
hfs_inode_read_fork(tree->inode, mdb->drXTExtRec, mdb->drXTFlSize, hfs_inode_read_fork(tree->inode, mdb->drXTExtRec, mdb->drXTFlSize,
mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz)); mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz));
if (HFS_I(tree->inode)->alloc_blocks >
HFS_I(tree->inode)->first_blocks) {
printk(KERN_ERR "hfs: invalid btree extent records\n");
unlock_new_inode(tree->inode);
goto free_inode;
}
tree->inode->i_mapping->a_ops = &hfs_btree_aops; tree->inode->i_mapping->a_ops = &hfs_btree_aops;
break; break;
case HFS_CAT_CNID: case HFS_CAT_CNID:
hfs_inode_read_fork(tree->inode, mdb->drCTExtRec, mdb->drCTFlSize, hfs_inode_read_fork(tree->inode, mdb->drCTExtRec, mdb->drCTFlSize,
mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz)); mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz));
if (!HFS_I(tree->inode)->first_blocks) {
printk(KERN_ERR "hfs: invalid btree extent records "
"(0 size).\n");
unlock_new_inode(tree->inode);
goto free_inode;
}
tree->inode->i_mapping->a_ops = &hfs_btree_aops; tree->inode->i_mapping->a_ops = &hfs_btree_aops;
break; break;
default: default:
...@@ -59,11 +74,6 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke ...@@ -59,11 +74,6 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
} }
unlock_new_inode(tree->inode); unlock_new_inode(tree->inode);
if (!HFS_I(tree->inode)->first_blocks) {
printk(KERN_ERR "hfs: invalid btree extent records (0 size).\n");
goto free_inode;
}
mapping = tree->inode->i_mapping; mapping = tree->inode->i_mapping;
page = read_mapping_page(mapping, 0, NULL); page = read_mapping_page(mapping, 0, NULL);
if (IS_ERR(page)) if (IS_ERR(page))
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/statfs.h> #include <linux/statfs.h>
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/mpage.h>
#include "isofs.h" #include "isofs.h"
#include "zisofs.h" #include "zisofs.h"
...@@ -1148,7 +1149,13 @@ struct buffer_head *isofs_bread(struct inode *inode, sector_t block) ...@@ -1148,7 +1149,13 @@ struct buffer_head *isofs_bread(struct inode *inode, sector_t block)
static int isofs_readpage(struct file *file, struct page *page) static int isofs_readpage(struct file *file, struct page *page)
{ {
return block_read_full_page(page,isofs_get_block); return mpage_readpage(page, isofs_get_block);
}
static int isofs_readpages(struct file *file, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages)
{
return mpage_readpages(mapping, pages, nr_pages, isofs_get_block);
} }
static sector_t _isofs_bmap(struct address_space *mapping, sector_t block) static sector_t _isofs_bmap(struct address_space *mapping, sector_t block)
...@@ -1158,6 +1165,7 @@ static sector_t _isofs_bmap(struct address_space *mapping, sector_t block) ...@@ -1158,6 +1165,7 @@ static sector_t _isofs_bmap(struct address_space *mapping, sector_t block)
static const struct address_space_operations isofs_aops = { static const struct address_space_operations isofs_aops = {
.readpage = isofs_readpage, .readpage = isofs_readpage,
.readpages = isofs_readpages,
.bmap = _isofs_bmap .bmap = _isofs_bmap
}; };
......
...@@ -1652,12 +1652,46 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b ...@@ -1652,12 +1652,46 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
return error; return error;
} }
static int proc_pid_fd_link_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
struct inode *inode = dentry->d_inode;
struct task_struct *task = get_proc_task(inode);
int rc;
if (task == NULL)
return -ESRCH;
rc = -EACCES;
if (lock_trace(task))
goto out_task;
generic_fillattr(inode, stat);
unlock_trace(task);
rc = 0;
out_task:
put_task_struct(task);
return rc;
}
static const struct inode_operations proc_pid_link_inode_operations = { static const struct inode_operations proc_pid_link_inode_operations = {
.readlink = proc_pid_readlink, .readlink = proc_pid_readlink,
.follow_link = proc_pid_follow_link, .follow_link = proc_pid_follow_link,
.setattr = proc_setattr, .setattr = proc_setattr,
}; };
static const struct inode_operations proc_fdinfo_link_inode_operations = {
.setattr = proc_setattr,
.getattr = proc_pid_fd_link_getattr,
};
static const struct inode_operations proc_fd_link_inode_operations = {
.readlink = proc_pid_readlink,
.follow_link = proc_pid_follow_link,
.setattr = proc_setattr,
.getattr = proc_pid_fd_link_getattr,
};
/* building an inode */ /* building an inode */
...@@ -1889,49 +1923,61 @@ static unsigned name_to_int(struct dentry *dentry) ...@@ -1889,49 +1923,61 @@ static unsigned name_to_int(struct dentry *dentry)
static int proc_fd_info(struct inode *inode, struct path *path, char *info) static int proc_fd_info(struct inode *inode, struct path *path, char *info)
{ {
struct task_struct *task = get_proc_task(inode); struct task_struct *task;
struct files_struct *files = NULL; struct files_struct *files;
struct file *file; struct file *file;
int fd = proc_fd(inode); int fd = proc_fd(inode);
int rc;
if (task) { task = get_proc_task(inode);
files = get_files_struct(task); if (!task)
put_task_struct(task); return -ENOENT;
}
if (files) { rc = -EACCES;
/* if (lock_trace(task))
* We are not taking a ref to the file structure, so we must goto out_task;
* hold ->file_lock.
*/ rc = -ENOENT;
spin_lock(&files->file_lock); files = get_files_struct(task);
file = fcheck_files(files, fd); if (files == NULL)
if (file) { goto out_unlock;
unsigned int f_flags;
struct fdtable *fdt; /*
* We are not taking a ref to the file structure, so we must
fdt = files_fdtable(files); * hold ->file_lock.
f_flags = file->f_flags & ~O_CLOEXEC; */
if (FD_ISSET(fd, fdt->close_on_exec)) spin_lock(&files->file_lock);
f_flags |= O_CLOEXEC; file = fcheck_files(files, fd);
if (file) {
if (path) { unsigned int f_flags;
*path = file->f_path; struct fdtable *fdt;
path_get(&file->f_path);
} fdt = files_fdtable(files);
if (info) f_flags = file->f_flags & ~O_CLOEXEC;
snprintf(info, PROC_FDINFO_MAX, if (FD_ISSET(fd, fdt->close_on_exec))
"pos:\t%lli\n" f_flags |= O_CLOEXEC;
"flags:\t0%o\n",
(long long) file->f_pos, if (path) {
f_flags); *path = file->f_path;
spin_unlock(&files->file_lock); path_get(&file->f_path);
put_files_struct(files);
return 0;
} }
spin_unlock(&files->file_lock); if (info)
put_files_struct(files); snprintf(info, PROC_FDINFO_MAX,
} "pos:\t%lli\n"
return -ENOENT; "flags:\t0%o\n",
(long long) file->f_pos,
f_flags);
rc = 0;
} else
rc = -ENOENT;
spin_unlock(&files->file_lock);
put_files_struct(files);
out_unlock:
unlock_trace(task);
out_task:
put_task_struct(task);
return rc;
} }
static int proc_fd_link(struct inode *inode, struct path *path) static int proc_fd_link(struct inode *inode, struct path *path)
...@@ -2026,7 +2072,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir, ...@@ -2026,7 +2072,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
spin_unlock(&files->file_lock); spin_unlock(&files->file_lock);
put_files_struct(files); put_files_struct(files);
inode->i_op = &proc_pid_link_inode_operations; inode->i_op = &proc_fd_link_inode_operations;
inode->i_size = 64; inode->i_size = 64;
ei->op.proc_get_link = proc_fd_link; ei->op.proc_get_link = proc_fd_link;
d_set_d_op(dentry, &tid_fd_dentry_operations); d_set_d_op(dentry, &tid_fd_dentry_operations);
...@@ -2058,7 +2104,12 @@ static struct dentry *proc_lookupfd_common(struct inode *dir, ...@@ -2058,7 +2104,12 @@ static struct dentry *proc_lookupfd_common(struct inode *dir,
if (fd == ~0U) if (fd == ~0U)
goto out; goto out;
result = ERR_PTR(-EACCES);
if (lock_trace(task))
goto out;
result = instantiate(dir, dentry, task, &fd); result = instantiate(dir, dentry, task, &fd);
unlock_trace(task);
out: out:
put_task_struct(task); put_task_struct(task);
out_no_task: out_no_task:
...@@ -2078,23 +2129,28 @@ static int proc_readfd_common(struct file * filp, void * dirent, ...@@ -2078,23 +2129,28 @@ static int proc_readfd_common(struct file * filp, void * dirent,
retval = -ENOENT; retval = -ENOENT;
if (!p) if (!p)
goto out_no_task; goto out_no_task;
retval = -EACCES;
if (lock_trace(p))
goto out;
retval = 0; retval = 0;
fd = filp->f_pos; fd = filp->f_pos;
switch (fd) { switch (fd) {
case 0: case 0:
if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
goto out; goto out_unlock;
filp->f_pos++; filp->f_pos++;
case 1: case 1:
ino = parent_ino(dentry); ino = parent_ino(dentry);
if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
goto out; goto out_unlock;
filp->f_pos++; filp->f_pos++;
default: default:
files = get_files_struct(p); files = get_files_struct(p);
if (!files) if (!files)
goto out; goto out_unlock;
rcu_read_lock(); rcu_read_lock();
for (fd = filp->f_pos-2; for (fd = filp->f_pos-2;
fd < files_fdtable(files)->max_fds; fd < files_fdtable(files)->max_fds;
...@@ -2118,6 +2174,9 @@ static int proc_readfd_common(struct file * filp, void * dirent, ...@@ -2118,6 +2174,9 @@ static int proc_readfd_common(struct file * filp, void * dirent,
rcu_read_unlock(); rcu_read_unlock();
put_files_struct(files); put_files_struct(files);
} }
out_unlock:
unlock_trace(p);
out: out:
put_task_struct(p); put_task_struct(p);
out_no_task: out_no_task:
...@@ -2195,6 +2254,7 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir, ...@@ -2195,6 +2254,7 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
ei->fd = fd; ei->fd = fd;
inode->i_mode = S_IFREG | S_IRUSR; inode->i_mode = S_IFREG | S_IRUSR;
inode->i_fop = &proc_fdinfo_file_operations; inode->i_fop = &proc_fdinfo_file_operations;
inode->i_op = &proc_fdinfo_link_inode_operations;
d_set_d_op(dentry, &tid_fd_dentry_operations); d_set_d_op(dentry, &tid_fd_dentry_operations);
d_add(dentry, inode); d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */ /* Close the race of the process dying before we return the dentry */
......
This diff is collapsed.
This diff is collapsed.
...@@ -117,6 +117,7 @@ struct kiocb { ...@@ -117,6 +117,7 @@ struct kiocb {
struct list_head ki_list; /* the aio core uses this struct list_head ki_list; /* the aio core uses this
* for cancellation */ * for cancellation */
struct list_head ki_batch; /* batch allocation */
/* /*
* If the aio_resfd field of the userspace iocb is not zero, * If the aio_resfd field of the userspace iocb is not zero,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -39,5 +39,6 @@ ...@@ -39,5 +39,6 @@
#define RIO_DID_IDTCPS1616 0x0379 #define RIO_DID_IDTCPS1616 0x0379
#define RIO_DID_IDTVPS1616 0x0377 #define RIO_DID_IDTVPS1616 0x0377
#define RIO_DID_IDTSPS1616 0x0378 #define RIO_DID_IDTSPS1616 0x0378
#define RIO_DID_TSI721 0x80ab
#endif /* LINUX_RIO_IDS_H */ #endif /* LINUX_RIO_IDS_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment