summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig4
-rw-r--r--drivers/block/aoe/aoechr.c3
-rw-r--r--drivers/block/blockconsole.c5
-rw-r--r--drivers/block/drbd/drbd_bitmap.c3
-rw-r--r--drivers/block/drbd/drbd_receiver.c5
-rw-r--r--drivers/block/drbd/drbd_worker.c9
-rw-r--r--drivers/block/drbd/drbd_wrappers.h9
-rw-r--r--drivers/block/floppy.c3
-rw-r--r--drivers/block/mg_disk.c2
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c86
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h8
-rw-r--r--drivers/block/pktcdvd.c9
-rw-r--r--drivers/block/swim3.c2
-rw-r--r--drivers/block/virtio_blk.c31
-rw-r--r--drivers/block/xen-blkback/blkback.c3
-rw-r--r--drivers/char/mem.c36
-rw-r--r--drivers/char/random.c30
-rw-r--r--drivers/firmware/dmi_scan.c80
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c8
-rw-r--r--drivers/infiniband/hw/amso1100/c2.h1
-rw-r--r--drivers/infiniband/hw/amso1100/c2_qp.c3
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_resource.c4
-rw-r--r--drivers/infiniband/hw/cxgb4/id_table.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c1
-rw-r--r--drivers/infiniband/hw/mlx4/cm.c4
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_file_ops.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c2
-rw-r--r--drivers/leds/leds-ot200.c14
-rw-r--r--drivers/lguest/page_tables.c2
-rw-r--r--drivers/md/bcache/alloc.c3
-rw-r--r--drivers/md/bcache/btree.c3
-rw-r--r--drivers/md/bcache/io.c6
-rw-r--r--drivers/md/bcache/journal.c9
-rw-r--r--drivers/md/bcache/movinggc.c3
-rw-r--r--drivers/md/bcache/request.c9
-rw-r--r--drivers/md/bcache/request.h3
-rw-r--r--drivers/md/bcache/super.c11
-rw-r--r--drivers/md/bcache/writeback.c8
-rw-r--r--drivers/md/dm-bufio.c9
-rw-r--r--drivers/md/dm-cache-target.c3
-rw-r--r--drivers/md/dm-crypt.c3
-rw-r--r--drivers/md/dm-io.c2
-rw-r--r--drivers/md/dm-snap.c3
-rw-r--r--drivers/md/dm-thin.c3
-rw-r--r--drivers/md/dm-verity.c3
-rw-r--r--drivers/md/dm.c8
-rw-r--r--drivers/md/faulty.c3
-rw-r--r--drivers/md/md.c9
-rw-r--r--drivers/md/multipath.c3
-rw-r--r--drivers/md/raid1.c12
-rw-r--r--drivers/md/raid10.c18
-rw-r--r--drivers/md/raid5.c15
-rw-r--r--drivers/media/platform/Kconfig1
-rw-r--r--drivers/media/platform/coda.c45
-rw-r--r--drivers/memstick/host/r592.c8
-rw-r--r--drivers/message/i2o/i2o_config.c10
-rw-r--r--drivers/misc/Kconfig9
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/sram.c121
-rw-r--r--drivers/mmc/core/core.c4
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c4
-rw-r--r--drivers/net/hamradio/baycom_epp.c2
-rw-r--r--drivers/net/hamradio/hdlcdrv.c2
-rw-r--r--drivers/net/hamradio/yam.c2
-rw-r--r--drivers/net/team/team_mode_random.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c2
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c4
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c10
-rw-r--r--drivers/pps/Kconfig6
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c4
-rw-r--r--drivers/rtc/class.c70
-rw-r--r--drivers/rtc/rtc-88pm80x.c5
-rw-r--r--drivers/rtc/rtc-ab3100.c21
-rw-r--r--drivers/rtc/rtc-at32ap700x.c12
-rw-r--r--drivers/rtc/rtc-at91rm9200.c36
-rw-r--r--drivers/rtc/rtc-au1xxx.c18
-rw-r--r--drivers/rtc/rtc-bq32k.c5
-rw-r--r--drivers/rtc/rtc-coh901331.c18
-rw-r--r--drivers/rtc/rtc-da9052.c5
-rw-r--r--drivers/rtc/rtc-da9055.c5
-rw-r--r--drivers/rtc/rtc-davinci.c24
-rw-r--r--drivers/rtc/rtc-dm355evm.c7
-rw-r--r--drivers/rtc/rtc-ds1286.c3
-rw-r--r--drivers/rtc/rtc-ds1302.c22
-rw-r--r--drivers/rtc/rtc-ds1307.c74
-rw-r--r--drivers/rtc/rtc-ds1374.c10
-rw-r--r--drivers/rtc/rtc-ds1390.c2
-rw-r--r--drivers/rtc/rtc-ds1511.c8
-rw-r--r--drivers/rtc/rtc-ds1553.c6
-rw-r--r--drivers/rtc/rtc-ds1672.c8
-rw-r--r--drivers/rtc/rtc-ds1742.c8
-rw-r--r--drivers/rtc/rtc-ds3234.c9
-rw-r--r--drivers/rtc/rtc-efi.c19
-rw-r--r--drivers/rtc/rtc-em3027.c7
-rw-r--r--drivers/rtc/rtc-ep93xx.c11
-rw-r--r--drivers/rtc/rtc-fm3130.c2
-rw-r--r--drivers/rtc/rtc-generic.c21
-rw-r--r--drivers/rtc/rtc-hid-sensor-time.c7
-rw-r--r--drivers/rtc/rtc-imxdi.c23
-rw-r--r--drivers/rtc/rtc-lp8788.c5
-rw-r--r--drivers/rtc/rtc-lpc32xx.c5
-rw-r--r--drivers/rtc/rtc-ls1x.c5
-rw-r--r--drivers/rtc/rtc-m41t93.c11
-rw-r--r--drivers/rtc/rtc-m41t94.c11
-rw-r--r--drivers/rtc/rtc-m48t86.c11
-rw-r--r--drivers/rtc/rtc-max6900.c9
-rw-r--r--drivers/rtc/rtc-max6902.c9
-rw-r--r--drivers/rtc/rtc-max77686.c71
-rw-r--r--drivers/rtc/rtc-max8907.c20
-rw-r--r--drivers/rtc/rtc-max8997.c17
-rw-r--r--drivers/rtc/rtc-mc13xxx.c12
-rw-r--r--drivers/rtc/rtc-msm6242.c13
-rw-r--r--drivers/rtc/rtc-mv.c23
-rw-r--r--drivers/rtc/rtc-mxc.c15
-rw-r--r--drivers/rtc/rtc-nuc900.c19
-rw-r--r--drivers/rtc/rtc-omap.c57
-rw-r--r--drivers/rtc/rtc-palmas.c19
-rw-r--r--drivers/rtc/rtc-pcap.c19
-rw-r--r--drivers/rtc/rtc-pcf8523.c6
-rw-r--r--drivers/rtc/rtc-ps3.c16
-rw-r--r--drivers/rtc/rtc-pxa.c88
-rw-r--r--drivers/rtc/rtc-r9701.c9
-rw-r--r--drivers/rtc/rtc-rc5t583.c19
-rw-r--r--drivers/rtc/rtc-rp5c01.c13
-rw-r--r--drivers/rtc/rtc-rs5c313.c6
-rw-r--r--drivers/rtc/rtc-rv3029c2.c16
-rw-r--r--drivers/rtc/rtc-rx4581.c9
-rw-r--r--drivers/rtc/rtc-rx8581.c8
-rw-r--r--drivers/rtc/rtc-s3c.c32
-rw-r--r--drivers/rtc/rtc-sa1100.c12
-rw-r--r--drivers/rtc/rtc-sh.c22
-rw-r--r--drivers/rtc/rtc-snvs.c6
-rw-r--r--drivers/rtc/rtc-spear.c5
-rw-r--r--drivers/rtc/rtc-starfire.c23
-rw-r--r--drivers/rtc/rtc-stk17ta8.c6
-rw-r--r--drivers/rtc/rtc-sun4v.c22
-rw-r--r--drivers/rtc/rtc-tegra.c64
-rw-r--r--drivers/rtc/rtc-test.c10
-rw-r--r--drivers/rtc/rtc-tile.c9
-rw-r--r--drivers/rtc/rtc-tps6586x.c14
-rw-r--r--drivers/rtc/rtc-tps65910.c13
-rw-r--r--drivers/rtc/rtc-tps80031.c11
-rw-r--r--drivers/rtc/rtc-tx4939.c19
-rw-r--r--drivers/rtc/rtc-v3020.c37
-rw-r--r--drivers/rtc/rtc-vt8500.c8
-rw-r--r--drivers/rtc/rtc-wm831x.c6
-rw-r--r--drivers/rtc/rtc-wm8350.c19
-rw-r--r--drivers/rtc/rtc-x1205.c14
-rw-r--r--drivers/scsi/fcoe/fcoe_ctlr.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c6
-rw-r--r--drivers/scsi/sg.c1
-rw-r--r--drivers/staging/android/logger.c1
-rw-r--r--drivers/staging/zcache/Kconfig6
-rw-r--r--drivers/staging/zcache/ramster.h6
-rw-r--r--drivers/staging/zcache/ramster/nodemanager.c9
-rw-r--r--drivers/staging/zcache/ramster/ramster.c29
-rw-r--r--drivers/staging/zcache/ramster/ramster.h2
-rw-r--r--drivers/staging/zcache/ramster/ramster_nodemanager.h2
-rw-r--r--drivers/staging/zcache/tmem.c6
-rw-r--r--drivers/staging/zcache/tmem.h8
-rw-r--r--drivers/staging/zcache/zcache-main.c64
-rw-r--r--drivers/staging/zcache/zcache.h2
-rw-r--r--drivers/target/target_core_iblock.c6
-rw-r--r--drivers/target/target_core_pscsi.c3
-rw-r--r--drivers/usb/gadget/amd5536udc.c4
-rw-r--r--drivers/usb/gadget/inode.c42
-rw-r--r--drivers/uwb/rsv.c4
-rw-r--r--drivers/video/Kconfig26
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/backlight/Kconfig9
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/adp5520_bl.c28
-rw-r--r--drivers/video/backlight/adp8860_bl.c23
-rw-r--r--drivers/video/backlight/adp8870_bl.c33
-rw-r--r--drivers/video/backlight/ams369fg06.c21
-rw-r--r--drivers/video/backlight/as3711_bl.c118
-rw-r--r--drivers/video/backlight/atmel-pwm-bl.c14
-rw-r--r--drivers/video/backlight/corgi_lcd.c18
-rw-r--r--drivers/video/backlight/da903x_bl.c30
-rw-r--r--drivers/video/backlight/ep93xx_bl.c20
-rw-r--r--drivers/video/backlight/generic_bl.c6
-rw-r--r--drivers/video/backlight/hp680_bl.c18
-rw-r--r--drivers/video/backlight/ili922x.c555
-rw-r--r--drivers/video/backlight/ili9320.c2
-rw-r--r--drivers/video/backlight/jornada720_bl.c18
-rw-r--r--drivers/video/backlight/jornada720_lcd.c21
-rw-r--r--drivers/video/backlight/kb3886_bl.c18
-rw-r--r--drivers/video/backlight/l4f00242t03.c27
-rw-r--r--drivers/video/backlight/ld9040.c20
-rw-r--r--drivers/video/backlight/lm3533_bl.c22
-rw-r--r--drivers/video/backlight/lms501kf03.c22
-rw-r--r--drivers/video/backlight/locomolcd.c16
-rw-r--r--drivers/video/backlight/lp855x_bl.c7
-rw-r--r--drivers/video/backlight/ltv350qv.c18
-rw-r--r--drivers/video/backlight/omap1_bl.c4
-rw-r--r--drivers/video/backlight/platform_lcd.c6
-rw-r--r--drivers/video/backlight/s6e63m0.c20
-rw-r--r--drivers/video/backlight/tdo24m.c18
-rw-r--r--drivers/video/console/fbcon_cw.c3
-rw-r--r--drivers/video/cyber2000fb.c3
-rw-r--r--drivers/video/ep93xx-fb.c18
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi.c8
-rw-r--r--drivers/video/hyperv_fb.c829
-rw-r--r--drivers/video/matrox/matroxfb_maven.c16
-rw-r--r--drivers/video/mmp/core.c2
-rw-r--r--drivers/video/mmp/hw/mmp_ctrl.h479
-rw-r--r--drivers/video/simplefb.c234
-rw-r--r--drivers/video/uvesafb.c2
-rw-r--r--drivers/xen/Kconfig4
-rw-r--r--drivers/xen/tmem.c55
-rw-r--r--drivers/xen/xen-selfballoon.c13
212 files changed, 3196 insertions, 1956 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 1d855bfce4da..9953a42809ec 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -120,6 +120,8 @@ source "drivers/vfio/Kconfig"
source "drivers/vlynq/Kconfig"
+source "drivers/virt/Kconfig"
+
source "drivers/virtio/Kconfig"
source "drivers/hv/Kconfig"
@@ -144,8 +146,6 @@ source "drivers/remoteproc/Kconfig"
source "drivers/rpmsg/Kconfig"
-source "drivers/virt/Kconfig"
-
source "drivers/devfreq/Kconfig"
source "drivers/extcon/Kconfig"
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 42e67ad6bd20..ab41be625a53 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -139,13 +139,12 @@ bail: spin_unlock_irqrestore(&emsgs_lock, flags);
return;
}
- mp = kmalloc(n, GFP_ATOMIC);
+ mp = kmemdup(msg, n, GFP_ATOMIC);
if (mp == NULL) {
printk(KERN_ERR "aoe: allocation failure, len=%ld\n", n);
goto bail;
}
- memcpy(mp, msg, n);
em->msg = mp;
em->flags |= EMFL_VALID;
em->len = n;
diff --git a/drivers/block/blockconsole.c b/drivers/block/blockconsole.c
index 01ddbc6fa6b6..1600a19c183a 100644
--- a/drivers/block/blockconsole.c
+++ b/drivers/block/blockconsole.c
@@ -164,7 +164,8 @@ static void bcon_advance_console_bytes(struct blockconsole *bc, int bytes)
} while (cmpxchg64(&bc->console_bytes, old, new) != old);
}
-static void request_complete(struct bio *bio, int err)
+static void request_complete(struct bio *bio, int err,
+ struct batch_complete *batch)
{
complete((struct completion *)bio->bi_private);
}
@@ -289,7 +290,7 @@ static void bcon_unregister(struct work_struct *work)
}
#define BCON_MAX_ERRORS 10
-static void bcon_end_io(struct bio *bio, int err)
+static void bcon_end_io(struct bio *bio, int err, struct batch_complete *batch)
{
struct bcon_bio *bcon_bio = container_of(bio, struct bcon_bio, bio);
struct blockconsole *bc = bio->bi_private;
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 64fbb8385cdc..046aa1793514 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -948,7 +948,8 @@ static void bm_aio_ctx_destroy(struct kref *kref)
}
/* bv_page may be a copy, or may be the original */
-static void bm_async_io_complete(struct bio *bio, int error)
+static void bm_async_io_complete(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct bm_aio_ctx *ctx = bio->bi_private;
struct drbd_conf *mdev = ctx->mdev;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 0f449bbf0edf..4222affff488 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -757,7 +757,8 @@ static struct socket *drbd_wait_for_connect(struct drbd_tconn *tconn, struct acc
rcu_read_unlock();
timeo = connect_int * HZ;
- timeo += (random32() & 1) ? timeo / 7 : -timeo / 7; /* 28.5% random jitter */
+ /* 28.5% random jitter */
+ timeo += (prandom_u32() & 1) ? timeo / 7 : -timeo / 7;
err = wait_for_completion_interruptible_timeout(&ad->door_bell, timeo);
if (err <= 0)
@@ -954,7 +955,7 @@ retry:
conn_warn(tconn, "Error receiving initial packet\n");
sock_release(s);
randomize:
- if (random32() & 1)
+ if (prandom_u32() & 1)
goto retry;
}
}
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 891c0ecaa292..04a80af8fddb 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -64,7 +64,8 @@ rwlock_t global_state_lock;
/* used for synchronous meta data and bitmap IO
* submitted by drbd_md_sync_page_io()
*/
-void drbd_md_io_complete(struct bio *bio, int error)
+void drbd_md_io_complete(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct drbd_md_io *md_io;
struct drbd_conf *mdev;
@@ -167,7 +168,8 @@ static void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __rel
/* writes on behalf of the partner, or resync writes,
* "submitted" by the receiver.
*/
-void drbd_peer_request_endio(struct bio *bio, int error)
+void drbd_peer_request_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct drbd_peer_request *peer_req = bio->bi_private;
struct drbd_conf *mdev = peer_req->w.mdev;
@@ -203,7 +205,8 @@ void drbd_peer_request_endio(struct bio *bio, int error)
/* read, readA or write requests on R_PRIMARY coming from drbd_make_request
*/
-void drbd_request_endio(struct bio *bio, int error)
+void drbd_request_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
unsigned long flags;
struct drbd_request *req = bio->bi_private;
diff --git a/drivers/block/drbd/drbd_wrappers.h b/drivers/block/drbd/drbd_wrappers.h
index 328f18e4b4ee..d443dc06b854 100644
--- a/drivers/block/drbd/drbd_wrappers.h
+++ b/drivers/block/drbd/drbd_wrappers.h
@@ -20,9 +20,12 @@ static inline void drbd_set_my_capacity(struct drbd_conf *mdev,
#define drbd_bio_uptodate(bio) bio_flagged(bio, BIO_UPTODATE)
/* bi_end_io handlers */
-extern void drbd_md_io_complete(struct bio *bio, int error);
-extern void drbd_peer_request_endio(struct bio *bio, int error);
-extern void drbd_request_endio(struct bio *bio, int error);
+extern void drbd_md_io_complete(struct bio *bio, int error,
+ struct batch_complete *batch);
+extern void drbd_peer_request_endio(struct bio *bio, int error,
+ struct batch_complete *batch);
+extern void drbd_request_endio(struct bio *bio, int error,
+ struct batch_complete *batch);
/*
* used to submit our private bio
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 83232639034e..629b6d506cd0 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3748,7 +3748,8 @@ static unsigned int floppy_check_events(struct gendisk *disk,
* a disk in the drive, and whether that disk is writable.
*/
-static void floppy_rb0_complete(struct bio *bio, int err)
+static void floppy_rb0_complete(struct bio *bio, int err,
+ struct batch_complete *batch)
{
complete((struct completion *)bio->bi_private);
}
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
index 076ae7f1b781..a56cfcd5d648 100644
--- a/drivers/block/mg_disk.c
+++ b/drivers/block/mg_disk.c
@@ -780,6 +780,7 @@ static const struct block_device_operations mg_disk_ops = {
.getgeo = mg_getgeo
};
+#ifdef CONFIG_PM_SLEEP
static int mg_suspend(struct device *dev)
{
struct mg_drv_data *prv_data = dev->platform_data;
@@ -824,6 +825,7 @@ static int mg_resume(struct device *dev)
return 0;
}
+#endif
static SIMPLE_DEV_PM_OPS(mg_pm, mg_suspend, mg_resume);
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 32c678028e53..122c7b9e5e0f 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -151,6 +151,9 @@ static void mtip_command_cleanup(struct driver_data *dd)
struct mtip_cmd *command;
struct mtip_port *port = dd->port;
static int in_progress;
+ struct batch_complete batch;
+
+ batch_complete_init(&batch);
if (in_progress)
return;
@@ -166,11 +169,9 @@ static void mtip_command_cleanup(struct driver_data *dd)
command = &port->commands[commandindex];
if (atomic_read(&command->active)
- && (command->async_callback)) {
- command->async_callback(command->async_data,
- -ENODEV);
- command->async_callback = NULL;
- command->async_data = NULL;
+ && (command->bio)) {
+ bio_endio_batch(command->bio, -ENODEV, &batch);
+ command->bio = NULL;
}
dma_unmap_sg(&port->dd->pdev->dev,
@@ -178,9 +179,10 @@ static void mtip_command_cleanup(struct driver_data *dd)
command->scatter_ents,
command->direction);
}
+ up(&port->cmd_slot);
}
- up(&port->cmd_slot);
+ batch_complete(&batch);
set_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag);
in_progress = 0;
@@ -580,6 +582,9 @@ static void mtip_timeout_function(unsigned long int data)
unsigned int bit, group;
unsigned int num_command_slots;
unsigned long to, tagaccum[SLOTBITS_IN_LONGS];
+ struct batch_complete batch;
+
+ batch_complete_init(&batch);
if (unlikely(!port))
return;
@@ -622,11 +627,9 @@ static void mtip_timeout_function(unsigned long int data)
writel(1 << bit, port->completed[group]);
/* Call the async completion callback. */
- if (likely(command->async_callback))
- command->async_callback(command->async_data,
- -EIO);
- command->async_callback = NULL;
- command->comp_func = NULL;
+ if (likely(command->bio))
+ bio_endio_batch(command->bio, -EIO, &batch);
+ command->bio = NULL;
/* Unmap the DMA scatter list entries */
dma_unmap_sg(&port->dd->pdev->dev,
@@ -645,6 +648,8 @@ static void mtip_timeout_function(unsigned long int data)
}
}
+ batch_complete(&batch);
+
if (cmdto_cnt) {
print_tags(port->dd, "timed out", tagaccum, cmdto_cnt);
if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
@@ -695,7 +700,8 @@ static void mtip_timeout_function(unsigned long int data)
static void mtip_async_complete(struct mtip_port *port,
int tag,
void *data,
- int status)
+ int status,
+ struct batch_complete *batch)
{
struct mtip_cmd *command;
struct driver_data *dd = data;
@@ -712,11 +718,10 @@ static void mtip_async_complete(struct mtip_port *port,
}
/* Upper layer callback */
- if (likely(command->async_callback))
- command->async_callback(command->async_data, cb_status);
+ if (likely(command->bio))
+ bio_endio_batch(command->bio, cb_status, batch);
- command->async_callback = NULL;
- command->comp_func = NULL;
+ command->bio = NULL;
/* Unmap the DMA scatter list entries */
dma_unmap_sg(&dd->pdev->dev,
@@ -749,24 +754,22 @@ static void mtip_async_complete(struct mtip_port *port,
static void mtip_completion(struct mtip_port *port,
int tag,
void *data,
- int status)
+ int status,
+ struct batch_complete *batch)
{
- struct mtip_cmd *command = &port->commands[tag];
struct completion *waiting = data;
if (unlikely(status == PORT_IRQ_TF_ERR))
dev_warn(&port->dd->pdev->dev,
"Internal command %d completed with TFE\n", tag);
- command->async_callback = NULL;
- command->comp_func = NULL;
-
complete(waiting);
}
static void mtip_null_completion(struct mtip_port *port,
int tag,
void *data,
- int status)
+ int status,
+ struct batch_complete *batch)
{
return;
}
@@ -795,6 +798,7 @@ static void mtip_handle_tfe(struct driver_data *dd)
unsigned char *buf;
char *fail_reason = NULL;
int fail_all_ncq_write = 0, fail_all_ncq_cmds = 0;
+ struct batch_complete batch;
dev_warn(&dd->pdev->dev, "Taskfile error\n");
@@ -812,13 +816,14 @@ static void mtip_handle_tfe(struct driver_data *dd)
atomic_inc(&cmd->active); /* active > 1 indicates error */
if (cmd->comp_data && cmd->comp_func) {
cmd->comp_func(port, MTIP_TAG_INTERNAL,
- cmd->comp_data, PORT_IRQ_TF_ERR);
+ cmd->comp_data, PORT_IRQ_TF_ERR, NULL);
}
goto handle_tfe_exit;
}
/* clear the tag accumulator */
memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
+ batch_complete_init(&batch);
/* Loop through all the groups */
for (group = 0; group < dd->slot_groups; group++) {
@@ -845,7 +850,7 @@ static void mtip_handle_tfe(struct driver_data *dd)
cmd->comp_func(port,
tag,
cmd->comp_data,
- 0);
+ 0, &batch);
} else {
dev_err(&port->dd->pdev->dev,
"Missing completion func for tag %d",
@@ -858,6 +863,7 @@ static void mtip_handle_tfe(struct driver_data *dd)
}
}
}
+ batch_complete(&batch);
print_tags(dd, "completed (TFE)", tagaccum, cmd_cnt);
@@ -899,6 +905,7 @@ static void mtip_handle_tfe(struct driver_data *dd)
/* clear the tag accumulator */
memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
+ batch_complete_init(&batch);
/* Loop through all the groups */
for (group = 0; group < dd->slot_groups; group++) {
@@ -932,7 +939,7 @@ static void mtip_handle_tfe(struct driver_data *dd)
if (cmd->comp_func) {
cmd->comp_func(port, tag,
cmd->comp_data,
- -ENODATA);
+ -ENODATA, &batch);
}
continue;
}
@@ -962,13 +969,15 @@ static void mtip_handle_tfe(struct driver_data *dd)
port,
tag,
cmd->comp_data,
- PORT_IRQ_TF_ERR);
+ PORT_IRQ_TF_ERR, &batch);
else
dev_warn(&port->dd->pdev->dev,
"Bad completion for tag %d\n",
tag);
}
}
+
+ batch_complete(&batch);
print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt);
handle_tfe_exit:
@@ -989,6 +998,9 @@ static inline void mtip_workq_sdbfx(struct mtip_port *port, int group,
struct driver_data *dd = port->dd;
int tag, bit;
struct mtip_cmd *command;
+ struct batch_complete batch;
+
+ batch_complete_init(&batch);
if (!completed) {
WARN_ON_ONCE(!completed);
@@ -1013,7 +1025,8 @@ static inline void mtip_workq_sdbfx(struct mtip_port *port, int group,
port,
tag,
command->comp_data,
- 0);
+ 0,
+ &batch);
} else {
dev_warn(&dd->pdev->dev,
"Null completion "
@@ -1023,13 +1036,16 @@ static inline void mtip_workq_sdbfx(struct mtip_port *port, int group,
if (mtip_check_surprise_removal(
dd->pdev)) {
mtip_command_cleanup(dd);
- return;
+ goto out;
}
}
}
completed >>= 1;
}
+out:
+ batch_complete(&batch);
+
/* If last, re-enable interrupts */
if (atomic_dec_return(&dd->irq_workers_active) == 0)
writel(0xffffffff, dd->mmio + HOST_IRQ_STAT);
@@ -1050,7 +1066,7 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat)
cmd->comp_func(port,
MTIP_TAG_INTERNAL,
cmd->comp_data,
- 0);
+ 0, NULL);
return;
}
}
@@ -2556,8 +2572,8 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
* None
*/
static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
- int nsect, int nents, int tag, void *callback,
- void *data, int dir)
+ int nsect, int nents, int tag,
+ struct bio *bio, int dir)
{
struct host_to_dev_fis *fis;
struct mtip_port *port = dd->port;
@@ -2612,12 +2628,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
command->comp_func = mtip_async_complete;
command->direction = dma_dir;
- /*
- * Set the completion function and data for the command passed
- * from the upper layer.
- */
- command->async_data = data;
- command->async_callback = callback;
+ command->bio = bio;
/*
* To prevent this command from being issued
@@ -3898,7 +3909,6 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
bio_sectors(bio),
nents,
tag,
- bio_endio,
bio,
bio_data_dir(bio));
} else
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index 8e8334c9dd0f..78456ec8fe6a 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -325,11 +325,9 @@ struct mtip_cmd {
void (*comp_func)(struct mtip_port *port,
int tag,
void *data,
- int status);
- /* Additional callback function that may be called by comp_func() */
- void (*async_callback)(void *data, int status);
-
- void *async_data; /* Addl. data passed to async_callback() */
+ int status,
+ struct batch_complete *batch);
+ struct bio *bio;
int scatter_ents; /* Number of scatter list entries used */
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index dcb18a3d3314..ce42c14808ac 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -980,7 +980,8 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec)
}
}
-static void pkt_end_io_read(struct bio *bio, int err)
+static void pkt_end_io_read(struct bio *bio, int err,
+ struct batch_complete *batch)
{
struct packet_data *pkt = bio->bi_private;
struct pktcdvd_device *pd = pkt->pd;
@@ -998,7 +999,8 @@ static void pkt_end_io_read(struct bio *bio, int err)
pkt_bio_finished(pd);
}
-static void pkt_end_io_packet_write(struct bio *bio, int err)
+static void pkt_end_io_packet_write(struct bio *bio, int err,
+ struct batch_complete *batch)
{
struct packet_data *pkt = bio->bi_private;
struct pktcdvd_device *pd = pkt->pd;
@@ -2339,7 +2341,8 @@ static int pkt_close(struct gendisk *disk, fmode_t mode)
}
-static void pkt_end_io_read_cloned(struct bio *bio, int err)
+static void pkt_end_io_read_cloned(struct bio *bio, int err,
+ struct batch_complete *batch)
{
struct packet_stacked_data *psd = bio->bi_private;
struct pktcdvd_device *pd = psd->pd;
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index 758f2ac878cf..deb722d63d68 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -775,7 +775,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
if (intr & ERROR_INTR) {
n = fs->scount - 1 - resid / 512;
if (n > 0) {
- blk_update_request(req, 0, n << 9);
+ blk_update_request(req, 0, n << 9, NULL);
fs->req_sector += n;
}
if (fs->retries < 5) {
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 64723953e1c9..49d0ec2472c5 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -217,7 +217,8 @@ static void virtblk_bio_send_flush_work(struct work_struct *work)
virtblk_bio_send_flush(vbr);
}
-static inline void virtblk_request_done(struct virtblk_req *vbr)
+static inline void virtblk_request_done(struct virtblk_req *vbr,
+ struct batch_complete *batch)
{
struct virtio_blk *vblk = vbr->vblk;
struct request *req = vbr->req;
@@ -231,11 +232,12 @@ static inline void virtblk_request_done(struct virtblk_req *vbr)
req->errors = (error != 0);
}
- __blk_end_request_all(req, error);
+ blk_end_request_all_batch(req, error, batch);
mempool_free(vbr, vblk->pool);
}
-static inline void virtblk_bio_flush_done(struct virtblk_req *vbr)
+static inline void virtblk_bio_flush_done(struct virtblk_req *vbr,
+ struct batch_complete *batch)
{
struct virtio_blk *vblk = vbr->vblk;
@@ -244,12 +246,13 @@ static inline void virtblk_bio_flush_done(struct virtblk_req *vbr)
INIT_WORK(&vbr->work, virtblk_bio_send_data_work);
queue_work(virtblk_wq, &vbr->work);
} else {
- bio_endio(vbr->bio, virtblk_result(vbr));
+ bio_endio_batch(vbr->bio, virtblk_result(vbr), batch);
mempool_free(vbr, vblk->pool);
}
}
-static inline void virtblk_bio_data_done(struct virtblk_req *vbr)
+static inline void virtblk_bio_data_done(struct virtblk_req *vbr,
+ struct batch_complete *batch)
{
struct virtio_blk *vblk = vbr->vblk;
@@ -259,17 +262,18 @@ static inline void virtblk_bio_data_done(struct virtblk_req *vbr)
INIT_WORK(&vbr->work, virtblk_bio_send_flush_work);
queue_work(virtblk_wq, &vbr->work);
} else {
- bio_endio(vbr->bio, virtblk_result(vbr));
+ bio_endio_batch(vbr->bio, virtblk_result(vbr), batch);
mempool_free(vbr, vblk->pool);
}
}
-static inline void virtblk_bio_done(struct virtblk_req *vbr)
+static inline void virtblk_bio_done(struct virtblk_req *vbr,
+ struct batch_complete *batch)
{
if (unlikely(vbr->flags & VBLK_IS_FLUSH))
- virtblk_bio_flush_done(vbr);
+ virtblk_bio_flush_done(vbr, batch);
else
- virtblk_bio_data_done(vbr);
+ virtblk_bio_data_done(vbr, batch);
}
static void virtblk_done(struct virtqueue *vq)
@@ -279,16 +283,19 @@ static void virtblk_done(struct virtqueue *vq)
struct virtblk_req *vbr;
unsigned long flags;
unsigned int len;
+ struct batch_complete batch;
+
+ batch_complete_init(&batch);
spin_lock_irqsave(vblk->disk->queue->queue_lock, flags);
do {
virtqueue_disable_cb(vq);
while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) {
if (vbr->bio) {
- virtblk_bio_done(vbr);
+ virtblk_bio_done(vbr, &batch);
bio_done = true;
} else {
- virtblk_request_done(vbr);
+ virtblk_request_done(vbr, &batch);
req_done = true;
}
}
@@ -298,6 +305,8 @@ static void virtblk_done(struct virtqueue *vq)
blk_start_queue(vblk->disk->queue);
spin_unlock_irqrestore(vblk->disk->queue->queue_lock, flags);
+ batch_complete(&batch);
+
if (bio_done)
wake_up(&vblk->queue_wait);
}
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index dd5b2fed97e9..990c1d81849f 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -741,7 +741,8 @@ static void __end_block_io_op(struct pending_req *pending_req, int error)
/*
* bio callback.
*/
-static void end_block_io_op(struct bio *bio, int error)
+static void end_block_io_op(struct bio *bio, int error,
+ struct batch_complete *batch)
{
__end_block_io_op(bio->bi_private, error);
bio_put(bio);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 2c644afbcdd4..1ccbe9482faa 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -28,6 +28,7 @@
#include <linux/pfn.h>
#include <linux/export.h>
#include <linux/io.h>
+#include <linux/aio.h>
#include <asm/uaccess.h>
@@ -627,6 +628,18 @@ static ssize_t write_null(struct file *file, const char __user *buf,
return count;
}
+static ssize_t aio_read_null(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
+{
+ return 0;
+}
+
+static ssize_t aio_write_null(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
+{
+ return iov_length(iov, nr_segs);
+}
+
static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf,
struct splice_desc *sd)
{
@@ -670,6 +683,24 @@ static ssize_t read_zero(struct file *file, char __user *buf,
return written ? written : -EFAULT;
}
+static ssize_t aio_read_zero(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
+{
+ size_t written = 0;
+ unsigned long i;
+ ssize_t ret;
+
+ for (i = 0; i < nr_segs; i++) {
+ ret = read_zero(iocb->ki_filp, iov[i].iov_base, iov[i].iov_len,
+ &pos);
+ if (ret < 0)
+ break;
+ written += ret;
+ }
+
+ return written ? written : -EFAULT;
+}
+
static int mmap_zero(struct file *file, struct vm_area_struct *vma)
{
#ifndef CONFIG_MMU
@@ -738,6 +769,7 @@ static int open_port(struct inode *inode, struct file *filp)
#define full_lseek null_lseek
#define write_zero write_null
#define read_full read_zero
+#define aio_write_zero aio_write_null
#define open_mem open_port
#define open_kmem open_mem
#define open_oldmem open_mem
@@ -766,6 +798,8 @@ static const struct file_operations null_fops = {
.llseek = null_lseek,
.read = read_null,
.write = write_null,
+ .aio_read = aio_read_null,
+ .aio_write = aio_write_null,
.splice_write = splice_write_null,
};
@@ -782,6 +816,8 @@ static const struct file_operations zero_fops = {
.llseek = zero_lseek,
.read = read_zero,
.write = write_zero,
+ .aio_read = aio_read_zero,
+ .aio_write = aio_write_zero,
.mmap = mmap_zero,
};
diff --git a/drivers/char/random.c b/drivers/char/random.c
index cd9a6211dcad..73e52b7796f9 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -957,10 +957,23 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
{
ssize_t ret = 0, i;
__u8 tmp[EXTRACT_SIZE];
+ unsigned long flags;
/* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
- if (fips_enabled && !r->last_data_init)
- nbytes += EXTRACT_SIZE;
+ if (fips_enabled) {
+ spin_lock_irqsave(&r->lock, flags);
+ if (!r->last_data_init) {
+ r->last_data_init = true;
+ spin_unlock_irqrestore(&r->lock, flags);
+ trace_extract_entropy(r->name, EXTRACT_SIZE,
+ r->entropy_count, _RET_IP_);
+ xfer_secondary_pool(r, EXTRACT_SIZE);
+ extract_buf(r, tmp);
+ spin_lock_irqsave(&r->lock, flags);
+ memcpy(r->last_data, tmp, EXTRACT_SIZE);
+ }
+ spin_unlock_irqrestore(&r->lock, flags);
+ }
trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);
xfer_secondary_pool(r, nbytes);
@@ -970,19 +983,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
extract_buf(r, tmp);
if (fips_enabled) {
- unsigned long flags;
-
-
- /* prime last_data value if need be, per fips 140-2 */
- if (!r->last_data_init) {
- spin_lock_irqsave(&r->lock, flags);
- memcpy(r->last_data, tmp, EXTRACT_SIZE);
- r->last_data_init = true;
- nbytes -= EXTRACT_SIZE;
- spin_unlock_irqrestore(&r->lock, flags);
- extract_buf(r, tmp);
- }
-
spin_lock_irqsave(&r->lock, flags);
if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
panic("Hardware RNG duplicated output!\n");
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 4cd392dbf115..40e940d4db6b 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -410,22 +410,45 @@ static void __init dmi_dump_ids(void)
printk(KERN_CONT "\n");
}
-static int __init dmi_present(const char __iomem *p)
+static int __init dmi_present(const u8 *buf)
{
- u8 buf[15];
+ int smbios_ver;
- memcpy_fromio(buf, p, 15);
- if (dmi_checksum(buf, 15)) {
+ if (memcmp(buf, "_SM_", 4) == 0 &&
+ buf[5] < 32 && dmi_checksum(buf, buf[5])) {
+ smbios_ver = (buf[6] << 8) + buf[7];
+
+ /* Some BIOS report weird SMBIOS version, fix that up */
+ switch (smbios_ver) {
+ case 0x021F:
+ case 0x0221:
+ pr_debug("SMBIOS version fixup(2.%d->2.%d)\n",
+ smbios_ver & 0xFF, 3);
+ smbios_ver = 0x0203;
+ break;
+ case 0x0233:
+ pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6);
+ smbios_ver = 0x0206;
+ break;
+ }
+ } else {
+ smbios_ver = 0;
+ }
+
+ buf += 16;
+
+ if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
dmi_num = (buf[13] << 8) | buf[12];
dmi_len = (buf[7] << 8) | buf[6];
dmi_base = (buf[11] << 24) | (buf[10] << 16) |
(buf[9] << 8) | buf[8];
if (dmi_walk_early(dmi_decode) == 0) {
- if (dmi_ver)
+ if (smbios_ver) {
+ dmi_ver = smbios_ver;
pr_info("SMBIOS %d.%d present.\n",
dmi_ver >> 8, dmi_ver & 0xFF);
- else {
+ } else {
dmi_ver = (buf[14] & 0xF0) << 4 |
(buf[14] & 0x0F);
pr_info("Legacy DMI %d.%d present.\n",
@@ -435,40 +458,14 @@ static int __init dmi_present(const char __iomem *p)
return 0;
}
}
- dmi_ver = 0;
- return 1;
-}
-static int __init smbios_present(const char __iomem *p)
-{
- u8 buf[32];
-
- memcpy_fromio(buf, p, 32);
- if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) {
- dmi_ver = (buf[6] << 8) + buf[7];
-
- /* Some BIOS report weird SMBIOS version, fix that up */
- switch (dmi_ver) {
- case 0x021F:
- case 0x0221:
- pr_debug("SMBIOS version fixup(2.%d->2.%d)\n",
- dmi_ver & 0xFF, 3);
- dmi_ver = 0x0203;
- break;
- case 0x0233:
- pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6);
- dmi_ver = 0x0206;
- break;
- }
- return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16);
- }
return 1;
}
void __init dmi_scan_machine(void)
{
char __iomem *p, *q;
- int rc;
+ char buf[32];
if (efi_enabled(EFI_CONFIG_TABLES)) {
if (efi.smbios == EFI_INVALID_TABLE_ADDR)
@@ -481,10 +478,10 @@ void __init dmi_scan_machine(void)
p = dmi_ioremap(efi.smbios, 32);
if (p == NULL)
goto error;
-
- rc = smbios_present(p);
+ memcpy_fromio(buf, p, 32);
dmi_iounmap(p, 32);
- if (!rc) {
+
+ if (!dmi_present(buf)) {
dmi_available = 1;
goto out;
}
@@ -499,18 +496,15 @@ void __init dmi_scan_machine(void)
if (p == NULL)
goto error;
+ memset(buf, 0, 16);
for (q = p; q < p + 0x10000; q += 16) {
- if (memcmp(q, "_SM_", 4) == 0 && q - p <= 0xFFE0)
- rc = smbios_present(q);
- else if (memcmp(q, "_DMI_", 5) == 0)
- rc = dmi_present(q);
- else
- continue;
- if (!rc) {
+ memcpy_fromio(buf + 16, q, 16);
+ if (!dmi_present(buf)) {
dmi_available = 1;
dmi_iounmap(p, 0x10000);
goto out;
}
+ memcpy(buf, buf + 16, 16);
}
dmi_iounmap(p, 0x10000);
}
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 6764dce44e84..5cd01936fd7c 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -399,6 +399,14 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
return;
/*
+ * fbdev->blank can be called from irq context in case of a panic.
+ * Since we already have our own special panic handler which will
+ * restore the fbdev console mode completely, just bail out early.
+ */
+ if (oops_in_progress)
+ return;
+
+ /*
* For each CRTC in this fb, turn the connectors on/off.
*/
drm_modeset_lock_all(dev);
diff --git a/drivers/infiniband/hw/amso1100/c2.h b/drivers/infiniband/hw/amso1100/c2.h
index ba7a1208ff9e..d619d735838b 100644
--- a/drivers/infiniband/hw/amso1100/c2.h
+++ b/drivers/infiniband/hw/amso1100/c2.h
@@ -265,7 +265,6 @@ struct c2_pd_table {
struct c2_qp_table {
struct idr idr;
spinlock_t lock;
- int last;
};
struct c2_element {
diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c
index 0ab826b280b2..86708dee58b1 100644
--- a/drivers/infiniband/hw/amso1100/c2_qp.c
+++ b/drivers/infiniband/hw/amso1100/c2_qp.c
@@ -385,8 +385,7 @@ static int c2_alloc_qpn(struct c2_dev *c2dev, struct c2_qp *qp)
idr_preload(GFP_KERNEL);
spin_lock_irq(&c2dev->qp_table.lock);
- ret = idr_alloc(&c2dev->qp_table.idr, qp, c2dev->qp_table.last++, 0,
- GFP_NOWAIT);
+ ret = idr_alloc_cyclic(&c2dev->qp_table.idr, qp, 0, 0, GFP_NOWAIT);
if (ret >= 0)
qp->qpn = ret;
diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c
index 31f9201b2980..c40088ecf9f3 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_resource.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c
@@ -62,13 +62,13 @@ static int __cxio_init_resource_fifo(struct kfifo *fifo,
kfifo_in(fifo, (unsigned char *) &entry, sizeof(u32));
if (random) {
j = 0;
- random_bytes = random32();
+ random_bytes = prandom_u32();
for (i = 0; i < RANDOM_SIZE; i++)
rarray[i] = i + skip_low;
for (i = skip_low + RANDOM_SIZE; i < nr - skip_high; i++) {
if (j >= RANDOM_SIZE) {
j = 0;
- random_bytes = random32();
+ random_bytes = prandom_u32();
}
idx = (random_bytes >> (j * 2)) & 0xF;
kfifo_in(fifo,
diff --git a/drivers/infiniband/hw/cxgb4/id_table.c b/drivers/infiniband/hw/cxgb4/id_table.c
index f95e5df30db2..0161ae6ad629 100644
--- a/drivers/infiniband/hw/cxgb4/id_table.c
+++ b/drivers/infiniband/hw/cxgb4/id_table.c
@@ -54,7 +54,7 @@ u32 c4iw_id_alloc(struct c4iw_id_table *alloc)
if (obj < alloc->max) {
if (alloc->flags & C4IW_ID_TABLE_F_RANDOM)
- alloc->last += random32() % RANDOM_SKIP;
+ alloc->last += prandom_u32() % RANDOM_SKIP;
else
alloc->last = obj + 1;
if (alloc->last >= alloc->max)
@@ -88,7 +88,7 @@ int c4iw_id_table_alloc(struct c4iw_id_table *alloc, u32 start, u32 num,
alloc->start = start;
alloc->flags = flags;
if (flags & C4IW_ID_TABLE_F_RANDOM)
- alloc->last = random32() % RANDOM_SKIP;
+ alloc->last = prandom_u32() % RANDOM_SKIP;
else
alloc->last = 0;
alloc->max = num;
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index aed8afee56da..6d7f453b4d05 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -40,6 +40,7 @@
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/io.h>
+#include <linux/aio.h>
#include <linux/jiffies.h>
#include <linux/cpu.h>
#include <asm/pgtable.h>
diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c
index add98d01476c..d1f5f1dd77b0 100644
--- a/drivers/infiniband/hw/mlx4/cm.c
+++ b/drivers/infiniband/hw/mlx4/cm.c
@@ -204,7 +204,6 @@ static struct id_map_entry *
id_map_alloc(struct ib_device *ibdev, int slave_id, u32 sl_cm_id)
{
int ret;
- static int next_id;
struct id_map_entry *ent;
struct mlx4_ib_sriov *sriov = &to_mdev(ibdev)->sriov;
@@ -223,9 +222,8 @@ id_map_alloc(struct ib_device *ibdev, int slave_id, u32 sl_cm_id)
idr_preload(GFP_KERNEL);
spin_lock(&to_mdev(ibdev)->sriov.id_map_lock);
- ret = idr_alloc(&sriov->pv_id_table, ent, next_id, 0, GFP_NOWAIT);
+ ret = idr_alloc_cyclic(&sriov->pv_id_table, ent, 0, 0, GFP_NOWAIT);
if (ret >= 0) {
- next_id = max(ret + 1, 0);
ent->pv_cm_id = (u32)ret;
sl_id_map_add(ibdev, ent);
list_add_tail(&ent->list, &sriov->cm_list);
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 934792c477bc..4d599cedbb0b 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -93,7 +93,7 @@ static void __propagate_pkey_ev(struct mlx4_ib_dev *dev, int port_num,
__be64 mlx4_ib_gen_node_guid(void)
{
#define NODE_GUID_HI ((u64) (((u64)IB_OPENIB_OUI) << 40))
- return cpu_to_be64(NODE_GUID_HI | random32());
+ return cpu_to_be64(NODE_GUID_HI | prandom_u32());
}
__be64 mlx4_ib_get_new_demux_tid(struct mlx4_ib_demux_ctx *ctx)
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c
index 4f7aa301b3b1..b56c9428f3c5 100644
--- a/drivers/infiniband/hw/qib/qib_file_ops.c
+++ b/drivers/infiniband/hw/qib/qib_file_ops.c
@@ -39,7 +39,7 @@
#include <linux/vmalloc.h>
#include <linux/highmem.h>
#include <linux/io.h>
-#include <linux/uio.h>
+#include <linux/aio.h>
#include <linux/jiffies.h>
#include <asm/pgtable.h>
#include <linux/delay.h>
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 1ef880de3a41..3eceb61e3532 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -460,7 +460,7 @@ static int ipoib_cm_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *even
goto err_qp;
}
- psn = random32() & 0xffffff;
+ psn = prandom_u32() & 0xffffff;
ret = ipoib_cm_modify_rx_qp(dev, cm_id, p->qp, psn);
if (ret)
goto err_modify;
diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c
index ee14662ed5ce..98cae529373f 100644
--- a/drivers/leds/leds-ot200.c
+++ b/drivers/leds/leds-ot200.c
@@ -47,37 +47,37 @@ static struct ot200_led leds[] = {
{
.name = "led_1",
.port = 0x49,
- .mask = BIT(7),
+ .mask = BIT(6),
},
{
.name = "led_2",
.port = 0x49,
- .mask = BIT(6),
+ .mask = BIT(5),
},
{
.name = "led_3",
.port = 0x49,
- .mask = BIT(5),
+ .mask = BIT(4),
},
{
.name = "led_4",
.port = 0x49,
- .mask = BIT(4),
+ .mask = BIT(3),
},
{
.name = "led_5",
.port = 0x49,
- .mask = BIT(3),
+ .mask = BIT(2),
},
{
.name = "led_6",
.port = 0x49,
- .mask = BIT(2),
+ .mask = BIT(1),
},
{
.name = "led_7",
.port = 0x49,
- .mask = BIT(1),
+ .mask = BIT(0),
}
};
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 3b62be160a6e..864baabaee25 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -686,7 +686,7 @@ static unsigned int new_pgdir(struct lg_cpu *cpu,
* We pick one entry at random to throw out. Choosing the Least
* Recently Used might be better, but this is easy.
*/
- next = random32() % ARRAY_SIZE(cpu->lg->pgdirs);
+ next = prandom_u32() % ARRAY_SIZE(cpu->lg->pgdirs);
/* If it's never been allocated at all before, try now. */
if (!cpu->lg->pgdirs[next].pgdir) {
cpu->lg->pgdirs[next].pgdir =
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index 2879487d036a..d94d058bdf25 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -156,7 +156,8 @@ static void discard_finish(struct work_struct *w)
closure_put(&ca->set->cl);
}
-static void discard_endio(struct bio *bio, int error)
+static void discard_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct discard *d = container_of(bio, struct discard, bio);
schedule_work(&d->work);
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index 852340793777..03e44c1a3bb4 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -134,7 +134,8 @@ static uint64_t btree_csum_set(struct btree *b, struct bset *i)
return crc ^ 0xffffffffffffffffULL;
}
-static void btree_bio_endio(struct bio *bio, int error)
+static void btree_bio_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct closure *cl = bio->bi_private;
struct btree *b = container_of(cl, struct btree, io.cl);
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c
index f565512f6fac..8bb275901fb8 100644
--- a/drivers/md/bcache/io.c
+++ b/drivers/md/bcache/io.c
@@ -9,7 +9,8 @@
#include "bset.h"
#include "debug.h"
-static void bch_bi_idx_hack_endio(struct bio *bio, int error)
+static void bch_bi_idx_hack_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct bio *p = bio->bi_private;
@@ -199,7 +200,8 @@ static void bch_bio_submit_split_done(struct closure *cl)
mempool_free(s, s->p->bio_split_hook);
}
-static void bch_bio_submit_split_endio(struct bio *bio, int error)
+static void bch_bio_submit_split_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct closure *cl = bio->bi_private;
struct bio_split_hook *s = container_of(cl, struct bio_split_hook, cl);
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 8c8dfdcd9d4c..bff194bb3e08 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -22,7 +22,8 @@
* bit.
*/
-static void journal_read_endio(struct bio *bio, int error)
+static void journal_read_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct closure *cl = bio->bi_private;
closure_put(cl);
@@ -390,7 +391,8 @@ found:
#define last_seq(j) ((j)->seq - fifo_used(&(j)->pin) + 1)
-static void journal_discard_endio(struct bio *bio, int error)
+static void journal_discard_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct journal_device *ja =
container_of(bio, struct journal_device, discard_bio);
@@ -535,7 +537,8 @@ void bch_journal_next(struct journal *j)
pr_debug("journal_pin full (%zu)", fifo_used(&j->pin));
}
-static void journal_write_endio(struct bio *bio, int error)
+static void journal_write_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct journal_write *w = bio->bi_private;
diff --git a/drivers/md/bcache/movinggc.c b/drivers/md/bcache/movinggc.c
index 8589512c972e..8bf7ae12d4b0 100644
--- a/drivers/md/bcache/movinggc.c
+++ b/drivers/md/bcache/movinggc.c
@@ -61,7 +61,8 @@ static void write_moving_finish(struct closure *cl)
closure_return_with_destructor(cl, moving_io_destructor);
}
-static void read_moving_endio(struct bio *bio, int error)
+static void read_moving_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct moving_io *io = container_of(bio->bi_private,
struct moving_io, s.cl);
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 83731dc36f34..478f487fa87a 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -456,7 +456,8 @@ static void bch_insert_data_error(struct closure *cl)
bch_journal(cl);
}
-static void bch_insert_data_endio(struct bio *bio, int error)
+static void bch_insert_data_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct closure *cl = bio->bi_private;
struct btree_op *op = container_of(cl, struct btree_op, cl);
@@ -621,7 +622,8 @@ void bch_btree_insert_async(struct closure *cl)
/* Common code for the make_request functions */
-static void request_endio(struct bio *bio, int error)
+static void request_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct closure *cl = bio->bi_private;
@@ -636,7 +638,8 @@ static void request_endio(struct bio *bio, int error)
closure_put(cl);
}
-void bch_cache_read_endio(struct bio *bio, int error)
+void bch_cache_read_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct bbio *b = container_of(bio, struct bbio, bio);
struct closure *cl = bio->bi_private;
diff --git a/drivers/md/bcache/request.h b/drivers/md/bcache/request.h
index 254d9ab5707c..3b794625c4c1 100644
--- a/drivers/md/bcache/request.h
+++ b/drivers/md/bcache/request.h
@@ -29,11 +29,10 @@ struct search {
struct btree_op op;
};
-void bch_cache_read_endio(struct bio *, int);
+void bch_cache_read_endio(struct bio *, int, struct batch_complete *batch);
int bch_get_congested(struct cache_set *);
void bch_insert_data(struct closure *cl);
void bch_btree_insert_async(struct closure *);
-void bch_cache_read_endio(struct bio *, int);
void bch_open_buckets_free(struct cache_set *);
int bch_open_buckets_alloc(struct cache_set *);
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 5fa3cd2d9ff0..f3bf310187c7 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -204,7 +204,8 @@ err:
return err;
}
-static void write_bdev_super_endio(struct bio *bio, int error)
+static void write_bdev_super_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct cached_dev *dc = bio->bi_private;
/* XXX: error checking */
@@ -265,7 +266,8 @@ void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent)
closure_return(cl);
}
-static void write_super_endio(struct bio *bio, int error)
+static void write_super_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct cache *ca = bio->bi_private;
@@ -306,7 +308,7 @@ void bcache_write_super(struct cache_set *c)
/* UUID io */
-static void uuid_endio(struct bio *bio, int error)
+static void uuid_endio(struct bio *bio, int error, struct batch_complete *batch)
{
struct closure *cl = bio->bi_private;
struct cache_set *c = container_of(cl, struct cache_set, uuid_write.cl);
@@ -470,7 +472,8 @@ static struct uuid_entry *uuid_find_empty(struct cache_set *c)
* disk.
*/
-static void prio_endio(struct bio *bio, int error)
+static void prio_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct cache *ca = bio->bi_private;
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
index 93e7e31a4bd3..daf9347833be 100644
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -253,7 +253,8 @@ static void write_dirty_finish(struct closure *cl)
closure_return_with_destructor(cl, dirty_io_destructor);
}
-static void dirty_endio(struct bio *bio, int error)
+static void dirty_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct keybuf_key *w = bio->bi_private;
struct dirty_io *io = w->private;
@@ -281,7 +282,8 @@ static void write_dirty(struct closure *cl)
continue_at(cl, write_dirty_finish, dirty_wq);
}
-static void read_dirty_endio(struct bio *bio, int error)
+static void read_dirty_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct keybuf_key *w = bio->bi_private;
struct dirty_io *io = w->private;
@@ -289,7 +291,7 @@ static void read_dirty_endio(struct bio *bio, int error)
bch_count_io_errors(PTR_CACHE(io->dc->disk.c, &w->key, 0),
error, "reading dirty data from cache");
- dirty_endio(bio, error);
+ dirty_endio(bio, error, NULL);
}
static void read_dirty_submit(struct closure *cl)
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index c6083132c4b8..6f1b57ab8868 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -472,7 +472,7 @@ static void dmio_complete(unsigned long error, void *context)
{
struct dm_buffer *b = context;
- b->bio.bi_end_io(&b->bio, error ? -EIO : 0);
+ b->bio.bi_end_io(&b->bio, error ? -EIO : 0, NULL);
}
static void use_dmio(struct dm_buffer *b, int rw, sector_t block,
@@ -503,7 +503,7 @@ static void use_dmio(struct dm_buffer *b, int rw, sector_t block,
r = dm_io(&io_req, 1, &region, NULL);
if (r)
- end_io(&b->bio, r);
+ end_io(&b->bio, r, NULL);
}
static void use_inline_bio(struct dm_buffer *b, int rw, sector_t block,
@@ -570,7 +570,8 @@ static void submit_io(struct dm_buffer *b, int rw, sector_t block,
* Set the error, clear B_WRITING bit and wake anyone who was waiting on
* it.
*/
-static void write_endio(struct bio *bio, int error)
+static void write_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct dm_buffer *b = container_of(bio, struct dm_buffer, bio);
@@ -943,7 +944,7 @@ found_buffer:
* The endio routine for reading: set the error, clear the bit and wake up
* anyone waiting on the buffer.
*/
-static void read_endio(struct bio *bio, int error)
+static void read_endio(struct bio *bio, int error, struct batch_complete *batch)
{
struct dm_buffer *b = container_of(bio, struct dm_buffer, bio);
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index 10744091e6ca..c5ce8a3b5505 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -652,7 +652,8 @@ static void defer_writethrough_bio(struct cache *cache, struct bio *bio)
wake_worker(cache);
}
-static void writethrough_endio(struct bio *bio, int err)
+static void writethrough_endio(struct bio *bio, int err,
+ struct batch_complete *batch)
{
struct per_bio_data *pb = get_per_bio_data(bio, PB_DATA_SIZE_WT);
bio->bi_end_io = pb->saved_bi_end_io;
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 6d2d41ae9e32..ec0e3c0883b5 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -929,7 +929,8 @@ static void crypt_dec_pending(struct dm_crypt_io *io)
* The work is done per CPU global for all dm-crypt instances.
* They should not depend on each other and do not block.
*/
-static void crypt_endio(struct bio *clone, int error)
+static void crypt_endio(struct bio *clone, int error,
+ struct batch_complete *batch)
{
struct dm_crypt_io *io = clone->bi_private;
struct crypt_config *cc = io->cc;
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index ea49834377c8..a727b267f86d 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -136,7 +136,7 @@ static void dec_count(struct io *io, unsigned int region, int error)
}
}
-static void endio(struct bio *bio, int error)
+static void endio(struct bio *bio, int error, struct batch_complete *batch)
{
struct io *io;
unsigned region;
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index c0e07026a8d1..eb32e35bca8f 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1485,7 +1485,8 @@ static void start_copy(struct dm_snap_pending_exception *pe)
dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, copy_callback, pe);
}
-static void full_bio_end_io(struct bio *bio, int error)
+static void full_bio_end_io(struct bio *bio, int error,
+ struct batch_complete *batch)
{
void *callback_data = bio->bi_private;
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 004ad1652b73..905b75f60cc7 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -553,7 +553,8 @@ static void copy_complete(int read_err, unsigned long write_err, void *context)
spin_unlock_irqrestore(&pool->lock, flags);
}
-static void overwrite_endio(struct bio *bio, int err)
+static void overwrite_endio(struct bio *bio, int err,
+ struct batch_complete *batch)
{
unsigned long flags;
struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c
index b948fd864d45..b373bb7d1c2d 100644
--- a/drivers/md/dm-verity.c
+++ b/drivers/md/dm-verity.c
@@ -413,7 +413,8 @@ static void verity_work(struct work_struct *w)
verity_finish_io(io, verity_verify_io(io));
}
-static void verity_end_io(struct bio *bio, int error)
+static void verity_end_io(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct dm_verity_io *io = bio->bi_private;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 7e469260fe5e..142f27185b30 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -616,7 +616,8 @@ static void dec_pending(struct dm_io *io, int error)
}
}
-static void clone_endio(struct bio *bio, int error)
+static void clone_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
int r = 0;
struct dm_target_io *tio = bio->bi_private;
@@ -651,7 +652,8 @@ static void clone_endio(struct bio *bio, int error)
/*
* Partial completion handling for request-based dm
*/
-static void end_clone_bio(struct bio *clone, int error)
+static void end_clone_bio(struct bio *clone, int error,
+ struct batch_complete *batch)
{
struct dm_rq_clone_bio_info *info = clone->bi_private;
struct dm_rq_target_io *tio = info->tio;
@@ -695,7 +697,7 @@ static void end_clone_bio(struct bio *clone, int error)
* Do not use blk_end_request() here, because it may complete
* the original request before the clone, and break the ordering.
*/
- blk_update_request(tio->orig, 0, nr_bytes);
+ blk_update_request(tio->orig, 0, nr_bytes, NULL);
}
/*
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 3193aefe982b..ac8af5253fb6 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -70,7 +70,8 @@
#include <linux/seq_file.h>
-static void faulty_fail(struct bio *bio, int error)
+static void faulty_fail(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct bio *b = bio->bi_private;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index b631b757ddf1..98e6a920be85 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -379,7 +379,8 @@ EXPORT_SYMBOL(mddev_congested);
* Generic flush handling for md
*/
-static void md_end_flush(struct bio *bio, int err)
+static void md_end_flush(struct bio *bio, int err,
+ struct batch_complete *batch)
{
struct md_rdev *rdev = bio->bi_private;
struct mddev *mddev = rdev->mddev;
@@ -756,7 +757,8 @@ void md_rdev_clear(struct md_rdev *rdev)
}
EXPORT_SYMBOL_GPL(md_rdev_clear);
-static void super_written(struct bio *bio, int error)
+static void super_written(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct md_rdev *rdev = bio->bi_private;
struct mddev *mddev = rdev->mddev;
@@ -807,7 +809,8 @@ void md_super_wait(struct mddev *mddev)
finish_wait(&mddev->sb_wait, &wq);
}
-static void bi_complete(struct bio *bio, int error)
+static void bi_complete(struct bio *bio, int error,
+ struct batch_complete *batch)
{
complete((struct completion*)bio->bi_private);
}
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 1642eae75a33..fecad70f53f6 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -83,7 +83,8 @@ static void multipath_end_bh_io (struct multipath_bh *mp_bh, int err)
mempool_free(mp_bh, conf->pool);
}
-static void multipath_end_request(struct bio *bio, int error)
+static void multipath_end_request(struct bio *bio, int error,
+ struct batch_complete *batch)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct multipath_bh *mp_bh = bio->bi_private;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index aeb4e3f74791..619ba71cc6a5 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -294,7 +294,8 @@ static int find_bio_disk(struct r1bio *r1_bio, struct bio *bio)
return mirror;
}
-static void raid1_end_read_request(struct bio *bio, int error)
+static void raid1_end_read_request(struct bio *bio, int error,
+ struct batch_complete *batch)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct r1bio *r1_bio = bio->bi_private;
@@ -379,7 +380,8 @@ static void r1_bio_write_done(struct r1bio *r1_bio)
}
}
-static void raid1_end_write_request(struct bio *bio, int error)
+static void raid1_end_write_request(struct bio *bio, int error,
+ struct batch_complete *batch)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct r1bio *r1_bio = bio->bi_private;
@@ -1607,7 +1609,8 @@ abort:
}
-static void end_sync_read(struct bio *bio, int error)
+static void end_sync_read(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct r1bio *r1_bio = bio->bi_private;
@@ -1625,7 +1628,8 @@ static void end_sync_read(struct bio *bio, int error)
reschedule_retry(r1_bio);
}
-static void end_sync_write(struct bio *bio, int error)
+static void end_sync_write(struct bio *bio, int error,
+ struct batch_complete *batch)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct r1bio *r1_bio = bio->bi_private;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index fc5f60ce9f8c..6005d9637ba7 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -101,7 +101,8 @@ static int enough(struct r10conf *conf, int ignore);
static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
int *skipped);
static void reshape_request_write(struct mddev *mddev, struct r10bio *r10_bio);
-static void end_reshape_write(struct bio *bio, int error);
+static void end_reshape_write(struct bio *bio, int error,
+ struct batch_complete *batch);
static void end_reshape(struct r10conf *conf);
static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
@@ -358,7 +359,8 @@ static int find_bio_disk(struct r10conf *conf, struct r10bio *r10_bio,
return r10_bio->devs[slot].devnum;
}
-static void raid10_end_read_request(struct bio *bio, int error)
+static void raid10_end_read_request(struct bio *bio, int error,
+ struct batch_complete *batch)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct r10bio *r10_bio = bio->bi_private;
@@ -441,7 +443,8 @@ static void one_write_done(struct r10bio *r10_bio)
}
}
-static void raid10_end_write_request(struct bio *bio, int error)
+static void raid10_end_write_request(struct bio *bio, int error,
+ struct batch_complete *batch)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct r10bio *r10_bio = bio->bi_private;
@@ -1907,7 +1910,8 @@ abort:
}
-static void end_sync_read(struct bio *bio, int error)
+static void end_sync_read(struct bio *bio, int error,
+ struct batch_complete *batch)
{
struct r10bio *r10_bio = bio->bi_private;
struct r10conf *conf = r10_bio->mddev->private;
@@ -1968,7 +1972,8 @@ static void end_sync_request(struct r10bio *r10_bio)
}
}
-static void end_sync_write(struct bio *bio, int error)
+static void end_sync_write(struct bio *bio, int error,
+ struct batch_complete *batch)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct r10bio *r10_bio = bio->bi_private;
@@ -4592,7 +4597,8 @@ static int handle_reshape_read_error(struct mddev *mddev,
return 0;
}
-static void end_reshape_write(struct bio *bio, int error)
+static void end_reshape_write(struct bio *bio, int error,
+ struct batch_complete *batch)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct r10bio *r10_bio = bio->bi_private;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index fd440cd3496c..16637f62122d 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -591,9 +591,11 @@ static int use_new_offset(struct r5conf *conf, struct stripe_head *sh)
}
static void
-raid5_end_read_request(struct bio *bi, int error);
+raid5_end_read_request(struct bio *bi, int error,
+ struct batch_complete *batch);
static void
-raid5_end_write_request(struct bio *bi, int error);
+raid5_end_write_request(struct bio *bi, int error,
+ struct batch_complete *batch);
static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
{
@@ -1772,7 +1774,8 @@ static void shrink_stripes(struct r5conf *conf)
conf->slab_cache = NULL;
}
-static void raid5_end_read_request(struct bio * bi, int error)
+static void raid5_end_read_request(struct bio *bi, int error,
+ struct batch_complete *batch)
{
struct stripe_head *sh = bi->bi_private;
struct r5conf *conf = sh->raid_conf;
@@ -1892,7 +1895,8 @@ static void raid5_end_read_request(struct bio * bi, int error)
release_stripe(sh);
}
-static void raid5_end_write_request(struct bio *bi, int error)
+static void raid5_end_write_request(struct bio *bi, int error,
+ struct batch_complete *batch)
{
struct stripe_head *sh = bi->bi_private;
struct r5conf *conf = sh->raid_conf;
@@ -3970,7 +3974,8 @@ static struct bio *remove_bio_from_retry(struct r5conf *conf)
* first).
* If the read failed..
*/
-static void raid5_align_endio(struct bio *bi, int error)
+static void raid5_align_endio(struct bio *bi, int error,
+ struct batch_complete *batch)
{
struct bio* raid_bi = bi->bi_private;
struct mddev *mddev;
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index ca4da8a375ba..0cbe1ff925f1 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -145,7 +145,6 @@ config VIDEO_CODA
depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
- select IRAM_ALLOC if SOC_IMX53
---help---
Coda is a range of video codec IPs that supports
H.264, MPEG-4, and other video formats.
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
index 20827ba168fc..b931c2a5c7fc 100644
--- a/drivers/media/platform/coda.c
+++ b/drivers/media/platform/coda.c
@@ -14,6 +14,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/firmware.h>
+#include <linux/genalloc.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
@@ -23,7 +24,7 @@
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/of.h>
-#include <linux/platform_data/imx-iram.h>
+#include <linux/platform_data/coda.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@@ -43,6 +44,7 @@
#define CODA7_WORK_BUF_SIZE (512 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
#define CODA_PARA_BUF_SIZE (10 * 1024)
#define CODA_ISRAM_SIZE (2048 * 2)
+#define CODADX6_IRAM_SIZE 0xb000
#define CODA7_IRAM_SIZE 0x14000 /* 81920 bytes */
#define CODA_MAX_FRAMEBUFFERS 2
@@ -128,7 +130,10 @@ struct coda_dev {
struct coda_aux_buf codebuf;
struct coda_aux_buf workbuf;
+ struct gen_pool *iram_pool;
+ long unsigned int iram_vaddr;
long unsigned int iram_paddr;
+ unsigned long iram_size;
spinlock_t irqlock;
struct mutex dev_mutex;
@@ -1926,6 +1931,9 @@ static int coda_probe(struct platform_device *pdev)
const struct of_device_id *of_id =
of_match_device(of_match_ptr(coda_dt_ids), &pdev->dev);
const struct platform_device_id *pdev_id;
+ struct coda_platform_data *pdata = pdev->dev.platform_data;
+ struct device_node *np = pdev->dev.of_node;
+ struct gen_pool *pool;
struct coda_dev *dev;
struct resource *res;
int ret, irq;
@@ -1988,6 +1996,16 @@ static int coda_probe(struct platform_device *pdev)
return -ENOENT;
}
+ /* Get IRAM pool from device tree or platform data */
+ pool = of_get_named_gen_pool(np, "iram", 0);
+ if (!pool && pdata)
+ pool = dev_get_gen_pool(pdata->iram_dev);
+ if (!pool) {
+ dev_err(&pdev->dev, "iram pool not available\n");
+ return -ENOMEM;
+ }
+ dev->iram_pool = pool;
+
ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
if (ret)
return ret;
@@ -2022,18 +2040,17 @@ static int coda_probe(struct platform_device *pdev)
return -ENOMEM;
}
- if (dev->devtype->product == CODA_DX6) {
- dev->iram_paddr = 0xffff4c00;
- } else {
- void __iomem *iram_vaddr;
-
- iram_vaddr = iram_alloc(CODA7_IRAM_SIZE,
- &dev->iram_paddr);
- if (!iram_vaddr) {
- dev_err(&pdev->dev, "unable to alloc iram\n");
- return -ENOMEM;
- }
+ if (dev->devtype->product == CODA_DX6)
+ dev->iram_size = CODADX6_IRAM_SIZE;
+ else
+ dev->iram_size = CODA7_IRAM_SIZE;
+ dev->iram_vaddr = gen_pool_alloc(dev->iram_pool, dev->iram_size);
+ if (!dev->iram_vaddr) {
+ dev_err(&pdev->dev, "unable to alloc iram\n");
+ return -ENOMEM;
}
+ dev->iram_paddr = gen_pool_virt_to_phys(dev->iram_pool,
+ dev->iram_vaddr);
platform_set_drvdata(pdev, dev);
@@ -2050,8 +2067,8 @@ static int coda_remove(struct platform_device *pdev)
if (dev->alloc_ctx)
vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
v4l2_device_unregister(&dev->v4l2_dev);
- if (dev->iram_paddr)
- iram_free(dev->iram_paddr, CODA7_IRAM_SIZE);
+ if (dev->iram_vaddr)
+ gen_pool_free(dev->iram_pool, dev->iram_vaddr, dev->iram_size);
if (dev->codebuf.vaddr)
dma_free_coherent(&pdev->dev, dev->codebuf.size,
&dev->codebuf.vaddr, dev->codebuf.paddr);
diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c
index a7c5b31c0d50..9718661c1fb6 100644
--- a/drivers/memstick/host/r592.c
+++ b/drivers/memstick/host/r592.c
@@ -847,7 +847,7 @@ static void r592_remove(struct pci_dev *pdev)
dev->dummy_dma_page_physical_address);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int r592_suspend(struct device *core_dev)
{
struct pci_dev *pdev = to_pci_dev(core_dev);
@@ -870,10 +870,10 @@ static int r592_resume(struct device *core_dev)
r592_update_card_detect(dev);
return 0;
}
-
-SIMPLE_DEV_PM_OPS(r592_pm_ops, r592_suspend, r592_resume);
#endif
+static SIMPLE_DEV_PM_OPS(r592_pm_ops, r592_suspend, r592_resume);
+
MODULE_DEVICE_TABLE(pci, r592_pci_id_tbl);
static struct pci_driver r852_pci_driver = {
@@ -881,9 +881,7 @@ static struct pci_driver r852_pci_driver = {
.id_table = r592_pci_id_tbl,
.probe = r592_probe,
.remove = r592_remove,
-#ifdef CONFIG_PM
.driver.pm = &r592_pm_ops,
-#endif
};
static __init int r592_module_init(void)
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 5451beff183f..a60c188c2bd9 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -687,6 +687,11 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd,
}
size = size >> 16;
size *= 4;
+ if (size > sizeof(rmsg)) {
+ rcode = -EINVAL;
+ goto sg_list_cleanup;
+ }
+
/* Copy in the user's I2O command */
if (copy_from_user(rmsg, user_msg, size)) {
rcode = -EFAULT;
@@ -922,6 +927,11 @@ static int i2o_cfg_passthru(unsigned long arg)
}
size = size >> 16;
size *= 4;
+ if (size > sizeof(rmsg)) {
+ rcode = -EFAULT;
+ goto sg_list_cleanup;
+ }
+
/* Copy in the user's I2O command */
if (copy_from_user(rmsg, user_msg, size)) {
rcode = -EFAULT;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b9e56546b493..021f0bc13259 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -518,6 +518,15 @@ config LATTICE_ECP3_CONFIG
If unsure, say N.
+config SRAM
+ bool "Generic on-chip SRAM driver"
+ depends on HAS_IOMEM
+ select GENERIC_ALLOCATOR
+ help
+ This driver allows you to declare a memory region to be managed by
+ the genalloc API. It is supposed to be used for small on-chip SRAM
+ areas found on many SoCs.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 865cbc6a7ae1..c235d5b68311 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -52,3 +52,4 @@ obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
obj-$(CONFIG_INTEL_MEI) += mei/
obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
+obj-$(CONFIG_SRAM) += sram.o
diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
new file mode 100644
index 000000000000..437192e43006
--- /dev/null
+++ b/drivers/misc/sram.c
@@ -0,0 +1,121 @@
+/*
+ * Generic on-chip SRAM allocation driver
+ *
+ * Copyright (C) 2012 Philipp Zabel, Pengutronix
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/genalloc.h>
+
+#define SRAM_GRANULARITY 32
+
+struct sram_dev {
+ struct gen_pool *pool;
+ struct clk *clk;
+};
+
+static int sram_probe(struct platform_device *pdev)
+{
+ void __iomem *virt_base;
+ struct sram_dev *sram;
+ struct resource *res;
+ unsigned long size;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EINVAL;
+
+ size = resource_size(res);
+
+ virt_base = devm_request_and_ioremap(&pdev->dev, res);
+ if (!virt_base)
+ return -EADDRNOTAVAIL;
+
+ sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL);
+ if (!sram)
+ return -ENOMEM;
+
+ sram->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(sram->clk))
+ sram->clk = NULL;
+ else
+ clk_prepare_enable(sram->clk);
+
+ sram->pool = devm_gen_pool_create(&pdev->dev, ilog2(SRAM_GRANULARITY), -1);
+ if (!sram->pool)
+ return -ENOMEM;
+
+ ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base,
+ res->start, size, -1);
+ if (ret < 0) {
+ gen_pool_destroy(sram->pool);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, sram);
+
+ dev_dbg(&pdev->dev, "SRAM pool: %ld KiB @ 0x%p\n", size / 1024, virt_base);
+
+ return 0;
+}
+
+static int sram_remove(struct platform_device *pdev)
+{
+ struct sram_dev *sram = platform_get_drvdata(pdev);
+
+ if (gen_pool_avail(sram->pool) < gen_pool_size(sram->pool))
+ dev_dbg(&pdev->dev, "removed while SRAM allocated\n");
+
+ gen_pool_destroy(sram->pool);
+
+ if (sram->clk)
+ clk_disable_unprepare(sram->clk);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id sram_dt_ids[] = {
+ { .compatible = "mmio-sram" },
+ {}
+};
+#endif
+
+static struct platform_driver sram_driver = {
+ .driver = {
+ .name = "sram",
+ .of_match_table = of_match_ptr(sram_dt_ids),
+ },
+ .probe = sram_probe,
+ .remove = sram_remove,
+};
+
+static int __init sram_init(void)
+{
+ return platform_driver_register(&sram_driver);
+}
+
+postcore_initcall(sram_init);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index ad7decc3340a..7b435a3e623f 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -120,8 +120,8 @@ static void mmc_should_fail_request(struct mmc_host *host,
!should_fail(&host->fail_mmc_request, data->blksz * data->blocks))
return;
- data->error = data_errors[random32() % ARRAY_SIZE(data_errors)];
- data->bytes_xfered = (random32() % (data->bytes_xfered >> 9)) << 9;
+ data->error = data_errors[prandom_u32() % ARRAY_SIZE(data_errors)];
+ data->bytes_xfered = (prandom_u32() % (data->bytes_xfered >> 9)) << 9;
}
#else /* CONFIG_FAIL_MMC_REQUEST */
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index 149a3a038491..5abdd4894082 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -4085,7 +4085,7 @@ static int cnic_cm_alloc_mem(struct cnic_dev *dev)
if (!cp->csk_tbl)
return -ENOMEM;
- port_id = random32();
+ port_id = prandom_u32();
port_id %= CNIC_LOCAL_PORT_RANGE;
if (cnic_init_id_tbl(&cp->csk_port_tbl, CNIC_LOCAL_PORT_RANGE,
CNIC_LOCAL_PORT_MIN, port_id)) {
@@ -4145,7 +4145,7 @@ static int cnic_cm_init_bnx2_hw(struct cnic_dev *dev)
{
u32 seed;
- seed = random32();
+ seed = prandom_u32();
cnic_ctx_wr(dev, 45, 0, seed);
return 0;
}
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 49b8b58fc5c6..484f77ec2ce1 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -449,7 +449,7 @@ static int transmit(struct baycom_state *bc, int cnt, unsigned char stat)
if ((--bc->hdlctx.slotcnt) > 0)
return 0;
bc->hdlctx.slotcnt = bc->ch_params.slottime;
- if ((random32() % 256) > bc->ch_params.ppersist)
+ if ((prandom_u32() % 256) > bc->ch_params.ppersist)
return 0;
}
}
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index a4a3516b6bbf..3169252613fa 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -389,7 +389,7 @@ void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
if ((--s->hdlctx.slotcnt) > 0)
return;
s->hdlctx.slotcnt = s->ch_params.slottime;
- if ((random32() % 256) > s->ch_params.ppersist)
+ if ((prandom_u32() % 256) > s->ch_params.ppersist)
return;
start_tx(dev, s);
}
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index b2d863f2ea42..0721e72f9299 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -638,7 +638,7 @@ static void yam_arbitrate(struct net_device *dev)
yp->slotcnt = yp->slot / 10;
/* is random > persist ? */
- if ((random32() % 256) > yp->pers)
+ if ((prandom_u32() % 256) > yp->pers)
return;
yam_start_tx(dev, yp);
diff --git a/drivers/net/team/team_mode_random.c b/drivers/net/team/team_mode_random.c
index 9eabfaa22f3e..5ca14d463ba7 100644
--- a/drivers/net/team/team_mode_random.c
+++ b/drivers/net/team/team_mode_random.c
@@ -18,7 +18,7 @@
static u32 random_N(unsigned int N)
{
- return reciprocal_divide(random32(), N);
+ return reciprocal_divide(prandom_u32(), N);
}
static bool rnd_transmit(struct team *team, struct sk_buff *skb)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 94ff045df2b3..6bd78cf2ef08 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -1128,7 +1128,7 @@ static void brcmf_p2p_afx_handler(struct work_struct *work)
if (afx_hdl->is_listen && afx_hdl->my_listen_chan)
/* 100ms ~ 300ms */
err = brcmf_p2p_discover_listen(p2p, afx_hdl->my_listen_chan,
- 100 * (1 + (random32() % 3)));
+ 100 * (1 + (prandom_u32() % 3)));
else
err = brcmf_p2p_act_frm_search(p2p, afx_hdl->peer_listen_chan);
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 47012947a447..8fc311f99bd8 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -216,7 +216,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
mwifiex_form_mgmt_frame(skb, buf, len);
mwifiex_queue_tx_pkt(priv, skb);
- *cookie = random32() | 1;
+ *cookie = prandom_u32() | 1;
cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true, GFP_ATOMIC);
wiphy_dbg(wiphy, "info: management frame transmitted\n");
@@ -271,7 +271,7 @@ mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
duration);
if (!ret) {
- *cookie = random32() | 1;
+ *cookie = prandom_u32() | 1;
priv->roc_cfg.cookie = *cookie;
priv->roc_cfg.chan = *chan;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 05272e676a28..54d31c0a9840 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -1964,9 +1964,6 @@ struct tp_nvram_state {
/* kthread for the hotkey poller */
static struct task_struct *tpacpi_hotkey_task;
-/* Acquired while the poller kthread is running, use to sync start/stop */
-static struct mutex hotkey_thread_mutex;
-
/*
* Acquire mutex to write poller control variables as an
* atomic block.
@@ -2462,8 +2459,6 @@ static int hotkey_kthread(void *data)
unsigned int poll_freq;
bool was_frozen;
- mutex_lock(&hotkey_thread_mutex);
-
if (tpacpi_lifecycle == TPACPI_LIFE_EXITING)
goto exit;
@@ -2523,7 +2518,6 @@ static int hotkey_kthread(void *data)
}
exit:
- mutex_unlock(&hotkey_thread_mutex);
return 0;
}
@@ -2533,9 +2527,6 @@ static void hotkey_poll_stop_sync(void)
if (tpacpi_hotkey_task) {
kthread_stop(tpacpi_hotkey_task);
tpacpi_hotkey_task = NULL;
- mutex_lock(&hotkey_thread_mutex);
- /* at this point, the thread did exit */
- mutex_unlock(&hotkey_thread_mutex);
}
}
@@ -3234,7 +3225,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
mutex_init(&hotkey_mutex);
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
- mutex_init(&hotkey_thread_mutex);
mutex_init(&hotkey_thread_data_mutex);
#endif
diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig
index 982d16b5a846..7512e98e9311 100644
--- a/drivers/pps/Kconfig
+++ b/drivers/pps/Kconfig
@@ -20,10 +20,10 @@ config PPS
To compile this driver as a module, choose M here: the module
will be called pps_core.ko.
+if PPS
config PPS_DEBUG
bool "PPS debugging messages"
- depends on PPS
help
Say Y here if you want the PPS support to produce a bunch of debug
messages to the system log. Select this if you are having a
@@ -31,13 +31,15 @@ config PPS_DEBUG
config NTP_PPS
bool "PPS kernel consumer support"
- depends on PPS && !NO_HZ
+ depends on !NO_HZ
help
This option adds support for direct in-kernel time
synchronization using an external PPS signal.
It doesn't work on tickless systems at the moment.
+endif
+
source drivers/pps/clients/Kconfig
source drivers/pps/generators/Kconfig
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index 33d827b30e95..56fceafec9ec 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -951,8 +951,10 @@ static int rpmsg_probe(struct virtio_device *vdev)
bufs_va = dma_alloc_coherent(vdev->dev.parent->parent,
RPMSG_TOTAL_BUF_SPACE,
&vrp->bufs_dma, GFP_KERNEL);
- if (!bufs_va)
+ if (!bufs_va) {
+ err = -ENOMEM;
goto vqs_del;
+ }
dev_dbg(&vdev->dev, "buffers: va %p, dma 0x%llx\n", bufs_va,
(unsigned long long)vrp->bufs_dma);
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 9b742d3ffb94..66385402d20e 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -259,6 +259,76 @@ void rtc_device_unregister(struct rtc_device *rtc)
}
EXPORT_SYMBOL_GPL(rtc_device_unregister);
+static void devm_rtc_device_release(struct device *dev, void *res)
+{
+ struct rtc_device *rtc = *(struct rtc_device **)res;
+
+ rtc_device_unregister(rtc);
+}
+
+static int devm_rtc_device_match(struct device *dev, void *res, void *data)
+{
+ struct rtc **r = res;
+
+ return *r == data;
+}
+
+/**
+ * devm_rtc_device_register - resource managed rtc_device_register()
+ * @dev: the device to register
+ * @name: the name of the device
+ * @ops: the rtc operations structure
+ * @owner: the module owner
+ *
+ * @return a struct rtc on success, or an ERR_PTR on error
+ *
+ * Managed rtc_device_register(). The rtc_device returned from this function
+ * are automatically freed on driver detach. See rtc_device_register()
+ * for more information.
+ */
+
+struct rtc_device *devm_rtc_device_register(struct device *dev,
+ const char *name,
+ const struct rtc_class_ops *ops,
+ struct module *owner)
+{
+ struct rtc_device **ptr, *rtc;
+
+ ptr = devres_alloc(devm_rtc_device_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ rtc = rtc_device_register(name, dev, ops, owner);
+ if (!IS_ERR(rtc)) {
+ *ptr = rtc;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return rtc;
+}
+EXPORT_SYMBOL_GPL(devm_rtc_device_register);
+
+/**
+ * devm_rtc_device_unregister - resource managed devm_rtc_device_unregister()
+ * @dev: the device to unregister
+ * @rtc: the RTC class device to unregister
+ *
+ * Deallocated a rtc allocated with devm_rtc_device_register(). Normally this
+ * function will not need to be called and the resource management code will
+ * ensure that the resource is freed.
+ */
+void devm_rtc_device_unregister(struct device *dev, struct rtc_device *rtc)
+{
+ int rc;
+
+ rc = devres_release(dev, devm_rtc_device_release,
+ devm_rtc_device_match, rtc);
+ WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_rtc_device_unregister);
+
static int __init rtc_init(void)
{
rtc_class = class_create(THIS_MODULE, "rtc");
diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c
index 63b17ebe90e8..f3742f364eb8 100644
--- a/drivers/rtc/rtc-88pm80x.c
+++ b/drivers/rtc/rtc-88pm80x.c
@@ -234,7 +234,7 @@ static const struct rtc_class_ops pm80x_rtc_ops = {
.alarm_irq_enable = pm80x_rtc_alarm_irq_enable,
};
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int pm80x_rtc_suspend(struct device *dev)
{
return pm80x_dev_suspend(dev);
@@ -312,7 +312,7 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
}
rtc_tm_to_time(&tm, &ticks);
- info->rtc_dev = rtc_device_register("88pm80x-rtc", &pdev->dev,
+ info->rtc_dev = devm_rtc_device_register(&pdev->dev, "88pm80x-rtc",
&pm80x_rtc_ops, THIS_MODULE);
if (IS_ERR(info->rtc_dev)) {
ret = PTR_ERR(info->rtc_dev);
@@ -346,7 +346,6 @@ static int pm80x_rtc_remove(struct platform_device *pdev)
{
struct pm80x_rtc_info *info = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
- rtc_device_unregister(info->rtc_dev);
pm80x_free_irq(info->chip, info->irq, info);
return 0;
}
diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c
index 261a07e0fb24..47a4f2c4d30e 100644
--- a/drivers/rtc/rtc-ab3100.c
+++ b/drivers/rtc/rtc-ab3100.c
@@ -229,8 +229,8 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev)
/* Ignore any error on this write */
}
- rtc = rtc_device_register("ab3100-rtc", &pdev->dev, &ab3100_rtc_ops,
- THIS_MODULE);
+ rtc = devm_rtc_device_register(&pdev->dev, "ab3100-rtc",
+ &ab3100_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
err = PTR_ERR(rtc);
return err;
@@ -242,9 +242,6 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev)
static int __exit ab3100_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtc = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtc);
platform_set_drvdata(pdev, NULL);
return 0;
}
@@ -257,19 +254,7 @@ static struct platform_driver ab3100_rtc_driver = {
.remove = __exit_p(ab3100_rtc_remove),
};
-static int __init ab3100_rtc_init(void)
-{
- return platform_driver_probe(&ab3100_rtc_driver,
- ab3100_rtc_probe);
-}
-
-static void __exit ab3100_rtc_exit(void)
-{
- platform_driver_unregister(&ab3100_rtc_driver);
-}
-
-module_init(ab3100_rtc_init);
-module_exit(ab3100_rtc_exit);
+module_platform_driver_probe(ab3100_rtc_driver, ab3100_rtc_probe);
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
MODULE_DESCRIPTION("AB3100 RTC Driver");
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c
index 8dd08305aae1..619c8877f2f1 100644
--- a/drivers/rtc/rtc-at32ap700x.c
+++ b/drivers/rtc/rtc-at32ap700x.c
@@ -302,17 +302,7 @@ static struct platform_driver at32_rtc_driver = {
},
};
-static int __init at32_rtc_init(void)
-{
- return platform_driver_probe(&at32_rtc_driver, at32_rtc_probe);
-}
-module_init(at32_rtc_init);
-
-static void __exit at32_rtc_exit(void)
-{
- platform_driver_unregister(&at32_rtc_driver);
-}
-module_exit(at32_rtc_exit);
+module_platform_driver_probe(at32_rtc_driver, at32_rtc_probe);
MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
MODULE_DESCRIPTION("Real time clock for AVR32 AT32AP700x");
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 434ebc3a99dc..a654071f57df 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -28,6 +28,8 @@
#include <linux/ioctl.h>
#include <linux/completion.h>
#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <asm/uaccess.h>
@@ -337,7 +339,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/* AT91RM9200 RTC Power management control */
@@ -369,39 +371,27 @@ static int at91_rtc_resume(struct device *dev)
}
return 0;
}
+#endif
-static const struct dev_pm_ops at91_rtc_pm = {
- .suspend = at91_rtc_suspend,
- .resume = at91_rtc_resume,
-};
-
-#define at91_rtc_pm_ptr &at91_rtc_pm
+static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume);
-#else
-#define at91_rtc_pm_ptr NULL
-#endif
+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 = {
.name = "at91_rtc",
.owner = THIS_MODULE,
- .pm = at91_rtc_pm_ptr,
+ .pm = &at91_rtc_pm_ops,
+ .of_match_table = of_match_ptr(at91_rtc_dt_ids),
},
};
-static int __init at91_rtc_init(void)
-{
- return platform_driver_probe(&at91_rtc_driver, at91_rtc_probe);
-}
-
-static void __exit at91_rtc_exit(void)
-{
- platform_driver_unregister(&at91_rtc_driver);
-}
-
-module_init(at91_rtc_init);
-module_exit(at91_rtc_exit);
+module_platform_driver_probe(at91_rtc_driver, at91_rtc_probe);
MODULE_AUTHOR("Rick Bronson");
MODULE_DESCRIPTION("RTC driver for Atmel AT91RM9200");
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c
index b309da4ec745..7995abc391fc 100644
--- a/drivers/rtc/rtc-au1xxx.c
+++ b/drivers/rtc/rtc-au1xxx.c
@@ -101,7 +101,7 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev)
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S)
msleep(1);
- rtcdev = rtc_device_register("rtc-au1xxx", &pdev->dev,
+ rtcdev = devm_rtc_device_register(&pdev->dev, "rtc-au1xxx",
&au1xtoy_rtc_ops, THIS_MODULE);
if (IS_ERR(rtcdev)) {
ret = PTR_ERR(rtcdev);
@@ -118,9 +118,6 @@ out_err:
static int au1xtoy_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtcdev = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtcdev);
platform_set_drvdata(pdev, NULL);
return 0;
@@ -134,18 +131,7 @@ static struct platform_driver au1xrtc_driver = {
.remove = au1xtoy_rtc_remove,
};
-static int __init au1xtoy_rtc_init(void)
-{
- return platform_driver_probe(&au1xrtc_driver, au1xtoy_rtc_probe);
-}
-
-static void __exit au1xtoy_rtc_exit(void)
-{
- platform_driver_unregister(&au1xrtc_driver);
-}
-
-module_init(au1xtoy_rtc_init);
-module_exit(au1xtoy_rtc_exit);
+module_platform_driver_probe(au1xrtc_driver, au1xtoy_rtc_probe);
MODULE_DESCRIPTION("Au1xxx TOY-counter-based RTC driver");
MODULE_AUTHOR("Manuel Lauss <manuel.lauss@gmail.com>");
diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c
index 036cb89f8188..fea78bc713ca 100644
--- a/drivers/rtc/rtc-bq32k.c
+++ b/drivers/rtc/rtc-bq32k.c
@@ -153,7 +153,7 @@ static int bq32k_probe(struct i2c_client *client,
if (error)
return error;
- rtc = rtc_device_register(bq32k_driver.driver.name, &client->dev,
+ rtc = devm_rtc_device_register(&client->dev, bq32k_driver.driver.name,
&bq32k_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -165,9 +165,6 @@ static int bq32k_probe(struct i2c_client *client,
static int bq32k_remove(struct i2c_client *client)
{
- struct rtc_device *rtc = i2c_get_clientdata(client);
-
- rtc_device_unregister(rtc);
return 0;
}
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 2d28ec1aa1cd..bf0387f80d2d 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -155,7 +155,6 @@ static int __exit coh901331_remove(struct platform_device *pdev)
struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev);
if (rtap) {
- rtc_device_unregister(rtap->rtc);
clk_unprepare(rtap->clk);
platform_set_drvdata(pdev, NULL);
}
@@ -211,8 +210,8 @@ static int __init coh901331_probe(struct platform_device *pdev)
clk_disable(rtap->clk);
platform_set_drvdata(pdev, rtap);
- rtap->rtc = rtc_device_register("coh901331", &pdev->dev, &coh901331_ops,
- THIS_MODULE);
+ rtap->rtc = devm_rtc_device_register(&pdev->dev, "coh901331",
+ &coh901331_ops, THIS_MODULE);
if (IS_ERR(rtap->rtc)) {
ret = PTR_ERR(rtap->rtc);
goto out_no_rtc;
@@ -287,18 +286,7 @@ static struct platform_driver coh901331_driver = {
.shutdown = coh901331_shutdown,
};
-static int __init coh901331_init(void)
-{
- return platform_driver_probe(&coh901331_driver, coh901331_probe);
-}
-
-static void __exit coh901331_exit(void)
-{
- platform_driver_unregister(&coh901331_driver);
-}
-
-module_init(coh901331_init);
-module_exit(coh901331_exit);
+module_platform_driver_probe(coh901331_driver, coh901331_probe);
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
MODULE_DESCRIPTION("ST-Ericsson AB COH 901 331 RTC Driver");
diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c
index 969abbad7fe3..7286b279cf2d 100644
--- a/drivers/rtc/rtc-da9052.c
+++ b/drivers/rtc/rtc-da9052.c
@@ -247,7 +247,7 @@ static int da9052_rtc_probe(struct platform_device *pdev)
return ret;
}
- rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&da9052_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc))
return PTR_ERR(rtc->rtc);
@@ -257,9 +257,6 @@ static int da9052_rtc_probe(struct platform_device *pdev)
static int da9052_rtc_remove(struct platform_device *pdev)
{
- struct da9052_rtc *rtc = pdev->dev.platform_data;
-
- rtc_device_unregister(rtc->rtc);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c
index 8f0dcfedb83c..73858ca9709a 100644
--- a/drivers/rtc/rtc-da9055.c
+++ b/drivers/rtc/rtc-da9055.c
@@ -294,7 +294,7 @@ static int da9055_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
- rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&da9055_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc);
@@ -317,9 +317,6 @@ err_rtc:
static int da9055_rtc_remove(struct platform_device *pdev)
{
- struct da9055_rtc *rtc = pdev->dev.platform_data;
-
- rtc_device_unregister(rtc->rtc);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c
index 56b73089bb29..a55048c3e26f 100644
--- a/drivers/rtc/rtc-davinci.c
+++ b/drivers/rtc/rtc-davinci.c
@@ -523,7 +523,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, davinci_rtc);
- davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ davinci_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&davinci_rtc_ops, THIS_MODULE);
if (IS_ERR(davinci_rtc->rtc)) {
ret = PTR_ERR(davinci_rtc->rtc);
@@ -543,7 +543,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
0, "davinci_rtc", davinci_rtc);
if (ret < 0) {
dev_err(dev, "unable to register davinci RTC interrupt\n");
- goto fail2;
+ goto fail1;
}
/* Enable interrupts */
@@ -557,14 +557,12 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
return 0;
-fail2:
- rtc_device_unregister(davinci_rtc->rtc);
fail1:
platform_set_drvdata(pdev, NULL);
return ret;
}
-static int davinci_rtc_remove(struct platform_device *pdev)
+static int __exit davinci_rtc_remove(struct platform_device *pdev)
{
struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev);
@@ -572,8 +570,6 @@ static int davinci_rtc_remove(struct platform_device *pdev)
rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
- rtc_device_unregister(davinci_rtc->rtc);
-
platform_set_drvdata(pdev, NULL);
return 0;
@@ -581,24 +577,14 @@ static int davinci_rtc_remove(struct platform_device *pdev)
static struct platform_driver davinci_rtc_driver = {
.probe = davinci_rtc_probe,
- .remove = davinci_rtc_remove,
+ .remove = __exit_p(davinci_rtc_remove),
.driver = {
.name = "rtc_davinci",
.owner = THIS_MODULE,
},
};
-static int __init rtc_init(void)
-{
- return platform_driver_probe(&davinci_rtc_driver, davinci_rtc_probe);
-}
-module_init(rtc_init);
-
-static void __exit rtc_exit(void)
-{
- platform_driver_unregister(&davinci_rtc_driver);
-}
-module_exit(rtc_exit);
+module_platform_driver_probe(davinci_rtc_driver, davinci_rtc_probe);
MODULE_AUTHOR("Miguel Aguilar <miguel.aguilar@ridgerun.com>");
MODULE_DESCRIPTION("Texas Instruments DaVinci PRTC Driver");
diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c
index b2ed2c94b081..1e1ca63d58a9 100644
--- a/drivers/rtc/rtc-dm355evm.c
+++ b/drivers/rtc/rtc-dm355evm.c
@@ -127,8 +127,8 @@ static int dm355evm_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
- rtc = rtc_device_register(pdev->name,
- &pdev->dev, &dm355evm_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+ &dm355evm_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
PTR_ERR(rtc));
@@ -141,9 +141,6 @@ static int dm355evm_rtc_probe(struct platform_device *pdev)
static int dm355evm_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtc = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtc);
platform_set_drvdata(pdev, NULL);
return 0;
}
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c
index d989412a348a..d120cb8bfcbe 100644
--- a/drivers/rtc/rtc-ds1286.c
+++ b/drivers/rtc/rtc-ds1286.c
@@ -270,7 +270,6 @@ static int ds1286_set_time(struct device *dev, struct rtc_time *tm)
static int ds1286_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
struct ds1286_priv *priv = dev_get_drvdata(dev);
- unsigned char cmd;
unsigned long flags;
/*
@@ -281,7 +280,7 @@ static int ds1286_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
alm->time.tm_min = ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x7f;
alm->time.tm_hour = ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x1f;
alm->time.tm_wday = ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x07;
- cmd = ds1286_rtc_read(priv, RTC_CMD);
+ ds1286_rtc_read(priv, RTC_CMD);
spin_unlock_irqrestore(&priv->lock, flags);
alm->time.tm_min = bcd2bin(alm->time.tm_min);
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index fdbcdb289d60..d13954346286 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -224,7 +224,7 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev)
return -ENODEV;
}
- rtc = rtc_device_register("ds1302", &pdev->dev,
+ rtc = devm_rtc_device_register(&pdev->dev, "ds1302",
&ds1302_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -234,11 +234,8 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev)
return 0;
}
-static int ds1302_rtc_remove(struct platform_device *pdev)
+static int __exit ds1302_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtc = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtc);
platform_set_drvdata(pdev, NULL);
return 0;
@@ -249,21 +246,10 @@ static struct platform_driver ds1302_platform_driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
},
- .remove = ds1302_rtc_remove,
+ .remove = __exit_p(ds1302_rtc_remove),
};
-static int __init ds1302_rtc_init(void)
-{
- return platform_driver_probe(&ds1302_platform_driver, ds1302_rtc_probe);
-}
-
-static void __exit ds1302_rtc_exit(void)
-{
- platform_driver_unregister(&ds1302_platform_driver);
-}
-
-module_init(ds1302_rtc_init);
-module_exit(ds1302_rtc_exit);
+module_platform_driver_probe(ds1302_platform_driver, ds1302_rtc_probe);
MODULE_DESCRIPTION("Dallas DS1302 RTC driver");
MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 970a236b147a..b53992ab3090 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -4,6 +4,7 @@
* Copyright (C) 2005 James Chapman (ds1337 core)
* Copyright (C) 2006 David Brownell
* Copyright (C) 2009 Matthias Fuchs (rx8025 support)
+ * Copyright (C) 2012 Bertrand Achard (nvram access fixes)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -196,7 +197,7 @@ static s32 ds1307_read_block_data_once(const struct i2c_client *client,
static s32 ds1307_read_block_data(const struct i2c_client *client, u8 command,
u8 length, u8 *values)
{
- u8 oldvalues[I2C_SMBUS_BLOCK_MAX];
+ u8 oldvalues[255];
s32 ret;
int tries = 0;
@@ -222,7 +223,7 @@ static s32 ds1307_read_block_data(const struct i2c_client *client, u8 command,
static s32 ds1307_write_block_data(const struct i2c_client *client, u8 command,
u8 length, const u8 *values)
{
- u8 currvalues[I2C_SMBUS_BLOCK_MAX];
+ u8 currvalues[255];
int tries = 0;
dev_dbg(&client->dev, "ds1307_write_block_data (length=%d)\n", length);
@@ -250,6 +251,57 @@ static s32 ds1307_write_block_data(const struct i2c_client *client, u8 command,
/*----------------------------------------------------------------------*/
+/* These RTC devices are not designed to be connected to a SMbus adapter.
+ SMbus limits block operations length to 32 bytes, whereas it's not
+ limited on I2C buses. As a result, accesses may exceed 32 bytes;
+ in that case, split them into smaller blocks */
+
+static s32 ds1307_native_smbus_write_block_data(const struct i2c_client *client,
+ u8 command, u8 length, const u8 *values)
+{
+ u8 suboffset = 0;
+
+ if (length <= I2C_SMBUS_BLOCK_MAX)
+ return i2c_smbus_write_i2c_block_data(client,
+ command, length, values);
+
+ while (suboffset < length) {
+ s32 retval = i2c_smbus_write_i2c_block_data(client,
+ command + suboffset,
+ min(I2C_SMBUS_BLOCK_MAX, length - suboffset),
+ values + suboffset);
+ if (retval < 0)
+ return retval;
+
+ suboffset += I2C_SMBUS_BLOCK_MAX;
+ }
+ return length;
+}
+
+static s32 ds1307_native_smbus_read_block_data(const struct i2c_client *client,
+ u8 command, u8 length, u8 *values)
+{
+ u8 suboffset = 0;
+
+ if (length <= I2C_SMBUS_BLOCK_MAX)
+ return i2c_smbus_read_i2c_block_data(client,
+ command, length, values);
+
+ while (suboffset < length) {
+ s32 retval = i2c_smbus_read_i2c_block_data(client,
+ command + suboffset,
+ min(I2C_SMBUS_BLOCK_MAX, length - suboffset),
+ values + suboffset);
+ if (retval < 0)
+ return retval;
+
+ suboffset += I2C_SMBUS_BLOCK_MAX;
+ }
+ return length;
+}
+
+/*----------------------------------------------------------------------*/
+
/*
* The IRQ logic includes a "real" handler running in IRQ context just
* long enough to schedule this workqueue entry. We need a task context
@@ -646,8 +698,8 @@ static int ds1307_probe(struct i2c_client *client,
buf = ds1307->regs;
if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
- ds1307->read_block_data = i2c_smbus_read_i2c_block_data;
- ds1307->write_block_data = i2c_smbus_write_i2c_block_data;
+ ds1307->read_block_data = ds1307_native_smbus_read_block_data;
+ ds1307->write_block_data = ds1307_native_smbus_write_block_data;
} else {
ds1307->read_block_data = ds1307_read_block_data;
ds1307->write_block_data = ds1307_write_block_data;
@@ -661,7 +713,7 @@ static int ds1307_probe(struct i2c_client *client,
tmp = ds1307->read_block_data(ds1307->client,
DS1337_REG_CONTROL, 2, buf);
if (tmp != 2) {
- pr_debug("read error %d\n", tmp);
+ dev_dbg(&client->dev, "read error %d\n", tmp);
err = -EIO;
goto exit_free;
}
@@ -700,7 +752,7 @@ static int ds1307_probe(struct i2c_client *client,
tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
if (tmp != 2) {
- pr_debug("read error %d\n", tmp);
+ dev_dbg(&client->dev, "read error %d\n", tmp);
err = -EIO;
goto exit_free;
}
@@ -744,7 +796,7 @@ static int ds1307_probe(struct i2c_client *client,
tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
if (tmp != 2) {
- pr_debug("read error %d\n", tmp);
+ dev_dbg(&client->dev, "read error %d\n", tmp);
err = -EIO;
goto exit_free;
}
@@ -772,7 +824,7 @@ read_rtc:
/* read RTC registers */
tmp = ds1307->read_block_data(ds1307->client, ds1307->offset, 8, buf);
if (tmp != 8) {
- pr_debug("read error %d\n", tmp);
+ dev_dbg(&client->dev, "read error %d\n", tmp);
err = -EIO;
goto exit_free;
}
@@ -814,7 +866,7 @@ read_rtc:
tmp = i2c_smbus_read_byte_data(client, DS1340_REG_FLAG);
if (tmp < 0) {
- pr_debug("read error %d\n", tmp);
+ dev_dbg(&client->dev, "read error %d\n", tmp);
err = -EIO;
goto exit_free;
}
@@ -908,8 +960,8 @@ read_rtc:
ds1307->nvram->attr.name = "nvram";
ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR;
sysfs_bin_attr_init(ds1307->nvram);
- ds1307->nvram->read = ds1307_nvram_read,
- ds1307->nvram->write = ds1307_nvram_write,
+ ds1307->nvram->read = ds1307_nvram_read;
+ ds1307->nvram->write = ds1307_nvram_write;
ds1307->nvram->size = chip->nvram_size;
ds1307->nvram_offset = chip->nvram_offset;
err = sysfs_create_bin_file(&client->dev.kobj, ds1307->nvram);
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index fef76868aae0..67cd1e3e77a5 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -409,7 +409,7 @@ static int ds1374_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int ds1374_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -427,19 +427,15 @@ static int ds1374_resume(struct device *dev)
disable_irq_wake(client->irq);
return 0;
}
+#endif
static SIMPLE_DEV_PM_OPS(ds1374_pm, ds1374_suspend, ds1374_resume);
-#define DS1374_PM (&ds1374_pm)
-#else
-#define DS1374_PM NULL
-#endif
-
static struct i2c_driver ds1374_driver = {
.driver = {
.name = "rtc-ds1374",
.owner = THIS_MODULE,
- .pm = DS1374_PM,
+ .pm = &ds1374_pm,
},
.probe = ds1374_probe,
.remove = ds1374_remove,
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c
index f994257981a0..11b70763bb53 100644
--- a/drivers/rtc/rtc-ds1390.c
+++ b/drivers/rtc/rtc-ds1390.c
@@ -136,7 +136,7 @@ static int ds1390_probe(struct spi_device *spi)
dev_err(&spi->dev, "unable to allocate device memory\n");
return -ENOMEM;
}
- dev_set_drvdata(&spi->dev, chip);
+ spi_set_drvdata(spi, chip);
res = ds1390_get_reg(&spi->dev, DS1390_REG_SECONDS, &tmp);
if (res != 0) {
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 6a3fcfe3b0e7..6ce8a997cf51 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -538,15 +538,14 @@ static int ds1511_rtc_probe(struct platform_device *pdev)
}
}
- rtc = rtc_device_register(pdev->name, &pdev->dev, &ds1511_rtc_ops,
- THIS_MODULE);
+ rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &ds1511_rtc_ops,
+ THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
pdata->rtc = rtc;
ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);
- if (ret)
- rtc_device_unregister(pdata->rtc);
+
return ret;
}
@@ -555,7 +554,6 @@ static int ds1511_rtc_remove(struct platform_device *pdev)
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);
- rtc_device_unregister(pdata->rtc);
if (pdata->irq > 0) {
/*
* disable the alarm interrupt
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 25ce0621ade9..8c6c952e90b1 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -326,15 +326,14 @@ static int ds1553_rtc_probe(struct platform_device *pdev)
}
}
- rtc = rtc_device_register(pdev->name, &pdev->dev,
+ rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&ds1553_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
pdata->rtc = rtc;
ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr);
- if (ret)
- rtc_device_unregister(rtc);
+
return ret;
}
@@ -343,7 +342,6 @@ static int ds1553_rtc_remove(struct platform_device *pdev)
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr);
- rtc_device_unregister(pdata->rtc);
if (pdata->irq > 0)
writeb(0, pdata->ioaddr + RTC_INTERRUPTS);
return 0;
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index 45d65c0b3a85..3fc2a4738027 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -155,11 +155,6 @@ static const struct rtc_class_ops ds1672_rtc_ops = {
static int ds1672_remove(struct i2c_client *client)
{
- struct rtc_device *rtc = i2c_get_clientdata(client);
-
- if (rtc)
- rtc_device_unregister(rtc);
-
return 0;
}
@@ -177,7 +172,7 @@ static int ds1672_probe(struct i2c_client *client,
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
- rtc = rtc_device_register(ds1672_driver.driver.name, &client->dev,
+ rtc = devm_rtc_device_register(&client->dev, ds1672_driver.driver.name,
&ds1672_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
@@ -202,7 +197,6 @@ static int ds1672_probe(struct i2c_client *client,
return 0;
exit_devreg:
- rtc_device_unregister(rtc);
return err;
}
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 609c870e2cc5..eccdc62ae1c0 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -208,17 +208,14 @@ static int ds1742_rtc_probe(struct platform_device *pdev)
pdata->last_jiffies = jiffies;
platform_set_drvdata(pdev, pdata);
- rtc = rtc_device_register(pdev->name, &pdev->dev,
+ rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&ds1742_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
pdata->rtc = rtc;
ret = sysfs_create_bin_file(&pdev->dev.kobj, &pdata->nvram_attr);
- if (ret) {
- dev_err(&pdev->dev, "creating nvram file in sysfs failed\n");
- rtc_device_unregister(rtc);
- }
+
return ret;
}
@@ -227,7 +224,6 @@ static int ds1742_rtc_remove(struct platform_device *pdev)
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
sysfs_remove_bin_file(&pdev->dev.kobj, &pdata->nvram_attr);
- rtc_device_unregister(pdata->rtc);
return 0;
}
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c
index 7a4495ef1c39..ba98c0e9580d 100644
--- a/drivers/rtc/rtc-ds3234.c
+++ b/drivers/rtc/rtc-ds3234.c
@@ -146,21 +146,18 @@ static int ds3234_probe(struct spi_device *spi)
ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp);
dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
- rtc = rtc_device_register("ds3234",
- &spi->dev, &ds3234_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&spi->dev, "ds3234",
+ &ds3234_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
- dev_set_drvdata(&spi->dev, rtc);
+ spi_set_drvdata(spi, rtc);
return 0;
}
static int ds3234_remove(struct spi_device *spi)
{
- struct rtc_device *rtc = spi_get_drvdata(spi);
-
- rtc_device_unregister(rtc);
return 0;
}
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c
index 1a0c37c9152b..b3c8c0b1709d 100644
--- a/drivers/rtc/rtc-efi.c
+++ b/drivers/rtc/rtc-efi.c
@@ -191,7 +191,7 @@ static int __init efi_rtc_probe(struct platform_device *dev)
{
struct rtc_device *rtc;
- rtc = rtc_device_register("rtc-efi", &dev->dev, &efi_rtc_ops,
+ rtc = devm_rtc_device_register(&dev->dev, "rtc-efi", &efi_rtc_ops,
THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -203,10 +203,6 @@ static int __init efi_rtc_probe(struct platform_device *dev)
static int __exit efi_rtc_remove(struct platform_device *dev)
{
- struct rtc_device *rtc = platform_get_drvdata(dev);
-
- rtc_device_unregister(rtc);
-
return 0;
}
@@ -218,18 +214,7 @@ static struct platform_driver efi_rtc_driver = {
.remove = __exit_p(efi_rtc_remove),
};
-static int __init efi_rtc_init(void)
-{
- return platform_driver_probe(&efi_rtc_driver, efi_rtc_probe);
-}
-
-static void __exit efi_rtc_exit(void)
-{
- platform_driver_unregister(&efi_rtc_driver);
-}
-
-module_init(efi_rtc_init);
-module_exit(efi_rtc_exit);
+module_platform_driver_probe(efi_rtc_driver, efi_rtc_probe);
MODULE_AUTHOR("dann frazier <dannf@hp.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c
index f6c24ce35d36..3f9eb57d0486 100644
--- a/drivers/rtc/rtc-em3027.c
+++ b/drivers/rtc/rtc-em3027.c
@@ -121,7 +121,7 @@ static int em3027_probe(struct i2c_client *client,
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
- rtc = rtc_device_register(em3027_driver.driver.name, &client->dev,
+ rtc = devm_rtc_device_register(&client->dev, em3027_driver.driver.name,
&em3027_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -133,11 +133,6 @@ static int em3027_probe(struct i2c_client *client,
static int em3027_remove(struct i2c_client *client)
{
- struct rtc_device *rtc = i2c_get_clientdata(client);
-
- if (rtc)
- rtc_device_unregister(rtc);
-
return 0;
}
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index 1a4e5e4a70cd..5807b77c444a 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -153,8 +153,8 @@ static int ep93xx_rtc_probe(struct platform_device *pdev)
pdev->dev.platform_data = ep93xx_rtc;
platform_set_drvdata(pdev, ep93xx_rtc);
- ep93xx_rtc->rtc = rtc_device_register(pdev->name,
- &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE);
+ ep93xx_rtc->rtc = devm_rtc_device_register(&pdev->dev,
+ pdev->name, &ep93xx_rtc_ops, THIS_MODULE);
if (IS_ERR(ep93xx_rtc->rtc)) {
err = PTR_ERR(ep93xx_rtc->rtc);
goto exit;
@@ -162,12 +162,10 @@ static int ep93xx_rtc_probe(struct platform_device *pdev)
err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
if (err)
- goto fail;
+ goto exit;
return 0;
-fail:
- rtc_device_unregister(ep93xx_rtc->rtc);
exit:
platform_set_drvdata(pdev, NULL);
pdev->dev.platform_data = NULL;
@@ -176,11 +174,8 @@ exit:
static int ep93xx_rtc_remove(struct platform_device *pdev)
{
- struct ep93xx_rtc *ep93xx_rtc = platform_get_drvdata(pdev);
-
sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
platform_set_drvdata(pdev, NULL);
- rtc_device_unregister(ep93xx_rtc->rtc);
pdev->dev.platform_data = NULL;
return 0;
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c
index bff3cdc5140e..4d4ad3fcb5e9 100644
--- a/drivers/rtc/rtc-fm3130.c
+++ b/drivers/rtc/rtc-fm3130.c
@@ -395,7 +395,7 @@ static int fm3130_probe(struct i2c_client *client,
tmp = i2c_transfer(adapter, fm3130->msg, 4);
if (tmp != 4) {
- pr_debug("read error %d\n", tmp);
+ dev_dbg(&client->dev, "read error %d\n", tmp);
err = -EIO;
goto exit_free;
}
diff --git a/drivers/rtc/rtc-generic.c b/drivers/rtc/rtc-generic.c
index 98322004ad2e..06279ce6bff2 100644
--- a/drivers/rtc/rtc-generic.c
+++ b/drivers/rtc/rtc-generic.c
@@ -38,8 +38,8 @@ static int __init generic_rtc_probe(struct platform_device *dev)
{
struct rtc_device *rtc;
- rtc = rtc_device_register("rtc-generic", &dev->dev, &generic_rtc_ops,
- THIS_MODULE);
+ rtc = devm_rtc_device_register(&dev->dev, "rtc-generic",
+ &generic_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -50,10 +50,6 @@ static int __init generic_rtc_probe(struct platform_device *dev)
static int __exit generic_rtc_remove(struct platform_device *dev)
{
- struct rtc_device *rtc = platform_get_drvdata(dev);
-
- rtc_device_unregister(rtc);
-
return 0;
}
@@ -65,18 +61,7 @@ static struct platform_driver generic_rtc_driver = {
.remove = __exit_p(generic_rtc_remove),
};
-static int __init generic_rtc_init(void)
-{
- return platform_driver_probe(&generic_rtc_driver, generic_rtc_probe);
-}
-
-static void __exit generic_rtc_fini(void)
-{
- platform_driver_unregister(&generic_rtc_driver);
-}
-
-module_init(generic_rtc_init);
-module_exit(generic_rtc_fini);
+module_platform_driver_probe(generic_rtc_driver, generic_rtc_probe);
MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c
index 31c5728ef629..63024505dddc 100644
--- a/drivers/rtc/rtc-hid-sensor-time.c
+++ b/drivers/rtc/rtc-hid-sensor-time.c
@@ -255,8 +255,9 @@ static int hid_time_probe(struct platform_device *pdev)
return ret;
}
- time_state->rtc = rtc_device_register("hid-sensor-time",
- &pdev->dev, &hid_time_rtc_ops, THIS_MODULE);
+ time_state->rtc = devm_rtc_device_register(&pdev->dev,
+ "hid-sensor-time", &hid_time_rtc_ops,
+ THIS_MODULE);
if (IS_ERR(time_state->rtc)) {
dev_err(&pdev->dev, "rtc device register failed!\n");
@@ -269,9 +270,7 @@ static int hid_time_probe(struct platform_device *pdev)
static int hid_time_remove(struct platform_device *pdev)
{
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
- struct hid_time_state *time_state = platform_get_drvdata(pdev);
- rtc_device_unregister(time_state->rtc);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
return 0;
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c
index 82aad695979e..d3a8c8e255de 100644
--- a/drivers/rtc/rtc-imxdi.c
+++ b/drivers/rtc/rtc-imxdi.c
@@ -369,7 +369,7 @@ static void dryice_work(struct work_struct *work)
/*
* probe for dryice rtc device
*/
-static int dryice_rtc_probe(struct platform_device *pdev)
+static int __init dryice_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
struct imxdi_dev *imxdi;
@@ -464,7 +464,7 @@ static int dryice_rtc_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, imxdi);
- imxdi->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ imxdi->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&dryice_rtc_ops, THIS_MODULE);
if (IS_ERR(imxdi->rtc)) {
rc = PTR_ERR(imxdi->rtc);
@@ -479,7 +479,7 @@ err:
return rc;
}
-static int dryice_rtc_remove(struct platform_device *pdev)
+static int __exit dryice_rtc_remove(struct platform_device *pdev)
{
struct imxdi_dev *imxdi = platform_get_drvdata(pdev);
@@ -488,8 +488,6 @@ static int dryice_rtc_remove(struct platform_device *pdev)
/* mask all interrupts */
__raw_writel(0, imxdi->ioaddr + DIER);
- rtc_device_unregister(imxdi->rtc);
-
clk_disable_unprepare(imxdi->clk);
return 0;
@@ -510,21 +508,10 @@ static struct platform_driver dryice_rtc_driver = {
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(dryice_dt_ids),
},
- .remove = dryice_rtc_remove,
+ .remove = __exit_p(dryice_rtc_remove),
};
-static int __init dryice_rtc_init(void)
-{
- return platform_driver_probe(&dryice_rtc_driver, dryice_rtc_probe);
-}
-
-static void __exit dryice_rtc_exit(void)
-{
- platform_driver_unregister(&dryice_rtc_driver);
-}
-
-module_init(dryice_rtc_init);
-module_exit(dryice_rtc_exit);
+module_platform_driver_probe(dryice_rtc_driver, dryice_rtc_probe);
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
diff --git a/drivers/rtc/rtc-lp8788.c b/drivers/rtc/rtc-lp8788.c
index 9a4631218f41..9853ac15b296 100644
--- a/drivers/rtc/rtc-lp8788.c
+++ b/drivers/rtc/rtc-lp8788.c
@@ -299,7 +299,7 @@ static int lp8788_rtc_probe(struct platform_device *pdev)
device_init_wakeup(dev, 1);
- rtc->rdev = rtc_device_register("lp8788_rtc", dev,
+ rtc->rdev = devm_rtc_device_register(dev, "lp8788_rtc",
&lp8788_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rdev)) {
dev_err(dev, "can not register rtc device\n");
@@ -314,9 +314,6 @@ static int lp8788_rtc_probe(struct platform_device *pdev)
static int lp8788_rtc_remove(struct platform_device *pdev)
{
- struct lp8788_rtc *rtc = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtc->rdev);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c
index 40a598332bac..787550d756e9 100644
--- a/drivers/rtc/rtc-lpc32xx.c
+++ b/drivers/rtc/rtc-lpc32xx.c
@@ -273,8 +273,8 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc);
- rtc->rtc = rtc_device_register(RTC_NAME, &pdev->dev, &lpc32xx_rtc_ops,
- THIS_MODULE);
+ rtc->rtc = devm_rtc_device_register(&pdev->dev, RTC_NAME,
+ &lpc32xx_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc)) {
dev_err(&pdev->dev, "Can't get RTC\n");
platform_set_drvdata(pdev, NULL);
@@ -307,7 +307,6 @@ static int lpc32xx_rtc_remove(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 0);
platform_set_drvdata(pdev, NULL);
- rtc_device_unregister(rtc->rtc);
return 0;
}
diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c
index f59b6349551a..db82f91f4562 100644
--- a/drivers/rtc/rtc-ls1x.c
+++ b/drivers/rtc/rtc-ls1x.c
@@ -172,7 +172,7 @@ static int ls1x_rtc_probe(struct platform_device *pdev)
while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS)
usleep_range(1000, 3000);
- rtcdev = rtc_device_register("ls1x-rtc", &pdev->dev,
+ rtcdev = devm_rtc_device_register(&pdev->dev, "ls1x-rtc",
&ls1x_rtc_ops , THIS_MODULE);
if (IS_ERR(rtcdev)) {
ret = PTR_ERR(rtcdev);
@@ -187,9 +187,6 @@ err:
static int ls1x_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtcdev = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtcdev);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c
index 49169680786e..9707d36e8b15 100644
--- a/drivers/rtc/rtc-m41t93.c
+++ b/drivers/rtc/rtc-m41t93.c
@@ -184,12 +184,12 @@ static int m41t93_probe(struct spi_device *spi)
return -ENODEV;
}
- rtc = rtc_device_register(m41t93_driver.driver.name,
- &spi->dev, &m41t93_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&spi->dev, m41t93_driver.driver.name,
+ &m41t93_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
- dev_set_drvdata(&spi->dev, rtc);
+ spi_set_drvdata(spi, rtc);
return 0;
}
@@ -197,11 +197,6 @@ static int m41t93_probe(struct spi_device *spi)
static int m41t93_remove(struct spi_device *spi)
{
- struct rtc_device *rtc = spi_get_drvdata(spi);
-
- if (rtc)
- rtc_device_unregister(rtc);
-
return 0;
}
diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c
index 89266c6764bc..7454ef0a4cfa 100644
--- a/drivers/rtc/rtc-m41t94.c
+++ b/drivers/rtc/rtc-m41t94.c
@@ -124,23 +124,18 @@ static int m41t94_probe(struct spi_device *spi)
return res;
}
- rtc = rtc_device_register(m41t94_driver.driver.name,
- &spi->dev, &m41t94_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&spi->dev, m41t94_driver.driver.name,
+ &m41t94_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
- dev_set_drvdata(&spi->dev, rtc);
+ spi_set_drvdata(spi, rtc);
return 0;
}
static int m41t94_remove(struct spi_device *spi)
{
- struct rtc_device *rtc = spi_get_drvdata(spi);
-
- if (rtc)
- rtc_device_unregister(rtc);
-
return 0;
}
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index 2ffbcacd2439..33a91c484533 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -148,8 +148,10 @@ static int m48t86_rtc_probe(struct platform_device *dev)
{
unsigned char reg;
struct m48t86_ops *ops = dev->dev.platform_data;
- struct rtc_device *rtc = rtc_device_register("m48t86",
- &dev->dev, &m48t86_rtc_ops, THIS_MODULE);
+ struct rtc_device *rtc;
+
+ rtc = devm_rtc_device_register(&dev->dev, "m48t86",
+ &m48t86_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -166,11 +168,6 @@ static int m48t86_rtc_probe(struct platform_device *dev)
static int m48t86_rtc_remove(struct platform_device *dev)
{
- struct rtc_device *rtc = platform_get_drvdata(dev);
-
- if (rtc)
- rtc_device_unregister(rtc);
-
platform_set_drvdata(dev, NULL);
return 0;
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c
index a00e33204b91..8669d6d09a00 100644
--- a/drivers/rtc/rtc-max6900.c
+++ b/drivers/rtc/rtc-max6900.c
@@ -214,11 +214,6 @@ static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int max6900_remove(struct i2c_client *client)
{
- struct rtc_device *rtc = i2c_get_clientdata(client);
-
- if (rtc)
- rtc_device_unregister(rtc);
-
return 0;
}
@@ -237,8 +232,8 @@ max6900_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
- rtc = rtc_device_register(max6900_driver.driver.name,
- &client->dev, &max6900_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&client->dev, max6900_driver.driver.name,
+ &max6900_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c
index 7d0bf698b79e..7730a6559188 100644
--- a/drivers/rtc/rtc-max6902.c
+++ b/drivers/rtc/rtc-max6902.c
@@ -134,20 +134,17 @@ static int max6902_probe(struct spi_device *spi)
if (res != 0)
return res;
- rtc = rtc_device_register("max6902",
- &spi->dev, &max6902_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&spi->dev, "max6902",
+ &max6902_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
- dev_set_drvdata(&spi->dev, rtc);
+ spi_set_drvdata(spi, rtc);
return 0;
}
static int max6902_remove(struct spi_device *spi)
{
- struct rtc_device *rtc = dev_get_drvdata(&spi->dev);
-
- rtc_device_unregister(rtc);
return 0;
}
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index 6b1337f9baf4..fb08b89c41e7 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -24,7 +24,7 @@
/* RTC Control Register */
#define BCD_EN_SHIFT 0
-#define BCD_EN_MASK (1 << BCD_EN_SHIFT)
+#define BCD_EN_MASK (1 << BCD_EN_SHIFT)
#define MODEL24_SHIFT 1
#define MODEL24_MASK (1 << MODEL24_SHIFT)
/* RTC Update Register1 */
@@ -33,12 +33,12 @@
#define RTC_RBUDR_SHIFT 4
#define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT)
/* WTSR and SMPL Register */
-#define WTSRT_SHIFT 0
-#define SMPLT_SHIFT 2
+#define WTSRT_SHIFT 0
+#define SMPLT_SHIFT 2
#define WTSR_EN_SHIFT 6
#define SMPL_EN_SHIFT 7
-#define WTSRT_MASK (3 << WTSRT_SHIFT)
-#define SMPLT_MASK (3 << SMPLT_SHIFT)
+#define WTSRT_MASK (3 << WTSRT_SHIFT)
+#define SMPLT_MASK (3 << SMPLT_SHIFT)
#define WTSR_EN_MASK (1 << WTSR_EN_SHIFT)
#define SMPL_EN_MASK (1 << SMPL_EN_SHIFT)
/* RTC Hour register */
@@ -466,7 +466,7 @@ static void max77686_rtc_enable_smpl(struct max77686_rtc_info *info, bool enable
val = 0;
regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val);
- pr_info("%s: WTSR_SMPL(0x%02x)\n", __func__, val);
+ dev_info(info->dev, "%s: WTSR_SMPL(0x%02x)\n", __func__, val);
}
#endif /* MAX77686_RTC_WTSR_SMPL */
@@ -505,7 +505,8 @@ static int max77686_rtc_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "%s\n", __func__);
- info = kzalloc(sizeof(struct max77686_rtc_info), GFP_KERNEL);
+ info = devm_kzalloc(&pdev->dev, sizeof(struct max77686_rtc_info),
+ GFP_KERNEL);
if (!info)
return -ENOMEM;
@@ -519,7 +520,6 @@ static int max77686_rtc_probe(struct platform_device *pdev)
ret = PTR_ERR(info->max77686->rtc_regmap);
dev_err(info->max77686->dev, "Failed to allocate register map: %d\n",
ret);
- kfree(info);
return ret;
}
platform_set_drvdata(pdev, info);
@@ -538,8 +538,8 @@ static int max77686_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
- info->rtc_dev = rtc_device_register("max77686-rtc", &pdev->dev,
- &max77686_rtc_ops, THIS_MODULE);
+ info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc",
+ &max77686_rtc_ops, THIS_MODULE);
if (IS_ERR(info->rtc_dev)) {
dev_info(&pdev->dev, "%s: fail\n", __func__);
@@ -551,36 +551,24 @@ static int max77686_rtc_probe(struct platform_device *pdev)
goto err_rtc;
}
virq = irq_create_mapping(max77686->irq_domain, MAX77686_RTCIRQ_RTCA1);
- if (!virq)
+ if (!virq) {
+ ret = -ENXIO;
goto err_rtc;
+ }
info->virq = virq;
- ret = request_threaded_irq(virq, NULL, max77686_rtc_alarm_irq, 0,
- "rtc-alarm0", info);
- if (ret < 0) {
+ ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
+ max77686_rtc_alarm_irq, 0, "rtc-alarm0", info);
+ if (ret < 0)
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
info->virq, ret);
- goto err_rtc;
- }
- goto out;
err_rtc:
- kfree(info);
- return ret;
-out:
return ret;
}
static int max77686_rtc_remove(struct platform_device *pdev)
{
- struct max77686_rtc_info *info = platform_get_drvdata(pdev);
-
- if (info) {
- free_irq(info->virq, info);
- rtc_device_unregister(info->rtc_dev);
- kfree(info);
- }
-
return 0;
}
@@ -594,11 +582,14 @@ static void max77686_rtc_shutdown(struct platform_device *pdev)
for (i = 0; i < 3; i++) {
max77686_rtc_enable_wtsr(info, false);
regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val);
- pr_info("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val);
- if (val & WTSR_EN_MASK)
- pr_emerg("%s: fail to disable WTSR\n", __func__);
- else {
- pr_info("%s: success to disable WTSR\n", __func__);
+ dev_info(info->dev, "%s: WTSR_SMPL reg(0x%02x)\n", __func__,
+ val);
+ if (val & WTSR_EN_MASK) {
+ dev_emerg(info->dev, "%s: fail to disable WTSR\n",
+ __func__);
+ } else {
+ dev_info(info->dev, "%s: success to disable WTSR\n",
+ __func__);
break;
}
}
@@ -624,18 +615,8 @@ static struct platform_driver max77686_rtc_driver = {
.id_table = rtc_id,
};
-static int __init max77686_rtc_init(void)
-{
- return platform_driver_register(&max77686_rtc_driver);
-}
-module_init(max77686_rtc_init);
-
-static void __exit max77686_rtc_exit(void)
-{
- platform_driver_unregister(&max77686_rtc_driver);
-}
-module_exit(max77686_rtc_exit);
+module_platform_driver(max77686_rtc_driver);
MODULE_DESCRIPTION("Maxim MAX77686 RTC driver");
-MODULE_AUTHOR("<woong.byun@samsung.com>");
+MODULE_AUTHOR("Chiwoong Byun <woong.byun@samsung.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-max8907.c b/drivers/rtc/rtc-max8907.c
index 31ca8faf9f05..86afb797125d 100644
--- a/drivers/rtc/rtc-max8907.c
+++ b/drivers/rtc/rtc-max8907.c
@@ -190,7 +190,7 @@ static int max8907_rtc_probe(struct platform_device *pdev)
rtc->max8907 = max8907;
rtc->regmap = max8907->regmap_rtc;
- rtc->rtc_dev = rtc_device_register("max8907-rtc", &pdev->dev,
+ rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, "max8907-rtc",
&max8907_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev)) {
ret = PTR_ERR(rtc->rtc_dev);
@@ -200,33 +200,21 @@ static int max8907_rtc_probe(struct platform_device *pdev)
rtc->irq = regmap_irq_get_virq(max8907->irqc_rtc,
MAX8907_IRQ_RTC_ALARM0);
- if (rtc->irq < 0) {
- ret = rtc->irq;
- goto err_unregister;
- }
+ if (rtc->irq < 0)
+ return rtc->irq;
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
max8907_irq_handler,
IRQF_ONESHOT, "max8907-alarm0", rtc);
- if (ret < 0) {
+ if (ret < 0)
dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n",
rtc->irq, ret);
- goto err_unregister;
- }
- return 0;
-
-err_unregister:
- rtc_device_unregister(rtc->rtc_dev);
return ret;
}
static int max8907_rtc_remove(struct platform_device *pdev)
{
- struct max8907_rtc *rtc = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtc->rtc_dev);
-
return 0;
}
diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c
index 00e505b6bee3..5693619614f4 100644
--- a/drivers/rtc/rtc-max8997.c
+++ b/drivers/rtc/rtc-max8997.c
@@ -479,8 +479,8 @@ static int max8997_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
- info->rtc_dev = rtc_device_register("max8997-rtc", &pdev->dev,
- &max8997_rtc_ops, THIS_MODULE);
+ info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max8997-rtc",
+ &max8997_rtc_ops, THIS_MODULE);
if (IS_ERR(info->rtc_dev)) {
ret = PTR_ERR(info->rtc_dev);
@@ -491,6 +491,7 @@ static int max8997_rtc_probe(struct platform_device *pdev)
virq = irq_create_mapping(max8997->irq_domain, MAX8997_PMICIRQ_RTCA1);
if (!virq) {
dev_err(&pdev->dev, "Failed to create mapping alarm IRQ\n");
+ ret = -ENXIO;
goto err_out;
}
info->virq = virq;
@@ -498,26 +499,16 @@ static int max8997_rtc_probe(struct platform_device *pdev)
ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
max8997_rtc_alarm_irq, 0,
"rtc-alarm0", info);
- if (ret < 0) {
+ if (ret < 0)
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
info->virq, ret);
- goto err_out;
- }
-
- return ret;
err_out:
- rtc_device_unregister(info->rtc_dev);
return ret;
}
static int max8997_rtc_remove(struct platform_device *pdev)
{
- struct max8997_rtc_info *info = platform_get_drvdata(pdev);
-
- if (info)
- rtc_device_unregister(info->rtc_dev);
-
return 0;
}
diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c
index 2643d8874925..5391b154b43c 100644
--- a/drivers/rtc/rtc-mc13xxx.c
+++ b/drivers/rtc/rtc-mc13xxx.c
@@ -420,17 +420,7 @@ static struct platform_driver mc13xxx_rtc_driver = {
},
};
-static int __init mc13xxx_rtc_init(void)
-{
- return platform_driver_probe(&mc13xxx_rtc_driver, &mc13xxx_rtc_probe);
-}
-module_init(mc13xxx_rtc_init);
-
-static void __exit mc13xxx_rtc_exit(void)
-{
- platform_driver_unregister(&mc13xxx_rtc_driver);
-}
-module_exit(mc13xxx_rtc_exit);
+module_platform_driver_probe(mc13xxx_rtc_driver, &mc13xxx_rtc_probe);
MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
MODULE_DESCRIPTION("RTC driver for Freescale MC13XXX PMIC");
diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c
index fcb113c11122..3ac1e8eca89d 100644
--- a/drivers/rtc/rtc-msm6242.c
+++ b/drivers/rtc/rtc-msm6242.c
@@ -252,18 +252,7 @@ static struct platform_driver msm6242_rtc_driver = {
.remove = __exit_p(msm6242_rtc_remove),
};
-static int __init msm6242_rtc_init(void)
-{
- return platform_driver_probe(&msm6242_rtc_driver, msm6242_rtc_probe);
-}
-
-static void __exit msm6242_rtc_fini(void)
-{
- platform_driver_unregister(&msm6242_rtc_driver);
-}
-
-module_init(msm6242_rtc_init);
-module_exit(msm6242_rtc_fini);
+module_platform_driver_probe(msm6242_rtc_driver, msm6242_rtc_probe);
MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index 8f87fec27ce7..baab802f2153 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -217,7 +217,7 @@ static const struct rtc_class_ops mv_rtc_alarm_ops = {
.alarm_irq_enable = mv_rtc_alarm_irq_enable,
};
-static int mv_rtc_probe(struct platform_device *pdev)
+static int __init mv_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
struct rtc_plat_data *pdata;
@@ -272,12 +272,13 @@ static int mv_rtc_probe(struct platform_device *pdev)
if (pdata->irq >= 0) {
device_init_wakeup(&pdev->dev, 1);
- pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&mv_rtc_alarm_ops,
THIS_MODULE);
- } else
- pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ } else {
+ pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&mv_rtc_ops, THIS_MODULE);
+ }
if (IS_ERR(pdata->rtc)) {
ret = PTR_ERR(pdata->rtc);
goto out;
@@ -308,7 +309,6 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
if (pdata->irq >= 0)
device_init_wakeup(&pdev->dev, 0);
- rtc_device_unregister(pdata->rtc);
if (!IS_ERR(pdata->clk))
clk_disable_unprepare(pdata->clk);
@@ -331,18 +331,7 @@ static struct platform_driver mv_rtc_driver = {
},
};
-static __init int mv_init(void)
-{
- return platform_driver_probe(&mv_rtc_driver, mv_rtc_probe);
-}
-
-static __exit void mv_exit(void)
-{
- platform_driver_unregister(&mv_rtc_driver);
-}
-
-module_init(mv_init);
-module_exit(mv_exit);
+module_platform_driver_probe(mv_rtc_driver, mv_rtc_probe);
MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
MODULE_DESCRIPTION("Marvell RTC driver");
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index 1c3ef7289565..9a3895bc4f4d 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -439,7 +439,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
if (pdata->irq >=0)
device_init_wakeup(&pdev->dev, 1);
- rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops,
+ rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &mxc_rtc_ops,
THIS_MODULE);
if (IS_ERR(rtc)) {
ret = PTR_ERR(rtc);
@@ -464,15 +464,13 @@ static int mxc_rtc_remove(struct platform_device *pdev)
{
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
- rtc_device_unregister(pdata->rtc);
-
clk_disable_unprepare(pdata->clk);
platform_set_drvdata(pdev, NULL);
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int mxc_rtc_suspend(struct device *dev)
{
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
@@ -492,19 +490,14 @@ static int mxc_rtc_resume(struct device *dev)
return 0;
}
-
-static struct dev_pm_ops mxc_rtc_pm_ops = {
- .suspend = mxc_rtc_suspend,
- .resume = mxc_rtc_resume,
-};
#endif
+static SIMPLE_DEV_PM_OPS(mxc_rtc_pm_ops, mxc_rtc_suspend, mxc_rtc_resume);
+
static struct platform_driver mxc_rtc_driver = {
.driver = {
.name = "mxc_rtc",
-#ifdef CONFIG_PM
.pm = &mxc_rtc_pm_ops,
-#endif
.owner = THIS_MODULE,
},
.id_table = imx_rtc_devtype,
diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c
index a63680850fef..4d9525cc1cf4 100644
--- a/drivers/rtc/rtc-nuc900.c
+++ b/drivers/rtc/rtc-nuc900.c
@@ -222,7 +222,7 @@ static struct rtc_class_ops nuc900_rtc_ops = {
.alarm_irq_enable = nuc900_alarm_irq_enable,
};
-static int nuc900_rtc_probe(struct platform_device *pdev)
+static int __init nuc900_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
struct nuc900_rtc *nuc900_rtc;
@@ -284,7 +284,7 @@ fail1: kfree(nuc900_rtc);
return err;
}
-static int nuc900_rtc_remove(struct platform_device *pdev)
+static int __exit nuc900_rtc_remove(struct platform_device *pdev)
{
struct nuc900_rtc *nuc900_rtc = platform_get_drvdata(pdev);
struct resource *res;
@@ -304,25 +304,14 @@ static int nuc900_rtc_remove(struct platform_device *pdev)
}
static struct platform_driver nuc900_rtc_driver = {
- .remove = nuc900_rtc_remove,
+ .remove = __exit_p(nuc900_rtc_remove),
.driver = {
.name = "nuc900-rtc",
.owner = THIS_MODULE,
},
};
-static int __init nuc900_rtc_init(void)
-{
- return platform_driver_probe(&nuc900_rtc_driver, nuc900_rtc_probe);
-}
-
-static void __exit nuc900_rtc_exit(void)
-{
- platform_driver_unregister(&nuc900_rtc_driver);
-}
-
-module_init(nuc900_rtc_init);
-module_exit(nuc900_rtc_exit);
+module_platform_driver_probe(nuc900_rtc_driver, nuc900_rtc_probe);
MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
MODULE_DESCRIPTION("nuc910/nuc920 RTC driver");
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 600971407aac..a1f9d30e162b 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -324,7 +324,7 @@ MODULE_DEVICE_TABLE(of, omap_rtc_of_match);
static int __init omap_rtc_probe(struct platform_device *pdev)
{
- struct resource *res, *mem;
+ struct resource *res;
struct rtc_device *rtc;
u8 reg, new_ctrl;
const struct platform_device_id *id_entry;
@@ -352,18 +352,9 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
return -ENOENT;
}
- mem = request_mem_region(res->start, resource_size(res), pdev->name);
- if (!mem) {
- pr_debug("%s: RTC registers at %08x are not free\n",
- pdev->name, res->start);
- return -EBUSY;
- }
-
- rtc_base = ioremap(res->start, resource_size(res));
- if (!rtc_base) {
- pr_debug("%s: RTC registers can't be mapped\n", pdev->name);
- goto fail;
- }
+ rtc_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(rtc_base))
+ return PTR_ERR(rtc_base);
/* Enable the clock/module so that we can access the registers */
pm_runtime_enable(&pdev->dev);
@@ -375,7 +366,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG);
}
- rtc = rtc_device_register(pdev->name, &pdev->dev,
+ rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&omap_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
pr_debug("%s: can't register RTC device, err %ld\n",
@@ -383,7 +374,6 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
goto fail0;
}
platform_set_drvdata(pdev, rtc);
- dev_set_drvdata(&rtc->dev, mem);
/* clear pending irqs, and set 1/second periodic,
* which we'll use instead of update irqs
@@ -401,18 +391,18 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
/* handle periodic and alarm irqs */
- if (request_irq(omap_rtc_timer, rtc_irq, 0,
+ if (devm_request_irq(&pdev->dev, omap_rtc_timer, rtc_irq, 0,
dev_name(&rtc->dev), rtc)) {
pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_timer);
- goto fail1;
+ goto fail0;
}
if ((omap_rtc_timer != omap_rtc_alarm) &&
- (request_irq(omap_rtc_alarm, rtc_irq, 0,
+ (devm_request_irq(&pdev->dev, omap_rtc_alarm, rtc_irq, 0,
dev_name(&rtc->dev), rtc))) {
pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_alarm);
- goto fail2;
+ goto fail0;
}
/* On boards with split power, RTC_ON_NOFF won't reset the RTC */
@@ -446,25 +436,16 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
return 0;
-fail2:
- free_irq(omap_rtc_timer, rtc);
-fail1:
- rtc_device_unregister(rtc);
fail0:
if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
rtc_writel(0, OMAP_RTC_KICK0_REG);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- iounmap(rtc_base);
-fail:
- release_mem_region(mem->start, resource_size(mem));
return -EIO;
}
static int __exit omap_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtc = platform_get_drvdata(pdev);
- struct resource *mem = dev_get_drvdata(&rtc->dev);
const struct platform_device_id *id_entry =
platform_get_device_id(pdev);
@@ -473,12 +454,6 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
/* leave rtc running, but disable irqs */
rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
- free_irq(omap_rtc_timer, rtc);
-
- if (omap_rtc_timer != omap_rtc_alarm)
- free_irq(omap_rtc_alarm, rtc);
-
- rtc_device_unregister(rtc);
if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
rtc_writel(0, OMAP_RTC_KICK0_REG);
@@ -486,8 +461,6 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- iounmap(rtc_base);
- release_mem_region(mem->start, resource_size(mem));
return 0;
}
@@ -550,17 +523,7 @@ static struct platform_driver omap_rtc_driver = {
.id_table = omap_rtc_devtype,
};
-static int __init rtc_init(void)
-{
- return platform_driver_probe(&omap_rtc_driver, omap_rtc_probe);
-}
-module_init(rtc_init);
-
-static void __exit rtc_exit(void)
-{
- platform_driver_unregister(&omap_rtc_driver);
-}
-module_exit(rtc_exit);
+module_platform_driver_probe(omap_rtc_driver, omap_rtc_probe);
MODULE_AUTHOR("George G. Davis (and others)");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-palmas.c b/drivers/rtc/rtc-palmas.c
index 59c42986254e..50204d474eb7 100644
--- a/drivers/rtc/rtc-palmas.c
+++ b/drivers/rtc/rtc-palmas.c
@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/mfd/palmas.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/rtc.h>
#include <linux/types.h>
#include <linux/platform_device.h>
@@ -264,7 +265,7 @@ static int palmas_rtc_probe(struct platform_device *pdev)
palmas_rtc->irq = platform_get_irq(pdev, 0);
- palmas_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ palmas_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&palmas_rtc_ops, THIS_MODULE);
if (IS_ERR(palmas_rtc->rtc)) {
ret = PTR_ERR(palmas_rtc->rtc);
@@ -272,14 +273,13 @@ static int palmas_rtc_probe(struct platform_device *pdev)
return ret;
}
- ret = request_threaded_irq(palmas_rtc->irq, NULL,
+ ret = devm_request_threaded_irq(&pdev->dev, palmas_rtc->irq, NULL,
palmas_rtc_interrupt,
IRQF_TRIGGER_LOW | IRQF_ONESHOT |
IRQF_EARLY_RESUME,
dev_name(&pdev->dev), palmas_rtc);
if (ret < 0) {
dev_err(&pdev->dev, "IRQ request failed, err = %d\n", ret);
- rtc_device_unregister(palmas_rtc->rtc);
return ret;
}
@@ -289,11 +289,7 @@ static int palmas_rtc_probe(struct platform_device *pdev)
static int palmas_rtc_remove(struct platform_device *pdev)
{
- struct palmas_rtc *palmas_rtc = platform_get_drvdata(pdev);
-
palmas_rtc_alarm_irq_enable(&pdev->dev, 0);
- free_irq(palmas_rtc->irq, palmas_rtc);
- rtc_device_unregister(palmas_rtc->rtc);
return 0;
}
@@ -321,6 +317,14 @@ static const struct dev_pm_ops palmas_rtc_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(palmas_rtc_suspend, palmas_rtc_resume)
};
+#ifdef CONFIG_OF
+static struct of_device_id of_palmas_rtc_match[] = {
+ { .compatible = "ti,palmas-rtc"},
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_palmas_rtc_match);
+#endif
+
static struct platform_driver palmas_rtc_driver = {
.probe = palmas_rtc_probe,
.remove = palmas_rtc_remove,
@@ -328,6 +332,7 @@ static struct platform_driver palmas_rtc_driver = {
.owner = THIS_MODULE,
.name = "palmas-rtc",
.pm = &palmas_rtc_pm_ops,
+ .of_match_table = of_match_ptr(of_palmas_rtc_match),
},
};
diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c
index e0019cd0bf71..ce0982490e8c 100644
--- a/drivers/rtc/rtc-pcap.c
+++ b/drivers/rtc/rtc-pcap.c
@@ -139,7 +139,7 @@ static const struct rtc_class_ops pcap_rtc_ops = {
.alarm_irq_enable = pcap_rtc_alarm_irq_enable,
};
-static int pcap_rtc_probe(struct platform_device *pdev)
+static int __init pcap_rtc_probe(struct platform_device *pdev)
{
struct pcap_rtc *pcap_rtc;
int timer_irq, alarm_irq;
@@ -183,7 +183,7 @@ fail_rtc:
return err;
}
-static int pcap_rtc_remove(struct platform_device *pdev)
+static int __exit pcap_rtc_remove(struct platform_device *pdev)
{
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
@@ -196,25 +196,14 @@ static int pcap_rtc_remove(struct platform_device *pdev)
}
static struct platform_driver pcap_rtc_driver = {
- .remove = pcap_rtc_remove,
+ .remove = __exit_p(pcap_rtc_remove),
.driver = {
.name = "pcap-rtc",
.owner = THIS_MODULE,
},
};
-static int __init rtc_pcap_init(void)
-{
- return platform_driver_probe(&pcap_rtc_driver, pcap_rtc_probe);
-}
-
-static void __exit rtc_pcap_exit(void)
-{
- platform_driver_unregister(&pcap_rtc_driver);
-}
-
-module_init(rtc_pcap_init);
-module_exit(rtc_pcap_exit);
+module_platform_driver_probe(pcap_rtc_driver, pcap_rtc_probe);
MODULE_DESCRIPTION("Motorola pcap rtc driver");
MODULE_AUTHOR("guiming zhuo <gmzhuo@gmail.com>");
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c
index 889e3160e701..305c9515e5bb 100644
--- a/drivers/rtc/rtc-pcf8523.c
+++ b/drivers/rtc/rtc-pcf8523.c
@@ -307,7 +307,7 @@ static int pcf8523_probe(struct i2c_client *client,
if (err < 0)
return err;
- pcf->rtc = rtc_device_register(DRIVER_NAME, &client->dev,
+ pcf->rtc = devm_rtc_device_register(&client->dev, DRIVER_NAME,
&pcf8523_rtc_ops, THIS_MODULE);
if (IS_ERR(pcf->rtc))
return PTR_ERR(pcf->rtc);
@@ -319,10 +319,6 @@ static int pcf8523_probe(struct i2c_client *client,
static int pcf8523_remove(struct i2c_client *client)
{
- struct pcf8523 *pcf = i2c_get_clientdata(client);
-
- rtc_device_unregister(pcf->rtc);
-
return 0;
}
diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c
index 968133ce1ee8..4bb825bb5804 100644
--- a/drivers/rtc/rtc-ps3.c
+++ b/drivers/rtc/rtc-ps3.c
@@ -62,7 +62,7 @@ static int __init ps3_rtc_probe(struct platform_device *dev)
{
struct rtc_device *rtc;
- rtc = rtc_device_register("rtc-ps3", &dev->dev, &ps3_rtc_ops,
+ rtc = devm_rtc_device_register(&dev->dev, "rtc-ps3", &ps3_rtc_ops,
THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -73,7 +73,6 @@ static int __init ps3_rtc_probe(struct platform_device *dev)
static int __exit ps3_rtc_remove(struct platform_device *dev)
{
- rtc_device_unregister(platform_get_drvdata(dev));
return 0;
}
@@ -85,18 +84,7 @@ static struct platform_driver ps3_rtc_driver = {
.remove = __exit_p(ps3_rtc_remove),
};
-static int __init ps3_rtc_init(void)
-{
- return platform_driver_probe(&ps3_rtc_driver, ps3_rtc_probe);
-}
-
-static void __exit ps3_rtc_fini(void)
-{
- platform_driver_unregister(&ps3_rtc_driver);
-}
-
-module_init(ps3_rtc_init);
-module_exit(ps3_rtc_fini);
+module_platform_driver_probe(ps3_rtc_driver, ps3_rtc_probe);
MODULE_AUTHOR("Sony Corporation");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c
index 03c85ee719a7..a2c75c1ed4cc 100644
--- a/drivers/rtc/rtc-pxa.c
+++ b/drivers/rtc/rtc-pxa.c
@@ -19,6 +19,7 @@
*
*/
+#include <linux/delay.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/module.h>
@@ -80,22 +81,29 @@
#define RYAR1 0x1c
#define RTCPICR 0x34
#define PIAR 0x38
+#define PSBR_RTC 0x00
#define rtc_readl(pxa_rtc, reg) \
__raw_readl((pxa_rtc)->base + (reg))
#define rtc_writel(pxa_rtc, reg, value) \
__raw_writel((value), (pxa_rtc)->base + (reg))
+#define rtc_readl_psbr(pxa_rtc, reg) \
+ __raw_readl((pxa_rtc)->base_psbr + (reg))
+#define rtc_writel_psbr(pxa_rtc, reg, value) \
+ __raw_writel((value), (pxa_rtc)->base_psbr + (reg))
struct pxa_rtc {
struct resource *ress;
+ struct resource *ress_psbr;
void __iomem *base;
+ void __iomem *base_psbr;
int irq_1Hz;
int irq_Alrm;
struct rtc_device *rtc;
spinlock_t lock; /* Protects this structure */
};
-
+static struct pxa_rtc *rtc_info;
static u32 ryxr_calc(struct rtc_time *tm)
{
return ((tm->tm_year + 1900) << RYxR_YEAR_S)
@@ -117,7 +125,7 @@ static void tm_calc(u32 rycr, u32 rdcr, struct rtc_time *tm)
tm->tm_year = ((rycr & RYxR_YEAR_MASK) >> RYxR_YEAR_S) - 1900;
tm->tm_mon = (((rycr & RYxR_MONTH_MASK) >> RYxR_MONTH_S)) - 1;
tm->tm_mday = (rycr & RYxR_DAY_MASK);
- tm->tm_wday = ((rycr & RDxR_DOW_MASK) >> RDxR_DOW_S) - 1;
+ tm->tm_wday = ((rdcr & RDxR_DOW_MASK) >> RDxR_DOW_S) - 1;
tm->tm_hour = (rdcr & RDxR_HOUR_MASK) >> RDxR_HOUR_S;
tm->tm_min = (rdcr & RDxR_MIN_MASK) >> RDxR_MIN_S;
tm->tm_sec = rdcr & RDxR_SEC_MASK;
@@ -175,7 +183,6 @@ static irqreturn_t pxa_rtc_irq(int irq, void *dev_id)
/* enable back rtc interrupts */
rtc_writel(pxa_rtc, RTSR, rtsr & ~RTSR_TRIG_MASK);
-
spin_unlock(&pxa_rtc->lock);
return IRQ_HANDLED;
}
@@ -250,12 +257,45 @@ static int pxa_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int pxa_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev);
-
+ /* sequence to wirte pxa rtc register RCNR RDCR RYCR is
+ *1. set PSBR[RWE] bit, take 2x32-khz to complete
+ *2. write to RTC register,take 2x32-khz to complete
+ *3. clear PSBR[RWE] bit,take 2x32-khz to complete
+ */
+ if ((tm->tm_year < 70) || (tm->tm_year > 138))
+ return -EINVAL;
+ rtc_writel_psbr(rtc_info, PSBR_RTC, 0x01);
+ udelay(100);
rtc_writel(pxa_rtc, RYCR, ryxr_calc(tm));
rtc_writel(pxa_rtc, RDCR, rdxr_calc(tm));
+ udelay(100);
+ rtc_writel_psbr(rtc_info, PSBR_RTC, 0x00);
+ udelay(100);
+ pxa_rtc_read_time(dev, tm);
+ dev_info(dev, "tm.year = %d, tm.month = %d, tm.day = %d\n",
+ tm->tm_year + 1900, tm->tm_mon, tm->tm_mday);
+ return 0;
+}
+int pxa_rtc_sync_time(unsigned int ticks)
+{
+ /* sequence to wirte pxa rtc register RCNR RDCR RYCR is
+ *1. set PSBR[RWE] bit, take 2x32-khz to complete
+ *2. write to RTC register,take 2x32-khz to complete
+ *3. clear PSBR[RWE] bit,take 2x32-khz to complete
+ */
+ struct rtc_time tm;
+ rtc_time_to_tm(ticks, &tm);
+ rtc_writel_psbr(rtc_info, PSBR_RTC, 0x01);
+ udelay(100);
+ rtc_writel(rtc_info, RYCR, ryxr_calc(&tm));
+ rtc_writel(rtc_info, RDCR, rdxr_calc(&tm));
+ udelay(100);
+ rtc_writel_psbr(rtc_info, PSBR_RTC, 0x00);
+ udelay(100);
return 0;
}
+EXPORT_SYMBOL(pxa_rtc_sync_time);
static int pxa_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
@@ -327,7 +367,7 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
pxa_rtc = kzalloc(sizeof(struct pxa_rtc), GFP_KERNEL);
if (!pxa_rtc)
return -ENOMEM;
-
+ rtc_info = pxa_rtc;
spin_lock_init(&pxa_rtc->lock);
platform_set_drvdata(pdev, pxa_rtc);
@@ -337,6 +377,11 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
dev_err(dev, "No I/O memory resource defined\n");
goto err_ress;
}
+ pxa_rtc->ress_psbr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!pxa_rtc->ress_psbr) {
+ dev_err(dev, "No I/O memory resource defined\n");
+ goto err_ress;
+ }
pxa_rtc->irq_1Hz = platform_get_irq(pdev, 0);
if (pxa_rtc->irq_1Hz < 0) {
@@ -348,7 +393,6 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
dev_err(dev, "No alarm IRQ resource defined\n");
goto err_ress;
}
- pxa_rtc_open(dev);
ret = -ENOMEM;
pxa_rtc->base = ioremap(pxa_rtc->ress->start,
resource_size(pxa_rtc->ress));
@@ -357,6 +401,12 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
goto err_map;
}
+ pxa_rtc->base_psbr = ioremap(pxa_rtc->ress_psbr->start,
+ resource_size(pxa_rtc->ress_psbr));
+ if (!pxa_rtc->base_psbr) {
+ dev_err(&pdev->dev, "Unable to map pxa RTC PSBR I/O memory\n");
+ goto err_map;
+ }
/*
* If the clock divider is uninitialized then reset it to the
* default value to get the 1Hz clock.
@@ -379,7 +429,7 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
}
device_init_wakeup(dev, 1);
-
+ pxa_rtc_open(dev);
return 0;
err_rtc_reg:
@@ -416,7 +466,7 @@ static struct of_device_id pxa_rtc_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pxa_rtc_dt_ids);
#endif
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int pxa_rtc_suspend(struct device *dev)
{
struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev);
@@ -434,36 +484,20 @@ static int pxa_rtc_resume(struct device *dev)
disable_irq_wake(pxa_rtc->irq_Alrm);
return 0;
}
-
-static const struct dev_pm_ops pxa_rtc_pm_ops = {
- .suspend = pxa_rtc_suspend,
- .resume = pxa_rtc_resume,
-};
#endif
+static SIMPLE_DEV_PM_OPS(pxa_rtc_pm_ops, pxa_rtc_suspend, pxa_rtc_resume);
+
static struct platform_driver pxa_rtc_driver = {
.remove = __exit_p(pxa_rtc_remove),
.driver = {
.name = "pxa-rtc",
.of_match_table = of_match_ptr(pxa_rtc_dt_ids),
-#ifdef CONFIG_PM
.pm = &pxa_rtc_pm_ops,
-#endif
},
};
-static int __init pxa_rtc_init(void)
-{
- return platform_driver_probe(&pxa_rtc_driver, pxa_rtc_probe);
-}
-
-static void __exit pxa_rtc_exit(void)
-{
- platform_driver_unregister(&pxa_rtc_driver);
-}
-
-module_init(pxa_rtc_init);
-module_exit(pxa_rtc_exit);
+module_platform_driver_probe(pxa_rtc_driver, pxa_rtc_probe);
MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
MODULE_DESCRIPTION("PXA27x/PXA3xx Realtime Clock Driver (RTC)");
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c
index 7726f4a4f2d0..feeedbd82000 100644
--- a/drivers/rtc/rtc-r9701.c
+++ b/drivers/rtc/rtc-r9701.c
@@ -154,21 +154,18 @@ static int r9701_probe(struct spi_device *spi)
}
}
- rtc = rtc_device_register("r9701",
- &spi->dev, &r9701_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&spi->dev, "r9701",
+ &r9701_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
- dev_set_drvdata(&spi->dev, rtc);
+ spi_set_drvdata(spi, rtc);
return 0;
}
static int r9701_remove(struct spi_device *spi)
{
- struct rtc_device *rtc = dev_get_drvdata(&spi->dev);
-
- rtc_device_unregister(rtc);
return 0;
}
diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c
index eb3194d664a8..8eabcf51b35a 100644
--- a/drivers/rtc/rtc-rc5t583.c
+++ b/drivers/rtc/rtc-rc5t583.c
@@ -256,7 +256,7 @@ static int rc5t583_rtc_probe(struct platform_device *pdev)
}
device_init_wakeup(&pdev->dev, 1);
- ricoh_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ ricoh_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&rc5t583_rtc_ops, THIS_MODULE);
if (IS_ERR(ricoh_rtc->rtc)) {
ret = PTR_ERR(ricoh_rtc->rtc);
@@ -276,13 +276,10 @@ static int rc5t583_rtc_remove(struct platform_device *pdev)
struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(&pdev->dev);
rc5t583_rtc_alarm_irq_enable(&rc5t583_rtc->rtc->dev, 0);
-
- rtc_device_unregister(rc5t583_rtc->rtc);
return 0;
}
#ifdef CONFIG_PM_SLEEP
-
static int rc5t583_rtc_suspend(struct device *dev)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
@@ -304,24 +301,18 @@ static int rc5t583_rtc_resume(struct device *dev)
return regmap_write(rc5t583->regmap, RC5T583_RTC_CTL1,
rc5t583_rtc->irqen);
}
-
-static const struct dev_pm_ops rc5t583_rtc_pm_ops = {
- .suspend = rc5t583_rtc_suspend,
- .resume = rc5t583_rtc_resume,
-};
-
-#define DEV_PM_OPS (&rc5t583_rtc_pm_ops)
-#else
-#define DEV_PM_OPS NULL
#endif
+static SIMPLE_DEV_PM_OPS(rc5t583_rtc_pm_ops, rc5t583_rtc_suspend,
+ rc5t583_rtc_resume);
+
static struct platform_driver rc5t583_rtc_driver = {
.probe = rc5t583_rtc_probe,
.remove = rc5t583_rtc_remove,
.driver = {
.owner = THIS_MODULE,
.name = "rtc-rc5t583",
- .pm = DEV_PM_OPS,
+ .pm = &rc5t583_rtc_pm_ops,
},
};
diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c
index 359da6d020b9..d25d2f6c0cad 100644
--- a/drivers/rtc/rtc-rp5c01.c
+++ b/drivers/rtc/rtc-rp5c01.c
@@ -294,18 +294,7 @@ static struct platform_driver rp5c01_rtc_driver = {
.remove = __exit_p(rp5c01_rtc_remove),
};
-static int __init rp5c01_rtc_init(void)
-{
- return platform_driver_probe(&rp5c01_rtc_driver, rp5c01_rtc_probe);
-}
-
-static void __exit rp5c01_rtc_fini(void)
-{
- platform_driver_unregister(&rp5c01_rtc_driver);
-}
-
-module_init(rp5c01_rtc_init);
-module_exit(rp5c01_rtc_fini);
+module_platform_driver_probe(rp5c01_rtc_driver, rp5c01_rtc_probe);
MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c
index d98ea5b759c8..8089fc63e403 100644
--- a/drivers/rtc/rtc-rs5c313.c
+++ b/drivers/rtc/rtc-rs5c313.c
@@ -367,7 +367,7 @@ static const struct rtc_class_ops rs5c313_rtc_ops = {
static int rs5c313_rtc_probe(struct platform_device *pdev)
{
- struct rtc_device *rtc = rtc_device_register("rs5c313", &pdev->dev,
+ struct rtc_device *rtc = devm_rtc_device_register(&pdev->dev, "rs5c313",
&rs5c313_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
@@ -380,10 +380,6 @@ static int rs5c313_rtc_probe(struct platform_device *pdev)
static int rs5c313_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtc = platform_get_drvdata( pdev );
-
- rtc_device_unregister(rtc);
-
return 0;
}
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index f8ee8ad7825e..5032c24ec159 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -395,9 +395,8 @@ static int rv3029c2_probe(struct i2c_client *client,
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
return -ENODEV;
- rtc = rtc_device_register(client->name,
- &client->dev, &rv3029c2_rtc_ops,
- THIS_MODULE);
+ rtc = devm_rtc_device_register(&client->dev, client->name,
+ &rv3029c2_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -407,23 +406,14 @@ static int rv3029c2_probe(struct i2c_client *client,
rc = rv3029c2_i2c_get_sr(client, buf);
if (rc < 0) {
dev_err(&client->dev, "reading status failed\n");
- goto exit_unregister;
+ return rc;
}
return 0;
-
-exit_unregister:
- rtc_device_unregister(rtc);
-
- return rc;
}
static int rv3029c2_remove(struct i2c_client *client)
{
- struct rtc_device *rtc = i2c_get_clientdata(client);
-
- rtc_device_unregister(rtc);
-
return 0;
}
diff --git a/drivers/rtc/rtc-rx4581.c b/drivers/rtc/rtc-rx4581.c
index 599ec73ec886..84eb08d65d30 100644
--- a/drivers/rtc/rtc-rx4581.c
+++ b/drivers/rtc/rtc-rx4581.c
@@ -273,20 +273,17 @@ static int rx4581_probe(struct spi_device *spi)
if (res != 0)
return res;
- rtc = rtc_device_register("rx4581",
- &spi->dev, &rx4581_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&spi->dev, "rx4581",
+ &rx4581_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
- dev_set_drvdata(&spi->dev, rtc);
+ spi_set_drvdata(spi, rtc);
return 0;
}
static int rx4581_remove(struct spi_device *spi)
{
- struct rtc_device *rtc = dev_get_drvdata(&spi->dev);
-
- rtc_device_unregister(rtc);
return 0;
}
diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c
index b0c272658fa2..07f3037b18f4 100644
--- a/drivers/rtc/rtc-rx8581.c
+++ b/drivers/rtc/rtc-rx8581.c
@@ -240,8 +240,8 @@ static int rx8581_probe(struct i2c_client *client,
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
- rtc = rtc_device_register(rx8581_driver.driver.name,
- &client->dev, &rx8581_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&client->dev, rx8581_driver.driver.name,
+ &rx8581_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -253,10 +253,6 @@ static int rx8581_probe(struct i2c_client *client,
static int rx8581_remove(struct i2c_client *client)
{
- struct rtc_device *rtc = i2c_get_clientdata(client);
-
- rtc_device_unregister(rtc);
-
return 0;
}
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index fb994e9ddc15..653a4dcbfe7d 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -51,7 +51,6 @@ static struct clk *rtc_clk;
static void __iomem *s3c_rtc_base;
static int s3c_rtc_alarmno = NO_IRQ;
static int s3c_rtc_tickno = NO_IRQ;
-static bool wake_en;
static enum s3c_cpu_type s3c_rtc_cpu_type;
static DEFINE_SPINLOCK(s3c_rtc_pie_lock);
@@ -423,10 +422,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en)
static int s3c_rtc_remove(struct platform_device *dev)
{
- struct rtc_device *rtc = platform_get_drvdata(dev);
-
platform_set_drvdata(dev, NULL);
- rtc_device_unregister(rtc);
s3c_rtc_setaie(&dev->dev, 0);
@@ -511,7 +507,7 @@ static int s3c_rtc_probe(struct platform_device *pdev)
/* register RTC and exit */
- rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops,
+ rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops,
THIS_MODULE);
if (IS_ERR(rtc)) {
@@ -574,7 +570,6 @@ static int s3c_rtc_probe(struct platform_device *pdev)
err_alarm_irq:
platform_set_drvdata(pdev, NULL);
- rtc_device_unregister(rtc);
err_nortc:
s3c_rtc_enable(pdev, 0);
@@ -583,14 +578,16 @@ static int s3c_rtc_probe(struct platform_device *pdev)
return ret;
}
-#ifdef CONFIG_PM
-
+#ifdef CONFIG_PM_SLEEP
/* RTC Power management control */
static int ticnt_save, ticnt_en_save;
+static bool wake_en;
-static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+static int s3c_rtc_suspend(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
+
clk_enable(rtc_clk);
/* save TICNT for anyone using periodic interrupts */
ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT);
@@ -600,19 +597,20 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state)
}
s3c_rtc_enable(pdev, 0);
- if (device_may_wakeup(&pdev->dev) && !wake_en) {
+ if (device_may_wakeup(dev) && !wake_en) {
if (enable_irq_wake(s3c_rtc_alarmno) == 0)
wake_en = true;
else
- dev_err(&pdev->dev, "enable_irq_wake failed\n");
+ dev_err(dev, "enable_irq_wake failed\n");
}
clk_disable(rtc_clk);
return 0;
}
-static int s3c_rtc_resume(struct platform_device *pdev)
+static int s3c_rtc_resume(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
unsigned int tmp;
clk_enable(rtc_clk);
@@ -623,7 +621,7 @@ static int s3c_rtc_resume(struct platform_device *pdev)
writew(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON);
}
- if (device_may_wakeup(&pdev->dev) && wake_en) {
+ if (device_may_wakeup(dev) && wake_en) {
disable_irq_wake(s3c_rtc_alarmno);
wake_en = false;
}
@@ -631,11 +629,10 @@ static int s3c_rtc_resume(struct platform_device *pdev)
return 0;
}
-#else
-#define s3c_rtc_suspend NULL
-#define s3c_rtc_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume);
+
#ifdef CONFIG_OF
static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = {
[TYPE_S3C2410] = { TYPE_S3C2410 },
@@ -685,12 +682,11 @@ MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids);
static struct platform_driver s3c_rtc_driver = {
.probe = s3c_rtc_probe,
.remove = s3c_rtc_remove,
- .suspend = s3c_rtc_suspend,
- .resume = s3c_rtc_resume,
.id_table = s3c_rtc_driver_ids,
.driver = {
.name = "s3c-rtc",
.owner = THIS_MODULE,
+ .pm = &s3c_rtc_pm_ops,
.of_match_table = of_match_ptr(s3c_rtc_dt_match),
},
};
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 5ec5036df0bc..7e0a0887c256 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -327,7 +327,7 @@ static int sa1100_rtc_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int sa1100_rtc_suspend(struct device *dev)
{
struct sa1100_rtc *info = dev_get_drvdata(dev);
@@ -343,13 +343,11 @@ static int sa1100_rtc_resume(struct device *dev)
disable_irq_wake(info->irq_alarm);
return 0;
}
-
-static const struct dev_pm_ops sa1100_rtc_pm_ops = {
- .suspend = sa1100_rtc_suspend,
- .resume = sa1100_rtc_resume,
-};
#endif
+static SIMPLE_DEV_PM_OPS(sa1100_rtc_pm_ops, sa1100_rtc_suspend,
+ sa1100_rtc_resume);
+
#ifdef CONFIG_OF
static struct of_device_id sa1100_rtc_dt_ids[] = {
{ .compatible = "mrvl,sa1100-rtc", },
@@ -364,9 +362,7 @@ static struct platform_driver sa1100_rtc_driver = {
.remove = sa1100_rtc_remove,
.driver = {
.name = "sa1100-rtc",
-#ifdef CONFIG_PM
.pm = &sa1100_rtc_pm_ops,
-#endif
.of_match_table = of_match_ptr(sa1100_rtc_dt_ids),
},
};
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index e55a7635ae5f..8d5bd2e36776 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -790,6 +790,7 @@ static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
}
}
+#ifdef CONFIG_PM_SLEEP
static int sh_rtc_suspend(struct device *dev)
{
if (device_may_wakeup(dev))
@@ -805,33 +806,20 @@ static int sh_rtc_resume(struct device *dev)
return 0;
}
+#endif
-static const struct dev_pm_ops sh_rtc_dev_pm_ops = {
- .suspend = sh_rtc_suspend,
- .resume = sh_rtc_resume,
-};
+static SIMPLE_DEV_PM_OPS(sh_rtc_pm_ops, sh_rtc_suspend, sh_rtc_resume);
static struct platform_driver sh_rtc_platform_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
- .pm = &sh_rtc_dev_pm_ops,
+ .pm = &sh_rtc_pm_ops,
},
.remove = __exit_p(sh_rtc_remove),
};
-static int __init sh_rtc_init(void)
-{
- return platform_driver_probe(&sh_rtc_platform_driver, sh_rtc_probe);
-}
-
-static void __exit sh_rtc_exit(void)
-{
- platform_driver_unregister(&sh_rtc_platform_driver);
-}
-
-module_init(sh_rtc_init);
-module_exit(sh_rtc_exit);
+module_platform_driver_probe(sh_rtc_platform_driver, sh_rtc_probe);
MODULE_DESCRIPTION("SuperH on-chip RTC driver");
MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
index f7d90703db5e..b04f09a1df2a 100644
--- a/drivers/rtc/rtc-snvs.c
+++ b/drivers/rtc/rtc-snvs.c
@@ -283,7 +283,7 @@ static int snvs_rtc_probe(struct platform_device *pdev)
return ret;
}
- data->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&snvs_rtc_ops, THIS_MODULE);
if (IS_ERR(data->rtc)) {
ret = PTR_ERR(data->rtc);
@@ -296,10 +296,6 @@ static int snvs_rtc_probe(struct platform_device *pdev)
static int snvs_rtc_remove(struct platform_device *pdev)
{
- struct snvs_rtc_data *data = platform_get_drvdata(pdev);
-
- rtc_device_unregister(data->rtc);
-
return 0;
}
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
index a18c3192ed40..db3ef610dd7c 100644
--- a/drivers/rtc/rtc-spear.c
+++ b/drivers/rtc/rtc-spear.c
@@ -400,8 +400,8 @@ static int spear_rtc_probe(struct platform_device *pdev)
spin_lock_init(&config->lock);
platform_set_drvdata(pdev, config);
- config->rtc = rtc_device_register(pdev->name, &pdev->dev,
- &spear_rtc_ops, THIS_MODULE);
+ config->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+ &spear_rtc_ops, THIS_MODULE);
if (IS_ERR(config->rtc)) {
dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
PTR_ERR(config->rtc));
@@ -427,7 +427,6 @@ static int spear_rtc_remove(struct platform_device *pdev)
{
struct spear_rtc_config *config = platform_get_drvdata(pdev);
- rtc_device_unregister(config->rtc);
spear_rtc_disable_interrupt(config);
clk_disable_unprepare(config->clk);
device_init_wakeup(&pdev->dev, 0);
diff --git a/drivers/rtc/rtc-starfire.c b/drivers/rtc/rtc-starfire.c
index 5be98bfd7ed3..987b5ec0ae56 100644
--- a/drivers/rtc/rtc-starfire.c
+++ b/drivers/rtc/rtc-starfire.c
@@ -39,8 +39,10 @@ static const struct rtc_class_ops starfire_rtc_ops = {
static int __init starfire_rtc_probe(struct platform_device *pdev)
{
- struct rtc_device *rtc = rtc_device_register("starfire", &pdev->dev,
- &starfire_rtc_ops, THIS_MODULE);
+ struct rtc_device *rtc;
+
+ rtc = devm_rtc_device_register(&pdev->dev, "starfire",
+ &starfire_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -51,10 +53,6 @@ static int __init starfire_rtc_probe(struct platform_device *pdev)
static int __exit starfire_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtc = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtc);
-
return 0;
}
@@ -66,15 +64,4 @@ static struct platform_driver starfire_rtc_driver = {
.remove = __exit_p(starfire_rtc_remove),
};
-static int __init starfire_rtc_init(void)
-{
- return platform_driver_probe(&starfire_rtc_driver, starfire_rtc_probe);
-}
-
-static void __exit starfire_rtc_exit(void)
-{
- platform_driver_unregister(&starfire_rtc_driver);
-}
-
-module_init(starfire_rtc_init);
-module_exit(starfire_rtc_exit);
+module_platform_driver_probe(starfire_rtc_driver, starfire_rtc_probe);
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index 7e4a6f65cb91..af5e97e3f272 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -336,14 +336,13 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev)
}
}
- pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&stk17ta8_rtc_ops, THIS_MODULE);
if (IS_ERR(pdata->rtc))
return PTR_ERR(pdata->rtc);
ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
- if (ret)
- rtc_device_unregister(pdata->rtc);
+
return ret;
}
@@ -352,7 +351,6 @@ static int stk17ta8_rtc_remove(struct platform_device *pdev)
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
- rtc_device_unregister(pdata->rtc);
if (pdata->irq > 0)
writeb(0, pdata->ioaddr + RTC_INTERRUPTS);
return 0;
diff --git a/drivers/rtc/rtc-sun4v.c b/drivers/rtc/rtc-sun4v.c
index 59b5c2dcb58c..ce42e5fa9e09 100644
--- a/drivers/rtc/rtc-sun4v.c
+++ b/drivers/rtc/rtc-sun4v.c
@@ -81,8 +81,10 @@ static const struct rtc_class_ops sun4v_rtc_ops = {
static int __init sun4v_rtc_probe(struct platform_device *pdev)
{
- struct rtc_device *rtc = rtc_device_register("sun4v", &pdev->dev,
- &sun4v_rtc_ops, THIS_MODULE);
+ struct rtc_device *rtc;
+
+ rtc = devm_rtc_device_register(&pdev->dev, "sun4v",
+ &sun4v_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -92,9 +94,6 @@ static int __init sun4v_rtc_probe(struct platform_device *pdev)
static int __exit sun4v_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtc = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtc);
return 0;
}
@@ -106,18 +105,7 @@ static struct platform_driver sun4v_rtc_driver = {
.remove = __exit_p(sun4v_rtc_remove),
};
-static int __init sun4v_rtc_init(void)
-{
- return platform_driver_probe(&sun4v_rtc_driver, sun4v_rtc_probe);
-}
-
-static void __exit sun4v_rtc_exit(void)
-{
- platform_driver_unregister(&sun4v_rtc_driver);
-}
-
-module_init(sun4v_rtc_init);
-module_exit(sun4v_rtc_exit);
+module_platform_driver_probe(sun4v_rtc_driver, sun4v_rtc_probe);
MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
MODULE_DESCRIPTION("SUN4V RTC driver");
diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c
index 7c033756d6b5..a34315d25478 100644
--- a/drivers/rtc/rtc-tegra.c
+++ b/drivers/rtc/rtc-tegra.c
@@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/rtc.h>
#include <linux/platform_device.h>
+#include <linux/pm.h>
/* set to 1 = busy every eight 32kHz clocks during copy of sec+msec to AHB */
#define TEGRA_RTC_REG_BUSY 0x004
@@ -309,7 +310,7 @@ static const struct of_device_id tegra_rtc_dt_match[] = {
};
MODULE_DEVICE_TABLE(of, tegra_rtc_dt_match);
-static int tegra_rtc_probe(struct platform_device *pdev)
+static int __init tegra_rtc_probe(struct platform_device *pdev)
{
struct tegra_rtc_info *info;
struct resource *res;
@@ -348,53 +349,35 @@ static int tegra_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
- info->rtc_dev = rtc_device_register(
- pdev->name, &pdev->dev, &tegra_rtc_ops, THIS_MODULE);
+ info->rtc_dev = devm_rtc_device_register(&pdev->dev,
+ dev_name(&pdev->dev), &tegra_rtc_ops,
+ THIS_MODULE);
if (IS_ERR(info->rtc_dev)) {
ret = PTR_ERR(info->rtc_dev);
- info->rtc_dev = NULL;
- dev_err(&pdev->dev,
- "Unable to register device (err=%d).\n",
+ dev_err(&pdev->dev, "Unable to register device (err=%d).\n",
ret);
return ret;
}
ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq,
tegra_rtc_irq_handler, IRQF_TRIGGER_HIGH,
- "rtc alarm", &pdev->dev);
+ dev_name(&pdev->dev), &pdev->dev);
if (ret) {
dev_err(&pdev->dev,
"Unable to request interrupt for device (err=%d).\n",
ret);
- goto err_dev_unreg;
+ return ret;
}
dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n");
return 0;
-
-err_dev_unreg:
- rtc_device_unregister(info->rtc_dev);
-
- return ret;
}
-static int tegra_rtc_remove(struct platform_device *pdev)
+#ifdef CONFIG_PM_SLEEP
+static int tegra_rtc_suspend(struct device *dev)
{
- struct tegra_rtc_info *info = platform_get_drvdata(pdev);
-
- rtc_device_unregister(info->rtc_dev);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int tegra_rtc_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct device *dev = &pdev->dev;
- struct tegra_rtc_info *info = platform_get_drvdata(pdev);
+ struct tegra_rtc_info *info = dev_get_drvdata(dev);
tegra_rtc_wait_while_busy(dev);
@@ -416,10 +399,9 @@ static int tegra_rtc_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
-static int tegra_rtc_resume(struct platform_device *pdev)
+static int tegra_rtc_resume(struct device *dev)
{
- struct device *dev = &pdev->dev;
- struct tegra_rtc_info *info = platform_get_drvdata(pdev);
+ struct tegra_rtc_info *info = dev_get_drvdata(dev);
dev_vdbg(dev, "Resume (device_may_wakeup=%d)\n",
device_may_wakeup(dev));
@@ -431,6 +413,8 @@ static int tegra_rtc_resume(struct platform_device *pdev)
}
#endif
+static SIMPLE_DEV_PM_OPS(tegra_rtc_pm_ops, tegra_rtc_suspend, tegra_rtc_resume);
+
static void tegra_rtc_shutdown(struct platform_device *pdev)
{
dev_vdbg(&pdev->dev, "disabling interrupts.\n");
@@ -439,30 +423,16 @@ static void tegra_rtc_shutdown(struct platform_device *pdev)
MODULE_ALIAS("platform:tegra_rtc");
static struct platform_driver tegra_rtc_driver = {
- .remove = tegra_rtc_remove,
.shutdown = tegra_rtc_shutdown,
.driver = {
.name = "tegra_rtc",
.owner = THIS_MODULE,
.of_match_table = tegra_rtc_dt_match,
+ .pm = &tegra_rtc_pm_ops,
},
-#ifdef CONFIG_PM
- .suspend = tegra_rtc_suspend,
- .resume = tegra_rtc_resume,
-#endif
};
-static int __init tegra_rtc_init(void)
-{
- return platform_driver_probe(&tegra_rtc_driver, tegra_rtc_probe);
-}
-module_init(tegra_rtc_init);
-
-static void __exit tegra_rtc_exit(void)
-{
- platform_driver_unregister(&tegra_rtc_driver);
-}
-module_exit(tegra_rtc_exit);
+module_platform_driver_probe(tegra_rtc_driver, tegra_rtc_probe);
MODULE_AUTHOR("Jon Mayo <jmayo@nvidia.com>");
MODULE_DESCRIPTION("driver for Tegra internal RTC");
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index b92e0f6383e6..7746e65b93f2 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -99,8 +99,10 @@ static DEVICE_ATTR(irq, S_IRUGO | S_IWUSR, test_irq_show, test_irq_store);
static int test_probe(struct platform_device *plat_dev)
{
int err;
- struct rtc_device *rtc = rtc_device_register("test", &plat_dev->dev,
- &test_rtc_ops, THIS_MODULE);
+ struct rtc_device *rtc;
+
+ rtc = devm_rtc_device_register(&plat_dev->dev, "test",
+ &test_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
err = PTR_ERR(rtc);
return err;
@@ -115,15 +117,11 @@ static int test_probe(struct platform_device *plat_dev)
return 0;
err:
- rtc_device_unregister(rtc);
return err;
}
static int test_remove(struct platform_device *plat_dev)
{
- struct rtc_device *rtc = platform_get_drvdata(plat_dev);
-
- rtc_device_unregister(rtc);
device_remove_file(&plat_dev->dev, &dev_attr_irq);
return 0;
diff --git a/drivers/rtc/rtc-tile.c b/drivers/rtc/rtc-tile.c
index 62db4841078b..249b6531f119 100644
--- a/drivers/rtc/rtc-tile.c
+++ b/drivers/rtc/rtc-tile.c
@@ -80,8 +80,8 @@ static int tile_rtc_probe(struct platform_device *dev)
{
struct rtc_device *rtc;
- rtc = rtc_device_register("tile",
- &dev->dev, &tile_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&dev->dev, "tile",
+ &tile_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -96,11 +96,6 @@ static int tile_rtc_probe(struct platform_device *dev)
*/
static int tile_rtc_remove(struct platform_device *dev)
{
- struct rtc_device *rtc = platform_get_drvdata(dev);
-
- if (rtc)
- rtc_device_unregister(rtc);
-
platform_set_drvdata(dev, NULL);
return 0;
diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c
index aab4e8c93622..459c2ffc95a6 100644
--- a/drivers/rtc/rtc-tps6586x.c
+++ b/drivers/rtc/rtc-tps6586x.c
@@ -274,7 +274,7 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, rtc);
- rtc->rtc = rtc_device_register(dev_name(&pdev->dev), &pdev->dev,
+ rtc->rtc = devm_rtc_device_register(&pdev->dev, dev_name(&pdev->dev),
&tps6586x_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc);
@@ -289,15 +289,12 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev, "request IRQ(%d) failed with ret %d\n",
rtc->irq, ret);
- goto fail_req_irq;
+ goto fail_rtc_register;
}
disable_irq(rtc->irq);
device_set_wakeup_capable(&pdev->dev, 1);
return 0;
-fail_req_irq:
- rtc_device_unregister(rtc->rtc);
-
fail_rtc_register:
tps6586x_update(tps_dev, RTC_CTRL, 0,
RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK);
@@ -306,12 +303,10 @@ fail_rtc_register:
static int tps6586x_rtc_remove(struct platform_device *pdev)
{
- struct tps6586x_rtc *rtc = platform_get_drvdata(pdev);
struct device *tps_dev = to_tps6586x_dev(&pdev->dev);
tps6586x_update(tps_dev, RTC_CTRL, 0,
RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK);
- rtc_device_unregister(rtc->rtc);
return 0;
}
@@ -335,9 +330,8 @@ static int tps6586x_rtc_resume(struct device *dev)
}
#endif
-static const struct dev_pm_ops tps6586x_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(tps6586x_rtc_suspend, tps6586x_rtc_resume)
-};
+static SIMPLE_DEV_PM_OPS(tps6586x_pm_ops, tps6586x_rtc_suspend,
+ tps6586x_rtc_resume);
static struct platform_driver tps6586x_rtc_driver = {
.driver = {
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c
index 8bd8115329b5..a9caf043b0ce 100644
--- a/drivers/rtc/rtc-tps65910.c
+++ b/drivers/rtc/rtc-tps65910.c
@@ -263,7 +263,7 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
if (irq <= 0) {
dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n",
irq);
- return ret;
+ return -ENXIO;
}
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
@@ -276,7 +276,7 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
tps_rtc->irq = irq;
device_set_wakeup_capable(&pdev->dev, 1);
- tps_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ tps_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&tps65910_rtc_ops, THIS_MODULE);
if (IS_ERR(tps_rtc->rtc)) {
ret = PTR_ERR(tps_rtc->rtc);
@@ -295,12 +295,8 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
*/
static int tps65910_rtc_remove(struct platform_device *pdev)
{
- /* leave rtc running, but disable irqs */
- struct tps65910_rtc *tps_rtc = platform_get_drvdata(pdev);
-
tps65910_rtc_alarm_irq_enable(&pdev->dev, 0);
- rtc_device_unregister(tps_rtc->rtc);
return 0;
}
@@ -324,9 +320,8 @@ static int tps65910_rtc_resume(struct device *dev)
}
#endif
-static const struct dev_pm_ops tps65910_rtc_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(tps65910_rtc_suspend, tps65910_rtc_resume)
-};
+static SIMPLE_DEV_PM_OPS(tps65910_rtc_pm_ops, tps65910_rtc_suspend,
+ tps65910_rtc_resume);
static struct platform_driver tps65910_rtc_driver = {
.probe = tps65910_rtc_probe,
diff --git a/drivers/rtc/rtc-tps80031.c b/drivers/rtc/rtc-tps80031.c
index 9aaf8aaebae9..72662eafb938 100644
--- a/drivers/rtc/rtc-tps80031.c
+++ b/drivers/rtc/rtc-tps80031.c
@@ -277,7 +277,7 @@ static int tps80031_rtc_probe(struct platform_device *pdev)
return ret;
}
- rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&tps80031_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc);
@@ -292,7 +292,6 @@ static int tps80031_rtc_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev, "request IRQ:%d failed, err = %d\n",
rtc->irq, ret);
- rtc_device_unregister(rtc->rtc);
return ret;
}
device_set_wakeup_capable(&pdev->dev, 1);
@@ -301,9 +300,6 @@ static int tps80031_rtc_probe(struct platform_device *pdev)
static int tps80031_rtc_remove(struct platform_device *pdev)
{
- struct tps80031_rtc *rtc = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtc->rtc);
return 0;
}
@@ -327,9 +323,8 @@ static int tps80031_rtc_resume(struct device *dev)
};
#endif
-static const struct dev_pm_ops tps80031_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(tps80031_rtc_suspend, tps80031_rtc_resume)
-};
+static SIMPLE_DEV_PM_OPS(tps80031_pm_ops, tps80031_rtc_suspend,
+ tps80031_rtc_resume);
static struct platform_driver tps80031_rtc_driver = {
.driver = {
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c
index a12bfac49d36..f9a0677e4e3b 100644
--- a/drivers/rtc/rtc-tx4939.c
+++ b/drivers/rtc/rtc-tx4939.c
@@ -268,14 +268,13 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev)
if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt,
0, pdev->name, &pdev->dev) < 0)
return -EBUSY;
- rtc = rtc_device_register(pdev->name, &pdev->dev,
+ rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&tx4939_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
pdata->rtc = rtc;
ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr);
- if (ret)
- rtc_device_unregister(rtc);
+
return ret;
}
@@ -284,7 +283,6 @@ static int __exit tx4939_rtc_remove(struct platform_device *pdev)
struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev);
sysfs_remove_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr);
- rtc_device_unregister(pdata->rtc);
spin_lock_irq(&pdata->lock);
tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
spin_unlock_irq(&pdata->lock);
@@ -299,18 +297,7 @@ static struct platform_driver tx4939_rtc_driver = {
},
};
-static int __init tx4939rtc_init(void)
-{
- return platform_driver_probe(&tx4939_rtc_driver, tx4939_rtc_probe);
-}
-
-static void __exit tx4939rtc_exit(void)
-{
- platform_driver_unregister(&tx4939_rtc_driver);
-}
-
-module_init(tx4939rtc_init);
-module_exit(tx4939rtc_exit);
+module_platform_driver_probe(tx4939_rtc_driver, tx4939_rtc_probe);
MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
MODULE_DESCRIPTION("TX4939 internal RTC driver");
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index bca5d677bc85..600798cd4d0c 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -49,18 +49,13 @@ struct v3020_chip_ops {
#define V3020_RD 2
#define V3020_IO 3
-struct v3020_gpio {
- const char *name;
- unsigned int gpio;
-};
-
struct v3020 {
/* MMIO access */
void __iomem *ioaddress;
int leftshift;
/* GPIO access */
- struct v3020_gpio *gpio;
+ struct gpio *gpio;
struct v3020_chip_ops *ops;
@@ -107,48 +102,40 @@ static struct v3020_chip_ops v3020_mmio_ops = {
.write_bit = v3020_mmio_write_bit,
};
-static struct v3020_gpio v3020_gpio[] = {
- { "RTC CS", 0 },
- { "RTC WR", 0 },
- { "RTC RD", 0 },
- { "RTC IO", 0 },
+static struct gpio v3020_gpio[] = {
+ { 0, GPIOF_OUT_INIT_HIGH, "RTC CS"},
+ { 0, GPIOF_OUT_INIT_HIGH, "RTC WR"},
+ { 0, GPIOF_OUT_INIT_HIGH, "RTC RD"},
+ { 0, GPIOF_OUT_INIT_HIGH, "RTC IO"},
};
static int v3020_gpio_map(struct v3020 *chip, struct platform_device *pdev,
struct v3020_platform_data *pdata)
{
- int i, err;
+ int err;
v3020_gpio[V3020_CS].gpio = pdata->gpio_cs;
v3020_gpio[V3020_WR].gpio = pdata->gpio_wr;
v3020_gpio[V3020_RD].gpio = pdata->gpio_rd;
v3020_gpio[V3020_IO].gpio = pdata->gpio_io;
- for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++) {
- err = gpio_request(v3020_gpio[i].gpio, v3020_gpio[i].name);
- if (err)
- goto err_request;
-
- gpio_direction_output(v3020_gpio[i].gpio, 1);
- }
+ err = gpio_request_array(v3020_gpio, ARRAY_SIZE(v3020_gpio));
+ if (err)
+ goto err_request;
chip->gpio = v3020_gpio;
return 0;
err_request:
- while (--i >= 0)
- gpio_free(v3020_gpio[i].gpio);
+ gpio_free_array(v3020_gpio, ARRAY_SIZE(v3020_gpio));
return err;
}
static void v3020_gpio_unmap(struct v3020 *chip)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++)
- gpio_free(v3020_gpio[i].gpio);
+ gpio_free_array(v3020_gpio, ARRAY_SIZE(v3020_gpio));
}
static void v3020_gpio_write_bit(struct v3020 *chip, unsigned char bit)
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c
index a000bc0a8bff..d89efee6d29e 100644
--- a/drivers/rtc/rtc-vt8500.c
+++ b/drivers/rtc/rtc-vt8500.c
@@ -252,7 +252,7 @@ static int vt8500_rtc_probe(struct platform_device *pdev)
writel(VT8500_RTC_CR_ENABLE,
vt8500_rtc->regbase + VT8500_RTC_CR);
- vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev,
+ vt8500_rtc->rtc = devm_rtc_device_register(&pdev->dev, "vt8500-rtc",
&vt8500_rtc_ops, THIS_MODULE);
if (IS_ERR(vt8500_rtc->rtc)) {
ret = PTR_ERR(vt8500_rtc->rtc);
@@ -266,13 +266,11 @@ static int vt8500_rtc_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev, "can't get irq %i, err %d\n",
vt8500_rtc->irq_alarm, ret);
- goto err_unreg;
+ goto err_return;
}
return 0;
-err_unreg:
- rtc_device_unregister(vt8500_rtc->rtc);
err_return:
return ret;
}
@@ -281,8 +279,6 @@ static int vt8500_rtc_remove(struct platform_device *pdev)
{
struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev);
- rtc_device_unregister(vt8500_rtc->rtc);
-
/* Disable alarm matching */
writel(0, vt8500_rtc->regbase + VT8500_RTC_IS);
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c
index 2f0ac7b30a0c..8d65b94e5a7e 100644
--- a/drivers/rtc/rtc-wm831x.c
+++ b/drivers/rtc/rtc-wm831x.c
@@ -436,7 +436,7 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
- wm831x_rtc->rtc = rtc_device_register("wm831x", &pdev->dev,
+ wm831x_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm831x",
&wm831x_rtc_ops, THIS_MODULE);
if (IS_ERR(wm831x_rtc->rtc)) {
ret = PTR_ERR(wm831x_rtc->rtc);
@@ -462,10 +462,6 @@ err:
static int wm831x_rtc_remove(struct platform_device *pdev)
{
- struct wm831x_rtc *wm831x_rtc = platform_get_drvdata(pdev);
-
- rtc_device_unregister(wm831x_rtc->rtc);
-
return 0;
}
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
index 8ad86ae0d30f..fa247deb9cf4 100644
--- a/drivers/rtc/rtc-wm8350.c
+++ b/drivers/rtc/rtc-wm8350.c
@@ -339,7 +339,7 @@ static const struct rtc_class_ops wm8350_rtc_ops = {
.alarm_irq_enable = wm8350_rtc_alarm_irq_enable,
};
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int wm8350_rtc_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -375,10 +375,6 @@ static int wm8350_rtc_resume(struct device *dev)
return 0;
}
-
-#else
-#define wm8350_rtc_suspend NULL
-#define wm8350_rtc_resume NULL
#endif
static int wm8350_rtc_probe(struct platform_device *pdev)
@@ -439,8 +435,8 @@ static int wm8350_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
- wm_rtc->rtc = rtc_device_register("wm8350", &pdev->dev,
- &wm8350_rtc_ops, THIS_MODULE);
+ wm_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm8350",
+ &wm8350_rtc_ops, THIS_MODULE);
if (IS_ERR(wm_rtc->rtc)) {
ret = PTR_ERR(wm_rtc->rtc);
dev_err(&pdev->dev, "failed to register RTC: %d\n", ret);
@@ -462,20 +458,15 @@ static int wm8350_rtc_probe(struct platform_device *pdev)
static int wm8350_rtc_remove(struct platform_device *pdev)
{
struct wm8350 *wm8350 = platform_get_drvdata(pdev);
- struct wm8350_rtc *wm_rtc = &wm8350->rtc;
wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350);
- rtc_device_unregister(wm_rtc->rtc);
-
return 0;
}
-static struct dev_pm_ops wm8350_rtc_pm_ops = {
- .suspend = wm8350_rtc_suspend,
- .resume = wm8350_rtc_resume,
-};
+static SIMPLE_DEV_PM_OPS(wm8350_rtc_pm_ops, wm8350_rtc_suspend,
+ wm8350_rtc_resume);
static struct platform_driver wm8350_rtc_driver = {
.probe = wm8350_rtc_probe,
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index f36e59c6bc01..fa9b0679fb60 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -630,8 +630,8 @@ static int x1205_probe(struct i2c_client *client,
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
- rtc = rtc_device_register(x1205_driver.driver.name, &client->dev,
- &x1205_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_device_register(&client->dev, x1205_driver.driver.name,
+ &x1205_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
@@ -653,21 +653,13 @@ static int x1205_probe(struct i2c_client *client,
err = x1205_sysfs_register(&client->dev);
if (err)
- goto exit_devreg;
+ return err;
return 0;
-
-exit_devreg:
- rtc_device_unregister(rtc);
-
- return err;
}
static int x1205_remove(struct i2c_client *client)
{
- struct rtc_device *rtc = i2c_get_clientdata(client);
-
- rtc_device_unregister(rtc);
x1205_sysfs_unregister(&client->dev);
return 0;
}
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index a76247201be5..cd743c545ce9 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -2161,7 +2161,7 @@ static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip)
if (fip->probe_tries < FIP_VN_RLIM_COUNT) {
fip->probe_tries++;
- wait = random32() % FIP_VN_PROBE_WAIT;
+ wait = prandom_u32() % FIP_VN_PROBE_WAIT;
} else
wait = FIP_VN_RLIM_INT;
mod_timer(&fip->timer, jiffies + msecs_to_jiffies(wait));
@@ -2794,7 +2794,7 @@ static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *fip)
fcoe_all_vn2vn, 0);
fip->port_ka_time = jiffies +
msecs_to_jiffies(FIP_VN_BEACON_INT +
- (random32() % FIP_VN_BEACON_FUZZ));
+ (prandom_u32() % FIP_VN_BEACON_FUZZ));
}
if (time_before(fip->port_ka_time, next_time))
next_time = fip->port_ka_time;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 240492208aba..326e05a65a73 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1735,7 +1735,7 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
* use through a sequence of @fcf_cnt eligible FCF records with equal
* probability. To perform integer manunipulation of random numbers with
* size unit32_t, the lower 16 bits of the 32-bit random number returned
- * from random32() are taken as the random random number generated.
+ * from prandom_u32() are taken as the random random number generated.
*
* Returns true when outcome is for the newly read FCF record should be
* chosen; otherwise, return false when outcome is for keeping the previously
@@ -1747,7 +1747,7 @@ lpfc_sli4_new_fcf_random_select(struct lpfc_hba *phba, uint32_t fcf_cnt)
uint32_t rand_num;
/* Get 16-bit uniform random number */
- rand_num = (0xFFFF & random32());
+ rand_num = 0xFFFF & prandom_u32();
/* Decision with probability 1/fcf_cnt */
if ((fcf_cnt * rand_num) < 0xFFFF)
@@ -2385,7 +2385,7 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
phba->fcf.eligible_fcf_cnt = 1;
/* Seeding the random number generator for random selection */
seed = (uint32_t)(0xFFFFFFFF & jiffies);
- srandom32(seed);
+ prandom_seed(seed);
}
spin_unlock_irq(&phba->hbalock);
goto read_next_fcf;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 9f0c46547459..df5e961484e1 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -35,6 +35,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/mm.h>
+#include <linux/aio.h>
#include <linux/errno.h>
#include <linux/mtio.h>
#include <linux/ioctl.h>
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
index b14a55742559..b040200a5a55 100644
--- a/drivers/staging/android/logger.c
+++ b/drivers/staging/android/logger.c
@@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
+#include <linux/aio.h>
#include "logger.h"
#include <asm/ioctls.h>
diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig
index c3b8a10e170f..d30722fe5730 100644
--- a/drivers/staging/zcache/Kconfig
+++ b/drivers/staging/zcache/Kconfig
@@ -1,5 +1,5 @@
config ZCACHE
- bool "Dynamic compression of swap pages and clean pagecache pages"
+ tristate "Dynamic compression of swap pages and clean pagecache pages"
depends on CRYPTO=y && SWAP=y && CLEANCACHE && FRONTSWAP
select CRYPTO_LZO
default n
@@ -19,8 +19,8 @@ config ZCACHE_DEBUG
how zcache is doing. You probably want to set this to 'N'.
config RAMSTER
- bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem"
- depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE=y
+ tristate "Cross-machine RAM capacity sharing, aka peer-to-peer tmem"
+ depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE
depends on NET
# must ensure struct page is 8-byte aligned
select HAVE_ALIGNED_STRUCT_PAGE if !64BIT
diff --git a/drivers/staging/zcache/ramster.h b/drivers/staging/zcache/ramster.h
index 1b71aea2ff62..e1f91d5a0f6a 100644
--- a/drivers/staging/zcache/ramster.h
+++ b/drivers/staging/zcache/ramster.h
@@ -11,10 +11,14 @@
#ifndef _ZCACHE_RAMSTER_H_
#define _ZCACHE_RAMSTER_H_
+#ifdef CONFIG_RAMSTER_MODULE
+#define CONFIG_RAMSTER
+#endif
+
#ifdef CONFIG_RAMSTER
#include "ramster/ramster.h"
#else
-static inline void ramster_init(bool x, bool y, bool z)
+static inline void ramster_init(bool x, bool y, bool z, bool w)
{
}
diff --git a/drivers/staging/zcache/ramster/nodemanager.c b/drivers/staging/zcache/ramster/nodemanager.c
index c0f48158735d..2cfe93342c0d 100644
--- a/drivers/staging/zcache/ramster/nodemanager.c
+++ b/drivers/staging/zcache/ramster/nodemanager.c
@@ -949,7 +949,7 @@ static void __exit exit_r2nm(void)
r2hb_exit();
}
-static int __init init_r2nm(void)
+int r2nm_init(void)
{
int ret = -1;
@@ -986,10 +986,11 @@ out_r2hb:
out:
return ret;
}
+EXPORT_SYMBOL_GPL(r2nm_init);
MODULE_AUTHOR("Oracle");
MODULE_LICENSE("GPL");
-/* module_init(init_r2nm) */
-late_initcall(init_r2nm);
-/* module_exit(exit_r2nm) */
+#ifndef CONFIG_RAMSTER_MODULE
+late_initcall(r2nm_init);
+#endif
diff --git a/drivers/staging/zcache/ramster/ramster.c b/drivers/staging/zcache/ramster/ramster.c
index c3d7f96b029a..3ead2482c4f8 100644
--- a/drivers/staging/zcache/ramster/ramster.c
+++ b/drivers/staging/zcache/ramster/ramster.c
@@ -126,7 +126,7 @@ static ssize_t ramster_remote_page_flushes_failed;
#include <linux/debugfs.h>
#define zdfs debugfs_create_size_t
#define zdfs64 debugfs_create_u64
-static int __init ramster_debugfs_init(void)
+static int ramster_debugfs_init(void)
{
struct dentry *root = debugfs_create_dir("ramster", NULL);
if (root == NULL)
@@ -226,6 +226,7 @@ int ramster_do_preload_flnode(struct tmem_pool *pool)
kmem_cache_free(ramster_flnode_cache, flnode);
return ret;
}
+EXPORT_SYMBOL_GPL(ramster_do_preload_flnode);
/*
* Called by the message handler after a (still compressed) page has been
@@ -493,6 +494,7 @@ void *ramster_pampd_free(void *pampd, struct tmem_pool *pool,
}
return local_pampd;
}
+EXPORT_SYMBOL_GPL(ramster_pampd_free);
void ramster_count_foreign_pages(bool eph, int count)
{
@@ -512,6 +514,7 @@ void ramster_count_foreign_pages(bool eph, int count)
}
}
}
+EXPORT_SYMBOL_GPL(ramster_count_foreign_pages);
/*
* For now, just push over a few pages every few seconds to
@@ -697,7 +700,7 @@ requeue:
ramster_remotify_queue_delayed_work(HZ);
}
-void __init ramster_remotify_init(void)
+void ramster_remotify_init(void)
{
unsigned long n = 60UL;
ramster_remotify_workqueue =
@@ -872,8 +875,10 @@ static bool frontswap_selfshrinking __read_mostly;
static void selfshrink_process(struct work_struct *work);
static DECLARE_DELAYED_WORK(selfshrink_worker, selfshrink_process);
+#ifndef CONFIG_RAMSTER_MODULE
/* Enable/disable with kernel boot option. */
static bool use_frontswap_selfshrink __initdata = true;
+#endif
/*
* The default values for the following parameters were deemed reasonable
@@ -928,6 +933,7 @@ static void frontswap_selfshrink(void)
frontswap_shrink(tgt_frontswap_pages);
}
+#ifndef CONFIG_RAMSTER_MODULE
static int __init ramster_nofrontswap_selfshrink_setup(char *s)
{
use_frontswap_selfshrink = false;
@@ -935,6 +941,7 @@ static int __init ramster_nofrontswap_selfshrink_setup(char *s)
}
__setup("noselfshrink", ramster_nofrontswap_selfshrink_setup);
+#endif
static void selfshrink_process(struct work_struct *work)
{
@@ -953,6 +960,7 @@ void ramster_cpu_up(int cpu)
per_cpu(ramster_remoteputmem1, cpu) = p1;
per_cpu(ramster_remoteputmem2, cpu) = p2;
}
+EXPORT_SYMBOL_GPL(ramster_cpu_up);
void ramster_cpu_down(int cpu)
{
@@ -968,6 +976,7 @@ void ramster_cpu_down(int cpu)
kp->flnode = NULL;
}
}
+EXPORT_SYMBOL_GPL(ramster_cpu_down);
void ramster_register_pamops(struct tmem_pamops *pamops)
{
@@ -978,9 +987,11 @@ void ramster_register_pamops(struct tmem_pamops *pamops)
pamops->repatriate = ramster_pampd_repatriate;
pamops->repatriate_preload = ramster_pampd_repatriate_preload;
}
+EXPORT_SYMBOL_GPL(ramster_register_pamops);
-void __init ramster_init(bool cleancache, bool frontswap,
- bool frontswap_exclusive_gets)
+void ramster_init(bool cleancache, bool frontswap,
+ bool frontswap_exclusive_gets,
+ bool frontswap_selfshrink)
{
int ret = 0;
@@ -995,10 +1006,17 @@ void __init ramster_init(bool cleancache, bool frontswap,
if (ret)
pr_err("ramster: can't create sysfs for ramster\n");
(void)r2net_register_handlers();
+#ifdef CONFIG_RAMSTER_MODULE
+ ret = r2nm_init();
+ if (ret)
+ pr_err("ramster: can't init r2net\n");
+ frontswap_selfshrinking = frontswap_selfshrink;
+#else
+ frontswap_selfshrinking = use_frontswap_selfshrink;
+#endif
INIT_LIST_HEAD(&ramster_rem_op_list);
ramster_flnode_cache = kmem_cache_create("ramster_flnode",
sizeof(struct flushlist_node), 0, 0, NULL);
- frontswap_selfshrinking = use_frontswap_selfshrink;
if (frontswap_selfshrinking) {
pr_info("ramster: Initializing frontswap selfshrink driver.\n");
schedule_delayed_work(&selfshrink_worker,
@@ -1006,3 +1024,4 @@ void __init ramster_init(bool cleancache, bool frontswap,
}
ramster_remotify_init();
}
+EXPORT_SYMBOL_GPL(ramster_init);
diff --git a/drivers/staging/zcache/ramster/ramster.h b/drivers/staging/zcache/ramster/ramster.h
index 12ae56f09ca4..6d41a7a772e3 100644
--- a/drivers/staging/zcache/ramster/ramster.h
+++ b/drivers/staging/zcache/ramster/ramster.h
@@ -147,7 +147,7 @@ extern int r2net_register_handlers(void);
extern int r2net_remote_target_node_set(int);
extern int ramster_remotify_pageframe(bool);
-extern void ramster_init(bool, bool, bool);
+extern void ramster_init(bool, bool, bool, bool);
extern void ramster_register_pamops(struct tmem_pamops *);
extern int ramster_localify(int, struct tmem_oid *oidp, uint32_t, char *,
unsigned int, void *);
diff --git a/drivers/staging/zcache/ramster/ramster_nodemanager.h b/drivers/staging/zcache/ramster/ramster_nodemanager.h
index 49f879d943ab..dbaae34ea613 100644
--- a/drivers/staging/zcache/ramster/ramster_nodemanager.h
+++ b/drivers/staging/zcache/ramster/ramster_nodemanager.h
@@ -36,4 +36,6 @@
/* host name, group name, cluster name all 64 bytes */
#define R2NM_MAX_NAME_LEN 64 /* __NEW_UTS_LEN */
+extern int r2nm_init(void);
+
#endif /* _RAMSTER_NODEMANAGER_H */
diff --git a/drivers/staging/zcache/tmem.c b/drivers/staging/zcache/tmem.c
index a2b7e03b6062..d7e51e4152eb 100644
--- a/drivers/staging/zcache/tmem.c
+++ b/drivers/staging/zcache/tmem.c
@@ -35,7 +35,8 @@
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/atomic.h>
-#ifdef CONFIG_RAMSTER
+#include <linux/export.h>
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
#include <linux/delay.h>
#endif
@@ -641,6 +642,7 @@ void *tmem_localify_get_pampd(struct tmem_pool *pool, struct tmem_oid *oidp,
/* note, hashbucket remains locked */
return pampd;
}
+EXPORT_SYMBOL_GPL(tmem_localify_get_pampd);
void tmem_localify_finish(struct tmem_obj *obj, uint32_t index,
void *pampd, void *saved_hb, bool delete)
@@ -658,6 +660,7 @@ void tmem_localify_finish(struct tmem_obj *obj, uint32_t index,
}
spin_unlock(&hb->lock);
}
+EXPORT_SYMBOL_GPL(tmem_localify_finish);
/*
* For ramster only. Helper function to support asynchronous tmem_get.
@@ -719,6 +722,7 @@ out:
spin_unlock(&hb->lock);
return ret;
}
+EXPORT_SYMBOL_GPL(tmem_replace);
#endif
/*
diff --git a/drivers/staging/zcache/tmem.h b/drivers/staging/zcache/tmem.h
index adbe5a8f28aa..d128ce290f1f 100644
--- a/drivers/staging/zcache/tmem.h
+++ b/drivers/staging/zcache/tmem.h
@@ -126,7 +126,7 @@ static inline unsigned tmem_oid_hash(struct tmem_oid *oidp)
TMEM_HASH_BUCKET_BITS);
}
-#ifdef CONFIG_RAMSTER
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
struct tmem_xhandle {
uint8_t client_id;
uint8_t xh_data_cksum;
@@ -171,7 +171,7 @@ struct tmem_obj {
unsigned int objnode_tree_height;
unsigned long objnode_count;
long pampd_count;
-#ifdef CONFIG_RAMSTER
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
/*
* for current design of ramster, all pages belonging to
* an object reside on the same remotenode and extra is
@@ -215,7 +215,7 @@ struct tmem_pamops {
uint32_t);
void (*free)(void *, struct tmem_pool *,
struct tmem_oid *, uint32_t, bool);
-#ifdef CONFIG_RAMSTER
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
void (*new_obj)(struct tmem_obj *);
void (*free_obj)(struct tmem_pool *, struct tmem_obj *, bool);
void *(*repatriate_preload)(void *, struct tmem_pool *,
@@ -247,7 +247,7 @@ extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *,
extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *);
extern int tmem_destroy_pool(struct tmem_pool *);
extern void tmem_new_pool(struct tmem_pool *, uint32_t);
-#ifdef CONFIG_RAMSTER
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index,
void *);
extern void *tmem_localify_get_pampd(struct tmem_pool *, struct tmem_oid *,
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c
index e23d814b5392..522cb8e55142 100644
--- a/drivers/staging/zcache/zcache-main.c
+++ b/drivers/staging/zcache/zcache-main.c
@@ -37,8 +37,10 @@
#include "debug.h"
#ifdef CONFIG_RAMSTER
static bool ramster_enabled __read_mostly;
+static int disable_frontswap_selfshrink;
#else
#define ramster_enabled false
+#define disable_frontswap_selfshrink 0
#endif
#ifndef __PG_WAS_ACTIVE
@@ -81,8 +83,12 @@ static char *namestr __read_mostly = "zcache";
(__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC)
/* crypto API for zcache */
+#ifdef CONFIG_ZCACHE_MODULE
+static char *zcache_comp_name = "lzo";
+#else
#define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME
static char zcache_comp_name[ZCACHE_COMP_NAME_SZ] __read_mostly;
+#endif
static struct crypto_comp * __percpu *zcache_comp_pcpu_tfms __read_mostly;
enum comp_op {
@@ -1576,9 +1582,9 @@ static struct cleancache_ops zcache_cleancache_ops = {
.init_fs = zcache_cleancache_init_fs
};
-struct cleancache_ops zcache_cleancache_register_ops(void)
+struct cleancache_ops *zcache_cleancache_register_ops(void)
{
- struct cleancache_ops old_ops =
+ struct cleancache_ops *old_ops =
cleancache_register_ops(&zcache_cleancache_ops);
return old_ops;
@@ -1707,9 +1713,9 @@ static struct frontswap_ops zcache_frontswap_ops = {
.init = zcache_frontswap_init
};
-struct frontswap_ops zcache_frontswap_register_ops(void)
+struct frontswap_ops *zcache_frontswap_register_ops(void)
{
- struct frontswap_ops old_ops =
+ struct frontswap_ops *old_ops =
frontswap_register_ops(&zcache_frontswap_ops);
return old_ops;
@@ -1721,6 +1727,7 @@ struct frontswap_ops zcache_frontswap_register_ops(void)
* OR NOTHING HAPPENS!
*/
+#ifndef CONFIG_ZCACHE_MODULE
static int __init enable_zcache(char *s)
{
zcache_enabled = true;
@@ -1787,18 +1794,27 @@ static int __init enable_zcache_compressor(char *s)
return 1;
}
__setup("zcache=", enable_zcache_compressor);
+#endif
-static int __init zcache_comp_init(void)
+static int zcache_comp_init(void)
{
int ret = 0;
/* check crypto algorithm */
+#ifdef CONFIG_ZCACHE_MODULE
+ ret = crypto_has_comp(zcache_comp_name, 0, 0);
+ if (!ret) {
+ ret = -1;
+ goto out;
+ }
+#else
if (*zcache_comp_name != '\0') {
ret = crypto_has_comp(zcache_comp_name, 0, 0);
if (!ret)
pr_info("zcache: %s not supported\n",
zcache_comp_name);
+ goto out;
}
if (!ret)
strcpy(zcache_comp_name, "lzo");
@@ -1807,6 +1823,7 @@ static int __init zcache_comp_init(void)
ret = 1;
goto out;
}
+#endif
pr_info("zcache: using %s compressor\n", zcache_comp_name);
/* alloc percpu transforms */
@@ -1818,10 +1835,13 @@ out:
return ret;
}
-static int __init zcache_init(void)
+static int zcache_init(void)
{
int ret = 0;
+#ifdef CONFIG_ZCACHE_MODULE
+ zcache_enabled = 1;
+#endif
if (ramster_enabled) {
namestr = "ramster";
ramster_register_pamops(&zcache_pamops);
@@ -1860,7 +1880,7 @@ static int __init zcache_init(void)
}
zbud_init();
if (zcache_enabled && !disable_cleancache) {
- struct cleancache_ops old_ops;
+ struct cleancache_ops *old_ops;
register_shrinker(&zcache_shrinker);
old_ops = zcache_cleancache_register_ops();
@@ -1870,11 +1890,11 @@ static int __init zcache_init(void)
pr_info("%s: cleancache: ignorenonactive = %d\n",
namestr, !disable_cleancache_ignore_nonactive);
#endif
- if (old_ops.init_fs != NULL)
+ if (old_ops != NULL)
pr_warn("%s: cleancache_ops overridden\n", namestr);
}
if (zcache_enabled && !disable_frontswap) {
- struct frontswap_ops old_ops;
+ struct frontswap_ops *old_ops;
old_ops = zcache_frontswap_register_ops();
if (frontswap_has_exclusive_gets)
@@ -1886,14 +1906,36 @@ static int __init zcache_init(void)
namestr, frontswap_has_exclusive_gets,
!disable_frontswap_ignore_nonactive);
#endif
- if (old_ops.init != NULL)
+ if (IS_ERR(old_ops) || old_ops) {
+ if (IS_ERR(old_ops))
+ return PTR_RET(old_ops);
pr_warn("%s: frontswap_ops overridden\n", namestr);
+ }
}
if (ramster_enabled)
ramster_init(!disable_cleancache, !disable_frontswap,
- frontswap_has_exclusive_gets);
+ frontswap_has_exclusive_gets,
+ !disable_frontswap_selfshrink);
out:
return ret;
}
+#ifdef CONFIG_ZCACHE_MODULE
+#ifdef CONFIG_RAMSTER
+module_param(ramster_enabled, int, S_IRUGO);
+module_param(disable_frontswap_selfshrink, int, S_IRUGO);
+#endif
+module_param(disable_cleancache, int, S_IRUGO);
+module_param(disable_frontswap, int, S_IRUGO);
+#ifdef FRONTSWAP_HAS_EXCLUSIVE_GETS
+module_param(frontswap_has_exclusive_gets, bool, S_IRUGO);
+#endif
+module_param(disable_frontswap_ignore_nonactive, int, S_IRUGO);
+module_param(zcache_comp_name, charp, S_IRUGO);
+module_init(zcache_init);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dan Magenheimer <dan.magenheimer@oracle.com>");
+MODULE_DESCRIPTION("In-kernel compression of cleancache/frontswap pages");
+#else
late_initcall(zcache_init);
+#endif
diff --git a/drivers/staging/zcache/zcache.h b/drivers/staging/zcache/zcache.h
index 81722b33b087..849120095e79 100644
--- a/drivers/staging/zcache/zcache.h
+++ b/drivers/staging/zcache/zcache.h
@@ -39,7 +39,7 @@ extern int zcache_flush_page(int, int, struct tmem_oid *, uint32_t);
extern int zcache_flush_object(int, int, struct tmem_oid *);
extern void zcache_decompress_to_page(char *, unsigned int, struct page *);
-#ifdef CONFIG_RAMSTER
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
extern void *zcache_pampd_create(char *, unsigned int, bool, int,
struct tmem_handle *);
int zcache_autocreate_pool(unsigned int cli_id, unsigned int pool_id, bool eph);
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 8bcc514ec8b6..c2e5ca9b8303 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -271,7 +271,8 @@ static void iblock_complete_cmd(struct se_cmd *cmd)
kfree(ibr);
}
-static void iblock_bio_done(struct bio *bio, int err)
+static void iblock_bio_done(struct bio *bio, int err,
+ struct batch_complete *batch)
{
struct se_cmd *cmd = bio->bi_private;
struct iblock_req *ibr = cmd->priv;
@@ -335,7 +336,8 @@ static void iblock_submit_bios(struct bio_list *list, int rw)
blk_finish_plug(&plug);
}
-static void iblock_end_io_flush(struct bio *bio, int err)
+static void iblock_end_io_flush(struct bio *bio, int err,
+ struct batch_complete *batch)
{
struct se_cmd *cmd = bio->bi_private;
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index e992b27aa090..1e9873179860 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -835,7 +835,8 @@ static ssize_t pscsi_show_configfs_dev_params(struct se_device *dev, char *b)
return bl;
}
-static void pscsi_bi_endio(struct bio *bio, int error)
+static void pscsi_bi_endio(struct bio *bio, int error,
+ struct batch_complete *batch)
{
bio_put(bio);
}
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index f52dcfe8f545..24bd363ca351 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -3099,7 +3099,7 @@ static int init_dma_pools(struct udc *dev)
}
/* DMA setup */
- dev->data_requests = dma_pool_create("data_requests", NULL,
+ dev->data_requests = dma_pool_create("data_requests", &dev->pdev->dev,
sizeof(struct udc_data_dma), 0, 0);
if (!dev->data_requests) {
DBG(dev, "can't get request data pool\n");
@@ -3111,7 +3111,7 @@ static int init_dma_pools(struct udc *dev)
dev->ep[UDC_EP0IN_IX].dma = &dev->regs->ctl;
/* dma desc for setup data */
- dev->stp_requests = dma_pool_create("setup requests", NULL,
+ dev->stp_requests = dma_pool_create("setup requests", &dev->pdev->dev,
sizeof(struct udc_stp_dma), 0, 0);
if (!dev->stp_requests) {
DBG(dev, "can't get stp request pool\n");
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index dda0dc4a5567..570c005062ab 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -24,6 +24,8 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
+#include <linux/mmu_context.h>
+#include <linux/aio.h>
#include <linux/device.h>
#include <linux/moduleparam.h>
@@ -513,6 +515,9 @@ static long ep_ioctl(struct file *fd, unsigned code, unsigned long value)
struct kiocb_priv {
struct usb_request *req;
struct ep_data *epdata;
+ struct kiocb *iocb;
+ struct mm_struct *mm;
+ struct work_struct work;
void *buf;
const struct iovec *iv;
unsigned long nr_segs;
@@ -528,7 +533,6 @@ static int ep_aio_cancel(struct kiocb *iocb, struct io_event *e)
local_irq_disable();
epdata = priv->epdata;
// spin_lock(&epdata->dev->lock);
- kiocbSetCancelled(iocb);
if (likely(epdata && epdata->ep && priv->req))
value = usb_ep_dequeue (epdata->ep, priv->req);
else
@@ -540,15 +544,12 @@ static int ep_aio_cancel(struct kiocb *iocb, struct io_event *e)
return value;
}
-static ssize_t ep_aio_read_retry(struct kiocb *iocb)
+static ssize_t ep_copy_to_user(struct kiocb_priv *priv)
{
- struct kiocb_priv *priv = iocb->private;
ssize_t len, total;
void *to_copy;
int i;
- /* we "retry" to get the right mm context for this: */
-
/* copy stuff into user buffers */
total = priv->actual;
len = 0;
@@ -568,9 +569,26 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb)
if (total == 0)
break;
}
+
+ return len;
+}
+
+static void ep_user_copy_worker(struct work_struct *work)
+{
+ struct kiocb_priv *priv = container_of(work, struct kiocb_priv, work);
+ struct mm_struct *mm = priv->mm;
+ struct kiocb *iocb = priv->iocb;
+ size_t ret;
+
+ use_mm(mm);
+ ret = ep_copy_to_user(priv);
+ unuse_mm(mm);
+
+ /* completing the iocb can drop the ctx and mm, don't touch mm after */
+ aio_complete(iocb, ret, ret);
+
kfree(priv->buf);
kfree(priv);
- return len;
}
static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
@@ -596,14 +614,14 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
aio_complete(iocb, req->actual ? req->actual : req->status,
req->status);
} else {
- /* retry() won't report both; so we hide some faults */
+ /* ep_copy_to_user() won't report both; we hide some faults */
if (unlikely(0 != req->status))
DBG(epdata->dev, "%s fault %d len %d\n",
ep->name, req->status, req->actual);
priv->buf = req->buf;
priv->actual = req->actual;
- kick_iocb(iocb);
+ schedule_work(&priv->work);
}
spin_unlock(&epdata->dev->lock);
@@ -633,8 +651,10 @@ fail:
return value;
}
iocb->private = priv;
+ priv->iocb = iocb;
priv->iv = iv;
priv->nr_segs = nr_segs;
+ INIT_WORK(&priv->work, ep_user_copy_worker);
value = get_ready_ep(iocb->ki_filp->f_flags, epdata);
if (unlikely(value < 0)) {
@@ -642,10 +662,11 @@ fail:
goto fail;
}
- iocb->ki_cancel = ep_aio_cancel;
+ kiocb_set_cancel_fn(iocb, ep_aio_cancel);
get_ep(epdata);
priv->epdata = epdata;
priv->actual = 0;
+ priv->mm = current->mm; /* mm teardown waits for iocbs in exit_aio() */
/* each kiocb is coupled to one usb_request, but we can't
* allocate or submit those if the host disconnected.
@@ -674,7 +695,7 @@ fail:
kfree(priv);
put_ep(epdata);
} else
- value = (iv ? -EIOCBRETRY : -EIOCBQUEUED);
+ value = -EIOCBQUEUED;
return value;
}
@@ -692,7 +713,6 @@ ep_aio_read(struct kiocb *iocb, const struct iovec *iov,
if (unlikely(!buf))
return -ENOMEM;
- iocb->ki_retry = ep_aio_read_retry;
return ep_aio_rwtail(iocb, buf, iocb->ki_left, epdata, iov, nr_segs);
}
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
index 0b0d8bce842e..f4ae05f78c42 100644
--- a/drivers/uwb/rsv.c
+++ b/drivers/uwb/rsv.c
@@ -231,7 +231,7 @@ void uwb_rsv_backoff_win_increment(struct uwb_rc *rc)
return;
bow->window <<= 1;
- bow->n = random32() & (bow->window - 1);
+ bow->n = prandom_u32() & (bow->window - 1);
dev_dbg(dev, "new_window=%d, n=%d\n: ", bow->window, bow->n);
/* reset the timer associated variables */
@@ -557,7 +557,7 @@ int uwb_rsv_establish(struct uwb_rsv *rsv)
if (ret)
goto out;
- rsv->tiebreaker = random32() & 1;
+ rsv->tiebreaker = prandom_u32() & 1;
/* get available mas bitmap */
uwb_drp_available(rc, &available);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 64a5709cadf1..5053a4ab576e 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2442,6 +2442,32 @@ config FB_PUV3_UNIGFX
Choose this option if you want to use the Unigfx device as a
framebuffer device. Without the support of PCI & AGP.
+config FB_HYPERV
+ tristate "Microsoft Hyper-V Synthetic Video support"
+ depends on FB && HYPERV
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
+
+config FB_SIMPLE
+ bool "Simple framebuffer support"
+ depends on (FB = y) && OF
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Say Y if you want support for a simple frame-buffer.
+
+ This driver assumes that the display hardware has been initialized
+ before the kernel boots, and the kernel will simply render to the
+ pre-allocated frame buffer surface.
+
+ Configuration re: surface address, size, and format must be provided
+ through device tree, or potentially plain old platform data in the
+ future.
+
source "drivers/video/omap/Kconfig"
source "drivers/video/omap2/Kconfig"
source "drivers/video/exynos/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index e414378d6a51..e8bae8dd4804 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -149,6 +149,7 @@ obj-$(CONFIG_FB_MSM) += msm/
obj-$(CONFIG_FB_NUC900) += nuc900fb.o
obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
+obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_UVESA) += uvesafb.o
@@ -165,6 +166,7 @@ obj-$(CONFIG_FB_MX3) += mx3fb.o
obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
obj-$(CONFIG_FB_MXS) += mxsfb.o
obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o
+obj-$(CONFIG_FB_SIMPLE) += simplefb.o
# the test framebuffer is last
obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index db10d0120d2b..2e166c3fc4c3 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -59,6 +59,13 @@ config LCD_LTV350QV
The LTV350QV panel is present on all ATSTK1000 boards.
+config LCD_ILI922X
+ tristate "ILI Technology ILI9221/ILI9222 support"
+ depends on SPI
+ help
+ If you have a panel based on the ILI9221/9222 controller
+ chip then say y to include a driver for it.
+
config LCD_ILI9320
tristate "ILI Technology ILI9320 controller support"
depends on SPI
@@ -161,7 +168,7 @@ if BACKLIGHT_CLASS_DEVICE
config BACKLIGHT_ATMEL_LCDC
bool "Atmel LCDC Contrast-as-Backlight control"
depends on FB_ATMEL
- default y if MACH_SAM9261EK || MACH_SAM9G10EK || MACH_SAM9263EK
+ default y if MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK
help
This provides a backlight control internal to the Atmel LCDC
driver. If the LCD "contrast control" on your board is wired
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 96c4d620c5ce..92711fe60464 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
obj-$(CONFIG_LCD_HX8357) += hx8357.o
+obj-$(CONFIG_LCD_ILI922X) += ili922x.o
obj-$(CONFIG_LCD_ILI9320) += ili9320.o
obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o
obj-$(CONFIG_LCD_LD9040) += ld9040.o
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
index a1e41d4faa71..c84701b7ca6e 100644
--- a/drivers/video/backlight/adp5520_bl.c
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -143,13 +143,16 @@ static int adp5520_bl_setup(struct backlight_device *bl)
static ssize_t adp5520_show(struct device *dev, char *buf, int reg)
{
struct adp5520_bl *data = dev_get_drvdata(dev);
- int error;
+ int ret;
uint8_t reg_val;
mutex_lock(&data->lock);
- error = adp5520_read(data->master, reg, &reg_val);
+ ret = adp5520_read(data->master, reg, &reg_val);
mutex_unlock(&data->lock);
+ if (ret < 0)
+ return ret;
+
return sprintf(buf, "%u\n", reg_val);
}
@@ -349,35 +352,34 @@ static int adp5520_bl_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
-static int adp5520_bl_suspend(struct platform_device *pdev,
- pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int adp5520_bl_suspend(struct device *dev)
{
- struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct backlight_device *bl = dev_get_drvdata(dev);
+
return adp5520_bl_set(bl, 0);
}
-static int adp5520_bl_resume(struct platform_device *pdev)
+static int adp5520_bl_resume(struct device *dev)
{
- struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct backlight_device *bl = dev_get_drvdata(dev);
backlight_update_status(bl);
return 0;
}
-#else
-#define adp5520_bl_suspend NULL
-#define adp5520_bl_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(adp5520_bl_pm_ops, adp5520_bl_suspend,
+ adp5520_bl_resume);
+
static struct platform_driver adp5520_bl_driver = {
.driver = {
.name = "adp5520-backlight",
.owner = THIS_MODULE,
+ .pm = &adp5520_bl_pm_ops,
},
.probe = adp5520_bl_probe,
.remove = adp5520_bl_remove,
- .suspend = adp5520_bl_suspend,
- .resume = adp5520_bl_resume,
};
module_platform_driver(adp5520_bl_driver);
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index a77c9cad3320..75b10f876127 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -249,12 +249,14 @@ static int adp8860_led_probe(struct i2c_client *client)
if (led_dat->id > 7 || led_dat->id < 1) {
dev_err(&client->dev, "Invalid LED ID %d\n",
led_dat->id);
+ ret = -EINVAL;
goto err;
}
if (pdata->bl_led_assign & (1 << (led_dat->id - 1))) {
dev_err(&client->dev, "LED %d used by Backlight\n",
led_dat->id);
+ ret = -EBUSY;
goto err;
}
@@ -773,25 +775,29 @@ static int adp8860_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_PM
-static int adp8860_i2c_suspend(struct i2c_client *client, pm_message_t message)
+#ifdef CONFIG_PM_SLEEP
+static int adp8860_i2c_suspend(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
+
adp8860_clr_bits(client, ADP8860_MDCR, NSTBY);
return 0;
}
-static int adp8860_i2c_resume(struct i2c_client *client)
+static int adp8860_i2c_resume(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
+
adp8860_set_bits(client, ADP8860_MDCR, NSTBY | BLEN);
return 0;
}
-#else
-#define adp8860_i2c_suspend NULL
-#define adp8860_i2c_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(adp8860_i2c_pm_ops, adp8860_i2c_suspend,
+ adp8860_i2c_resume);
+
static const struct i2c_device_id adp8860_id[] = {
{ "adp8860", adp8860 },
{ "adp8861", adp8861 },
@@ -802,12 +808,11 @@ MODULE_DEVICE_TABLE(i2c, adp8860_id);
static struct i2c_driver adp8860_driver = {
.driver = {
- .name = KBUILD_MODNAME,
+ .name = KBUILD_MODNAME,
+ .pm = &adp8860_i2c_pm_ops,
},
.probe = adp8860_probe,
.remove = adp8860_remove,
- .suspend = adp8860_i2c_suspend,
- .resume = adp8860_i2c_resume,
.id_table = adp8860_id,
};
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index 712c25a0d8fe..90049d7b5c60 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -274,12 +274,14 @@ static int adp8870_led_probe(struct i2c_client *client)
if (led_dat->id > 7 || led_dat->id < 1) {
dev_err(&client->dev, "Invalid LED ID %d\n",
led_dat->id);
+ ret = -EINVAL;
goto err;
}
if (pdata->bl_led_assign & (1 << (led_dat->id - 1))) {
dev_err(&client->dev, "LED %d used by Backlight\n",
led_dat->id);
+ ret = -EBUSY;
goto err;
}
@@ -895,13 +897,13 @@ static int adp8870_probe(struct i2c_client *client,
data->bl = bl;
- if (pdata->en_ambl_sens)
+ if (pdata->en_ambl_sens) {
ret = sysfs_create_group(&bl->dev.kobj,
&adp8870_bl_attr_group);
-
- if (ret) {
- dev_err(&client->dev, "failed to register sysfs\n");
- goto out1;
+ if (ret) {
+ dev_err(&client->dev, "failed to register sysfs\n");
+ goto out1;
+ }
}
ret = adp8870_bl_setup(bl);
@@ -947,25 +949,29 @@ static int adp8870_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_PM
-static int adp8870_i2c_suspend(struct i2c_client *client, pm_message_t message)
+#ifdef CONFIG_PM_SLEEP
+static int adp8870_i2c_suspend(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
+
adp8870_clr_bits(client, ADP8870_MDCR, NSTBY);
return 0;
}
-static int adp8870_i2c_resume(struct i2c_client *client)
+static int adp8870_i2c_resume(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
+
adp8870_set_bits(client, ADP8870_MDCR, NSTBY | BLEN);
return 0;
}
-#else
-#define adp8870_i2c_suspend NULL
-#define adp8870_i2c_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(adp8870_i2c_pm_ops, adp8870_i2c_suspend,
+ adp8870_i2c_resume);
+
static const struct i2c_device_id adp8870_id[] = {
{ "adp8870", 0 },
{ }
@@ -974,12 +980,11 @@ MODULE_DEVICE_TABLE(i2c, adp8870_id);
static struct i2c_driver adp8870_driver = {
.driver = {
- .name = KBUILD_MODNAME,
+ .name = KBUILD_MODNAME,
+ .pm = &adp8870_i2c_pm_ops,
},
.probe = adp8870_probe,
.remove = adp8870_remove,
- .suspend = adp8870_i2c_suspend,
- .resume = adp8870_i2c_resume,
.id_table = adp8870_id,
};
diff --git a/drivers/video/backlight/ams369fg06.c b/drivers/video/backlight/ams369fg06.c
index c02aa2c2575a..319fef6cb422 100644
--- a/drivers/video/backlight/ams369fg06.c
+++ b/drivers/video/backlight/ams369fg06.c
@@ -533,12 +533,12 @@ static int ams369fg06_remove(struct spi_device *spi)
return 0;
}
-#if defined(CONFIG_PM)
-static int ams369fg06_suspend(struct spi_device *spi, pm_message_t mesg)
+#ifdef CONFIG_PM_SLEEP
+static int ams369fg06_suspend(struct device *dev)
{
- struct ams369fg06 *lcd = spi_get_drvdata(spi);
+ struct ams369fg06 *lcd = dev_get_drvdata(dev);
- dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
+ dev_dbg(dev, "lcd->power = %d\n", lcd->power);
/*
* when lcd panel is suspend, lcd panel becomes off
@@ -547,19 +547,19 @@ static int ams369fg06_suspend(struct spi_device *spi, pm_message_t mesg)
return ams369fg06_power(lcd, FB_BLANK_POWERDOWN);
}
-static int ams369fg06_resume(struct spi_device *spi)
+static int ams369fg06_resume(struct device *dev)
{
- struct ams369fg06 *lcd = spi_get_drvdata(spi);
+ struct ams369fg06 *lcd = dev_get_drvdata(dev);
lcd->power = FB_BLANK_POWERDOWN;
return ams369fg06_power(lcd, FB_BLANK_UNBLANK);
}
-#else
-#define ams369fg06_suspend NULL
-#define ams369fg06_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(ams369fg06_pm_ops, ams369fg06_suspend,
+ ams369fg06_resume);
+
static void ams369fg06_shutdown(struct spi_device *spi)
{
struct ams369fg06 *lcd = spi_get_drvdata(spi);
@@ -571,12 +571,11 @@ static struct spi_driver ams369fg06_driver = {
.driver = {
.name = "ams369fg06",
.owner = THIS_MODULE,
+ .pm = &ams369fg06_pm_ops,
},
.probe = ams369fg06_probe,
.remove = ams369fg06_remove,
.shutdown = ams369fg06_shutdown,
- .suspend = ams369fg06_suspend,
- .resume = ams369fg06_resume,
};
module_spi_driver(ams369fg06_driver);
diff --git a/drivers/video/backlight/as3711_bl.c b/drivers/video/backlight/as3711_bl.c
index 41d52fe52543..123887cd76bd 100644
--- a/drivers/video/backlight/as3711_bl.c
+++ b/drivers/video/backlight/as3711_bl.c
@@ -258,6 +258,109 @@ static int as3711_bl_register(struct platform_device *pdev,
return 0;
}
+static int as3711_backlight_parse_dt(struct device *dev)
+{
+ struct as3711_bl_pdata *pdata = dev_get_platdata(dev);
+ struct device_node *bl =
+ of_find_node_by_name(dev->parent->of_node, "backlight"), *fb;
+ int ret;
+
+ if (!bl) {
+ dev_dbg(dev, "backlight node not found\n");
+ return -ENODEV;
+ }
+
+ fb = of_parse_phandle(bl, "su1-dev", 0);
+ if (fb) {
+ pdata->su1_fb = fb->full_name;
+
+ ret = of_property_read_u32(bl, "su1-max-uA", &pdata->su1_max_uA);
+ if (pdata->su1_max_uA <= 0)
+ ret = -EINVAL;
+ if (ret < 0)
+ return ret;
+ }
+
+ fb = of_parse_phandle(bl, "su2-dev", 0);
+ if (fb) {
+ int count = 0;
+
+ pdata->su2_fb = fb->full_name;
+
+ ret = of_property_read_u32(bl, "su2-max-uA", &pdata->su2_max_uA);
+ if (pdata->su2_max_uA <= 0)
+ ret = -EINVAL;
+ if (ret < 0)
+ return ret;
+
+ if (of_find_property(bl, "su2-feedback-voltage", NULL)) {
+ pdata->su2_feedback = AS3711_SU2_VOLTAGE;
+ count++;
+ }
+ if (of_find_property(bl, "su2-feedback-curr1", NULL)) {
+ pdata->su2_feedback = AS3711_SU2_CURR1;
+ count++;
+ }
+ if (of_find_property(bl, "su2-feedback-curr2", NULL)) {
+ pdata->su2_feedback = AS3711_SU2_CURR2;
+ count++;
+ }
+ if (of_find_property(bl, "su2-feedback-curr3", NULL)) {
+ pdata->su2_feedback = AS3711_SU2_CURR3;
+ count++;
+ }
+ if (of_find_property(bl, "su2-feedback-curr-auto", NULL)) {
+ pdata->su2_feedback = AS3711_SU2_CURR_AUTO;
+ count++;
+ }
+ if (count != 1)
+ return -EINVAL;
+
+ count = 0;
+ if (of_find_property(bl, "su2-fbprot-lx-sd4", NULL)) {
+ pdata->su2_fbprot = AS3711_SU2_LX_SD4;
+ count++;
+ }
+ if (of_find_property(bl, "su2-fbprot-gpio2", NULL)) {
+ pdata->su2_fbprot = AS3711_SU2_GPIO2;
+ count++;
+ }
+ if (of_find_property(bl, "su2-fbprot-gpio3", NULL)) {
+ pdata->su2_fbprot = AS3711_SU2_GPIO3;
+ count++;
+ }
+ if (of_find_property(bl, "su2-fbprot-gpio4", NULL)) {
+ pdata->su2_fbprot = AS3711_SU2_GPIO4;
+ count++;
+ }
+ if (count != 1)
+ return -EINVAL;
+
+ count = 0;
+ if (of_find_property(bl, "su2-auto-curr1", NULL)) {
+ pdata->su2_auto_curr1 = true;
+ count++;
+ }
+ if (of_find_property(bl, "su2-auto-curr2", NULL)) {
+ pdata->su2_auto_curr2 = true;
+ count++;
+ }
+ if (of_find_property(bl, "su2-auto-curr3", NULL)) {
+ pdata->su2_auto_curr3 = true;
+ count++;
+ }
+
+ /*
+ * At least one su2-auto-curr* must be specified iff
+ * AS3711_SU2_CURR_AUTO is used
+ */
+ if (!count ^ (pdata->su2_feedback != AS3711_SU2_CURR_AUTO))
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int as3711_backlight_probe(struct platform_device *pdev)
{
struct as3711_bl_pdata *pdata = dev_get_platdata(&pdev->dev);
@@ -267,11 +370,24 @@ static int as3711_backlight_probe(struct platform_device *pdev)
unsigned int max_brightness;
int ret;
- if (!pdata || (!pdata->su1_fb && !pdata->su2_fb)) {
+ if (!pdata) {
dev_err(&pdev->dev, "No platform data, exiting...\n");
return -ENODEV;
}
+ if (pdev->dev.parent->of_node) {
+ ret = as3711_backlight_parse_dt(&pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "DT parsing failed: %d\n", ret);
+ return ret;
+ }
+ }
+
+ if (!pdata->su1_fb && !pdata->su2_fb) {
+ dev_err(&pdev->dev, "No framebuffer specified\n");
+ return -EINVAL;
+ }
+
/*
* Due to possible hardware damage I chose to block all modes,
* unsupported on my hardware. Anyone, wishing to use any of those modes
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index de5e5e74e2a7..a60d6afca97c 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -118,7 +118,7 @@ static const struct backlight_ops atmel_pwm_bl_ops = {
.update_status = atmel_pwm_bl_set_intensity,
};
-static int atmel_pwm_bl_probe(struct platform_device *pdev)
+static int __init atmel_pwm_bl_probe(struct platform_device *pdev)
{
struct backlight_properties props;
const struct atmel_pwm_bl_platform_data *pdata;
@@ -225,17 +225,7 @@ static struct platform_driver atmel_pwm_bl_driver = {
.remove = __exit_p(atmel_pwm_bl_remove),
};
-static int __init atmel_pwm_bl_init(void)
-{
- return platform_driver_probe(&atmel_pwm_bl_driver, atmel_pwm_bl_probe);
-}
-module_init(atmel_pwm_bl_init);
-
-static void __exit atmel_pwm_bl_exit(void)
-{
- platform_driver_unregister(&atmel_pwm_bl_driver);
-}
-module_exit(atmel_pwm_bl_exit);
+module_platform_driver_probe(atmel_pwm_bl_driver, atmel_pwm_bl_probe);
MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
MODULE_DESCRIPTION("Atmel PWM backlight driver");
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index aa782f302983..c97867a717a7 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -457,10 +457,10 @@ static const struct backlight_ops corgi_bl_ops = {
.update_status = corgi_bl_update_status,
};
-#ifdef CONFIG_PM
-static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int corgi_lcd_suspend(struct device *dev)
{
- struct corgi_lcd *lcd = spi_get_drvdata(spi);
+ struct corgi_lcd *lcd = dev_get_drvdata(dev);
corgibl_flags |= CORGIBL_SUSPENDED;
corgi_bl_set_intensity(lcd, 0);
@@ -468,20 +468,19 @@ static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state)
return 0;
}
-static int corgi_lcd_resume(struct spi_device *spi)
+static int corgi_lcd_resume(struct device *dev)
{
- struct corgi_lcd *lcd = spi_get_drvdata(spi);
+ struct corgi_lcd *lcd = dev_get_drvdata(dev);
corgibl_flags &= ~CORGIBL_SUSPENDED;
corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
backlight_update_status(lcd->bl_dev);
return 0;
}
-#else
-#define corgi_lcd_suspend NULL
-#define corgi_lcd_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(corgi_lcd_pm_ops, corgi_lcd_suspend, corgi_lcd_resume);
+
static int setup_gpio_backlight(struct corgi_lcd *lcd,
struct corgi_lcd_platform_data *pdata)
{
@@ -611,11 +610,10 @@ static struct spi_driver corgi_lcd_driver = {
.driver = {
.name = "corgi-lcd",
.owner = THIS_MODULE,
+ .pm = &corgi_lcd_pm_ops,
},
.probe = corgi_lcd_probe,
.remove = corgi_lcd_remove,
- .suspend = corgi_lcd_suspend,
- .resume = corgi_lcd_resume,
};
module_spi_driver(corgi_lcd_driver);
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index 8179cef0730f..67cadd30e273 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -88,16 +88,21 @@ static int da903x_backlight_update_status(struct backlight_device *bl)
if (bl->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
+ if (bl->props.state & BL_CORE_SUSPENDED)
+ brightness = 0;
+
return da903x_backlight_set(bl, brightness);
}
static int da903x_backlight_get_brightness(struct backlight_device *bl)
{
struct da903x_backlight_data *data = bl_get_data(bl);
+
return data->current_brightness;
}
static const struct backlight_ops da903x_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
.update_status = da903x_backlight_update_status,
.get_brightness = da903x_backlight_get_brightness,
};
@@ -161,35 +166,10 @@ static int da903x_backlight_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
-static int da903x_backlight_suspend(struct device *dev)
-{
- struct backlight_device *bl = dev_get_drvdata(dev);
-
- return da903x_backlight_set(bl, 0);
-}
-
-static int da903x_backlight_resume(struct device *dev)
-{
- struct backlight_device *bl = dev_get_drvdata(dev);
-
- backlight_update_status(bl);
- return 0;
-}
-
-static const struct dev_pm_ops da903x_backlight_pm_ops = {
- .suspend = da903x_backlight_suspend,
- .resume = da903x_backlight_resume,
-};
-#endif
-
static struct platform_driver da903x_backlight_driver = {
.driver = {
.name = "da903x-backlight",
.owner = THIS_MODULE,
-#ifdef CONFIG_PM
- .pm = &da903x_backlight_pm_ops,
-#endif
},
.probe = da903x_backlight_probe,
.remove = da903x_backlight_remove,
diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c
index ef3e21e8f825..33455821dd31 100644
--- a/drivers/video/backlight/ep93xx_bl.c
+++ b/drivers/video/backlight/ep93xx_bl.c
@@ -60,7 +60,7 @@ static const struct backlight_ops ep93xxbl_ops = {
.get_brightness = ep93xxbl_get_brightness,
};
-static int __init ep93xxbl_probe(struct platform_device *dev)
+static int ep93xxbl_probe(struct platform_device *dev)
{
struct ep93xxbl *ep93xxbl;
struct backlight_device *bl;
@@ -115,35 +115,33 @@ static int ep93xxbl_remove(struct platform_device *dev)
return 0;
}
-#ifdef CONFIG_PM
-static int ep93xxbl_suspend(struct platform_device *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int ep93xxbl_suspend(struct device *dev)
{
- struct backlight_device *bl = platform_get_drvdata(dev);
+ struct backlight_device *bl = dev_get_drvdata(dev);
return ep93xxbl_set(bl, 0);
}
-static int ep93xxbl_resume(struct platform_device *dev)
+static int ep93xxbl_resume(struct device *dev)
{
- struct backlight_device *bl = platform_get_drvdata(dev);
+ struct backlight_device *bl = dev_get_drvdata(dev);
backlight_update_status(bl);
return 0;
}
-#else
-#define ep93xxbl_suspend NULL
-#define ep93xxbl_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(ep93xxbl_pm_ops, ep93xxbl_suspend, ep93xxbl_resume);
+
static struct platform_driver ep93xxbl_driver = {
.driver = {
.name = "ep93xx-bl",
.owner = THIS_MODULE,
+ .pm = &ep93xxbl_pm_ops,
},
.probe = ep93xxbl_probe,
.remove = ep93xxbl_remove,
- .suspend = ep93xxbl_suspend,
- .resume = ep93xxbl_resume,
};
module_platform_driver(ep93xxbl_driver);
diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c
index 0ae155be9c89..19e393b41438 100644
--- a/drivers/video/backlight/generic_bl.c
+++ b/drivers/video/backlight/generic_bl.c
@@ -9,8 +9,6 @@
*
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -108,7 +106,7 @@ static int genericbl_probe(struct platform_device *pdev)
generic_backlight_device = bd;
- pr_info("Generic Backlight Driver Initialized.\n");
+ dev_info(&pdev->dev, "Generic Backlight Driver Initialized.\n");
return 0;
}
@@ -122,7 +120,7 @@ static int genericbl_remove(struct platform_device *pdev)
backlight_device_unregister(bd);
- pr_info("Generic Backlight Driver Unloaded\n");
+ dev_info(&pdev->dev, "Generic Backlight Driver Unloaded\n");
return 0;
}
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 5cefd73526f8..00076ecfe9b8 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -64,29 +64,28 @@ static void hp680bl_send_intensity(struct backlight_device *bd)
}
-#ifdef CONFIG_PM
-static int hp680bl_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int hp680bl_suspend(struct device *dev)
{
- struct backlight_device *bd = platform_get_drvdata(pdev);
+ struct backlight_device *bd = dev_get_drvdata(dev);
hp680bl_suspended = 1;
hp680bl_send_intensity(bd);
return 0;
}
-static int hp680bl_resume(struct platform_device *pdev)
+static int hp680bl_resume(struct device *dev)
{
- struct backlight_device *bd = platform_get_drvdata(pdev);
+ struct backlight_device *bd = dev_get_drvdata(dev);
hp680bl_suspended = 0;
hp680bl_send_intensity(bd);
return 0;
}
-#else
-#define hp680bl_suspend NULL
-#define hp680bl_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(hp680bl_pm_ops, hp680bl_suspend, hp680bl_resume);
+
static int hp680bl_set_intensity(struct backlight_device *bd)
{
hp680bl_send_intensity(bd);
@@ -140,10 +139,9 @@ static int hp680bl_remove(struct platform_device *pdev)
static struct platform_driver hp680bl_driver = {
.probe = hp680bl_probe,
.remove = hp680bl_remove,
- .suspend = hp680bl_suspend,
- .resume = hp680bl_resume,
.driver = {
.name = "hp680-bl",
+ .pm = &hp680bl_pm_ops,
},
};
diff --git a/drivers/video/backlight/ili922x.c b/drivers/video/backlight/ili922x.c
new file mode 100644
index 000000000000..d9f65c2d9b01
--- /dev/null
+++ b/drivers/video/backlight/ili922x.c
@@ -0,0 +1,555 @@
+/*
+ * (C) Copyright 2008
+ * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
+ *
+ * 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 driver implements a lcd device for the ILITEK 922x display
+ * controller. The interface to the display is SPI and the display's
+ * memory is cyclically updated over the RGB interface.
+ */
+
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/string.h>
+
+/* Register offset, see manual section 8.2 */
+#define REG_START_OSCILLATION 0x00
+#define REG_DRIVER_CODE_READ 0x00
+#define REG_DRIVER_OUTPUT_CONTROL 0x01
+#define REG_LCD_AC_DRIVEING_CONTROL 0x02
+#define REG_ENTRY_MODE 0x03
+#define REG_COMPARE_1 0x04
+#define REG_COMPARE_2 0x05
+#define REG_DISPLAY_CONTROL_1 0x07
+#define REG_DISPLAY_CONTROL_2 0x08
+#define REG_DISPLAY_CONTROL_3 0x09
+#define REG_FRAME_CYCLE_CONTROL 0x0B
+#define REG_EXT_INTF_CONTROL 0x0C
+#define REG_POWER_CONTROL_1 0x10
+#define REG_POWER_CONTROL_2 0x11
+#define REG_POWER_CONTROL_3 0x12
+#define REG_POWER_CONTROL_4 0x13
+#define REG_RAM_ADDRESS_SET 0x21
+#define REG_WRITE_DATA_TO_GRAM 0x22
+#define REG_RAM_WRITE_MASK1 0x23
+#define REG_RAM_WRITE_MASK2 0x24
+#define REG_GAMMA_CONTROL_1 0x30
+#define REG_GAMMA_CONTROL_2 0x31
+#define REG_GAMMA_CONTROL_3 0x32
+#define REG_GAMMA_CONTROL_4 0x33
+#define REG_GAMMA_CONTROL_5 0x34
+#define REG_GAMMA_CONTROL_6 0x35
+#define REG_GAMMA_CONTROL_7 0x36
+#define REG_GAMMA_CONTROL_8 0x37
+#define REG_GAMMA_CONTROL_9 0x38
+#define REG_GAMMA_CONTROL_10 0x39
+#define REG_GATE_SCAN_CONTROL 0x40
+#define REG_VERT_SCROLL_CONTROL 0x41
+#define REG_FIRST_SCREEN_DRIVE_POS 0x42
+#define REG_SECOND_SCREEN_DRIVE_POS 0x43
+#define REG_RAM_ADDR_POS_H 0x44
+#define REG_RAM_ADDR_POS_V 0x45
+#define REG_OSCILLATOR_CONTROL 0x4F
+#define REG_GPIO 0x60
+#define REG_OTP_VCM_PROGRAMMING 0x61
+#define REG_OTP_VCM_STATUS_ENABLE 0x62
+#define REG_OTP_PROGRAMMING_ID_KEY 0x65
+
+/*
+ * maximum frequency for register access
+ * (not for the GRAM access)
+ */
+#define ILITEK_MAX_FREQ_REG 4000000
+
+/*
+ * Device ID as found in the datasheet (supports 9221 and 9222)
+ */
+#define ILITEK_DEVICE_ID 0x9220
+#define ILITEK_DEVICE_ID_MASK 0xFFF0
+
+/* Last two bits in the START BYTE */
+#define START_RS_INDEX 0
+#define START_RS_REG 1
+#define START_RW_WRITE 0
+#define START_RW_READ 1
+
+/**
+ * START_BYTE(id, rs, rw)
+ *
+ * Set the start byte according to the required operation.
+ * The start byte is defined as:
+ * ----------------------------------
+ * | 0 | 1 | 1 | 1 | 0 | ID | RS | RW |
+ * ----------------------------------
+ * @id: display's id as set by the manufacturer
+ * @rs: operation type bit, one of:
+ * - START_RS_INDEX set the index register
+ * - START_RS_REG write/read registers/GRAM
+ * @rw: read/write operation
+ * - START_RW_WRITE write
+ * - START_RW_READ read
+ */
+#define START_BYTE(id, rs, rw) \
+ (0x70 | (((id) & 0x01) << 2) | (((rs) & 0x01) << 1) | ((rw) & 0x01))
+
+/**
+ * CHECK_FREQ_REG(spi_device s, spi_transfer x) - Check the frequency
+ * for the SPI transfer. According to the datasheet, the controller
+ * accept higher frequency for the GRAM transfer, but it requires
+ * lower frequency when the registers are read/written.
+ * The macro sets the frequency in the spi_transfer structure if
+ * the frequency exceeds the maximum value.
+ */
+#define CHECK_FREQ_REG(s, x) \
+ do { \
+ if (s->max_speed_hz > ILITEK_MAX_FREQ_REG) \
+ ((struct spi_transfer *)x)->speed_hz = \
+ ILITEK_MAX_FREQ_REG; \
+ } while (0)
+
+#define CMD_BUFSIZE 16
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define set_tx_byte(b) (tx_invert ? ~(b) : b)
+
+/**
+ * ili922x_id - id as set by manufacturer
+ */
+static int ili922x_id = 1;
+module_param(ili922x_id, int, 0);
+
+static int tx_invert;
+module_param(tx_invert, int, 0);
+
+/**
+ * driver's private structure
+ */
+struct ili922x {
+ struct spi_device *spi;
+ struct lcd_device *ld;
+ int power;
+};
+
+/**
+ * ili922x_read_status - read status register from display
+ * @spi: spi device
+ * @rs: output value
+ */
+static int ili922x_read_status(struct spi_device *spi, u16 *rs)
+{
+ struct spi_message msg;
+ struct spi_transfer xfer;
+ unsigned char tbuf[CMD_BUFSIZE];
+ unsigned char rbuf[CMD_BUFSIZE];
+ int ret, i;
+
+ memset(&xfer, 0, sizeof(struct spi_transfer));
+ spi_message_init(&msg);
+ xfer.tx_buf = tbuf;
+ xfer.rx_buf = rbuf;
+ xfer.cs_change = 1;
+ CHECK_FREQ_REG(spi, &xfer);
+
+ tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_INDEX,
+ START_RW_READ));
+ /*
+ * we need 4-byte xfer here due to invalid dummy byte
+ * received after start byte
+ */
+ for (i = 1; i < 4; i++)
+ tbuf[i] = set_tx_byte(0); /* dummy */
+
+ xfer.bits_per_word = 8;
+ xfer.len = 4;
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(spi, &msg);
+ if (ret < 0) {
+ dev_dbg(&spi->dev, "Error sending SPI message 0x%x", ret);
+ return ret;
+ }
+
+ *rs = (rbuf[2] << 8) + rbuf[3];
+ return 0;
+}
+
+/**
+ * ili922x_read - read register from display
+ * @spi: spi device
+ * @reg: offset of the register to be read
+ * @rx: output value
+ */
+static int ili922x_read(struct spi_device *spi, u8 reg, u16 *rx)
+{
+ struct spi_message msg;
+ struct spi_transfer xfer_regindex, xfer_regvalue;
+ unsigned char tbuf[CMD_BUFSIZE];
+ unsigned char rbuf[CMD_BUFSIZE];
+ int ret, len = 0, send_bytes;
+
+ memset(&xfer_regindex, 0, sizeof(struct spi_transfer));
+ memset(&xfer_regvalue, 0, sizeof(struct spi_transfer));
+ spi_message_init(&msg);
+ xfer_regindex.tx_buf = tbuf;
+ xfer_regindex.rx_buf = rbuf;
+ xfer_regindex.cs_change = 1;
+ CHECK_FREQ_REG(spi, &xfer_regindex);
+
+ tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_INDEX,
+ START_RW_WRITE));
+ tbuf[1] = set_tx_byte(0);
+ tbuf[2] = set_tx_byte(reg);
+ xfer_regindex.bits_per_word = 8;
+ len = xfer_regindex.len = 3;
+ spi_message_add_tail(&xfer_regindex, &msg);
+
+ send_bytes = len;
+
+ tbuf[len++] = set_tx_byte(START_BYTE(ili922x_id, START_RS_REG,
+ START_RW_READ));
+ tbuf[len++] = set_tx_byte(0);
+ tbuf[len] = set_tx_byte(0);
+
+ xfer_regvalue.cs_change = 1;
+ xfer_regvalue.len = 3;
+ xfer_regvalue.tx_buf = &tbuf[send_bytes];
+ xfer_regvalue.rx_buf = &rbuf[send_bytes];
+ CHECK_FREQ_REG(spi, &xfer_regvalue);
+
+ spi_message_add_tail(&xfer_regvalue, &msg);
+ ret = spi_sync(spi, &msg);
+ if (ret < 0) {
+ dev_dbg(&spi->dev, "Error sending SPI message 0x%x", ret);
+ return ret;
+ }
+
+ *rx = (rbuf[1 + send_bytes] << 8) + rbuf[2 + send_bytes];
+ return 0;
+}
+
+/**
+ * ili922x_write - write a controller register
+ * @spi: struct spi_device *
+ * @reg: offset of the register to be written
+ * @value: value to be written
+ */
+static int ili922x_write(struct spi_device *spi, u8 reg, u16 value)
+{
+ struct spi_message msg;
+ struct spi_transfer xfer_regindex, xfer_regvalue;
+ unsigned char tbuf[CMD_BUFSIZE];
+ unsigned char rbuf[CMD_BUFSIZE];
+ int ret, len = 0;
+
+ memset(&xfer_regindex, 0, sizeof(struct spi_transfer));
+ memset(&xfer_regvalue, 0, sizeof(struct spi_transfer));
+
+ spi_message_init(&msg);
+ xfer_regindex.tx_buf = tbuf;
+ xfer_regindex.rx_buf = rbuf;
+ xfer_regindex.cs_change = 1;
+ CHECK_FREQ_REG(spi, &xfer_regindex);
+
+ tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_INDEX,
+ START_RW_WRITE));
+ tbuf[1] = set_tx_byte(0);
+ tbuf[2] = set_tx_byte(reg);
+ xfer_regindex.bits_per_word = 8;
+ xfer_regindex.len = 3;
+ spi_message_add_tail(&xfer_regindex, &msg);
+
+ ret = spi_sync(spi, &msg);
+
+ spi_message_init(&msg);
+ len = 0;
+ tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_REG,
+ START_RW_WRITE));
+ tbuf[1] = set_tx_byte((value & 0xFF00) >> 8);
+ tbuf[2] = set_tx_byte(value & 0x00FF);
+
+ xfer_regvalue.cs_change = 1;
+ xfer_regvalue.len = 3;
+ xfer_regvalue.tx_buf = tbuf;
+ xfer_regvalue.rx_buf = rbuf;
+ CHECK_FREQ_REG(spi, &xfer_regvalue);
+
+ spi_message_add_tail(&xfer_regvalue, &msg);
+
+ ret = spi_sync(spi, &msg);
+ if (ret < 0) {
+ dev_err(&spi->dev, "Error sending SPI message 0x%x", ret);
+ return ret;
+ }
+ return 0;
+}
+
+#ifdef DEBUG
+/**
+ * ili922x_reg_dump - dump all registers
+ */
+static void ili922x_reg_dump(struct spi_device *spi)
+{
+ u8 reg;
+ u16 rx;
+
+ dev_dbg(&spi->dev, "ILI922x configuration registers:\n");
+ for (reg = REG_START_OSCILLATION;
+ reg <= REG_OTP_PROGRAMMING_ID_KEY; reg++) {
+ ili922x_read(spi, reg, &rx);
+ dev_dbg(&spi->dev, "reg @ 0x%02X: 0x%04X\n", reg, rx);
+ }
+}
+#else
+static inline void ili922x_reg_dump(struct spi_device *spi) {}
+#endif
+
+/**
+ * set_write_to_gram_reg - initialize the display to write the GRAM
+ * @spi: spi device
+ */
+static void set_write_to_gram_reg(struct spi_device *spi)
+{
+ struct spi_message msg;
+ struct spi_transfer xfer;
+ unsigned char tbuf[CMD_BUFSIZE];
+
+ memset(&xfer, 0, sizeof(struct spi_transfer));
+
+ spi_message_init(&msg);
+ xfer.tx_buf = tbuf;
+ xfer.rx_buf = NULL;
+ xfer.cs_change = 1;
+
+ tbuf[0] = START_BYTE(ili922x_id, START_RS_INDEX, START_RW_WRITE);
+ tbuf[1] = 0;
+ tbuf[2] = REG_WRITE_DATA_TO_GRAM;
+
+ xfer.bits_per_word = 8;
+ xfer.len = 3;
+ spi_message_add_tail(&xfer, &msg);
+ spi_sync(spi, &msg);
+}
+
+/**
+ * ili922x_poweron - turn the display on
+ * @spi: spi device
+ *
+ * The sequence to turn on the display is taken from
+ * the datasheet and/or the example code provided by the
+ * manufacturer.
+ */
+static int ili922x_poweron(struct spi_device *spi)
+{
+ int ret;
+
+ /* Power on */
+ ret = ili922x_write(spi, REG_POWER_CONTROL_1, 0x0000);
+ usleep_range(10000, 10500);
+ ret += ili922x_write(spi, REG_POWER_CONTROL_2, 0x0000);
+ ret += ili922x_write(spi, REG_POWER_CONTROL_3, 0x0000);
+ msleep(40);
+ ret += ili922x_write(spi, REG_POWER_CONTROL_4, 0x0000);
+ msleep(40);
+ /* register 0x56 is not documented in the datasheet */
+ ret += ili922x_write(spi, 0x56, 0x080F);
+ ret += ili922x_write(spi, REG_POWER_CONTROL_1, 0x4240);
+ usleep_range(10000, 10500);
+ ret += ili922x_write(spi, REG_POWER_CONTROL_2, 0x0000);
+ ret += ili922x_write(spi, REG_POWER_CONTROL_3, 0x0014);
+ msleep(40);
+ ret += ili922x_write(spi, REG_POWER_CONTROL_4, 0x1319);
+ msleep(40);
+
+ return ret;
+}
+
+/**
+ * ili922x_poweroff - turn the display off
+ * @spi: spi device
+ */
+static int ili922x_poweroff(struct spi_device *spi)
+{
+ int ret;
+
+ /* Power off */
+ ret = ili922x_write(spi, REG_POWER_CONTROL_1, 0x0000);
+ usleep_range(10000, 10500);
+ ret += ili922x_write(spi, REG_POWER_CONTROL_2, 0x0000);
+ ret += ili922x_write(spi, REG_POWER_CONTROL_3, 0x0000);
+ msleep(40);
+ ret += ili922x_write(spi, REG_POWER_CONTROL_4, 0x0000);
+ msleep(40);
+
+ return ret;
+}
+
+/**
+ * ili922x_display_init - initialize the display by setting
+ * the configuration registers
+ * @spi: spi device
+ */
+static void ili922x_display_init(struct spi_device *spi)
+{
+ ili922x_write(spi, REG_START_OSCILLATION, 1);
+ usleep_range(10000, 10500);
+ ili922x_write(spi, REG_DRIVER_OUTPUT_CONTROL, 0x691B);
+ ili922x_write(spi, REG_LCD_AC_DRIVEING_CONTROL, 0x0700);
+ ili922x_write(spi, REG_ENTRY_MODE, 0x1030);
+ ili922x_write(spi, REG_COMPARE_1, 0x0000);
+ ili922x_write(spi, REG_COMPARE_2, 0x0000);
+ ili922x_write(spi, REG_DISPLAY_CONTROL_1, 0x0037);
+ ili922x_write(spi, REG_DISPLAY_CONTROL_2, 0x0202);
+ ili922x_write(spi, REG_DISPLAY_CONTROL_3, 0x0000);
+ ili922x_write(spi, REG_FRAME_CYCLE_CONTROL, 0x0000);
+
+ /* Set RGB interface */
+ ili922x_write(spi, REG_EXT_INTF_CONTROL, 0x0110);
+
+ ili922x_poweron(spi);
+
+ ili922x_write(spi, REG_GAMMA_CONTROL_1, 0x0302);
+ ili922x_write(spi, REG_GAMMA_CONTROL_2, 0x0407);
+ ili922x_write(spi, REG_GAMMA_CONTROL_3, 0x0304);
+ ili922x_write(spi, REG_GAMMA_CONTROL_4, 0x0203);
+ ili922x_write(spi, REG_GAMMA_CONTROL_5, 0x0706);
+ ili922x_write(spi, REG_GAMMA_CONTROL_6, 0x0407);
+ ili922x_write(spi, REG_GAMMA_CONTROL_7, 0x0706);
+ ili922x_write(spi, REG_GAMMA_CONTROL_8, 0x0000);
+ ili922x_write(spi, REG_GAMMA_CONTROL_9, 0x0C06);
+ ili922x_write(spi, REG_GAMMA_CONTROL_10, 0x0F00);
+ ili922x_write(spi, REG_RAM_ADDRESS_SET, 0x0000);
+ ili922x_write(spi, REG_GATE_SCAN_CONTROL, 0x0000);
+ ili922x_write(spi, REG_VERT_SCROLL_CONTROL, 0x0000);
+ ili922x_write(spi, REG_FIRST_SCREEN_DRIVE_POS, 0xDB00);
+ ili922x_write(spi, REG_SECOND_SCREEN_DRIVE_POS, 0xDB00);
+ ili922x_write(spi, REG_RAM_ADDR_POS_H, 0xAF00);
+ ili922x_write(spi, REG_RAM_ADDR_POS_V, 0xDB00);
+ ili922x_reg_dump(spi);
+ set_write_to_gram_reg(spi);
+}
+
+static int ili922x_lcd_power(struct ili922x *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = ili922x_poweron(lcd->spi);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = ili922x_poweroff(lcd->spi);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int ili922x_set_power(struct lcd_device *ld, int power)
+{
+ struct ili922x *ili = lcd_get_data(ld);
+
+ return ili922x_lcd_power(ili, power);
+}
+
+static int ili922x_get_power(struct lcd_device *ld)
+{
+ struct ili922x *ili = lcd_get_data(ld);
+
+ return ili->power;
+}
+
+static struct lcd_ops ili922x_ops = {
+ .get_power = ili922x_get_power,
+ .set_power = ili922x_set_power,
+};
+
+static int ili922x_probe(struct spi_device *spi)
+{
+ struct ili922x *ili;
+ struct lcd_device *lcd;
+ int ret;
+ u16 reg = 0;
+
+ ili = devm_kzalloc(&spi->dev, sizeof(*ili), GFP_KERNEL);
+ if (!ili) {
+ dev_err(&spi->dev, "cannot alloc priv data\n");
+ return -ENOMEM;
+ }
+
+ ili->spi = spi;
+ spi_set_drvdata(spi, ili);
+
+ /* check if the device is connected */
+ ret = ili922x_read(spi, REG_DRIVER_CODE_READ, &reg);
+ if (ret || ((reg & ILITEK_DEVICE_ID_MASK) != ILITEK_DEVICE_ID)) {
+ dev_err(&spi->dev,
+ "no LCD found: Chip ID 0x%x, ret %d\n",
+ reg, ret);
+ return -ENODEV;
+ } else {
+ dev_info(&spi->dev, "ILI%x found, SPI freq %d, mode %d\n",
+ reg, spi->max_speed_hz, spi->mode);
+ }
+
+ ret = ili922x_read_status(spi, &reg);
+ if (ret) {
+ dev_err(&spi->dev, "reading RS failed...\n");
+ return ret;
+ } else
+ dev_dbg(&spi->dev, "status: 0x%x\n", reg);
+
+ ili922x_display_init(spi);
+
+ ili->power = FB_BLANK_POWERDOWN;
+
+ lcd = lcd_device_register("ili922xlcd", &spi->dev, ili,
+ &ili922x_ops);
+ if (IS_ERR(lcd)) {
+ dev_err(&spi->dev, "cannot register LCD\n");
+ return PTR_ERR(lcd);
+ }
+
+ ili->ld = lcd;
+ spi_set_drvdata(spi, ili);
+
+ ili922x_lcd_power(ili, FB_BLANK_UNBLANK);
+
+ return 0;
+}
+
+static int ili922x_remove(struct spi_device *spi)
+{
+ struct ili922x *ili = spi_get_drvdata(spi);
+
+ ili922x_poweroff(spi);
+ lcd_device_unregister(ili->ld);
+ return 0;
+}
+
+static struct spi_driver ili922x_driver = {
+ .driver = {
+ .name = "ili922x",
+ .owner = THIS_MODULE,
+ },
+ .probe = ili922x_probe,
+ .remove = ili922x_remove,
+};
+
+module_spi_driver(ili922x_driver);
+
+MODULE_AUTHOR("Stefano Babic <sbabic@denx.de>");
+MODULE_DESCRIPTION("ILI9221/9222 LCD driver");
+MODULE_LICENSE("GPL");
+MODULE_PARM_DESC(ili922x_id, "set controller identifier (default=1)");
+MODULE_PARM_DESC(tx_invert, "invert bytes before sending");
diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c
index 1235bf9defc4..c3a529966dd0 100644
--- a/drivers/video/backlight/ili9320.c
+++ b/drivers/video/backlight/ili9320.c
@@ -231,7 +231,7 @@ int ili9320_probe_spi(struct spi_device *spi,
ili->power = FB_BLANK_POWERDOWN;
ili->platdata = cfg;
- dev_set_drvdata(&spi->dev, ili);
+ spi_set_drvdata(spi, ili);
ili9320_setup_spi(ili, spi);
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c
index fef6ce4fad71..3ccb89340f22 100644
--- a/drivers/video/backlight/jornada720_bl.c
+++ b/drivers/video/backlight/jornada720_bl.c
@@ -9,8 +9,6 @@
*
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/backlight.h>
#include <linux/device.h>
#include <linux/fb.h>
@@ -40,11 +38,13 @@ static int jornada_bl_get_brightness(struct backlight_device *bd)
ret = jornada_ssp_byte(GETBRIGHTNESS);
if (jornada_ssp_byte(GETBRIGHTNESS) != TXDUMMY) {
- pr_err("get brightness timeout\n");
+ dev_err(&bd->dev, "get brightness timeout\n");
jornada_ssp_end();
return -ETIMEDOUT;
- } else /* exchange txdummy for value */
+ } else {
+ /* exchange txdummy for value */
ret = jornada_ssp_byte(TXDUMMY);
+ }
jornada_ssp_end();
@@ -61,7 +61,7 @@ static int jornada_bl_update_status(struct backlight_device *bd)
if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
ret = jornada_ssp_byte(BRIGHTNESSOFF);
if (ret != TXDUMMY) {
- pr_info("brightness off timeout\n");
+ dev_info(&bd->dev, "brightness off timeout\n");
/* turn off backlight */
PPSR &= ~PPC_LDD1;
PPDR |= PPC_LDD1;
@@ -72,7 +72,7 @@ static int jornada_bl_update_status(struct backlight_device *bd)
/* send command to our mcu */
if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) {
- pr_info("failed to set brightness\n");
+ dev_info(&bd->dev, "failed to set brightness\n");
ret = -ETIMEDOUT;
goto out;
}
@@ -86,7 +86,7 @@ static int jornada_bl_update_status(struct backlight_device *bd)
*/
if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness)
!= TXDUMMY) {
- pr_err("set brightness failed\n");
+ dev_err(&bd->dev, "set brightness failed\n");
ret = -ETIMEDOUT;
}
@@ -120,7 +120,7 @@ static int jornada_bl_probe(struct platform_device *pdev)
if (IS_ERR(bd)) {
ret = PTR_ERR(bd);
- pr_err("failed to register device, err=%x\n", ret);
+ dev_err(&pdev->dev, "failed to register device, err=%x\n", ret);
return ret;
}
@@ -134,7 +134,7 @@ static int jornada_bl_probe(struct platform_device *pdev)
jornada_bl_update_status(bd);
platform_set_drvdata(pdev, bd);
- pr_info("HP Jornada 700 series backlight driver\n");
+ dev_info(&pdev->dev, "HP Jornada 700 series backlight driver\n");
return 0;
}
diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c
index 635b30523fd5..b061413f1a65 100644
--- a/drivers/video/backlight/jornada720_lcd.c
+++ b/drivers/video/backlight/jornada720_lcd.c
@@ -9,8 +9,6 @@
*
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/kernel.h>
@@ -27,7 +25,7 @@
#define LCD_MAX_CONTRAST 0xff
#define LCD_DEF_CONTRAST 0x80
-static int jornada_lcd_get_power(struct lcd_device *dev)
+static int jornada_lcd_get_power(struct lcd_device *ld)
{
/* LDD2 in PPC = LCD POWER */
if (PPSR & PPC_LDD2)
@@ -36,17 +34,17 @@ static int jornada_lcd_get_power(struct lcd_device *dev)
return FB_BLANK_POWERDOWN; /* PW OFF */
}
-static int jornada_lcd_get_contrast(struct lcd_device *dev)
+static int jornada_lcd_get_contrast(struct lcd_device *ld)
{
int ret;
- if (jornada_lcd_get_power(dev) != FB_BLANK_UNBLANK)
+ if (jornada_lcd_get_power(ld) != FB_BLANK_UNBLANK)
return 0;
jornada_ssp_start();
if (jornada_ssp_byte(GETCONTRAST) != TXDUMMY) {
- pr_err("get contrast failed\n");
+ dev_err(&ld->dev, "get contrast failed\n");
jornada_ssp_end();
return -ETIMEDOUT;
} else {
@@ -56,7 +54,7 @@ static int jornada_lcd_get_contrast(struct lcd_device *dev)
}
}
-static int jornada_lcd_set_contrast(struct lcd_device *dev, int value)
+static int jornada_lcd_set_contrast(struct lcd_device *ld, int value)
{
int ret;
@@ -67,7 +65,7 @@ static int jornada_lcd_set_contrast(struct lcd_device *dev, int value)
/* push the new value */
if (jornada_ssp_byte(value) != TXDUMMY) {
- pr_err("set contrast failed\n");
+ dev_err(&ld->dev, "set contrast failed\n");
jornada_ssp_end();
return -ETIMEDOUT;
}
@@ -78,13 +76,14 @@ static int jornada_lcd_set_contrast(struct lcd_device *dev, int value)
return 0;
}
-static int jornada_lcd_set_power(struct lcd_device *dev, int power)
+static int jornada_lcd_set_power(struct lcd_device *ld, int power)
{
if (power != FB_BLANK_UNBLANK) {
PPSR &= ~PPC_LDD2;
PPDR |= PPC_LDD2;
- } else
+ } else {
PPSR |= PPC_LDD2;
+ }
return 0;
}
@@ -105,7 +104,7 @@ static int jornada_lcd_probe(struct platform_device *pdev)
if (IS_ERR(lcd_device)) {
ret = PTR_ERR(lcd_device);
- pr_err("failed to register device\n");
+ dev_err(&pdev->dev, "failed to register device\n");
return ret;
}
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c
index 6c5ed6b242cc..bca6ccc74dfb 100644
--- a/drivers/video/backlight/kb3886_bl.c
+++ b/drivers/video/backlight/kb3886_bl.c
@@ -106,29 +106,28 @@ static int kb3886bl_send_intensity(struct backlight_device *bd)
return 0;
}
-#ifdef CONFIG_PM
-static int kb3886bl_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int kb3886bl_suspend(struct device *dev)
{
- struct backlight_device *bd = platform_get_drvdata(pdev);
+ struct backlight_device *bd = dev_get_drvdata(dev);
kb3886bl_flags |= KB3886BL_SUSPENDED;
backlight_update_status(bd);
return 0;
}
-static int kb3886bl_resume(struct platform_device *pdev)
+static int kb3886bl_resume(struct device *dev)
{
- struct backlight_device *bd = platform_get_drvdata(pdev);
+ struct backlight_device *bd = dev_get_drvdata(dev);
kb3886bl_flags &= ~KB3886BL_SUSPENDED;
backlight_update_status(bd);
return 0;
}
-#else
-#define kb3886bl_suspend NULL
-#define kb3886bl_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(kb3886bl_pm_ops, kb3886bl_suspend, kb3886bl_resume);
+
static int kb3886bl_get_intensity(struct backlight_device *bd)
{
return kb3886bl_intensity;
@@ -179,10 +178,9 @@ static int kb3886bl_remove(struct platform_device *pdev)
static struct platform_driver kb3886bl_driver = {
.probe = kb3886bl_probe,
.remove = kb3886bl_remove,
- .suspend = kb3886bl_suspend,
- .resume = kb3886bl_resume,
.driver = {
.name = "kb3886-bl",
+ .pm = &kb3886bl_pm_ops,
},
};
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
index fb6155771326..a35a38c709cf 100644
--- a/drivers/video/backlight/l4f00242t03.c
+++ b/drivers/video/backlight/l4f00242t03.c
@@ -51,14 +51,33 @@ static void l4f00242t03_lcd_init(struct spi_device *spi)
struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) };
+ int ret;
dev_dbg(&spi->dev, "initializing LCD\n");
- regulator_set_voltage(priv->io_reg, 1800000, 1800000);
- regulator_enable(priv->io_reg);
+ ret = regulator_set_voltage(priv->io_reg, 1800000, 1800000);
+ if (ret) {
+ dev_err(&spi->dev, "failed to set the IO regulator voltage.\n");
+ return;
+ }
+ ret = regulator_enable(priv->io_reg);
+ if (ret) {
+ dev_err(&spi->dev, "failed to enable the IO regulator.\n");
+ return;
+ }
- regulator_set_voltage(priv->core_reg, 2800000, 2800000);
- regulator_enable(priv->core_reg);
+ ret = regulator_set_voltage(priv->core_reg, 2800000, 2800000);
+ if (ret) {
+ dev_err(&spi->dev, "failed to set the core regulator voltage.\n");
+ regulator_disable(priv->io_reg);
+ return;
+ }
+ ret = regulator_enable(priv->core_reg);
+ if (ret) {
+ dev_err(&spi->dev, "failed to enable the core regulator.\n");
+ regulator_disable(priv->io_reg);
+ return;
+ }
l4f00242t03_reset(pdata->reset_gpio);
diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c
index 1b642f5f381a..1e0a3093ce50 100644
--- a/drivers/video/backlight/ld9040.c
+++ b/drivers/video/backlight/ld9040.c
@@ -775,12 +775,12 @@ static int ld9040_remove(struct spi_device *spi)
return 0;
}
-#if defined(CONFIG_PM)
-static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg)
+#ifdef CONFIG_PM_SLEEP
+static int ld9040_suspend(struct device *dev)
{
- struct ld9040 *lcd = spi_get_drvdata(spi);
+ struct ld9040 *lcd = dev_get_drvdata(dev);
- dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
+ dev_dbg(dev, "lcd->power = %d\n", lcd->power);
/*
* when lcd panel is suspend, lcd panel becomes off
@@ -789,19 +789,18 @@ static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg)
return ld9040_power(lcd, FB_BLANK_POWERDOWN);
}
-static int ld9040_resume(struct spi_device *spi)
+static int ld9040_resume(struct device *dev)
{
- struct ld9040 *lcd = spi_get_drvdata(spi);
+ struct ld9040 *lcd = dev_get_drvdata(dev);
lcd->power = FB_BLANK_POWERDOWN;
return ld9040_power(lcd, FB_BLANK_UNBLANK);
}
-#else
-#define ld9040_suspend NULL
-#define ld9040_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(ld9040_pm_ops, ld9040_suspend, ld9040_resume);
+
/* Power down all displays on reboot, poweroff or halt. */
static void ld9040_shutdown(struct spi_device *spi)
{
@@ -814,12 +813,11 @@ static struct spi_driver ld9040_driver = {
.driver = {
.name = "ld9040",
.owner = THIS_MODULE,
+ .pm = &ld9040_pm_ops,
},
.probe = ld9040_probe,
.remove = ld9040_remove,
.shutdown = ld9040_shutdown,
- .suspend = ld9040_suspend,
- .resume = ld9040_resume,
};
module_spi_driver(ld9040_driver);
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
index 5d18d4d7f470..1d1dbfb789e3 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -368,29 +368,28 @@ static int lm3533_bl_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
-static int lm3533_bl_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int lm3533_bl_suspend(struct device *dev)
{
- struct lm3533_bl *bl = platform_get_drvdata(pdev);
+ struct lm3533_bl *bl = dev_get_drvdata(dev);
- dev_dbg(&pdev->dev, "%s\n", __func__);
+ dev_dbg(dev, "%s\n", __func__);
return lm3533_ctrlbank_disable(&bl->cb);
}
-static int lm3533_bl_resume(struct platform_device *pdev)
+static int lm3533_bl_resume(struct device *dev)
{
- struct lm3533_bl *bl = platform_get_drvdata(pdev);
+ struct lm3533_bl *bl = dev_get_drvdata(dev);
- dev_dbg(&pdev->dev, "%s\n", __func__);
+ dev_dbg(dev, "%s\n", __func__);
return lm3533_ctrlbank_enable(&bl->cb);
}
-#else
-#define lm3533_bl_suspend NULL
-#define lm3533_bl_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(lm3533_bl_pm_ops, lm3533_bl_suspend, lm3533_bl_resume);
+
static void lm3533_bl_shutdown(struct platform_device *pdev)
{
struct lm3533_bl *bl = platform_get_drvdata(pdev);
@@ -404,12 +403,11 @@ static struct platform_driver lm3533_bl_driver = {
.driver = {
.name = "lm3533-backlight",
.owner = THIS_MODULE,
+ .pm = &lm3533_bl_pm_ops,
},
.probe = lm3533_bl_probe,
.remove = lm3533_bl_remove,
.shutdown = lm3533_bl_shutdown,
- .suspend = lm3533_bl_suspend,
- .resume = lm3533_bl_resume,
};
module_platform_driver(lm3533_bl_driver);
diff --git a/drivers/video/backlight/lms501kf03.c b/drivers/video/backlight/lms501kf03.c
index b43882abefaf..cf01b9ac8131 100644
--- a/drivers/video/backlight/lms501kf03.c
+++ b/drivers/video/backlight/lms501kf03.c
@@ -387,13 +387,12 @@ static int lms501kf03_remove(struct spi_device *spi)
return 0;
}
-#if defined(CONFIG_PM)
-
-static int lms501kf03_suspend(struct spi_device *spi, pm_message_t mesg)
+#ifdef CONFIG_PM_SLEEP
+static int lms501kf03_suspend(struct device *dev)
{
- struct lms501kf03 *lcd = spi_get_drvdata(spi);
+ struct lms501kf03 *lcd = dev_get_drvdata(dev);
- dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
+ dev_dbg(dev, "lcd->power = %d\n", lcd->power);
/*
* when lcd panel is suspend, lcd panel becomes off
@@ -402,19 +401,19 @@ static int lms501kf03_suspend(struct spi_device *spi, pm_message_t mesg)
return lms501kf03_power(lcd, FB_BLANK_POWERDOWN);
}
-static int lms501kf03_resume(struct spi_device *spi)
+static int lms501kf03_resume(struct device *dev)
{
- struct lms501kf03 *lcd = spi_get_drvdata(spi);
+ struct lms501kf03 *lcd = dev_get_drvdata(dev);
lcd->power = FB_BLANK_POWERDOWN;
return lms501kf03_power(lcd, FB_BLANK_UNBLANK);
}
-#else
-#define lms501kf03_suspend NULL
-#define lms501kf03_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(lms501kf03_pm_ops, lms501kf03_suspend,
+ lms501kf03_resume);
+
static void lms501kf03_shutdown(struct spi_device *spi)
{
struct lms501kf03 *lcd = spi_get_drvdata(spi);
@@ -426,12 +425,11 @@ static struct spi_driver lms501kf03_driver = {
.driver = {
.name = "lms501kf03",
.owner = THIS_MODULE,
+ .pm = &lms501kf03_pm_ops,
},
.probe = lms501kf03_probe,
.remove = lms501kf03_remove,
.shutdown = lms501kf03_shutdown,
- .suspend = lms501kf03_suspend,
- .resume = lms501kf03_resume,
};
module_spi_driver(lms501kf03_driver);
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index 146fea8aa431..6c3ec4259a60 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -157,25 +157,24 @@ static const struct backlight_ops locomobl_data = {
.update_status = locomolcd_set_intensity,
};
-#ifdef CONFIG_PM
-static int locomolcd_suspend(struct locomo_dev *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int locomolcd_suspend(struct device *dev)
{
locomolcd_flags |= LOCOMOLCD_SUSPENDED;
locomolcd_set_intensity(locomolcd_bl_device);
return 0;
}
-static int locomolcd_resume(struct locomo_dev *dev)
+static int locomolcd_resume(struct device *dev)
{
locomolcd_flags &= ~LOCOMOLCD_SUSPENDED;
locomolcd_set_intensity(locomolcd_bl_device);
return 0;
}
-#else
-#define locomolcd_suspend NULL
-#define locomolcd_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(locomolcd_pm_ops, locomolcd_suspend, locomolcd_resume);
+
static int locomolcd_probe(struct locomo_dev *ldev)
{
struct backlight_properties props;
@@ -230,13 +229,12 @@ static int locomolcd_remove(struct locomo_dev *dev)
static struct locomo_driver poodle_lcd_driver = {
.drv = {
- .name = "locomo-backlight",
+ .name = "locomo-backlight",
+ .pm = &locomolcd_pm_ops,
},
.devid = LOCOMO_DEVID_BACKLIGHT,
.probe = locomolcd_probe,
.remove = locomolcd_remove,
- .suspend = locomolcd_suspend,
- .resume = locomolcd_resume,
};
static int __init locomolcd_init(void)
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
index 7ae9ae6f4655..c98bdbfdc697 100644
--- a/drivers/video/backlight/lp855x_bl.c
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -35,7 +35,6 @@
#define LP8557_EPROM_START 0x10
#define LP8557_EPROM_END 0x1E
-#define BUF_SIZE 20
#define DEFAULT_BL_NAME "lcd-backlight"
#define MAX_BRIGHTNESS 255
@@ -304,7 +303,7 @@ static ssize_t lp855x_get_chip_id(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct lp855x *lp = dev_get_drvdata(dev);
- return scnprintf(buf, BUF_SIZE, "%s\n", lp->chipname);
+ return scnprintf(buf, PAGE_SIZE, "%s\n", lp->chipname);
}
static ssize_t lp855x_get_bl_ctl_mode(struct device *dev,
@@ -319,7 +318,7 @@ static ssize_t lp855x_get_bl_ctl_mode(struct device *dev,
else if (mode == REGISTER_BASED)
strmode = "register based";
- return scnprintf(buf, BUF_SIZE, "%s\n", strmode);
+ return scnprintf(buf, PAGE_SIZE, "%s\n", strmode);
}
static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL);
@@ -339,7 +338,6 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
struct lp855x *lp;
struct lp855x_platform_data *pdata = cl->dev.platform_data;
- enum lp855x_brightness_ctrl_mode mode;
int ret;
if (!pdata) {
@@ -354,7 +352,6 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
if (!lp)
return -ENOMEM;
- mode = pdata->mode;
lp->client = cl;
lp->dev = &cl->dev;
lp->pdata = pdata;
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index c0b4b8f2de98..ed1b39268131 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -271,25 +271,24 @@ static int ltv350qv_remove(struct spi_device *spi)
return 0;
}
-#ifdef CONFIG_PM
-static int ltv350qv_suspend(struct spi_device *spi, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int ltv350qv_suspend(struct device *dev)
{
- struct ltv350qv *lcd = spi_get_drvdata(spi);
+ struct ltv350qv *lcd = dev_get_drvdata(dev);
return ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
}
-static int ltv350qv_resume(struct spi_device *spi)
+static int ltv350qv_resume(struct device *dev)
{
- struct ltv350qv *lcd = spi_get_drvdata(spi);
+ struct ltv350qv *lcd = dev_get_drvdata(dev);
return ltv350qv_power(lcd, FB_BLANK_UNBLANK);
}
-#else
-#define ltv350qv_suspend NULL
-#define ltv350qv_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(ltv350qv_pm_ops, ltv350qv_suspend, ltv350qv_resume);
+
/* Power down all displays on reboot, poweroff or halt */
static void ltv350qv_shutdown(struct spi_device *spi)
{
@@ -302,13 +301,12 @@ static struct spi_driver ltv350qv_driver = {
.driver = {
.name = "ltv350qv",
.owner = THIS_MODULE,
+ .pm = &ltv350qv_pm_ops,
},
.probe = ltv350qv_probe,
.remove = ltv350qv_remove,
.shutdown = ltv350qv_shutdown,
- .suspend = ltv350qv_suspend,
- .resume = ltv350qv_resume,
};
module_spi_driver(ltv350qv_driver);
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index 627110163067..0aed176cd6a0 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -18,8 +18,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -170,7 +168,7 @@ static int omapbl_probe(struct platform_device *pdev)
dev->props.brightness = pdata->default_intensity;
omapbl_update_status(dev);
- pr_info("OMAP LCD backlight initialised\n");
+ dev_info(&pdev->dev, "OMAP LCD backlight initialised\n");
return 0;
}
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
index 17a6b83f97af..54d94de652b0 100644
--- a/drivers/video/backlight/platform_lcd.c
+++ b/drivers/video/backlight/platform_lcd.c
@@ -121,7 +121,7 @@ static int platform_lcd_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int platform_lcd_suspend(struct device *dev)
{
struct platform_lcd *plcd = dev_get_drvdata(dev);
@@ -141,10 +141,10 @@ static int platform_lcd_resume(struct device *dev)
return 0;
}
+#endif
static SIMPLE_DEV_PM_OPS(platform_lcd_pm_ops, platform_lcd_suspend,
platform_lcd_resume);
-#endif
#ifdef CONFIG_OF
static const struct of_device_id platform_lcd_of_match[] = {
@@ -158,9 +158,7 @@ static struct platform_driver platform_lcd_driver = {
.driver = {
.name = "platform-lcd",
.owner = THIS_MODULE,
-#ifdef CONFIG_PM
.pm = &platform_lcd_pm_ops,
-#endif
.of_match_table = of_match_ptr(platform_lcd_of_match),
},
.probe = platform_lcd_probe,
diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c
index 9c2677f0ef7d..b37bb1854bf4 100644
--- a/drivers/video/backlight/s6e63m0.c
+++ b/drivers/video/backlight/s6e63m0.c
@@ -817,12 +817,12 @@ static int s6e63m0_remove(struct spi_device *spi)
return 0;
}
-#if defined(CONFIG_PM)
-static int s6e63m0_suspend(struct spi_device *spi, pm_message_t mesg)
+#ifdef CONFIG_PM_SLEEP
+static int s6e63m0_suspend(struct device *dev)
{
- struct s6e63m0 *lcd = spi_get_drvdata(spi);
+ struct s6e63m0 *lcd = dev_get_drvdata(dev);
- dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
+ dev_dbg(dev, "lcd->power = %d\n", lcd->power);
/*
* when lcd panel is suspend, lcd panel becomes off
@@ -831,19 +831,18 @@ static int s6e63m0_suspend(struct spi_device *spi, pm_message_t mesg)
return s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
}
-static int s6e63m0_resume(struct spi_device *spi)
+static int s6e63m0_resume(struct device *dev)
{
- struct s6e63m0 *lcd = spi_get_drvdata(spi);
+ struct s6e63m0 *lcd = dev_get_drvdata(dev);
lcd->power = FB_BLANK_POWERDOWN;
return s6e63m0_power(lcd, FB_BLANK_UNBLANK);
}
-#else
-#define s6e63m0_suspend NULL
-#define s6e63m0_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(s6e63m0_pm_ops, s6e63m0_suspend, s6e63m0_resume);
+
/* Power down all displays on reboot, poweroff or halt. */
static void s6e63m0_shutdown(struct spi_device *spi)
{
@@ -856,12 +855,11 @@ static struct spi_driver s6e63m0_driver = {
.driver = {
.name = "s6e63m0",
.owner = THIS_MODULE,
+ .pm = &s6e63m0_pm_ops,
},
.probe = s6e63m0_probe,
.remove = s6e63m0_remove,
.shutdown = s6e63m0_shutdown,
- .suspend = s6e63m0_suspend,
- .resume = s6e63m0_resume,
};
module_spi_driver(s6e63m0_driver);
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c
index 00162085eec0..18cdf466d50a 100644
--- a/drivers/video/backlight/tdo24m.c
+++ b/drivers/video/backlight/tdo24m.c
@@ -412,25 +412,24 @@ static int tdo24m_remove(struct spi_device *spi)
return 0;
}
-#ifdef CONFIG_PM
-static int tdo24m_suspend(struct spi_device *spi, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int tdo24m_suspend(struct device *dev)
{
- struct tdo24m *lcd = spi_get_drvdata(spi);
+ struct tdo24m *lcd = dev_get_drvdata(dev);
return tdo24m_power(lcd, FB_BLANK_POWERDOWN);
}
-static int tdo24m_resume(struct spi_device *spi)
+static int tdo24m_resume(struct device *dev)
{
- struct tdo24m *lcd = spi_get_drvdata(spi);
+ struct tdo24m *lcd = dev_get_drvdata(dev);
return tdo24m_power(lcd, FB_BLANK_UNBLANK);
}
-#else
-#define tdo24m_suspend NULL
-#define tdo24m_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(tdo24m_pm_ops, tdo24m_suspend, tdo24m_resume);
+
/* Power down all displays on reboot, poweroff or halt */
static void tdo24m_shutdown(struct spi_device *spi)
{
@@ -443,12 +442,11 @@ static struct spi_driver tdo24m_driver = {
.driver = {
.name = "tdo24m",
.owner = THIS_MODULE,
+ .pm = &tdo24m_pm_ops,
},
.probe = tdo24m_probe,
.remove = tdo24m_remove,
.shutdown = tdo24m_shutdown,
- .suspend = tdo24m_suspend,
- .resume = tdo24m_resume,
};
module_spi_driver(tdo24m_driver);
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index 6a737827beb1..a93670ef7f89 100644
--- a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -27,7 +27,7 @@ static void cw_update_attr(u8 *dst, u8 *src, int attribute,
{
int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
int width = (vc->vc_font.height + 7) >> 3;
- u8 c, t = 0, msk = ~(0xff >> offset);
+ u8 c, msk = ~(0xff >> offset);
for (i = 0; i < vc->vc_font.width; i++) {
for (j = 0; j < width; j++) {
@@ -40,7 +40,6 @@ static void cw_update_attr(u8 *dst, u8 *src, int attribute,
c = ~c;
src++;
*dst++ = c;
- t = c;
}
}
}
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 57886787ead0..e78d9f2233b8 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -518,6 +518,9 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
cyber2000_grphw(0xb9, 0x00, cfb);
spin_unlock(&cfb->reg_b0_lock);
+ /* wait (for the PLL?) to avoid palette corruption at higher clocks */
+ msleep(1000);
+
cfb->ramdac_ctrl = hw->ramdac;
cyber2000fb_write_ramdac_ctrl(cfb);
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
index e06cd5d90c97..ee1ee5401544 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/ep93xx-fb.c
@@ -419,7 +419,7 @@ static struct fb_ops ep93xxfb_ops = {
.fb_mmap = ep93xxfb_mmap,
};
-static int __init ep93xxfb_calc_fbsize(struct ep93xxfb_mach_info *mach_info)
+static int ep93xxfb_calc_fbsize(struct ep93xxfb_mach_info *mach_info)
{
int i, fb_size = 0;
@@ -441,7 +441,7 @@ static int __init ep93xxfb_calc_fbsize(struct ep93xxfb_mach_info *mach_info)
return fb_size;
}
-static int __init ep93xxfb_alloc_videomem(struct fb_info *info)
+static int ep93xxfb_alloc_videomem(struct fb_info *info)
{
struct ep93xx_fbi *fbi = info->par;
char __iomem *virt_addr;
@@ -627,19 +627,7 @@ static struct platform_driver ep93xxfb_driver = {
.owner = THIS_MODULE,
},
};
-
-static int ep93xxfb_init(void)
-{
- return platform_driver_register(&ep93xxfb_driver);
-}
-
-static void __exit ep93xxfb_exit(void)
-{
- platform_driver_unregister(&ep93xxfb_driver);
-}
-
-module_init(ep93xxfb_init);
-module_exit(ep93xxfb_exit);
+module_platform_driver(ep93xxfb_driver);
MODULE_DESCRIPTION("EP93XX Framebuffer Driver");
MODULE_ALIAS("platform:ep93xx-fb");
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index fac7df6d1aba..87cd13b5dee6 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -32,6 +32,7 @@
#include <linux/notifier.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
+#include <linux/err.h>
#include <video/exynos_mipi_dsim.h>
@@ -384,10 +385,9 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dsim->reg_base = devm_request_and_ioremap(&pdev->dev, res);
- if (!dsim->reg_base) {
- dev_err(&pdev->dev, "failed to remap io region\n");
- ret = -ENOMEM;
+ dsim->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dsim->reg_base)) {
+ ret = PTR_ERR(dsim->reg_base);
goto error;
}
diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c
new file mode 100644
index 000000000000..d4d2c5fe2488
--- /dev/null
+++ b/drivers/video/hyperv_fb.c
@@ -0,0 +1,829 @@
+/*
+ * Copyright (c) 2012, Microsoft Corporation.
+ *
+ * Author:
+ * Haiyang Zhang <haiyangz@microsoft.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ */
+
+/*
+ * Hyper-V Synthetic Video Frame Buffer Driver
+ *
+ * This is the driver for the Hyper-V Synthetic Video, which supports
+ * screen resolution up to Full HD 1920x1080 with 32 bit color on Windows
+ * Server 2012, and 1600x1200 with 16 bit color on Windows Server 2008 R2
+ * or earlier.
+ *
+ * It also solves the double mouse cursor issue of the emulated video mode.
+ *
+ * The default screen resolution is 1152x864, which may be changed by a
+ * kernel parameter:
+ * video=hyperv_fb:<width>x<height>
+ * For example: video=hyperv_fb:1280x1024
+ *
+ * Portrait orientation is also supported:
+ * For example: video=hyperv_fb:864x1152
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/completion.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+
+#include <linux/hyperv.h>
+
+
+/* Hyper-V Synthetic Video Protocol definitions and structures */
+#define MAX_VMBUS_PKT_SIZE 0x4000
+
+#define SYNTHVID_VERSION(major, minor) ((minor) << 16 | (major))
+#define SYNTHVID_VERSION_WIN7 SYNTHVID_VERSION(3, 0)
+#define SYNTHVID_VERSION_WIN8 SYNTHVID_VERSION(3, 2)
+
+#define SYNTHVID_DEPTH_WIN7 16
+#define SYNTHVID_DEPTH_WIN8 32
+
+#define SYNTHVID_FB_SIZE_WIN7 (4 * 1024 * 1024)
+#define SYNTHVID_WIDTH_MAX_WIN7 1600
+#define SYNTHVID_HEIGHT_MAX_WIN7 1200
+
+#define SYNTHVID_FB_SIZE_WIN8 (8 * 1024 * 1024)
+
+#define PCI_VENDOR_ID_MICROSOFT 0x1414
+#define PCI_DEVICE_ID_HYPERV_VIDEO 0x5353
+
+
+enum pipe_msg_type {
+ PIPE_MSG_INVALID,
+ PIPE_MSG_DATA,
+ PIPE_MSG_MAX
+};
+
+struct pipe_msg_hdr {
+ u32 type;
+ u32 size; /* size of message after this field */
+} __packed;
+
+
+enum synthvid_msg_type {
+ SYNTHVID_ERROR = 0,
+ SYNTHVID_VERSION_REQUEST = 1,
+ SYNTHVID_VERSION_RESPONSE = 2,
+ SYNTHVID_VRAM_LOCATION = 3,
+ SYNTHVID_VRAM_LOCATION_ACK = 4,
+ SYNTHVID_SITUATION_UPDATE = 5,
+ SYNTHVID_SITUATION_UPDATE_ACK = 6,
+ SYNTHVID_POINTER_POSITION = 7,
+ SYNTHVID_POINTER_SHAPE = 8,
+ SYNTHVID_FEATURE_CHANGE = 9,
+ SYNTHVID_DIRT = 10,
+
+ SYNTHVID_MAX = 11
+};
+
+struct synthvid_msg_hdr {
+ u32 type;
+ u32 size; /* size of this header + payload after this field*/
+} __packed;
+
+
+struct synthvid_version_req {
+ u32 version;
+} __packed;
+
+struct synthvid_version_resp {
+ u32 version;
+ u8 is_accepted;
+ u8 max_video_outputs;
+} __packed;
+
+struct synthvid_vram_location {
+ u64 user_ctx;
+ u8 is_vram_gpa_specified;
+ u64 vram_gpa;
+} __packed;
+
+struct synthvid_vram_location_ack {
+ u64 user_ctx;
+} __packed;
+
+struct video_output_situation {
+ u8 active;
+ u32 vram_offset;
+ u8 depth_bits;
+ u32 width_pixels;
+ u32 height_pixels;
+ u32 pitch_bytes;
+} __packed;
+
+struct synthvid_situation_update {
+ u64 user_ctx;
+ u8 video_output_count;
+ struct video_output_situation video_output[1];
+} __packed;
+
+struct synthvid_situation_update_ack {
+ u64 user_ctx;
+} __packed;
+
+struct synthvid_pointer_position {
+ u8 is_visible;
+ u8 video_output;
+ s32 image_x;
+ s32 image_y;
+} __packed;
+
+
+#define CURSOR_MAX_X 96
+#define CURSOR_MAX_Y 96
+#define CURSOR_ARGB_PIXEL_SIZE 4
+#define CURSOR_MAX_SIZE (CURSOR_MAX_X * CURSOR_MAX_Y * CURSOR_ARGB_PIXEL_SIZE)
+#define CURSOR_COMPLETE (-1)
+
+struct synthvid_pointer_shape {
+ u8 part_idx;
+ u8 is_argb;
+ u32 width; /* CURSOR_MAX_X at most */
+ u32 height; /* CURSOR_MAX_Y at most */
+ u32 hot_x; /* hotspot relative to upper-left of pointer image */
+ u32 hot_y;
+ u8 data[4];
+} __packed;
+
+struct synthvid_feature_change {
+ u8 is_dirt_needed;
+ u8 is_ptr_pos_needed;
+ u8 is_ptr_shape_needed;
+ u8 is_situ_needed;
+} __packed;
+
+struct rect {
+ s32 x1, y1; /* top left corner */
+ s32 x2, y2; /* bottom right corner, exclusive */
+} __packed;
+
+struct synthvid_dirt {
+ u8 video_output;
+ u8 dirt_count;
+ struct rect rect[1];
+} __packed;
+
+struct synthvid_msg {
+ struct pipe_msg_hdr pipe_hdr;
+ struct synthvid_msg_hdr vid_hdr;
+ union {
+ struct synthvid_version_req ver_req;
+ struct synthvid_version_resp ver_resp;
+ struct synthvid_vram_location vram;
+ struct synthvid_vram_location_ack vram_ack;
+ struct synthvid_situation_update situ;
+ struct synthvid_situation_update_ack situ_ack;
+ struct synthvid_pointer_position ptr_pos;
+ struct synthvid_pointer_shape ptr_shape;
+ struct synthvid_feature_change feature_chg;
+ struct synthvid_dirt dirt;
+ };
+} __packed;
+
+
+
+/* FB driver definitions and structures */
+#define HVFB_WIDTH 1152 /* default screen width */
+#define HVFB_HEIGHT 864 /* default screen height */
+#define HVFB_WIDTH_MIN 640
+#define HVFB_HEIGHT_MIN 480
+
+#define RING_BUFSIZE (256 * 1024)
+#define VSP_TIMEOUT (10 * HZ)
+#define HVFB_UPDATE_DELAY (HZ / 20)
+
+struct hvfb_par {
+ struct fb_info *info;
+ bool fb_ready; /* fb device is ready */
+ struct completion wait;
+ u32 synthvid_version;
+
+ struct delayed_work dwork;
+ bool update;
+
+ u32 pseudo_palette[16];
+ u8 init_buf[MAX_VMBUS_PKT_SIZE];
+ u8 recv_buf[MAX_VMBUS_PKT_SIZE];
+};
+
+static uint screen_width = HVFB_WIDTH;
+static uint screen_height = HVFB_HEIGHT;
+static uint screen_depth;
+static uint screen_fb_size;
+
+/* Send message to Hyper-V host */
+static inline int synthvid_send(struct hv_device *hdev,
+ struct synthvid_msg *msg)
+{
+ static atomic64_t request_id = ATOMIC64_INIT(0);
+ int ret;
+
+ msg->pipe_hdr.type = PIPE_MSG_DATA;
+ msg->pipe_hdr.size = msg->vid_hdr.size;
+
+ ret = vmbus_sendpacket(hdev->channel, msg,
+ msg->vid_hdr.size + sizeof(struct pipe_msg_hdr),
+ atomic64_inc_return(&request_id),
+ VM_PKT_DATA_INBAND, 0);
+
+ if (ret)
+ pr_err("Unable to send packet via vmbus\n");
+
+ return ret;
+}
+
+
+/* Send screen resolution info to host */
+static int synthvid_send_situ(struct hv_device *hdev)
+{
+ struct fb_info *info = hv_get_drvdata(hdev);
+ struct synthvid_msg msg;
+
+ if (!info)
+ return -ENODEV;
+
+ memset(&msg, 0, sizeof(struct synthvid_msg));
+
+ msg.vid_hdr.type = SYNTHVID_SITUATION_UPDATE;
+ msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
+ sizeof(struct synthvid_situation_update);
+ msg.situ.user_ctx = 0;
+ msg.situ.video_output_count = 1;
+ msg.situ.video_output[0].active = 1;
+ msg.situ.video_output[0].vram_offset = 0;
+ msg.situ.video_output[0].depth_bits = info->var.bits_per_pixel;
+ msg.situ.video_output[0].width_pixels = info->var.xres;
+ msg.situ.video_output[0].height_pixels = info->var.yres;
+ msg.situ.video_output[0].pitch_bytes = info->fix.line_length;
+
+ synthvid_send(hdev, &msg);
+
+ return 0;
+}
+
+/* Send mouse pointer info to host */
+static int synthvid_send_ptr(struct hv_device *hdev)
+{
+ struct synthvid_msg msg;
+
+ memset(&msg, 0, sizeof(struct synthvid_msg));
+ msg.vid_hdr.type = SYNTHVID_POINTER_POSITION;
+ msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
+ sizeof(struct synthvid_pointer_position);
+ msg.ptr_pos.is_visible = 1;
+ msg.ptr_pos.video_output = 0;
+ msg.ptr_pos.image_x = 0;
+ msg.ptr_pos.image_y = 0;
+ synthvid_send(hdev, &msg);
+
+ memset(&msg, 0, sizeof(struct synthvid_msg));
+ msg.vid_hdr.type = SYNTHVID_POINTER_SHAPE;
+ msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
+ sizeof(struct synthvid_pointer_shape);
+ msg.ptr_shape.part_idx = CURSOR_COMPLETE;
+ msg.ptr_shape.is_argb = 1;
+ msg.ptr_shape.width = 1;
+ msg.ptr_shape.height = 1;
+ msg.ptr_shape.hot_x = 0;
+ msg.ptr_shape.hot_y = 0;
+ msg.ptr_shape.data[0] = 0;
+ msg.ptr_shape.data[1] = 1;
+ msg.ptr_shape.data[2] = 1;
+ msg.ptr_shape.data[3] = 1;
+ synthvid_send(hdev, &msg);
+
+ return 0;
+}
+
+/* Send updated screen area (dirty rectangle) location to host */
+static int synthvid_update(struct fb_info *info)
+{
+ struct hv_device *hdev = device_to_hv_device(info->device);
+ struct synthvid_msg msg;
+
+ memset(&msg, 0, sizeof(struct synthvid_msg));
+
+ msg.vid_hdr.type = SYNTHVID_DIRT;
+ msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
+ sizeof(struct synthvid_dirt);
+ msg.dirt.video_output = 0;
+ msg.dirt.dirt_count = 1;
+ msg.dirt.rect[0].x1 = 0;
+ msg.dirt.rect[0].y1 = 0;
+ msg.dirt.rect[0].x2 = info->var.xres;
+ msg.dirt.rect[0].y2 = info->var.yres;
+
+ synthvid_send(hdev, &msg);
+
+ return 0;
+}
+
+
+/*
+ * Actions on received messages from host:
+ * Complete the wait event.
+ * Or, reply with screen and cursor info.
+ */
+static void synthvid_recv_sub(struct hv_device *hdev)
+{
+ struct fb_info *info = hv_get_drvdata(hdev);
+ struct hvfb_par *par;
+ struct synthvid_msg *msg;
+
+ if (!info)
+ return;
+
+ par = info->par;
+ msg = (struct synthvid_msg *)par->recv_buf;
+
+ /* Complete the wait event */
+ if (msg->vid_hdr.type == SYNTHVID_VERSION_RESPONSE ||
+ msg->vid_hdr.type == SYNTHVID_VRAM_LOCATION_ACK) {
+ memcpy(par->init_buf, msg, MAX_VMBUS_PKT_SIZE);
+ complete(&par->wait);
+ return;
+ }
+
+ /* Reply with screen and cursor info */
+ if (msg->vid_hdr.type == SYNTHVID_FEATURE_CHANGE) {
+ if (par->fb_ready) {
+ synthvid_send_ptr(hdev);
+ synthvid_send_situ(hdev);
+ }
+
+ par->update = msg->feature_chg.is_dirt_needed;
+ if (par->update)
+ schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);
+ }
+}
+
+/* Receive callback for messages from the host */
+static void synthvid_receive(void *ctx)
+{
+ struct hv_device *hdev = ctx;
+ struct fb_info *info = hv_get_drvdata(hdev);
+ struct hvfb_par *par;
+ struct synthvid_msg *recv_buf;
+ u32 bytes_recvd;
+ u64 req_id;
+ int ret;
+
+ if (!info)
+ return;
+
+ par = info->par;
+ recv_buf = (struct synthvid_msg *)par->recv_buf;
+
+ do {
+ ret = vmbus_recvpacket(hdev->channel, recv_buf,
+ MAX_VMBUS_PKT_SIZE,
+ &bytes_recvd, &req_id);
+ if (bytes_recvd > 0 &&
+ recv_buf->pipe_hdr.type == PIPE_MSG_DATA)
+ synthvid_recv_sub(hdev);
+ } while (bytes_recvd > 0 && ret == 0);
+}
+
+/* Check synthetic video protocol version with the host */
+static int synthvid_negotiate_ver(struct hv_device *hdev, u32 ver)
+{
+ struct fb_info *info = hv_get_drvdata(hdev);
+ struct hvfb_par *par = info->par;
+ struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf;
+ int t, ret = 0;
+
+ memset(msg, 0, sizeof(struct synthvid_msg));
+ msg->vid_hdr.type = SYNTHVID_VERSION_REQUEST;
+ msg->vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
+ sizeof(struct synthvid_version_req);
+ msg->ver_req.version = ver;
+ synthvid_send(hdev, msg);
+
+ t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT);
+ if (!t) {
+ pr_err("Time out on waiting version response\n");
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+ if (!msg->ver_resp.is_accepted) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ par->synthvid_version = ver;
+
+out:
+ return ret;
+}
+
+/* Connect to VSP (Virtual Service Provider) on host */
+static int synthvid_connect_vsp(struct hv_device *hdev)
+{
+ struct fb_info *info = hv_get_drvdata(hdev);
+ struct hvfb_par *par = info->par;
+ int ret;
+
+ ret = vmbus_open(hdev->channel, RING_BUFSIZE, RING_BUFSIZE,
+ NULL, 0, synthvid_receive, hdev);
+ if (ret) {
+ pr_err("Unable to open vmbus channel\n");
+ return ret;
+ }
+
+ /* Negotiate the protocol version with host */
+ if (vmbus_proto_version == VERSION_WS2008 ||
+ vmbus_proto_version == VERSION_WIN7)
+ ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN7);
+ else
+ ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN8);
+
+ if (ret) {
+ pr_err("Synthetic video device version not accepted\n");
+ goto error;
+ }
+
+ if (par->synthvid_version == SYNTHVID_VERSION_WIN7) {
+ screen_depth = SYNTHVID_DEPTH_WIN7;
+ screen_fb_size = SYNTHVID_FB_SIZE_WIN7;
+ } else {
+ screen_depth = SYNTHVID_DEPTH_WIN8;
+ screen_fb_size = SYNTHVID_FB_SIZE_WIN8;
+ }
+
+ return 0;
+
+error:
+ vmbus_close(hdev->channel);
+ return ret;
+}
+
+/* Send VRAM and Situation messages to the host */
+static int synthvid_send_config(struct hv_device *hdev)
+{
+ struct fb_info *info = hv_get_drvdata(hdev);
+ struct hvfb_par *par = info->par;
+ struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf;
+ int t, ret = 0;
+
+ /* Send VRAM location */
+ memset(msg, 0, sizeof(struct synthvid_msg));
+ msg->vid_hdr.type = SYNTHVID_VRAM_LOCATION;
+ msg->vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
+ sizeof(struct synthvid_vram_location);
+ msg->vram.user_ctx = msg->vram.vram_gpa = info->fix.smem_start;
+ msg->vram.is_vram_gpa_specified = 1;
+ synthvid_send(hdev, msg);
+
+ t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT);
+ if (!t) {
+ pr_err("Time out on waiting vram location ack\n");
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+ if (msg->vram_ack.user_ctx != info->fix.smem_start) {
+ pr_err("Unable to set VRAM location\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* Send pointer and situation update */
+ synthvid_send_ptr(hdev);
+ synthvid_send_situ(hdev);
+
+out:
+ return ret;
+}
+
+
+/*
+ * Delayed work callback:
+ * It is called at HVFB_UPDATE_DELAY or longer time interval to process
+ * screen updates. It is re-scheduled if further update is necessary.
+ */
+static void hvfb_update_work(struct work_struct *w)
+{
+ struct hvfb_par *par = container_of(w, struct hvfb_par, dwork.work);
+ struct fb_info *info = par->info;
+
+ if (par->fb_ready)
+ synthvid_update(info);
+
+ if (par->update)
+ schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);
+}
+
+
+/* Framebuffer operation handlers */
+
+static int hvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ if (var->xres < HVFB_WIDTH_MIN || var->yres < HVFB_HEIGHT_MIN ||
+ var->xres > screen_width || var->yres > screen_height ||
+ var->bits_per_pixel != screen_depth)
+ return -EINVAL;
+
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres;
+
+ return 0;
+}
+
+static int hvfb_set_par(struct fb_info *info)
+{
+ struct hv_device *hdev = device_to_hv_device(info->device);
+
+ return synthvid_send_situ(hdev);
+}
+
+
+static inline u32 chan_to_field(u32 chan, struct fb_bitfield *bf)
+{
+ return ((chan & 0xffff) >> (16 - bf->length)) << bf->offset;
+}
+
+static int hvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp, struct fb_info *info)
+{
+ u32 *pal = info->pseudo_palette;
+
+ if (regno > 15)
+ return -EINVAL;
+
+ pal[regno] = chan_to_field(red, &info->var.red)
+ | chan_to_field(green, &info->var.green)
+ | chan_to_field(blue, &info->var.blue)
+ | chan_to_field(transp, &info->var.transp);
+
+ return 0;
+}
+
+
+static struct fb_ops hvfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = hvfb_check_var,
+ .fb_set_par = hvfb_set_par,
+ .fb_setcolreg = hvfb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+
+/* Get options from kernel paramenter "video=" */
+static void hvfb_get_option(struct fb_info *info)
+{
+ struct hvfb_par *par = info->par;
+ char *opt = NULL, *p;
+ uint x = 0, y = 0;
+
+ if (fb_get_options(KBUILD_MODNAME, &opt) || !opt || !*opt)
+ return;
+
+ p = strsep(&opt, "x");
+ if (!*p || kstrtouint(p, 0, &x) ||
+ !opt || !*opt || kstrtouint(opt, 0, &y)) {
+ pr_err("Screen option is invalid: skipped\n");
+ return;
+ }
+
+ if (x < HVFB_WIDTH_MIN || y < HVFB_HEIGHT_MIN ||
+ (par->synthvid_version == SYNTHVID_VERSION_WIN8 &&
+ x * y * screen_depth / 8 > SYNTHVID_FB_SIZE_WIN8) ||
+ (par->synthvid_version == SYNTHVID_VERSION_WIN7 &&
+ (x > SYNTHVID_WIDTH_MAX_WIN7 || y > SYNTHVID_HEIGHT_MAX_WIN7))) {
+ pr_err("Screen resolution option is out of range: skipped\n");
+ return;
+ }
+
+ screen_width = x;
+ screen_height = y;
+ return;
+}
+
+
+/* Get framebuffer memory from Hyper-V video pci space */
+static int hvfb_getmem(struct fb_info *info)
+{
+ struct pci_dev *pdev;
+ ulong fb_phys;
+ void __iomem *fb_virt;
+
+ pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
+ PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
+ if (!pdev) {
+ pr_err("Unable to find PCI Hyper-V video\n");
+ return -ENODEV;
+ }
+
+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
+ pci_resource_len(pdev, 0) < screen_fb_size)
+ goto err1;
+
+ fb_phys = pci_resource_end(pdev, 0) - screen_fb_size + 1;
+ if (!request_mem_region(fb_phys, screen_fb_size, KBUILD_MODNAME))
+ goto err1;
+
+ fb_virt = ioremap(fb_phys, screen_fb_size);
+ if (!fb_virt)
+ goto err2;
+
+ info->apertures = alloc_apertures(1);
+ if (!info->apertures)
+ goto err3;
+
+ info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
+ info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
+ info->fix.smem_start = fb_phys;
+ info->fix.smem_len = screen_fb_size;
+ info->screen_base = fb_virt;
+ info->screen_size = screen_fb_size;
+
+ pci_dev_put(pdev);
+ return 0;
+
+err3:
+ iounmap(fb_virt);
+err2:
+ release_mem_region(fb_phys, screen_fb_size);
+err1:
+ pci_dev_put(pdev);
+ return -ENOMEM;
+}
+
+/* Release the framebuffer */
+static void hvfb_putmem(struct fb_info *info)
+{
+ iounmap(info->screen_base);
+ release_mem_region(info->fix.smem_start, screen_fb_size);
+}
+
+
+static int hvfb_probe(struct hv_device *hdev,
+ const struct hv_vmbus_device_id *dev_id)
+{
+ struct fb_info *info;
+ struct hvfb_par *par;
+ int ret;
+
+ info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device);
+ if (!info) {
+ pr_err("No memory for framebuffer info\n");
+ return -ENOMEM;
+ }
+
+ par = info->par;
+ par->info = info;
+ par->fb_ready = false;
+ init_completion(&par->wait);
+ INIT_DELAYED_WORK(&par->dwork, hvfb_update_work);
+
+ /* Connect to VSP */
+ hv_set_drvdata(hdev, info);
+ ret = synthvid_connect_vsp(hdev);
+ if (ret) {
+ pr_err("Unable to connect to VSP\n");
+ goto error1;
+ }
+
+ ret = hvfb_getmem(info);
+ if (ret) {
+ pr_err("No memory for framebuffer\n");
+ goto error2;
+ }
+
+ hvfb_get_option(info);
+ pr_info("Screen resolution: %dx%d, Color depth: %d\n",
+ screen_width, screen_height, screen_depth);
+
+
+ /* Set up fb_info */
+ info->flags = FBINFO_DEFAULT;
+
+ info->var.xres_virtual = info->var.xres = screen_width;
+ info->var.yres_virtual = info->var.yres = screen_height;
+ info->var.bits_per_pixel = screen_depth;
+
+ if (info->var.bits_per_pixel == 16) {
+ info->var.red = (struct fb_bitfield){11, 5, 0};
+ info->var.green = (struct fb_bitfield){5, 6, 0};
+ info->var.blue = (struct fb_bitfield){0, 5, 0};
+ info->var.transp = (struct fb_bitfield){0, 0, 0};
+ } else {
+ info->var.red = (struct fb_bitfield){16, 8, 0};
+ info->var.green = (struct fb_bitfield){8, 8, 0};
+ info->var.blue = (struct fb_bitfield){0, 8, 0};
+ info->var.transp = (struct fb_bitfield){24, 8, 0};
+ }
+
+ info->var.activate = FB_ACTIVATE_NOW;
+ info->var.height = -1;
+ info->var.width = -1;
+ info->var.vmode = FB_VMODE_NONINTERLACED;
+
+ strcpy(info->fix.id, KBUILD_MODNAME);
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->fix.line_length = screen_width * screen_depth / 8;
+ info->fix.accel = FB_ACCEL_NONE;
+
+ info->fbops = &hvfb_ops;
+ info->pseudo_palette = par->pseudo_palette;
+
+ /* Send config to host */
+ ret = synthvid_send_config(hdev);
+ if (ret)
+ goto error;
+
+ ret = register_framebuffer(info);
+ if (ret) {
+ pr_err("Unable to register framebuffer\n");
+ goto error;
+ }
+
+ par->fb_ready = true;
+
+ return 0;
+
+error:
+ hvfb_putmem(info);
+error2:
+ vmbus_close(hdev->channel);
+error1:
+ cancel_delayed_work_sync(&par->dwork);
+ hv_set_drvdata(hdev, NULL);
+ framebuffer_release(info);
+ return ret;
+}
+
+
+static int hvfb_remove(struct hv_device *hdev)
+{
+ struct fb_info *info = hv_get_drvdata(hdev);
+ struct hvfb_par *par = info->par;
+
+ par->update = false;
+ par->fb_ready = false;
+
+ unregister_framebuffer(info);
+ cancel_delayed_work_sync(&par->dwork);
+
+ vmbus_close(hdev->channel);
+ hv_set_drvdata(hdev, NULL);
+
+ hvfb_putmem(info);
+ framebuffer_release(info);
+
+ return 0;
+}
+
+
+static const struct hv_vmbus_device_id id_table[] = {
+ /* Synthetic Video Device GUID */
+ {HV_SYNTHVID_GUID},
+ {}
+};
+
+MODULE_DEVICE_TABLE(vmbus, id_table);
+
+static struct hv_driver hvfb_drv = {
+ .name = KBUILD_MODNAME,
+ .id_table = id_table,
+ .probe = hvfb_probe,
+ .remove = hvfb_remove,
+};
+
+
+static int __init hvfb_drv_init(void)
+{
+ return vmbus_driver_register(&hvfb_drv);
+}
+
+static void __exit hvfb_drv_exit(void)
+{
+ vmbus_driver_unregister(&hvfb_drv);
+}
+
+module_init(hvfb_drv_init);
+module_exit(hvfb_drv_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION(HV_DRV_VERSION);
+MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver");
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index 217678e0b983..fd2897455696 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -137,8 +137,20 @@ static int* get_ctrl_ptr(struct maven_data* md, int idx) {
static int maven_get_reg(struct i2c_client* c, char reg) {
char dst;
- struct i2c_msg msgs[] = {{ c->addr, I2C_M_REV_DIR_ADDR, sizeof(reg), &reg },
- { c->addr, I2C_M_RD | I2C_M_NOSTART, sizeof(dst), &dst }};
+ struct i2c_msg msgs[] = {
+ {
+ .addr = c->addr,
+ .flags = I2C_M_REV_DIR_ADDR,
+ .len = sizeof(reg),
+ .buf = &reg
+ },
+ {
+ .addr = c->addr,
+ .flags = I2C_M_RD | I2C_M_NOSTART,
+ .len = sizeof(dst),
+ .buf = &dst
+ }
+ };
s32 err;
err = i2c_transfer(c->adapter, msgs, 2);
diff --git a/drivers/video/mmp/core.c b/drivers/video/mmp/core.c
index 9ed83419038b..84de2632857a 100644
--- a/drivers/video/mmp/core.c
+++ b/drivers/video/mmp/core.c
@@ -252,7 +252,5 @@ void mmp_unregister_path(struct mmp_path *path)
kfree(path);
mutex_unlock(&disp_lock);
-
- dev_info(path->dev, "de-register %s\n", path->name);
}
EXPORT_SYMBOL_GPL(mmp_unregister_path);
diff --git a/drivers/video/mmp/hw/mmp_ctrl.h b/drivers/video/mmp/hw/mmp_ctrl.h
index 6408d8ef3abb..edd2002b0e99 100644
--- a/drivers/video/mmp/hw/mmp_ctrl.h
+++ b/drivers/video/mmp/hw/mmp_ctrl.h
@@ -961,56 +961,7 @@ struct lcd_regs {
LCD_TVG_CUTVLN : PN2_LCD_GRA_CUTVLN) : LCD_GRA_CUTVLN)
/*
- * defined Video Memory Color format for DMA control 0 register
- * DMA0 bit[23:20]
- */
-#define VMODE_RGB565 0x0
-#define VMODE_RGB1555 0x1
-#define VMODE_RGB888PACKED 0x2
-#define VMODE_RGB888UNPACKED 0x3
-#define VMODE_RGBA888 0x4
-#define VMODE_YUV422PACKED 0x5
-#define VMODE_YUV422PLANAR 0x6
-#define VMODE_YUV420PLANAR 0x7
-#define VMODE_SMPNCMD 0x8
-#define VMODE_PALETTE4BIT 0x9
-#define VMODE_PALETTE8BIT 0xa
-#define VMODE_RESERVED 0xb
-
-/*
- * defined Graphic Memory Color format for DMA control 0 register
- * DMA0 bit[19:16]
- */
-#define GMODE_RGB565 0x0
-#define GMODE_RGB1555 0x1
-#define GMODE_RGB888PACKED 0x2
-#define GMODE_RGB888UNPACKED 0x3
-#define GMODE_RGBA888 0x4
-#define GMODE_YUV422PACKED 0x5
-#define GMODE_YUV422PLANAR 0x6
-#define GMODE_YUV420PLANAR 0x7
-#define GMODE_SMPNCMD 0x8
-#define GMODE_PALETTE4BIT 0x9
-#define GMODE_PALETTE8BIT 0xa
-#define GMODE_RESERVED 0xb
-
-/*
- * define for DMA control 1 register
- */
-#define DMA1_FRAME_TRIG 31 /* bit location */
-#define DMA1_VSYNC_MODE 28
-#define DMA1_VSYNC_INV 27
-#define DMA1_CKEY 24
-#define DMA1_CARRY 23
-#define DMA1_LNBUF_ENA 22
-#define DMA1_GATED_ENA 21
-#define DMA1_PWRDN_ENA 20
-#define DMA1_DSCALE 18
-#define DMA1_ALPHA_MODE 16
-#define DMA1_ALPHA 08
-#define DMA1_PXLCMD 00
-
-/*
+ * defined for Configure Dumb Mode
* defined for Configure Dumb Mode
* DUMB LCD Panel bit[31:28]
*/
@@ -1050,18 +1001,6 @@ struct lcd_regs {
#define CFG_CYC_BURST_LEN16 (1<<4)
#define CFG_CYC_BURST_LEN8 (0<<4)
-/*
- * defined Dumb Panel Clock Divider register
- * SCLK_Source bit[31]
- */
- /* 0: PLL clock select*/
-#define AXI_BUS_SEL 0x80000000
-#define CCD_CLK_SEL 0x40000000
-#define DCON_CLK_SEL 0x20000000
-#define ENA_CLK_INT_DIV CONFIG_FB_DOVE_CLCD_SCLK_DIV
-#define IDLE_CLK_INT_DIV 0x1 /* idle Integer Divider */
-#define DIS_CLK_INT_DIV 0x0 /* Disable Integer Divider */
-
/* SRAM ID */
#define SRAMID_GAMMA_YR 0x0
#define SRAMID_GAMMA_UG 0x1
@@ -1471,422 +1410,6 @@ struct dsi_regs {
#define LVDS_FREQ_OFFSET_MODE_CK_DIV4_OUT (0x1 << 1)
#define LVDS_FREQ_OFFSET_MODE_EN (0x1 << 0)
-/* VDMA */
-struct vdma_ch_regs {
-#define VDMA_DC_SADDR_1 0x320
-#define VDMA_DC_SADDR_2 0x3A0
-#define VDMA_DC_SZ_1 0x324
-#define VDMA_DC_SZ_2 0x3A4
-#define VDMA_CTRL_1 0x328
-#define VDMA_CTRL_2 0x3A8
-#define VDMA_SRC_SZ_1 0x32C
-#define VDMA_SRC_SZ_2 0x3AC
-#define VDMA_SA_1 0x330
-#define VDMA_SA_2 0x3B0
-#define VDMA_DA_1 0x334
-#define VDMA_DA_2 0x3B4
-#define VDMA_SZ_1 0x338
-#define VDMA_SZ_2 0x3B8
- u32 dc_saddr;
- u32 dc_size;
- u32 ctrl;
- u32 src_size;
- u32 src_addr;
- u32 dst_addr;
- u32 dst_size;
-#define VDMA_PITCH_1 0x33C
-#define VDMA_PITCH_2 0x3BC
-#define VDMA_ROT_CTRL_1 0x340
-#define VDMA_ROT_CTRL_2 0x3C0
-#define VDMA_RAM_CTRL0_1 0x344
-#define VDMA_RAM_CTRL0_2 0x3C4
-#define VDMA_RAM_CTRL1_1 0x348
-#define VDMA_RAM_CTRL1_2 0x3C8
- u32 pitch;
- u32 rot_ctrl;
- u32 ram_ctrl0;
- u32 ram_ctrl1;
-
-};
-struct vdma_regs {
-#define VDMA_ARBR_CTRL 0x300
-#define VDMA_IRQR 0x304
-#define VDMA_IRQM 0x308
-#define VDMA_IRQS 0x30C
-#define VDMA_MDMA_ARBR_CTRL 0x310
- u32 arbr_ctr;
- u32 irq_raw;
- u32 irq_mask;
- u32 irq_status;
- u32 mdma_arbr_ctrl;
- u32 reserved[3];
-
- struct vdma_ch_regs ch1;
- u32 reserved2[21];
- struct vdma_ch_regs ch2;
-};
-
-/* CMU */
-#define CMU_PIP_DE_H_CFG 0x0008
-#define CMU_PRI1_H_CFG 0x000C
-#define CMU_PRI2_H_CFG 0x0010
-#define CMU_ACE_MAIN_DE1_H_CFG 0x0014
-#define CMU_ACE_MAIN_DE2_H_CFG 0x0018
-#define CMU_ACE_PIP_DE1_H_CFG 0x001C
-#define CMU_ACE_PIP_DE2_H_CFG 0x0020
-#define CMU_PIP_DE_V_CFG 0x0024
-#define CMU_PRI_V_CFG 0x0028
-#define CMU_ACE_MAIN_DE_V_CFG 0x002C
-#define CMU_ACE_PIP_DE_V_CFG 0x0030
-#define CMU_BAR_0_CFG 0x0034
-#define CMU_BAR_1_CFG 0x0038
-#define CMU_BAR_2_CFG 0x003C
-#define CMU_BAR_3_CFG 0x0040
-#define CMU_BAR_4_CFG 0x0044
-#define CMU_BAR_5_CFG 0x0048
-#define CMU_BAR_6_CFG 0x004C
-#define CMU_BAR_7_CFG 0x0050
-#define CMU_BAR_8_CFG 0x0054
-#define CMU_BAR_9_CFG 0x0058
-#define CMU_BAR_10_CFG 0x005C
-#define CMU_BAR_11_CFG 0x0060
-#define CMU_BAR_12_CFG 0x0064
-#define CMU_BAR_13_CFG 0x0068
-#define CMU_BAR_14_CFG 0x006C
-#define CMU_BAR_15_CFG 0x0070
-#define CMU_BAR_CTRL 0x0074
-#define PATTERN_TOTAL 0x0078
-#define PATTERN_ACTIVE 0x007C
-#define PATTERN_FRONT_PORCH 0x0080
-#define PATTERN_BACK_PORCH 0x0084
-#define CMU_CLK_CTRL 0x0088
-
-#define CMU_ICSC_M_C0_L 0x0900
-#define CMU_ICSC_M_C0_H 0x0901
-#define CMU_ICSC_M_C1_L 0x0902
-#define CMU_ICSC_M_C1_H 0x0903
-#define CMU_ICSC_M_C2_L 0x0904
-#define CMU_ICSC_M_C2_H 0x0905
-#define CMU_ICSC_M_C3_L 0x0906
-#define CMU_ICSC_M_C3_H 0x0907
-#define CMU_ICSC_M_C4_L 0x0908
-#define CMU_ICSC_M_C4_H 0x0909
-#define CMU_ICSC_M_C5_L 0x090A
-#define CMU_ICSC_M_C5_H 0x090B
-#define CMU_ICSC_M_C6_L 0x090C
-#define CMU_ICSC_M_C6_H 0x090D
-#define CMU_ICSC_M_C7_L 0x090E
-#define CMU_ICSC_M_C7_H 0x090F
-#define CMU_ICSC_M_C8_L 0x0910
-#define CMU_ICSC_M_C8_H 0x0911
-#define CMU_ICSC_M_O1_0 0x0914
-#define CMU_ICSC_M_O1_1 0x0915
-#define CMU_ICSC_M_O1_2 0x0916
-#define CMU_ICSC_M_O2_0 0x0918
-#define CMU_ICSC_M_O2_1 0x0919
-#define CMU_ICSC_M_O2_2 0x091A
-#define CMU_ICSC_M_O3_0 0x091C
-#define CMU_ICSC_M_O3_1 0x091D
-#define CMU_ICSC_M_O3_2 0x091E
-#define CMU_ICSC_P_C0_L 0x0920
-#define CMU_ICSC_P_C0_H 0x0921
-#define CMU_ICSC_P_C1_L 0x0922
-#define CMU_ICSC_P_C1_H 0x0923
-#define CMU_ICSC_P_C2_L 0x0924
-#define CMU_ICSC_P_C2_H 0x0925
-#define CMU_ICSC_P_C3_L 0x0926
-#define CMU_ICSC_P_C3_H 0x0927
-#define CMU_ICSC_P_C4_L 0x0928
-#define CMU_ICSC_P_C4_H 0x0929
-#define CMU_ICSC_P_C5_L 0x092A
-#define CMU_ICSC_P_C5_H 0x092B
-#define CMU_ICSC_P_C6_L 0x092C
-#define CMU_ICSC_P_C6_H 0x092D
-#define CMU_ICSC_P_C7_L 0x092E
-#define CMU_ICSC_P_C7_H 0x092F
-#define CMU_ICSC_P_C8_L 0x0930
-#define CMU_ICSC_P_C8_H 0x0931
-#define CMU_ICSC_P_O1_0 0x0934
-#define CMU_ICSC_P_O1_1 0x0935
-#define CMU_ICSC_P_O1_2 0x0936
-#define CMU_ICSC_P_O2_0 0x0938
-#define CMU_ICSC_P_O2_1 0x0939
-#define CMU_ICSC_P_O2_2 0x093A
-#define CMU_ICSC_P_O3_0 0x093C
-#define CMU_ICSC_P_O3_1 0x093D
-#define CMU_ICSC_P_O3_2 0x093E
-#define CMU_BR_M_EN 0x0940
-#define CMU_BR_M_TH1_L 0x0942
-#define CMU_BR_M_TH1_H 0x0943
-#define CMU_BR_M_TH2_L 0x0944
-#define CMU_BR_M_TH2_H 0x0945
-#define CMU_ACE_M_EN 0x0950
-#define CMU_ACE_M_WFG1 0x0951
-#define CMU_ACE_M_WFG2 0x0952
-#define CMU_ACE_M_WFG3 0x0953
-#define CMU_ACE_M_TH0 0x0954
-#define CMU_ACE_M_TH1 0x0955
-#define CMU_ACE_M_TH2 0x0956
-#define CMU_ACE_M_TH3 0x0957
-#define CMU_ACE_M_TH4 0x0958
-#define CMU_ACE_M_TH5 0x0959
-#define CMU_ACE_M_OP0_L 0x095A
-#define CMU_ACE_M_OP0_H 0x095B
-#define CMU_ACE_M_OP5_L 0x095C
-#define CMU_ACE_M_OP5_H 0x095D
-#define CMU_ACE_M_GB2 0x095E
-#define CMU_ACE_M_GB3 0x095F
-#define CMU_ACE_M_MS1 0x0960
-#define CMU_ACE_M_MS2 0x0961
-#define CMU_ACE_M_MS3 0x0962
-#define CMU_BR_P_EN 0x0970
-#define CMU_BR_P_TH1_L 0x0972
-#define CMU_BR_P_TH1_H 0x0973
-#define CMU_BR_P_TH2_L 0x0974
-#define CMU_BR_P_TH2_H 0x0975
-#define CMU_ACE_P_EN 0x0980
-#define CMU_ACE_P_WFG1 0x0981
-#define CMU_ACE_P_WFG2 0x0982
-#define CMU_ACE_P_WFG3 0x0983
-#define CMU_ACE_P_TH0 0x0984
-#define CMU_ACE_P_TH1 0x0985
-#define CMU_ACE_P_TH2 0x0986
-#define CMU_ACE_P_TH3 0x0987
-#define CMU_ACE_P_TH4 0x0988
-#define CMU_ACE_P_TH5 0x0989
-#define CMU_ACE_P_OP0_L 0x098A
-#define CMU_ACE_P_OP0_H 0x098B
-#define CMU_ACE_P_OP5_L 0x098C
-#define CMU_ACE_P_OP5_H 0x098D
-#define CMU_ACE_P_GB2 0x098E
-#define CMU_ACE_P_GB3 0x098F
-#define CMU_ACE_P_MS1 0x0990
-#define CMU_ACE_P_MS2 0x0991
-#define CMU_ACE_P_MS3 0x0992
-#define CMU_FTDC_M_EN 0x09A0
-#define CMU_FTDC_P_EN 0x09A1
-#define CMU_FTDC_INLOW_L 0x09A2
-#define CMU_FTDC_INLOW_H 0x09A3
-#define CMU_FTDC_INHIGH_L 0x09A4
-#define CMU_FTDC_INHIGH_H 0x09A5
-#define CMU_FTDC_OUTLOW_L 0x09A6
-#define CMU_FTDC_OUTLOW_H 0x09A7
-#define CMU_FTDC_OUTHIGH_L 0x09A8
-#define CMU_FTDC_OUTHIGH_H 0x09A9
-#define CMU_FTDC_YLOW 0x09AA
-#define CMU_FTDC_YHIGH 0x09AB
-#define CMU_FTDC_CH1 0x09AC
-#define CMU_FTDC_CH2_L 0x09AE
-#define CMU_FTDC_CH2_H 0x09AF
-#define CMU_FTDC_CH3_L 0x09B0
-#define CMU_FTDC_CH3_H 0x09B1
-#define CMU_FTDC_1_C00_6 0x09B2
-#define CMU_FTDC_1_C01_6 0x09B8
-#define CMU_FTDC_1_C11_6 0x09BE
-#define CMU_FTDC_1_C10_6 0x09C4
-#define CMU_FTDC_1_OFF00_6 0x09CA
-#define CMU_FTDC_1_OFF10_6 0x09D0
-#define CMU_HS_M_EN 0x0A00
-#define CMU_HS_M_AX1_L 0x0A02
-#define CMU_HS_M_AX1_H 0x0A03
-#define CMU_HS_M_AX2_L 0x0A04
-#define CMU_HS_M_AX2_H 0x0A05
-#define CMU_HS_M_AX3_L 0x0A06
-#define CMU_HS_M_AX3_H 0x0A07
-#define CMU_HS_M_AX4_L 0x0A08
-#define CMU_HS_M_AX4_H 0x0A09
-#define CMU_HS_M_AX5_L 0x0A0A
-#define CMU_HS_M_AX5_H 0x0A0B
-#define CMU_HS_M_AX6_L 0x0A0C
-#define CMU_HS_M_AX6_H 0x0A0D
-#define CMU_HS_M_AX7_L 0x0A0E
-#define CMU_HS_M_AX7_H 0x0A0F
-#define CMU_HS_M_AX8_L 0x0A10
-#define CMU_HS_M_AX8_H 0x0A11
-#define CMU_HS_M_AX9_L 0x0A12
-#define CMU_HS_M_AX9_H 0x0A13
-#define CMU_HS_M_AX10_L 0x0A14
-#define CMU_HS_M_AX10_H 0x0A15
-#define CMU_HS_M_AX11_L 0x0A16
-#define CMU_HS_M_AX11_H 0x0A17
-#define CMU_HS_M_AX12_L 0x0A18
-#define CMU_HS_M_AX12_H 0x0A19
-#define CMU_HS_M_AX13_L 0x0A1A
-#define CMU_HS_M_AX13_H 0x0A1B
-#define CMU_HS_M_AX14_L 0x0A1C
-#define CMU_HS_M_AX14_H 0x0A1D
-#define CMU_HS_M_H1_H14 0x0A1E
-#define CMU_HS_M_S1_S14 0x0A2C
-#define CMU_HS_M_GL 0x0A3A
-#define CMU_HS_M_MAXSAT_RGB_Y_L 0x0A3C
-#define CMU_HS_M_MAXSAT_RGB_Y_H 0x0A3D
-#define CMU_HS_M_MAXSAT_RCR_L 0x0A3E
-#define CMU_HS_M_MAXSAT_RCR_H 0x0A3F
-#define CMU_HS_M_MAXSAT_RCB_L 0x0A40
-#define CMU_HS_M_MAXSAT_RCB_H 0x0A41
-#define CMU_HS_M_MAXSAT_GCR_L 0x0A42
-#define CMU_HS_M_MAXSAT_GCR_H 0x0A43
-#define CMU_HS_M_MAXSAT_GCB_L 0x0A44
-#define CMU_HS_M_MAXSAT_GCB_H 0x0A45
-#define CMU_HS_M_MAXSAT_BCR_L 0x0A46
-#define CMU_HS_M_MAXSAT_BCR_H 0x0A47
-#define CMU_HS_M_MAXSAT_BCB_L 0x0A48
-#define CMU_HS_M_MAXSAT_BCB_H 0x0A49
-#define CMU_HS_M_ROFF_L 0x0A4A
-#define CMU_HS_M_ROFF_H 0x0A4B
-#define CMU_HS_M_GOFF_L 0x0A4C
-#define CMU_HS_M_GOFF_H 0x0A4D
-#define CMU_HS_M_BOFF_L 0x0A4E
-#define CMU_HS_M_BOFF_H 0x0A4F
-#define CMU_HS_P_EN 0x0A50
-#define CMU_HS_P_AX1_L 0x0A52
-#define CMU_HS_P_AX1_H 0x0A53
-#define CMU_HS_P_AX2_L 0x0A54
-#define CMU_HS_P_AX2_H 0x0A55
-#define CMU_HS_P_AX3_L 0x0A56
-#define CMU_HS_P_AX3_H 0x0A57
-#define CMU_HS_P_AX4_L 0x0A58
-#define CMU_HS_P_AX4_H 0x0A59
-#define CMU_HS_P_AX5_L 0x0A5A
-#define CMU_HS_P_AX5_H 0x0A5B
-#define CMU_HS_P_AX6_L 0x0A5C
-#define CMU_HS_P_AX6_H 0x0A5D
-#define CMU_HS_P_AX7_L 0x0A5E
-#define CMU_HS_P_AX7_H 0x0A5F
-#define CMU_HS_P_AX8_L 0x0A60
-#define CMU_HS_P_AX8_H 0x0A61
-#define CMU_HS_P_AX9_L 0x0A62
-#define CMU_HS_P_AX9_H 0x0A63
-#define CMU_HS_P_AX10_L 0x0A64
-#define CMU_HS_P_AX10_H 0x0A65
-#define CMU_HS_P_AX11_L 0x0A66
-#define CMU_HS_P_AX11_H 0x0A67
-#define CMU_HS_P_AX12_L 0x0A68
-#define CMU_HS_P_AX12_H 0x0A69
-#define CMU_HS_P_AX13_L 0x0A6A
-#define CMU_HS_P_AX13_H 0x0A6B
-#define CMU_HS_P_AX14_L 0x0A6C
-#define CMU_HS_P_AX14_H 0x0A6D
-#define CMU_HS_P_H1_H14 0x0A6E
-#define CMU_HS_P_S1_S14 0x0A7C
-#define CMU_HS_P_GL 0x0A8A
-#define CMU_HS_P_MAXSAT_RGB_Y_L 0x0A8C
-#define CMU_HS_P_MAXSAT_RGB_Y_H 0x0A8D
-#define CMU_HS_P_MAXSAT_RCR_L 0x0A8E
-#define CMU_HS_P_MAXSAT_RCR_H 0x0A8F
-#define CMU_HS_P_MAXSAT_RCB_L 0x0A90
-#define CMU_HS_P_MAXSAT_RCB_H 0x0A91
-#define CMU_HS_P_MAXSAT_GCR_L 0x0A92
-#define CMU_HS_P_MAXSAT_GCR_H 0x0A93
-#define CMU_HS_P_MAXSAT_GCB_L 0x0A94
-#define CMU_HS_P_MAXSAT_GCB_H 0x0A95
-#define CMU_HS_P_MAXSAT_BCR_L 0x0A96
-#define CMU_HS_P_MAXSAT_BCR_H 0x0A97
-#define CMU_HS_P_MAXSAT_BCB_L 0x0A98
-#define CMU_HS_P_MAXSAT_BCB_H 0x0A99
-#define CMU_HS_P_ROFF_L 0x0A9A
-#define CMU_HS_P_ROFF_H 0x0A9B
-#define CMU_HS_P_GOFF_L 0x0A9C
-#define CMU_HS_P_GOFF_H 0x0A9D
-#define CMU_HS_P_BOFF_L 0x0A9E
-#define CMU_HS_P_BOFF_H 0x0A9F
-#define CMU_GLCSC_M_C0_L 0x0AA0
-#define CMU_GLCSC_M_C0_H 0x0AA1
-#define CMU_GLCSC_M_C1_L 0x0AA2
-#define CMU_GLCSC_M_C1_H 0x0AA3
-#define CMU_GLCSC_M_C2_L 0x0AA4
-#define CMU_GLCSC_M_C2_H 0x0AA5
-#define CMU_GLCSC_M_C3_L 0x0AA6
-#define CMU_GLCSC_M_C3_H 0x0AA7
-#define CMU_GLCSC_M_C4_L 0x0AA8
-#define CMU_GLCSC_M_C4_H 0x0AA9
-#define CMU_GLCSC_M_C5_L 0x0AAA
-#define CMU_GLCSC_M_C5_H 0x0AAB
-#define CMU_GLCSC_M_C6_L 0x0AAC
-#define CMU_GLCSC_M_C6_H 0x0AAD
-#define CMU_GLCSC_M_C7_L 0x0AAE
-#define CMU_GLCSC_M_C7_H 0x0AAF
-#define CMU_GLCSC_M_C8_L 0x0AB0
-#define CMU_GLCSC_M_C8_H 0x0AB1
-#define CMU_GLCSC_M_O1_1 0x0AB4
-#define CMU_GLCSC_M_O1_2 0x0AB5
-#define CMU_GLCSC_M_O1_3 0x0AB6
-#define CMU_GLCSC_M_O2_1 0x0AB8
-#define CMU_GLCSC_M_O2_2 0x0AB9
-#define CMU_GLCSC_M_O2_3 0x0ABA
-#define CMU_GLCSC_M_O3_1 0x0ABC
-#define CMU_GLCSC_M_O3_2 0x0ABD
-#define CMU_GLCSC_M_O3_3 0x0ABE
-#define CMU_GLCSC_P_C0_L 0x0AC0
-#define CMU_GLCSC_P_C0_H 0x0AC1
-#define CMU_GLCSC_P_C1_L 0x0AC2
-#define CMU_GLCSC_P_C1_H 0x0AC3
-#define CMU_GLCSC_P_C2_L 0x0AC4
-#define CMU_GLCSC_P_C2_H 0x0AC5
-#define CMU_GLCSC_P_C3_L 0x0AC6
-#define CMU_GLCSC_P_C3_H 0x0AC7
-#define CMU_GLCSC_P_C4_L 0x0AC8
-#define CMU_GLCSC_P_C4_H 0x0AC9
-#define CMU_GLCSC_P_C5_L 0x0ACA
-#define CMU_GLCSC_P_C5_H 0x0ACB
-#define CMU_GLCSC_P_C6_L 0x0ACC
-#define CMU_GLCSC_P_C6_H 0x0ACD
-#define CMU_GLCSC_P_C7_L 0x0ACE
-#define CMU_GLCSC_P_C7_H 0x0ACF
-#define CMU_GLCSC_P_C8_L 0x0AD0
-#define CMU_GLCSC_P_C8_H 0x0AD1
-#define CMU_GLCSC_P_O1_1 0x0AD4
-#define CMU_GLCSC_P_O1_2 0x0AD5
-#define CMU_GLCSC_P_O1_3 0x0AD6
-#define CMU_GLCSC_P_O2_1 0x0AD8
-#define CMU_GLCSC_P_O2_2 0x0AD9
-#define CMU_GLCSC_P_O2_3 0x0ADA
-#define CMU_GLCSC_P_O3_1 0x0ADC
-#define CMU_GLCSC_P_O3_2 0x0ADD
-#define CMU_GLCSC_P_O3_3 0x0ADE
-#define CMU_PIXVAL_M_EN 0x0AE0
-#define CMU_PIXVAL_P_EN 0x0AE1
-
-#define CMU_CLK_CTRL_TCLK 0x0
-#define CMU_CLK_CTRL_SCLK 0x2
-#define CMU_CLK_CTRL_MSK 0x2
-#define CMU_CLK_CTRL_ENABLE 0x1
-
-#define LCD_TOP_CTRL_TV 0x2
-#define LCD_TOP_CTRL_PN 0x0
-#define LCD_TOP_CTRL_SEL_MSK 0x2
-#define LCD_IO_CMU_IN_SEL_MSK (0x3 << 20)
-#define LCD_IO_CMU_IN_SEL_TV 0
-#define LCD_IO_CMU_IN_SEL_PN 1
-#define LCD_IO_CMU_IN_SEL_PN2 2
-#define LCD_IO_TV_OUT_SEL_MSK (0x3 << 26)
-#define LCD_IO_PN_OUT_SEL_MSK (0x3 << 24)
-#define LCD_IO_PN2_OUT_SEL_MSK (0x3 << 28)
-#define LCD_IO_TV_OUT_SEL_NON 3
-#define LCD_IO_PN_OUT_SEL_NON 3
-#define LCD_IO_PN2_OUT_SEL_NON 3
-#define LCD_TOP_CTRL_CMU_ENABLE 0x1
-#define LCD_IO_OVERL_MSK 0xC00000
-#define LCD_IO_OVERL_TV 0x0
-#define LCD_IO_OVERL_LCD1 0x400000
-#define LCD_IO_OVERL_LCD2 0xC00000
-#define HINVERT_MSK 0x4
-#define VINVERT_MSK 0x8
-#define HINVERT_LEN 0x2
-#define VINVERT_LEN 0x3
-
-#define CMU_CTRL 0x88
-#define CMU_CTRL_A0_MSK 0x6
-#define CMU_CTRL_A0_TV 0x0
-#define CMU_CTRL_A0_LCD1 0x1
-#define CMU_CTRL_A0_LCD2 0x2
-#define CMU_CTRL_A0_HDMI 0x3
-
-#define ICR_DRV_ROUTE_OFF 0x0
-#define ICR_DRV_ROUTE_TV 0x1
-#define ICR_DRV_ROUTE_LCD1 0x2
-#define ICR_DRV_ROUTE_LCD2 0x3
-
enum {
PATH_PN = 0,
PATH_TV,
diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c
new file mode 100644
index 000000000000..e2e9e3e61b72
--- /dev/null
+++ b/drivers/video/simplefb.c
@@ -0,0 +1,234 @@
+/*
+ * Simplest possible simple frame-buffer driver, as a platform device
+ *
+ * Copyright (c) 2013, Stephen Warren
+ *
+ * Based on q40fb.c, which was:
+ * Copyright (C) 2001 Richard Zidlicky <rz@linux-m68k.org>
+ *
+ * Also based on offb.c, which was:
+ * Copyright (C) 1997 Geert Uytterhoeven
+ * Copyright (C) 1996 Paul Mackerras
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+static struct fb_fix_screeninfo simplefb_fix = {
+ .id = "simple",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .accel = FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo simplefb_var = {
+ .height = -1,
+ .width = -1,
+ .activate = FB_ACTIVATE_NOW,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
+
+static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ u32 *pal = info->pseudo_palette;
+ u32 cr = red >> (16 - info->var.red.length);
+ u32 cg = green >> (16 - info->var.green.length);
+ u32 cb = blue >> (16 - info->var.blue.length);
+ u32 value;
+
+ if (regno >= 16)
+ return -EINVAL;
+
+ value = (cr << info->var.red.offset) |
+ (cg << info->var.green.offset) |
+ (cb << info->var.blue.offset);
+ if (info->var.transp.length > 0) {
+ u32 mask = (1 << info->var.transp.length) - 1;
+ mask <<= info->var.transp.offset;
+ value |= mask;
+ }
+ pal[regno] = value;
+
+ return 0;
+}
+
+static struct fb_ops simplefb_ops = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = simplefb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+struct simplefb_format {
+ const char *name;
+ u32 bits_per_pixel;
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+};
+
+static struct simplefb_format simplefb_formats[] = {
+ { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} },
+};
+
+struct simplefb_params {
+ u32 width;
+ u32 height;
+ u32 stride;
+ struct simplefb_format *format;
+};
+
+static int simplefb_parse_dt(struct platform_device *pdev,
+ struct simplefb_params *params)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int ret;
+ const char *format;
+ int i;
+
+ ret = of_property_read_u32(np, "width", &params->width);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't parse width property\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "height", &params->height);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't parse height property\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "stride", &params->stride);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't parse stride property\n");
+ return ret;
+ }
+
+ ret = of_property_read_string(np, "format", &format);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't parse format property\n");
+ return ret;
+ }
+ params->format = NULL;
+ for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) {
+ if (strcmp(format, simplefb_formats[i].name))
+ continue;
+ params->format = &simplefb_formats[i];
+ break;
+ }
+ if (!params->format) {
+ dev_err(&pdev->dev, "Invalid format value\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int simplefb_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct simplefb_params params;
+ struct fb_info *info;
+ struct resource *mem;
+
+ if (fb_get_options("simplefb", NULL))
+ return -ENODEV;
+
+ ret = simplefb_parse_dt(pdev, &params);
+ if (ret)
+ return ret;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "No memory resource\n");
+ return -EINVAL;
+ }
+
+ info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
+ if (!info)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, info);
+
+ info->fix = simplefb_fix;
+ info->fix.smem_start = mem->start;
+ info->fix.smem_len = resource_size(mem);
+ info->fix.line_length = params.stride;
+
+ info->var = simplefb_var;
+ info->var.xres = params.width;
+ info->var.yres = params.height;
+ info->var.xres_virtual = params.width;
+ info->var.yres_virtual = params.height;
+ info->var.bits_per_pixel = params.format->bits_per_pixel;
+ info->var.red = params.format->red;
+ info->var.green = params.format->green;
+ info->var.blue = params.format->blue;
+ info->var.transp = params.format->transp;
+
+ info->fbops = &simplefb_ops;
+ info->flags = FBINFO_DEFAULT;
+ info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start,
+ info->fix.smem_len);
+ if (!info->screen_base) {
+ framebuffer_release(info);
+ return -ENODEV;
+ }
+ info->pseudo_palette = (void *)(info + 1);
+
+ ret = register_framebuffer(info);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
+ framebuffer_release(info);
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
+
+ return 0;
+}
+
+static int simplefb_remove(struct platform_device *pdev)
+{
+ struct fb_info *info = platform_get_drvdata(pdev);
+
+ unregister_framebuffer(info);
+ framebuffer_release(info);
+
+ return 0;
+}
+
+static const struct of_device_id simplefb_of_match[] = {
+ { .compatible = "simple-framebuffer", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, simplefb_of_match);
+
+static struct platform_driver simplefb_driver = {
+ .driver = {
+ .name = "simple-framebuffer",
+ .owner = THIS_MODULE,
+ .of_match_table = simplefb_of_match,
+ },
+ .probe = simplefb_probe,
+ .remove = simplefb_remove,
+};
+module_platform_driver(simplefb_driver);
+
+MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>");
+MODULE_DESCRIPTION("Simple framebuffer driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index d4284458377e..e328a61b64ba 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -166,7 +166,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
memcpy(&m->id, &uvesafb_cn_id, sizeof(m->id));
m->seq = seq;
m->len = len;
- m->ack = random32();
+ m->ack = prandom_u32();
/* uvesafb_task structure */
memcpy(m + 1, &task->t, sizeof(task->t));
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 67af155cf602..dd4d9cb86243 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -145,9 +145,9 @@ config SWIOTLB_XEN
select SWIOTLB
config XEN_TMEM
- bool
+ tristate
depends on !ARM
- default y if (CLEANCACHE || FRONTSWAP)
+ default m if (CLEANCACHE || FRONTSWAP)
help
Shim to interface in-kernel Transcendent Memory hooks
(e.g. cleancache and frontswap) to Xen tmem hypercalls.
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c
index 3ee836d42581..e3600be4e7fa 100644
--- a/drivers/xen/tmem.c
+++ b/drivers/xen/tmem.c
@@ -5,6 +5,7 @@
* Author: Dan Magenheimer
*/
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
@@ -128,6 +129,7 @@ static int xen_tmem_flush_object(u32 pool_id, struct tmem_oid oid)
return xen_tmem_op(TMEM_FLUSH_OBJECT, pool_id, oid, 0, 0, 0, 0, 0);
}
+#ifndef CONFIG_XEN_TMEM_MODULE
bool __read_mostly tmem_enabled = false;
static int __init enable_tmem(char *s)
@@ -136,6 +138,7 @@ static int __init enable_tmem(char *s)
return 1;
}
__setup("tmem", enable_tmem);
+#endif
#ifdef CONFIG_CLEANCACHE
static int xen_tmem_destroy_pool(u32 pool_id)
@@ -227,16 +230,21 @@ static int tmem_cleancache_init_shared_fs(char *uuid, size_t pagesize)
return xen_tmem_new_pool(shared_uuid, TMEM_POOL_SHARED, pagesize);
}
-static bool __initdata use_cleancache = true;
-
+static bool disable_cleancache __read_mostly;
+static bool disable_selfballooning __read_mostly;
+#ifdef CONFIG_XEN_TMEM_MODULE
+module_param(disable_cleancache, bool, S_IRUGO);
+module_param(disable_selfballooning, bool, S_IRUGO);
+#else
static int __init no_cleancache(char *s)
{
- use_cleancache = false;
+ disable_cleancache = true;
return 1;
}
__setup("nocleancache", no_cleancache);
+#endif
-static struct cleancache_ops __initdata tmem_cleancache_ops = {
+static struct cleancache_ops tmem_cleancache_ops = {
.put_page = tmem_cleancache_put_page,
.get_page = tmem_cleancache_get_page,
.invalidate_page = tmem_cleancache_flush_page,
@@ -353,54 +361,71 @@ static void tmem_frontswap_init(unsigned ignored)
xen_tmem_new_pool(private, TMEM_POOL_PERSIST, PAGE_SIZE);
}
-static bool __initdata use_frontswap = true;
-
+static bool disable_frontswap __read_mostly;
+static bool disable_frontswap_selfshrinking __read_mostly;
+#ifdef CONFIG_XEN_TMEM_MODULE
+module_param(disable_frontswap, bool, S_IRUGO);
+module_param(disable_frontswap_selfshrinking, bool, S_IRUGO);
+#else
static int __init no_frontswap(char *s)
{
- use_frontswap = false;
+ disable_frontswap = true;
return 1;
}
__setup("nofrontswap", no_frontswap);
+#endif
-static struct frontswap_ops __initdata tmem_frontswap_ops = {
+static struct frontswap_ops tmem_frontswap_ops = {
.store = tmem_frontswap_store,
.load = tmem_frontswap_load,
.invalidate_page = tmem_frontswap_flush_page,
.invalidate_area = tmem_frontswap_flush_area,
.init = tmem_frontswap_init
};
+#else /* CONFIG_FRONTSWAP */
+#define disable_frontswap_selfshrinking 1
#endif
-static int __init xen_tmem_init(void)
+static int xen_tmem_init(void)
{
if (!xen_domain())
return 0;
#ifdef CONFIG_FRONTSWAP
- if (tmem_enabled && use_frontswap) {
+ if (tmem_enabled && !disable_frontswap) {
char *s = "";
- struct frontswap_ops old_ops =
+ struct frontswap_ops *old_ops =
frontswap_register_ops(&tmem_frontswap_ops);
tmem_frontswap_poolid = -1;
- if (old_ops.init != NULL)
+ if (IS_ERR(old_ops) || old_ops) {
+ if (IS_ERR(old_ops))
+ return PTR_ERR(old_ops);
s = " (WARNING: frontswap_ops overridden)";
+ }
printk(KERN_INFO "frontswap enabled, RAM provided by "
"Xen Transcendent Memory%s\n", s);
}
#endif
#ifdef CONFIG_CLEANCACHE
BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid));
- if (tmem_enabled && use_cleancache) {
+ if (tmem_enabled && !disable_cleancache) {
char *s = "";
- struct cleancache_ops old_ops =
+ struct cleancache_ops *old_ops =
cleancache_register_ops(&tmem_cleancache_ops);
- if (old_ops.init_fs != NULL)
+ if (old_ops)
s = " (WARNING: cleancache_ops overridden)";
printk(KERN_INFO "cleancache enabled, RAM provided by "
"Xen Transcendent Memory%s\n", s);
}
#endif
+#ifdef CONFIG_XEN_SELFBALLOONING
+ xen_selfballoon_init(!disable_selfballooning,
+ !disable_frontswap_selfshrinking);
+#endif
return 0;
}
module_init(xen_tmem_init)
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dan Magenheimer <dan.magenheimer@oracle.com>");
+MODULE_DESCRIPTION("Shim to Xen transcendent memory");
diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c
index 2552d3e0a70f..f2ef569c7cc1 100644
--- a/drivers/xen/xen-selfballoon.c
+++ b/drivers/xen/xen-selfballoon.c
@@ -121,7 +121,7 @@ static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process);
static bool frontswap_selfshrinking __read_mostly;
/* Enable/disable with kernel boot option. */
-static bool use_frontswap_selfshrink __initdata = true;
+static bool use_frontswap_selfshrink = true;
/*
* The default values for the following parameters were deemed reasonable
@@ -185,7 +185,7 @@ static int __init xen_nofrontswap_selfshrink_setup(char *s)
__setup("noselfshrink", xen_nofrontswap_selfshrink_setup);
/* Disable with kernel boot option. */
-static bool use_selfballooning __initdata = true;
+static bool use_selfballooning = true;
static int __init xen_noselfballooning_setup(char *s)
{
@@ -196,7 +196,7 @@ static int __init xen_noselfballooning_setup(char *s)
__setup("noselfballooning", xen_noselfballooning_setup);
#else /* !CONFIG_FRONTSWAP */
/* Enable with kernel boot option. */
-static bool use_selfballooning __initdata = false;
+static bool use_selfballooning;
static int __init xen_selfballooning_setup(char *s)
{
@@ -537,7 +537,7 @@ int register_xen_selfballooning(struct device *dev)
}
EXPORT_SYMBOL(register_xen_selfballooning);
-static int __init xen_selfballoon_init(void)
+int xen_selfballoon_init(bool use_selfballooning, bool use_frontswap_selfshrink)
{
bool enable = false;
@@ -571,7 +571,4 @@ static int __init xen_selfballoon_init(void)
return 0;
}
-
-subsys_initcall(xen_selfballoon_init);
-
-MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(xen_selfballoon_init);