Skip to content

Commit

Permalink
Merge branch 'akpm' (updates from Andrew Morton)
Browse files Browse the repository at this point in the history
Merge misc fixes from Andrew Morton:
 "Bunch of fixes and one little addition to math64.h"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (27 commits)
  include/linux/math64.h: add div64_ul()
  mm: memcontrol: fix lockless reclaim hierarchy iterator
  frontswap: fix incorrect zeroing and allocation size for frontswap_map
  kernel/audit_tree.c:audit_add_tree_rule(): protect `rule' from kill_rules()
  mm: migration: add migrate_entry_wait_huge()
  ocfs2: add missing lockres put in dlm_mig_lockres_handler
  mm/page_alloc.c: fix watermark check in __zone_watermark_ok()
  drivers/misc/sgi-gru/grufile.c: fix info leak in gru_get_config_info()
  aio: fix io_destroy() regression by using call_rcu()
  rtc-at91rm9200: use shadow IMR on at91sam9x5
  rtc-at91rm9200: add shadow interrupt mask
  rtc-at91rm9200: refactor interrupt-register handling
  rtc-at91rm9200: add configuration support
  rtc-at91rm9200: add match-table compile guard
  fs/ocfs2/namei.c: remove unecessary ERROR when removing non-empty directory
  swap: avoid read_swap_cache_async() race to deadlock while waiting on discard I/O completion
  drivers/rtc/rtc-twl.c: fix missing device_init_wakeup() when booted with device tree
  cciss: fix broken mutex usage in ioctl
  audit: wait_for_auditd() should use TASK_UNINTERRUPTIBLE
  drivers/rtc/rtc-cmos.c: fix accidentally enabling rtc channel
  ...
  • Loading branch information
Linus Torvalds committed Jun 12, 2013
2 parents 1a9c3d6 + c2853c8 commit a568fa1
Show file tree
Hide file tree
Showing 28 changed files with 321 additions and 168 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Atmel AT91RM9200 Real Time Clock

Required properties:
- compatible: should be: "atmel,at91rm9200-rtc"
- compatible: should be: "atmel,at91rm9200-rtc" or "atmel,at91sam9x5-rtc"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: rtc alarm/event interrupt
Expand Down
32 changes: 16 additions & 16 deletions drivers/block/cciss.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,6 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id);
static int cciss_open(struct block_device *bdev, fmode_t mode);
static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode);
static void cciss_release(struct gendisk *disk, fmode_t mode);
static int do_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg);
static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg);
static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
Expand Down Expand Up @@ -235,7 +233,7 @@ static const struct block_device_operations cciss_fops = {
.owner = THIS_MODULE,
.open = cciss_unlocked_open,
.release = cciss_release,
.ioctl = do_ioctl,
.ioctl = cciss_ioctl,
.getgeo = cciss_getgeo,
#ifdef CONFIG_COMPAT
.compat_ioctl = cciss_compat_ioctl,
Expand Down Expand Up @@ -1143,16 +1141,6 @@ static void cciss_release(struct gendisk *disk, fmode_t mode)
mutex_unlock(&cciss_mutex);
}

static int do_ioctl(struct block_device *bdev, fmode_t mode,
unsigned cmd, unsigned long arg)
{
int ret;
mutex_lock(&cciss_mutex);
ret = cciss_ioctl(bdev, mode, cmd, arg);
mutex_unlock(&cciss_mutex);
return ret;
}

#ifdef CONFIG_COMPAT

static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
Expand All @@ -1179,7 +1167,7 @@ static int cciss_compat_ioctl(struct block_device *bdev, fmode_t mode,
case CCISS_REGNEWD:
case CCISS_RESCANDISK:
case CCISS_GETLUNINFO:
return do_ioctl(bdev, mode, cmd, arg);
return cciss_ioctl(bdev, mode, cmd, arg);

case CCISS_PASSTHRU32:
return cciss_ioctl32_passthru(bdev, mode, cmd, arg);
Expand Down Expand Up @@ -1219,7 +1207,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
if (err)
return -EFAULT;

err = do_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p);
err = cciss_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p);
if (err)
return err;
err |=
Expand Down Expand Up @@ -1261,7 +1249,7 @@ static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode,
if (err)
return -EFAULT;

err = do_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p);
err = cciss_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p);
if (err)
return err;
err |=
Expand Down Expand Up @@ -1311,11 +1299,14 @@ static int cciss_getpciinfo(ctlr_info_t *h, void __user *argp)
static int cciss_getintinfo(ctlr_info_t *h, void __user *argp)
{
cciss_coalint_struct intinfo;
unsigned long flags;

if (!argp)
return -EINVAL;
spin_lock_irqsave(&h->lock, flags);
intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay);
intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount);
spin_unlock_irqrestore(&h->lock, flags);
if (copy_to_user
(argp, &intinfo, sizeof(cciss_coalint_struct)))
return -EFAULT;
Expand Down Expand Up @@ -1356,12 +1347,15 @@ static int cciss_setintinfo(ctlr_info_t *h, void __user *argp)
static int cciss_getnodename(ctlr_info_t *h, void __user *argp)
{
NodeName_type NodeName;
unsigned long flags;
int i;

if (!argp)
return -EINVAL;
spin_lock_irqsave(&h->lock, flags);
for (i = 0; i < 16; i++)
NodeName[i] = readb(&h->cfgtable->ServerName[i]);
spin_unlock_irqrestore(&h->lock, flags);
if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
return -EFAULT;
return 0;
Expand Down Expand Up @@ -1398,10 +1392,13 @@ static int cciss_setnodename(ctlr_info_t *h, void __user *argp)
static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp)
{
Heartbeat_type heartbeat;
unsigned long flags;

if (!argp)
return -EINVAL;
spin_lock_irqsave(&h->lock, flags);
heartbeat = readl(&h->cfgtable->HeartBeat);
spin_unlock_irqrestore(&h->lock, flags);
if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type)))
return -EFAULT;
return 0;
Expand All @@ -1410,10 +1407,13 @@ static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp)
static int cciss_getbustypes(ctlr_info_t *h, void __user *argp)
{
BusTypes_type BusTypes;
unsigned long flags;

if (!argp)
return -EINVAL;
spin_lock_irqsave(&h->lock, flags);
BusTypes = readl(&h->cfgtable->BusTypes);
spin_unlock_irqrestore(&h->lock, flags);
if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type)))
return -EFAULT;
return 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/misc/sgi-gru/grufile.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static long gru_get_config_info(unsigned long arg)
nodesperblade = 2;
else
nodesperblade = 1;
memset(&info, 0, sizeof(info));
info.cpus = num_online_cpus();
info.nodes = num_online_nodes();
info.blades = info.nodes / nodesperblade;
Expand Down
131 changes: 111 additions & 20 deletions drivers/rtc/rtc-at91rm9200.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/ioctl.h>
#include <linux/completion.h>
#include <linux/io.h>
Expand All @@ -42,10 +43,65 @@

#define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */

struct at91_rtc_config {
bool use_shadow_imr;
};

static const struct at91_rtc_config *at91_rtc_config;
static DECLARE_COMPLETION(at91_rtc_updated);
static unsigned int at91_alarm_year = AT91_RTC_EPOCH;
static void __iomem *at91_rtc_regs;
static int irq;
static DEFINE_SPINLOCK(at91_rtc_lock);
static u32 at91_rtc_shadow_imr;

static void at91_rtc_write_ier(u32 mask)
{
unsigned long flags;

spin_lock_irqsave(&at91_rtc_lock, flags);
at91_rtc_shadow_imr |= mask;
at91_rtc_write(AT91_RTC_IER, mask);
spin_unlock_irqrestore(&at91_rtc_lock, flags);
}

static void at91_rtc_write_idr(u32 mask)
{
unsigned long flags;

spin_lock_irqsave(&at91_rtc_lock, flags);
at91_rtc_write(AT91_RTC_IDR, mask);
/*
* Register read back (of any RTC-register) needed to make sure
* IDR-register write has reached the peripheral before updating
* shadow mask.
*
* Note that there is still a possibility that the mask is updated
* before interrupts have actually been disabled in hardware. The only
* way to be certain would be to poll the IMR-register, which is is
* the very register we are trying to emulate. The register read back
* is a reasonable heuristic.
*/
at91_rtc_read(AT91_RTC_SR);
at91_rtc_shadow_imr &= ~mask;
spin_unlock_irqrestore(&at91_rtc_lock, flags);
}

static u32 at91_rtc_read_imr(void)
{
unsigned long flags;
u32 mask;

if (at91_rtc_config->use_shadow_imr) {
spin_lock_irqsave(&at91_rtc_lock, flags);
mask = at91_rtc_shadow_imr;
spin_unlock_irqrestore(&at91_rtc_lock, flags);
} else {
mask = at91_rtc_read(AT91_RTC_IMR);
}

return mask;
}

/*
* Decode time/date into rtc_time structure
Expand Down Expand Up @@ -110,9 +166,9 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
cr = at91_rtc_read(AT91_RTC_CR);
at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM);

at91_rtc_write(AT91_RTC_IER, AT91_RTC_ACKUPD);
at91_rtc_write_ier(AT91_RTC_ACKUPD);
wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */
at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD);
at91_rtc_write_idr(AT91_RTC_ACKUPD);

at91_rtc_write(AT91_RTC_TIMR,
bin2bcd(tm->tm_sec) << 0
Expand Down Expand Up @@ -144,7 +200,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
tm->tm_year = at91_alarm_year - 1900;

alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM)
alrm->enabled = (at91_rtc_read_imr() & AT91_RTC_ALARM)
? 1 : 0;

dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
Expand All @@ -169,7 +225,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
tm.tm_min = alrm->time.tm_min;
tm.tm_sec = alrm->time.tm_sec;

at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM);
at91_rtc_write_idr(AT91_RTC_ALARM);
at91_rtc_write(AT91_RTC_TIMALR,
bin2bcd(tm.tm_sec) << 0
| bin2bcd(tm.tm_min) << 8
Expand All @@ -182,7 +238,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)

if (alrm->enabled) {
at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM);
at91_rtc_write_ier(AT91_RTC_ALARM);
}

dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
Expand All @@ -198,9 +254,9 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)

if (enabled) {
at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM);
at91_rtc_write_ier(AT91_RTC_ALARM);
} else
at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM);
at91_rtc_write_idr(AT91_RTC_ALARM);

return 0;
}
Expand All @@ -209,7 +265,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
*/
static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
{
unsigned long imr = at91_rtc_read(AT91_RTC_IMR);
unsigned long imr = at91_rtc_read_imr();

seq_printf(seq, "update_IRQ\t: %s\n",
(imr & AT91_RTC_ACKUPD) ? "yes" : "no");
Expand All @@ -229,7 +285,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
unsigned int rtsr;
unsigned long events = 0;

rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read(AT91_RTC_IMR);
rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read_imr();
if (rtsr) { /* this interrupt is shared! Is it ours? */
if (rtsr & AT91_RTC_ALARM)
events |= (RTC_AF | RTC_IRQF);
Expand All @@ -250,6 +306,43 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
return IRQ_NONE; /* not handled */
}

static const struct at91_rtc_config at91rm9200_config = {
};

static const struct at91_rtc_config at91sam9x5_config = {
.use_shadow_imr = true,
};

#ifdef CONFIG_OF
static const struct of_device_id at91_rtc_dt_ids[] = {
{
.compatible = "atmel,at91rm9200-rtc",
.data = &at91rm9200_config,
}, {
.compatible = "atmel,at91sam9x5-rtc",
.data = &at91sam9x5_config,
}, {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids);
#endif

static const struct at91_rtc_config *
at91_rtc_get_config(struct platform_device *pdev)
{
const struct of_device_id *match;

if (pdev->dev.of_node) {
match = of_match_node(at91_rtc_dt_ids, pdev->dev.of_node);
if (!match)
return NULL;
return (const struct at91_rtc_config *)match->data;
}

return &at91rm9200_config;
}

static const struct rtc_class_ops at91_rtc_ops = {
.read_time = at91_rtc_readtime,
.set_time = at91_rtc_settime,
Expand All @@ -268,6 +361,10 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
struct resource *regs;
int ret = 0;

at91_rtc_config = at91_rtc_get_config(pdev);
if (!at91_rtc_config)
return -ENODEV;

regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
dev_err(&pdev->dev, "no mmio resource defined\n");
Expand All @@ -290,7 +387,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
at91_rtc_write(AT91_RTC_MR, 0); /* 24 hour mode */

/* Disable all interrupts */
at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM |
at91_rtc_write_idr(AT91_RTC_ACKUPD | AT91_RTC_ALARM |
AT91_RTC_SECEV | AT91_RTC_TIMEV |
AT91_RTC_CALEV);

Expand Down Expand Up @@ -335,7 +432,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
struct rtc_device *rtc = platform_get_drvdata(pdev);

/* Disable all interrupts */
at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM |
at91_rtc_write_idr(AT91_RTC_ACKUPD | AT91_RTC_ALARM |
AT91_RTC_SECEV | AT91_RTC_TIMEV |
AT91_RTC_CALEV);
free_irq(irq, pdev);
Expand All @@ -358,13 +455,13 @@ static int at91_rtc_suspend(struct device *dev)
/* this IRQ is shared with DBGU and other hardware which isn't
* necessarily doing PM like we are...
*/
at91_rtc_imr = at91_rtc_read(AT91_RTC_IMR)
at91_rtc_imr = at91_rtc_read_imr()
& (AT91_RTC_ALARM|AT91_RTC_SECEV);
if (at91_rtc_imr) {
if (device_may_wakeup(dev))
enable_irq_wake(irq);
else
at91_rtc_write(AT91_RTC_IDR, at91_rtc_imr);
at91_rtc_write_idr(at91_rtc_imr);
}
return 0;
}
Expand All @@ -375,20 +472,14 @@ static int at91_rtc_resume(struct device *dev)
if (device_may_wakeup(dev))
disable_irq_wake(irq);
else
at91_rtc_write(AT91_RTC_IER, at91_rtc_imr);
at91_rtc_write_ier(at91_rtc_imr);
}
return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume);

static const struct of_device_id at91_rtc_dt_ids[] = {
{ .compatible = "atmel,at91rm9200-rtc" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids);

static struct platform_driver at91_rtc_driver = {
.remove = __exit_p(at91_rtc_remove),
.driver = {
Expand Down
Loading

0 comments on commit a568fa1

Please sign in to comment.