diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 19:47:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 19:47:50 -0700 |
commit | 56847d857cb0c3ee78c22ce776a26f88d9ffd4d4 (patch) | |
tree | a85bcf204a53e45d26f6a3984f16ddd525eef3e7 | |
parent | 191a712090bb8a10e6f129360eeed2d68f3d4c9a (diff) | |
parent | 8d564368a9a3197f43e56dadf4a18c5738849f94 (diff) | |
download | blackbird-op-linux-56847d857cb0c3ee78c22ce776a26f88d9ffd4d4.tar.gz blackbird-op-linux-56847d857cb0c3ee78c22ce776a26f88d9ffd4d4.zip |
Merge branch 'akpm' (incoming from Andrew)
Merge second batch of fixes from Andrew Morton:
- various misc bits
- some printk updates
- a new "SRAM" driver.
- MAINTAINERS updates
- the backlight driver queue
- checkpatch updates
- a few init/ changes
- a huge number of drivers/rtc changes
- fatfs updates
- some lib/idr.c work
- some renaming of the random driver interfaces
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (285 commits)
net: rename random32 to prandom
net/core: remove duplicate statements by do-while loop
net/core: rename random32() to prandom_u32()
net/netfilter: rename random32() to prandom_u32()
net/sched: rename random32() to prandom_u32()
net/sunrpc: rename random32() to prandom_u32()
scsi: rename random32() to prandom_u32()
lguest: rename random32() to prandom_u32()
uwb: rename random32() to prandom_u32()
video/uvesafb: rename random32() to prandom_u32()
mmc: rename random32() to prandom_u32()
drbd: rename random32() to prandom_u32()
kernel/: rename random32() to prandom_u32()
mm/: rename random32() to prandom_u32()
lib/: rename random32() to prandom_u32()
x86: rename random32() to prandom_u32()
x86: pageattr-test: remove srandom32 call
uuid: use prandom_bytes()
raid6test: use prandom_bytes()
sctp: convert sctp_assoc_set_id() to use idr_alloc_cyclic()
...
218 files changed, 2859 insertions, 2303 deletions
@@ -761,6 +761,10 @@ S: Northampton S: NN1 3QT S: United Kingdom +N: Massimo Dal Zotto +E: dz@debian.org +D: i8k Dell laptop SMM driver + N: Uwe Dannowski E: Uwe.Dannowski@ira.uka.de W: http://i30www.ira.uka.de/~dannowsk/ diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index aa0c1e63f050..6e97e73d87b5 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -420,7 +420,7 @@ person it names. This tag documents that potentially interested parties have been included in the discussion -14) Using Reported-by:, Tested-by: and Reviewed-by: +14) Using Reported-by:, Tested-by:, Reviewed-by: and Suggested-by: If this patch fixes a problem reported by somebody else, consider adding a Reported-by: tag to credit the reporter for their contribution. Please @@ -468,6 +468,13 @@ done on the patch. Reviewed-by: tags, when supplied by reviewers known to understand the subject area and to perform thorough reviews, will normally increase the likelihood of your patch getting into the kernel. +A Suggested-by: tag indicates that the patch idea is suggested by the person +named and ensures credit to the person for the idea. Please note that this +tag should not be added without the reporter's permission, especially if the +idea was not posted in a public forum. That said, if we diligently credit our +idea reporters, they will, hopefully, be inspired to help us again in the +future. + 15) The canonical patch format diff --git a/Documentation/backlight/lp855x-driver.txt b/Documentation/backlight/lp855x-driver.txt index 18b06ca038ea..1c732f0c6758 100644 --- a/Documentation/backlight/lp855x-driver.txt +++ b/Documentation/backlight/lp855x-driver.txt @@ -32,14 +32,10 @@ Platform data for lp855x For supporting platform specific data, the lp855x platform data can be used. * name : Backlight driver name. If it is not defined, default name is set. -* mode : Brightness control mode. PWM or register based. * device_control : Value of DEVICE CONTROL register. * initial_brightness : Initial value of backlight brightness. * period_ns : Platform specific PWM period value. unit is nano. Only valid when brightness is pwm input mode. -* load_new_rom_data : - 0 : use default configuration data - 1 : update values of eeprom or eprom registers on loading driver * size_program : Total size of lp855x_rom_data. * rom_data : List of new eeprom/eprom registers. @@ -54,10 +50,8 @@ static struct lp855x_rom_data lp8552_eeprom_arr[] = { static struct lp855x_platform_data lp8552_pdata = { .name = "lcd-bl", - .mode = REGISTER_BASED, .device_control = I2C_CONFIG(LP8552), .initial_brightness = INITIAL_BRT, - .load_new_rom_data = 1, .size_program = ARRAY_SIZE(lp8552_eeprom_arr), .rom_data = lp8552_eeprom_arr, }; @@ -65,7 +59,6 @@ static struct lp855x_platform_data lp8552_pdata = { example 2) lp8556 platform data : pwm input mode with default rom data static struct lp855x_platform_data lp8556_pdata = { - .mode = PWM_BASED, .device_control = PWM_CONFIG(LP8556), .initial_brightness = INITIAL_BRT, .period_ns = 1000000, diff --git a/Documentation/devicetree/bindings/media/coda.txt b/Documentation/devicetree/bindings/media/coda.txt new file mode 100644 index 000000000000..2865d04e4030 --- /dev/null +++ b/Documentation/devicetree/bindings/media/coda.txt @@ -0,0 +1,30 @@ +Chips&Media Coda multi-standard codec IP +======================================== + +Coda codec IPs are present in i.MX SoCs in various versions, +called VPU (Video Processing Unit). + +Required properties: +- compatible : should be "fsl,<chip>-src" for i.MX SoCs: + (a) "fsl,imx27-vpu" for CodaDx6 present in i.MX27 + (b) "fsl,imx53-vpu" for CODA7541 present in i.MX53 + (c) "fsl,imx6q-vpu" for CODA960 present in i.MX6q +- reg: should be register base and length as documented in the + SoC reference manual +- interrupts : Should contain the VPU interrupt. For CODA960, + a second interrupt is needed for the MJPEG unit. +- clocks : Should contain the ahb and per clocks, in the order + determined by the clock-names property. +- clock-names : Should be "ahb", "per" +- iram : phandle pointing to the SRAM device node + +Example: + +vpu: vpu@63ff4000 { + compatible = "fsl,imx53-vpu"; + reg = <0x63ff4000 0x1000>; + interrupts = <9>; + clocks = <&clks 63>, <&clks 63>; + clock-names = "ahb", "per"; + iram = <&ocram>; +}; diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt new file mode 100644 index 000000000000..4d0a00e453a8 --- /dev/null +++ b/Documentation/devicetree/bindings/misc/sram.txt @@ -0,0 +1,16 @@ +Generic on-chip SRAM + +Simple IO memory regions to be managed by the genalloc API. + +Required properties: + +- compatible : mmio-sram + +- reg : SRAM iomem address range + +Example: + +sram: sram@5c000000 { + compatible = "mmio-sram"; + reg = <0x5c000000 0x40000>; /* 256 KiB SRAM at address 0x5c000000 */ +}; diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt new file mode 100644 index 000000000000..2a3feabd3b22 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt @@ -0,0 +1,15 @@ +Atmel AT91RM9200 Real Time Clock + +Required properties: +- compatible: should be: "atmel,at91rm9200-rtc" +- reg: physical base address of the controller and length of memory mapped + region. +- interrupts: rtc alarm/event interrupt + +Example: + +rtc@fffffe00 { + compatible = "atmel,at91rm9200-rtc"; + reg = <0xfffffe00 0x100>; + interrupts = <1 4 7>; +}; diff --git a/Documentation/devicetree/bindings/video/backlight/lp855x.txt b/Documentation/devicetree/bindings/video/backlight/lp855x.txt new file mode 100644 index 000000000000..1482103d288f --- /dev/null +++ b/Documentation/devicetree/bindings/video/backlight/lp855x.txt @@ -0,0 +1,41 @@ +lp855x bindings + +Required properties: + - compatible: "ti,lp8550", "ti,lp8551", "ti,lp8552", "ti,lp8553", + "ti,lp8556", "ti,lp8557" + - reg: I2C slave address (u8) + - dev-ctrl: Value of DEVICE CONTROL register (u8). It depends on the device. + +Optional properties: + - bl-name: Backlight device name (string) + - init-brt: Initial value of backlight brightness (u8) + - pwm-period: PWM period value. Set only PWM input mode used (u32) + - rom-addr: Register address of ROM area to be updated (u8) + - rom-val: Register value to be updated (u8) + +Example: + + /* LP8556 */ + backlight@2c { + compatible = "ti,lp8556"; + reg = <0x2c>; + + bl-name = "lcd-bl"; + dev-ctrl = /bits/ 8 <0x85>; + init-brt = /bits/ 8 <0x10>; + }; + + /* LP8557 */ + backlight@2c { + compatible = "ti,lp8557"; + reg = <0x2c>; + + dev-ctrl = /bits/ 8 <0x41>; + init-brt = /bits/ 8 <0x0a>; + + /* 4V OV, 4 output LED string enabled */ + rom_14h { + rom-addr = /bits/ 8 <0x14>; + rom-val = /bits/ 8 <0xcf>; + }; + }; diff --git a/Documentation/devicetree/bindings/video/backlight/tps65217-backlight.txt b/Documentation/devicetree/bindings/video/backlight/tps65217-backlight.txt new file mode 100644 index 000000000000..5fb9279ac287 --- /dev/null +++ b/Documentation/devicetree/bindings/video/backlight/tps65217-backlight.txt @@ -0,0 +1,27 @@ +TPS65217 family of regulators + +The TPS65217 chip contains a boost converter and current sinks which can be +used to drive LEDs for use as backlights. + +Required properties: +- compatible: "ti,tps65217" +- reg: I2C slave address +- backlight: node for specifying WLED1 and WLED2 lines in TPS65217 +- isel: selection bit, valid values: 1 for ISEL1 (low-level) and 2 for ISEL2 (high-level) +- fdim: PWM dimming frequency, valid values: 100, 200, 500, 1000 +- default-brightness: valid values: 0-100 + +Each regulator is defined using the standard binding for regulators. + +Example: + + tps: tps@24 { + reg = <0x24>; + compatible = "ti,tps65217"; + backlight { + isel = <1>; /* 1 - ISET1, 2 ISET2 */ + fdim = <100>; /* TPS65217_BL_FDIM_100HZ */ + default-brightness = <50>; + }; + }; + diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt index d230dd9c99b0..4a93e98b290a 100644 --- a/Documentation/filesystems/vfat.txt +++ b/Documentation/filesystems/vfat.txt @@ -150,12 +150,28 @@ discard -- If set, issues discard/TRIM commands to the block device when blocks are freed. This is useful for SSD devices and sparse/thinly-provisoned LUNs. -nfs -- This option maintains an index (cache) of directory - inodes by i_logstart which is used by the nfs-related code to - improve look-ups. +nfs=stale_rw|nostale_ro + Enable this only if you want to export the FAT filesystem + over NFS. + + stale_rw: This option maintains an index (cache) of directory + inodes by i_logstart which is used by the nfs-related code to + improve look-ups. Full file operations (read/write) over NFS is + supported but with cache eviction at NFS server, this could + result in ESTALE issues. + + nostale_ro: This option bases the inode number and filehandle + on the on-disk location of a file in the MS-DOS directory entry. + This ensures that ESTALE will not be returned after a file is + evicted from the inode cache. However, it means that operations + such as rename, create and unlink could cause filehandles that + previously pointed at one file to point at a different file, + potentially causing data corruption. For this reason, this + option also mounts the filesystem readonly. + + To maintain backward compatibility, '-o nfs' is also accepted, + defaulting to stale_rw - Enable this only if you want to export the FAT filesystem - over NFS <bool>: 0,1,yes,no,true,false diff --git a/MAINTAINERS b/MAINTAINERS index 0d0108fea26f..e8f8c3549684 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -90,6 +90,9 @@ Descriptions of section entries: F: drivers/net/* all files in drivers/net, but not below F: */net/* all files in "any top level directory"/net One pattern per line. Multiple F: lines acceptable. + N: Files and directories with regex patterns. + N: [^a-z]tegra all files whose path contains the word tegra + One pattern per line. Multiple N: lines acceptable. X: Files and directories that are NOT maintained, same rules as F: Files exclusions are tested before file matches. Can be useful for excluding a specific subdirectory, for instance: @@ -97,13 +100,12 @@ Descriptions of section entries: X: net/ipv6/ matches all files in and below net excluding net/ipv6/ K: Keyword perl extended regex pattern to match content in a - patch or file, or an affected filename. For instance: + patch or file. For instance: K: of_get_profile - matches patch or file content, or filenames, that contain - "of_get_profile" + matches patches or files that contain "of_get_profile" K: \b(printk|pr_(info|err))\b - matches patch or file content, or filenames, that contain one or - more of the words printk, pr_info or pr_err + matches patches or files that contain one or more of the words + printk, pr_info or pr_err One regex pattern per line. Multiple K: lines acceptable. Note: For the hard of thinking, this list is meant to remain in alphabetical @@ -2442,9 +2444,7 @@ S: Maintained F: drivers/platform/x86/dell-laptop.c DELL LAPTOP SMM DRIVER -M: Massimo Dal Zotto <dz@debian.org> -W: http://www.debian.org/~dz/i8k/ -S: Maintained +S: Orphan F: drivers/char/i8k.c F: include/uapi/linux/i8k.h @@ -7893,7 +7893,7 @@ L: linux-tegra@vger.kernel.org Q: http://patchwork.ozlabs.org/project/linux-tegra/list/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra.git S: Supported -K: (?i)[^a-z]tegra +N: [^a-z]tegra TEHUTI ETHERNET DRIVER M: Andy Gospodarek <andy@greyhouse.net> @@ -8379,9 +8379,10 @@ S: Maintained F: drivers/usb/serial/option.c USB PEGASUS DRIVER -M: Petko Manolov <petkan@users.sourceforge.net> +M: Petko Manolov <petkan@nucleusys.com> L: linux-usb@vger.kernel.org L: netdev@vger.kernel.org +T: git git://git.code.sf.net/p/pegasus2/git W: http://pegasus2.sourceforge.net/ S: Maintained F: drivers/net/usb/pegasus.* @@ -8401,9 +8402,10 @@ S: Supported F: drivers/usb/class/usblp.c USB RTL8150 DRIVER -M: Petko Manolov <petkan@users.sourceforge.net> +M: Petko Manolov <petkan@nucleusys.com> L: linux-usb@vger.kernel.org L: netdev@vger.kernel.org +T: git git://git.code.sf.net/p/pegasus2/git W: http://pegasus2.sourceforge.net/ S: Maintained F: drivers/net/usb/rtl8150.c diff --git a/arch/arm/kernel/early_printk.c b/arch/arm/kernel/early_printk.c index 85aa2b292692..43076536965c 100644 --- a/arch/arm/kernel/early_printk.c +++ b/arch/arm/kernel/early_printk.c @@ -29,28 +29,17 @@ static void early_console_write(struct console *con, const char *s, unsigned n) early_write(s, n); } -static struct console early_console = { +static struct console early_console_dev = { .name = "earlycon", .write = early_console_write, .flags = CON_PRINTBUFFER | CON_BOOT, .index = -1, }; -asmlinkage void early_printk(const char *fmt, ...) -{ - char buf[512]; - int n; - va_list ap; - - va_start(ap, fmt); - n = vscnprintf(buf, sizeof(buf), fmt, ap); - early_write(buf, n); - va_end(ap); -} - static int __init setup_early_printk(char *buf) { - register_console(&early_console); + early_console = &early_console_dev; + register_console(&early_console_dev); return 0; } diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c index 84ed8375113c..61fbd2de993d 100644 --- a/arch/blackfin/kernel/early_printk.c +++ b/arch/blackfin/kernel/early_printk.c @@ -25,8 +25,6 @@ extern struct console *bfin_earlyserial_init(unsigned int port, extern struct console *bfin_jc_early_init(void); #endif -static struct console *early_console; - /* Default console */ #define DEFAULT_PORT 0 #define DEFAULT_CFLAG CS8|B57600 diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c index 60dcacc68038..365f2d53f1b2 100644 --- a/arch/microblaze/kernel/early_printk.c +++ b/arch/microblaze/kernel/early_printk.c @@ -21,7 +21,6 @@ #include <asm/setup.h> #include <asm/prom.h> -static u32 early_console_initialized; static u32 base_addr; #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE @@ -109,27 +108,11 @@ static struct console early_serial_uart16550_console = { }; #endif /* CONFIG_SERIAL_8250_CONSOLE */ -static struct console *early_console; - -void early_printk(const char *fmt, ...) -{ - char buf[512]; - int n; - va_list ap; - - if (early_console_initialized) { - va_start(ap, fmt); - n = vscnprintf(buf, 512, fmt, ap); - early_console->write(early_console, buf, n); - va_end(ap); - } -} - int __init setup_early_printk(char *opt) { int version = 0; - if (early_console_initialized) + if (early_console) return 1; base_addr = of_early_console(&version); @@ -159,7 +142,6 @@ int __init setup_early_printk(char *opt) } register_console(early_console); - early_console_initialized = 1; return 0; } return 1; @@ -169,7 +151,7 @@ int __init setup_early_printk(char *opt) * only for early console because of performance degression */ void __init remap_early_printk(void) { - if (!early_console_initialized || !early_console) + if (!early_console) return; pr_info("early_printk_console remapping from 0x%x to ", base_addr); base_addr = (u32) ioremap(base_addr, PAGE_SIZE); @@ -194,9 +176,9 @@ void __init remap_early_printk(void) void __init disable_early_printk(void) { - if (!early_console_initialized || !early_console) + if (!early_console) return; pr_warn("disabling early console\n"); unregister_console(early_console); - early_console_initialized = 0; + early_console = NULL; } diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c index 9e6440eaa455..505cb77d1280 100644 --- a/arch/mips/kernel/early_printk.c +++ b/arch/mips/kernel/early_printk.c @@ -7,7 +7,9 @@ * Copyright (C) 2007 MIPS Technologies, Inc. * written by Ralf Baechle (ralf@linux-mips.org) */ +#include <linux/kernel.h> #include <linux/console.h> +#include <linux/printk.h> #include <linux/init.h> #include <asm/setup.h> @@ -24,20 +26,18 @@ static void early_console_write(struct console *con, const char *s, unsigned n) } } -static struct console early_console = { +static struct console early_console_prom = { .name = "early", .write = early_console_write, .flags = CON_PRINTBUFFER | CON_BOOT, .index = -1 }; -static int early_console_initialized __initdata; - void __init setup_early_printk(void) { - if (early_console_initialized) + if (early_console) return; - early_console_initialized = 1; + early_console = &early_console_prom; - register_console(&early_console); + register_console(&early_console_prom); } diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index f9748498fe58..13b867093499 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c @@ -156,15 +156,13 @@ static struct console udbg_console = { .index = 0, }; -static int early_console_initialized; - /* * Called by setup_system after ppc_md->probe and ppc_md->early_init. * Call it again after setting udbg_putc in ppc_md->setup_arch. */ void __init register_early_udbg_console(void) { - if (early_console_initialized) + if (early_console) return; if (!udbg_putc) @@ -174,7 +172,7 @@ void __init register_early_udbg_console(void) printk(KERN_INFO "early console immortal !\n"); udbg_console.flags &= ~CON_BOOT; } - early_console_initialized = 1; + early_console = &udbg_console; register_console(&udbg_console); } diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index 47475cca068a..fe584e516964 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c @@ -104,6 +104,7 @@ void sh_bios_vbr_reload(void) ); } +#ifdef CONFIG_EARLY_PRINTK /* * Print a string through the BIOS */ @@ -144,8 +145,6 @@ static struct console bios_console = { .index = -1, }; -static struct console *early_console; - static int __init setup_early_printk(char *buf) { int keep_early = 0; @@ -170,3 +169,4 @@ static int __init setup_early_printk(char *buf) return 0; } early_param("earlyprintk", setup_early_printk); +#endif diff --git a/arch/tile/kernel/early_printk.c b/arch/tile/kernel/early_printk.c index afb9c9a0d887..34d72a151bf3 100644 --- a/arch/tile/kernel/early_printk.c +++ b/arch/tile/kernel/early_printk.c @@ -17,6 +17,7 @@ #include <linux/init.h> #include <linux/string.h> #include <linux/irqflags.h> +#include <linux/printk.h> #include <asm/setup.h> #include <hv/hypervisor.h> @@ -33,25 +34,8 @@ static struct console early_hv_console = { }; /* Direct interface for emergencies */ -static struct console *early_console = &early_hv_console; -static int early_console_initialized; static int early_console_complete; -static void early_vprintk(const char *fmt, va_list ap) -{ - char buf[512]; - int n = vscnprintf(buf, sizeof(buf), fmt, ap); - early_console->write(early_console, buf, n); -} - -void early_printk(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - early_vprintk(fmt, ap); - va_end(ap); -} - void early_panic(const char *fmt, ...) { va_list ap; @@ -69,14 +53,13 @@ static int __initdata keep_early; static int __init setup_early_printk(char *str) { - if (early_console_initialized) + if (early_console) return 1; if (str != NULL && strncmp(str, "keep", 4) == 0) keep_early = 1; early_console = &early_hv_console; - early_console_initialized = 1; register_console(early_console); return 0; @@ -85,12 +68,12 @@ static int __init setup_early_printk(char *str) void __init disable_early_printk(void) { early_console_complete = 1; - if (!early_console_initialized || !early_console) + if (!early_console) return; if (!keep_early) { early_printk("disabling early console\n"); unregister_console(early_console); - early_console_initialized = 0; + early_console = NULL; } else { early_printk("keeping early console\n"); } @@ -98,7 +81,7 @@ void __init disable_early_printk(void) void warn_early_printk(void) { - if (early_console_complete || early_console_initialized) + if (early_console_complete || early_console) return; early_printk("\ Machine shutting down before console output is fully initialized.\n\ diff --git a/arch/um/kernel/early_printk.c b/arch/um/kernel/early_printk.c index 49480f092456..4a0800bc37b2 100644 --- a/arch/um/kernel/early_printk.c +++ b/arch/um/kernel/early_printk.c @@ -16,7 +16,7 @@ static void early_console_write(struct console *con, const char *s, unsigned int um_early_printk(s, n); } -static struct console early_console = { +static struct console early_console_dev = { .name = "earlycon", .write = early_console_write, .flags = CON_BOOT, @@ -25,8 +25,10 @@ static struct console early_console = { static int __init setup_early_printk(char *buf) { - register_console(&early_console); - + if (!early_console) { + early_console = &early_console_dev; + register_console(&early_console_dev); + } return 0; } diff --git a/arch/unicore32/kernel/early_printk.c b/arch/unicore32/kernel/early_printk.c index 3922255f1fa8..9be0d5d02a9a 100644 --- a/arch/unicore32/kernel/early_printk.c +++ b/arch/unicore32/kernel/early_printk.c @@ -33,21 +33,17 @@ static struct console early_ocd_console = { .index = -1, }; -/* Direct interface for emergencies */ -static struct console *early_console = &early_ocd_console; - -static int __initdata keep_early; - static int __init setup_early_printk(char *buf) { - if (!buf) + int keep_early; + + if (!buf || early_console) return 0; if (strstr(buf, "keep")) keep_early = 1; - if (!strncmp(buf, "ocd", 3)) - early_console = &early_ocd_console; + early_console = &early_ocd_console; if (keep_early) early_console->flags &= ~CON_BOOT; diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 9b9f18b49918..d15f575a861b 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -169,25 +169,9 @@ static struct console early_serial_console = { .index = -1, }; -/* Direct interface for emergencies */ -static struct console *early_console = &early_vga_console; -static int __initdata early_console_initialized; - -asmlinkage void early_printk(const char *fmt, ...) -{ - char buf[512]; - int n; - va_list ap; - - va_start(ap, fmt); - n = vscnprintf(buf, sizeof(buf), fmt, ap); - early_console->write(early_console, buf, n); - va_end(ap); -} - static inline void early_console_register(struct console *con, int keep_early) { - if (early_console->index != -1) { + if (con->index != -1) { printk(KERN_CRIT "ERROR: earlyprintk= %s already used\n", con->name); return; @@ -207,9 +191,8 @@ static int __init setup_early_printk(char *buf) if (!buf) return 0; - if (early_console_initialized) + if (early_console) return 0; - early_console_initialized = 1; keep = (strstr(buf, "keep") != NULL); diff --git a/arch/x86/mm/pageattr-test.c b/arch/x86/mm/pageattr-test.c index 0e38951e65eb..d0b1773d9d2e 100644 --- a/arch/x86/mm/pageattr-test.c +++ b/arch/x86/mm/pageattr-test.c @@ -130,13 +130,12 @@ static int pageattr_test(void) } failed += print_split(&sa); - srandom32(100); for (i = 0; i < NTEST; i++) { - unsigned long pfn = random32() % max_pfn_mapped; + unsigned long pfn = prandom_u32() % max_pfn_mapped; addr[i] = (unsigned long)__va(pfn << PAGE_SHIFT); - len[i] = random32() % 100; + len[i] = prandom_u32() % 100; len[i] = min_t(unsigned long, len[i], max_pfn_mapped - pfn - 1); if (len[i] == 0) diff --git a/crypto/async_tx/raid6test.c b/crypto/async_tx/raid6test.c index aa2b0270ed16..4a92bac744dc 100644 --- a/crypto/async_tx/raid6test.c +++ b/crypto/async_tx/raid6test.c @@ -46,15 +46,10 @@ static void callback(void *param) static void makedata(int disks) { - int i, j; + int i; for (i = 0; i < disks; i++) { - for (j = 0; j < PAGE_SIZE/sizeof(u32); j += sizeof(u32)) { - u32 *p = page_address(data[i]) + j; - - *p = random32(); - } - + prandom_bytes(page_address(data[i]), PAGE_SIZE); dataptrs[i] = data[i]; } } diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index a9eccfc6079b..83c5ae0ed56b 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) @@ -953,7 +954,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/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/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/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/media/platform/Kconfig b/drivers/media/platform/Kconfig index a0639e779973..26500094de7c 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/misc/Kconfig b/drivers/misc/Kconfig index e29e7980a359..3659d00efdc5 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 08a3cf2a7610..9290bb51a06a 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/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index a59684b5fc68..7861f1119b7d 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-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index f663746f4603..0f2b91bfee37 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -318,14 +318,14 @@ static int pm860x_rtc_probe(struct platform_device *pdev) pdata = pdev->dev.platform_data; - info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL); + info = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_rtc_info), + GFP_KERNEL); if (!info) return -ENOMEM; info->irq = platform_get_irq(pdev, 0); if (info->irq < 0) { dev_err(&pdev->dev, "No IRQ resource!\n"); - ret = -EINVAL; - goto out; + return info->irq; } info->chip = chip; @@ -333,12 +333,13 @@ static int pm860x_rtc_probe(struct platform_device *pdev) info->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, info); - ret = request_threaded_irq(info->irq, NULL, rtc_update_handler, - IRQF_ONESHOT, "rtc", info); + ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, + rtc_update_handler, IRQF_ONESHOT, "rtc", + info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq, ret); - goto out; + return ret; } /* set addresses of 32-bit base value for RTC time */ @@ -350,7 +351,7 @@ static int pm860x_rtc_probe(struct platform_device *pdev) ret = pm860x_rtc_read_time(&pdev->dev, &tm); if (ret < 0) { dev_err(&pdev->dev, "Failed to read initial time.\n"); - goto out_rtc; + return ret; } if ((tm.tm_year < 70) || (tm.tm_year > 138)) { tm.tm_year = 70; @@ -362,7 +363,7 @@ static int pm860x_rtc_probe(struct platform_device *pdev) ret = pm860x_rtc_set_time(&pdev->dev, &tm); if (ret < 0) { dev_err(&pdev->dev, "Failed to set initial time.\n"); - goto out_rtc; + return ret; } } rtc_tm_to_time(&tm, &ticks); @@ -373,12 +374,12 @@ static int pm860x_rtc_probe(struct platform_device *pdev) } } - info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev, + info->rtc_dev = devm_rtc_device_register(&pdev->dev, "88pm860x-rtc", &pm860x_rtc_ops, THIS_MODULE); ret = PTR_ERR(info->rtc_dev); if (IS_ERR(info->rtc_dev)) { dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); - goto out_rtc; + return ret; } /* @@ -405,11 +406,6 @@ static int pm860x_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); return 0; -out_rtc: - free_irq(info->irq, info); -out: - kfree(info); - return ret; } static int pm860x_rtc_remove(struct platform_device *pdev) @@ -423,9 +419,6 @@ static int pm860x_rtc_remove(struct platform_device *pdev) #endif /* VRTC_CALIBRATION */ platform_set_drvdata(pdev, NULL); - rtc_device_unregister(info->rtc_dev); - free_irq(info->irq, info); - kfree(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-ab8500.c b/drivers/rtc/rtc-ab8500.c index 57cde2b061e6..63cfa314a39f 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -422,20 +422,19 @@ static int ab8500_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, true); - rtc = rtc_device_register("ab8500-rtc", &pdev->dev, &ab8500_rtc_ops, - THIS_MODULE); + rtc = devm_rtc_device_register(&pdev->dev, "ab8500-rtc", + &ab8500_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { dev_err(&pdev->dev, "Registration failed\n"); err = PTR_ERR(rtc); return err; } - err = request_threaded_irq(irq, NULL, rtc_alarm_handler, - IRQF_NO_SUSPEND | IRQF_ONESHOT, "ab8500-rtc", rtc); - if (err < 0) { - rtc_device_unregister(rtc); + err = devm_request_threaded_irq(&pdev->dev, irq, NULL, + rtc_alarm_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT, + "ab8500-rtc", rtc); + if (err < 0) return err; - } platform_set_drvdata(pdev, rtc); @@ -450,13 +449,8 @@ static int ab8500_rtc_probe(struct platform_device *pdev) static int ab8500_rtc_remove(struct platform_device *pdev) { - struct rtc_device *rtc = platform_get_drvdata(pdev); - int irq = platform_get_irq_byname(pdev, "ALARM"); - ab8500_sysfs_rtc_unregister(&pdev->dev); - free_irq(irq, rtc); - rtc_device_unregister(rtc); platform_set_drvdata(pdev, NULL); return 0; diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index 8dd08305aae1..f47fbb5eee8b 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c @@ -202,7 +202,8 @@ static int __init at32_rtc_probe(struct platform_device *pdev) int irq; int ret; - rtc = kzalloc(sizeof(struct rtc_at32ap700x), GFP_KERNEL); + rtc = devm_kzalloc(&pdev->dev, sizeof(struct rtc_at32ap700x), + GFP_KERNEL); if (!rtc) { dev_dbg(&pdev->dev, "out of memory\n"); return -ENOMEM; @@ -223,7 +224,7 @@ static int __init at32_rtc_probe(struct platform_device *pdev) } rtc->irq = irq; - rtc->regs = ioremap(regs->start, resource_size(regs)); + rtc->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); if (!rtc->regs) { ret = -ENOMEM; dev_dbg(&pdev->dev, "could not map I/O memory\n"); @@ -244,20 +245,21 @@ static int __init at32_rtc_probe(struct platform_device *pdev) | RTC_BIT(CTRL_EN)); } - ret = request_irq(irq, at32_rtc_interrupt, IRQF_SHARED, "rtc", rtc); + ret = devm_request_irq(&pdev->dev, irq, at32_rtc_interrupt, IRQF_SHARED, + "rtc", rtc); if (ret) { dev_dbg(&pdev->dev, "could not request irq %d\n", irq); - goto out_iounmap; + goto out; } platform_set_drvdata(pdev, rtc); - rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, + rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &at32_rtc_ops, THIS_MODULE); if (IS_ERR(rtc->rtc)) { dev_dbg(&pdev->dev, "could not register rtc device\n"); ret = PTR_ERR(rtc->rtc); - goto out_free_irq; + goto out; } device_init_wakeup(&pdev->dev, 1); @@ -267,26 +269,15 @@ static int __init at32_rtc_probe(struct platform_device *pdev) return 0; -out_free_irq: - platform_set_drvdata(pdev, NULL); - free_irq(irq, rtc); -out_iounmap: - iounmap(rtc->regs); out: - kfree(rtc); + platform_set_drvdata(pdev, NULL); return ret; } static int __exit at32_rtc_remove(struct platform_device *pdev) { - struct rtc_at32ap700x *rtc = platform_get_drvdata(pdev); - device_init_wakeup(&pdev->dev, 0); - free_irq(rtc->irq, rtc); - iounmap(rtc->regs); - rtc_device_unregister(rtc->rtc); - kfree(rtc); platform_set_drvdata(pdev, NULL); return 0; @@ -302,17 +293,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..0eab77b22340 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> @@ -297,7 +299,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) "at91_rtc", pdev); if (ret) { dev_err(&pdev->dev, "IRQ %d already in use.\n", irq); - return ret; + goto err_unmap; } /* cpu init code should really have flagged this device as @@ -309,13 +311,20 @@ static int __init at91_rtc_probe(struct platform_device *pdev) rtc = rtc_device_register(pdev->name, &pdev->dev, &at91_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { - free_irq(irq, pdev); - return PTR_ERR(rtc); + ret = PTR_ERR(rtc); + goto err_free_irq; } platform_set_drvdata(pdev, rtc); dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n"); return 0; + +err_free_irq: + free_irq(irq, pdev); +err_unmap: + iounmap(at91_rtc_regs); + + return ret; } /* @@ -332,12 +341,13 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) free_irq(irq, pdev); rtc_device_unregister(rtc); + iounmap(at91_rtc_regs); platform_set_drvdata(pdev, NULL); return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP /* AT91RM9200 RTC Power management control */ @@ -369,39 +379,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-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 39cfd2ee0042..b60a34cb145a 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -20,6 +20,7 @@ #include <linux/ioctl.h> #include <linux/slab.h> #include <linux/platform_data/atmel.h> +#include <linux/io.h> #include <mach/at91_rtt.h> #include <mach/cpu.h> @@ -309,7 +310,7 @@ static int at91_rtc_probe(struct platform_device *pdev) return irq; } - rtc = kzalloc(sizeof *rtc, GFP_KERNEL); + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); if (!rtc) return -ENOMEM; @@ -320,18 +321,19 @@ static int at91_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); platform_set_drvdata(pdev, rtc); - rtc->rtt = ioremap(r->start, resource_size(r)); + rtc->rtt = devm_ioremap(&pdev->dev, r->start, resource_size(r)); if (!rtc->rtt) { dev_err(&pdev->dev, "failed to map registers, aborting.\n"); ret = -ENOMEM; goto fail; } - rtc->gpbr = ioremap(r_gpbr->start, resource_size(r_gpbr)); + rtc->gpbr = devm_ioremap(&pdev->dev, r_gpbr->start, + resource_size(r_gpbr)); if (!rtc->gpbr) { dev_err(&pdev->dev, "failed to map gpbr registers, aborting.\n"); ret = -ENOMEM; - goto fail_gpbr; + goto fail; } mr = rtt_readl(rtc, MR); @@ -346,20 +348,19 @@ static int at91_rtc_probe(struct platform_device *pdev) mr &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); rtt_writel(rtc, MR, mr); - rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev, - &at91_rtc_ops, THIS_MODULE); + rtc->rtcdev = devm_rtc_device_register(&pdev->dev, pdev->name, + &at91_rtc_ops, THIS_MODULE); if (IS_ERR(rtc->rtcdev)) { ret = PTR_ERR(rtc->rtcdev); - goto fail_register; + goto fail; } /* register irq handler after we know what name we'll use */ - ret = request_irq(rtc->irq, at91_rtc_interrupt, IRQF_SHARED, - dev_name(&rtc->rtcdev->dev), rtc); + ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt, + IRQF_SHARED, dev_name(&rtc->rtcdev->dev), rtc); if (ret) { dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq); - rtc_device_unregister(rtc->rtcdev); - goto fail_register; + goto fail; } /* NOTE: sam9260 rev A silicon has a ROM bug which resets the @@ -374,13 +375,8 @@ static int at91_rtc_probe(struct platform_device *pdev) return 0; -fail_register: - iounmap(rtc->gpbr); -fail_gpbr: - iounmap(rtc->rtt); fail: platform_set_drvdata(pdev, NULL); - kfree(rtc); return ret; } @@ -394,14 +390,8 @@ static int at91_rtc_remove(struct platform_device *pdev) /* disable all interrupts */ rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); - free_irq(rtc->irq, rtc); - - rtc_device_unregister(rtc->rtcdev); - iounmap(rtc->gpbr); - iounmap(rtc->rtt); platform_set_drvdata(pdev, NULL); - kfree(rtc); return 0; } @@ -414,14 +404,13 @@ static void at91_rtc_shutdown(struct platform_device *pdev) rtt_writel(rtc, MR, mr & ~rtc->imr); } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP /* AT91SAM9 RTC Power management control */ -static int at91_rtc_suspend(struct platform_device *pdev, - pm_message_t state) +static int at91_rtc_suspend(struct device *dev) { - struct sam9_rtc *rtc = platform_get_drvdata(pdev); + struct sam9_rtc *rtc = dev_get_drvdata(dev); u32 mr = rtt_readl(rtc, MR); /* @@ -430,7 +419,7 @@ static int at91_rtc_suspend(struct platform_device *pdev, */ rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); if (rtc->imr) { - if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { + if (device_may_wakeup(dev) && (mr & AT91_RTT_ALMIEN)) { enable_irq_wake(rtc->irq); /* don't let RTTINC cause wakeups */ if (mr & AT91_RTT_RTTINCIEN) @@ -442,13 +431,13 @@ static int at91_rtc_suspend(struct platform_device *pdev, return 0; } -static int at91_rtc_resume(struct platform_device *pdev) +static int at91_rtc_resume(struct device *dev) { - struct sam9_rtc *rtc = platform_get_drvdata(pdev); + struct sam9_rtc *rtc = dev_get_drvdata(dev); u32 mr; if (rtc->imr) { - if (device_may_wakeup(&pdev->dev)) + if (device_may_wakeup(dev)) disable_irq_wake(rtc->irq); mr = rtt_readl(rtc, MR); rtt_writel(rtc, MR, mr | rtc->imr); @@ -456,20 +445,18 @@ static int at91_rtc_resume(struct platform_device *pdev) return 0; } -#else -#define at91_rtc_suspend NULL -#define at91_rtc_resume NULL #endif +static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume); + static struct platform_driver at91_rtc_driver = { .probe = at91_rtc_probe, .remove = at91_rtc_remove, .shutdown = at91_rtc_shutdown, - .suspend = at91_rtc_suspend, - .resume = at91_rtc_resume, .driver = { .name = "rtc-at91sam9", .owner = THIS_MODULE, + .pm = &at91_rtc_pm_ops, }, }; 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-bfin.c b/drivers/rtc/rtc-bfin.c index 4ec614b0954d..ad44ec5dc29a 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -352,14 +352,14 @@ static int bfin_rtc_probe(struct platform_device *pdev) dev_dbg_stamp(dev); /* Allocate memory for our RTC struct */ - rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); + rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL); if (unlikely(!rtc)) return -ENOMEM; platform_set_drvdata(pdev, rtc); device_init_wakeup(dev, 1); /* Register our RTC with the RTC framework */ - rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, + rtc->rtc_dev = devm_rtc_device_register(dev, pdev->name, &bfin_rtc_ops, THIS_MODULE); if (unlikely(IS_ERR(rtc->rtc_dev))) { ret = PTR_ERR(rtc->rtc_dev); @@ -367,9 +367,10 @@ static int bfin_rtc_probe(struct platform_device *pdev) } /* Grab the IRQ and init the hardware */ - ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, 0, pdev->name, dev); + ret = devm_request_irq(dev, IRQ_RTC, bfin_rtc_interrupt, 0, + pdev->name, dev); if (unlikely(ret)) - goto err_reg; + goto err; /* sometimes the bootloader touched things, but the write complete was not * enabled, so let's just do a quick timeout here since the IRQ will not fire ... */ @@ -381,32 +382,23 @@ static int bfin_rtc_probe(struct platform_device *pdev) return 0; -err_reg: - rtc_device_unregister(rtc->rtc_dev); err: - kfree(rtc); return ret; } static int bfin_rtc_remove(struct platform_device *pdev) { - struct bfin_rtc *rtc = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; bfin_rtc_reset(dev, 0); - free_irq(IRQ_RTC, dev); - rtc_device_unregister(rtc->rtc_dev); platform_set_drvdata(pdev, NULL); - kfree(rtc); return 0; } -#ifdef CONFIG_PM -static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int bfin_rtc_suspend(struct device *dev) { - struct device *dev = &pdev->dev; - dev_dbg_stamp(dev); if (device_may_wakeup(dev)) { @@ -418,10 +410,8 @@ static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int bfin_rtc_resume(struct platform_device *pdev) +static int bfin_rtc_resume(struct device *dev) { - struct device *dev = &pdev->dev; - dev_dbg_stamp(dev); if (device_may_wakeup(dev)) @@ -440,20 +430,18 @@ static int bfin_rtc_resume(struct platform_device *pdev) return 0; } -#else -# define bfin_rtc_suspend NULL -# define bfin_rtc_resume NULL #endif +static SIMPLE_DEV_PM_OPS(bfin_rtc_pm_ops, bfin_rtc_suspend, bfin_rtc_resume); + static struct platform_driver bfin_rtc_driver = { .driver = { .name = "rtc-bfin", .owner = THIS_MODULE, + .pm = &bfin_rtc_pm_ops, }, .probe = bfin_rtc_probe, .remove = bfin_rtc_remove, - .suspend = bfin_rtc_suspend, - .resume = bfin_rtc_resume, }; module_platform_driver(bfin_rtc_driver); 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-bq4802.c b/drivers/rtc/rtc-bq4802.c index 693be71b5b18..af2886784a7b 100644 --- a/drivers/rtc/rtc-bq4802.c +++ b/drivers/rtc/rtc-bq4802.c @@ -142,7 +142,7 @@ static const struct rtc_class_ops bq4802_ops = { static int bq4802_probe(struct platform_device *pdev) { - struct bq4802 *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct bq4802 *p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); int err = -ENOMEM; if (!p) @@ -155,54 +155,41 @@ static int bq4802_probe(struct platform_device *pdev) p->r = platform_get_resource(pdev, IORESOURCE_IO, 0); err = -EINVAL; if (!p->r) - goto out_free; + goto out; } if (p->r->flags & IORESOURCE_IO) { p->ioport = p->r->start; p->read = bq4802_read_io; p->write = bq4802_write_io; } else if (p->r->flags & IORESOURCE_MEM) { - p->regs = ioremap(p->r->start, resource_size(p->r)); + p->regs = devm_ioremap(&pdev->dev, p->r->start, + resource_size(p->r)); p->read = bq4802_read_mem; p->write = bq4802_write_mem; } else { err = -EINVAL; - goto out_free; + goto out; } platform_set_drvdata(pdev, p); - p->rtc = rtc_device_register("bq4802", &pdev->dev, - &bq4802_ops, THIS_MODULE); + p->rtc = devm_rtc_device_register(&pdev->dev, "bq4802", + &bq4802_ops, THIS_MODULE); if (IS_ERR(p->rtc)) { err = PTR_ERR(p->rtc); - goto out_iounmap; + goto out; } err = 0; out: return err; -out_iounmap: - if (p->r->flags & IORESOURCE_MEM) - iounmap(p->regs); -out_free: - kfree(p); - goto out; } static int bq4802_remove(struct platform_device *pdev) { - struct bq4802 *p = platform_get_drvdata(pdev); - - rtc_device_unregister(p->rtc); - if (p->r->flags & IORESOURCE_MEM) - iounmap(p->regs); - platform_set_drvdata(pdev, NULL); - kfree(p); - return 0; } diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index af97c94e8a3a..cc5bea9c4b1c 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -804,9 +804,8 @@ static int cmos_suspend(struct device *dev) mask = RTC_IRQMASK; tmp &= ~mask; CMOS_WRITE(tmp, RTC_CONTROL); + hpet_mask_rtc_irq_bit(mask); - /* shut down hpet emulation - we don't need it for alarm */ - hpet_mask_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE); cmos_checkintr(cmos, tmp); } spin_unlock_irq(&rtc_lock); @@ -870,6 +869,7 @@ static int cmos_resume(struct device *dev) rtc_update_irq(cmos->rtc, 1, mask); tmp &= ~RTC_AIE; hpet_mask_rtc_irq_bit(RTC_AIE); + hpet_rtc_timer_init(); } while (mask & RTC_AIE); spin_unlock_irq(&rtc_lock); } diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 2d28ec1aa1cd..93c06588ddca 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c @@ -47,7 +47,7 @@ struct coh901331_port { u32 physize; void __iomem *virtbase; int irq; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP u32 irqmaskstore; #endif }; @@ -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; @@ -226,17 +225,17 @@ static int __init coh901331_probe(struct platform_device *pdev) return ret; } -#ifdef CONFIG_PM -static int coh901331_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int coh901331_suspend(struct device *dev) { - struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); + struct coh901331_port *rtap = dev_get_drvdata(dev); /* * If this RTC alarm will be used for waking the system up, * don't disable it of course. Else we just disable the alarm * and await suspension. */ - if (device_may_wakeup(&pdev->dev)) { + if (device_may_wakeup(dev)) { enable_irq_wake(rtap->irq); } else { clk_enable(rtap->clk); @@ -248,12 +247,12 @@ static int coh901331_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int coh901331_resume(struct platform_device *pdev) +static int coh901331_resume(struct device *dev) { - struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); + struct coh901331_port *rtap = dev_get_drvdata(dev); clk_prepare(rtap->clk); - if (device_may_wakeup(&pdev->dev)) { + if (device_may_wakeup(dev)) { disable_irq_wake(rtap->irq); } else { clk_enable(rtap->clk); @@ -262,11 +261,10 @@ static int coh901331_resume(struct platform_device *pdev) } return 0; } -#else -#define coh901331_suspend NULL -#define coh901331_resume NULL #endif +static SIMPLE_DEV_PM_OPS(coh901331_pm_ops, coh901331_suspend, coh901331_resume); + static void coh901331_shutdown(struct platform_device *pdev) { struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); @@ -280,25 +278,13 @@ static struct platform_driver coh901331_driver = { .driver = { .name = "rtc-coh901331", .owner = THIS_MODULE, + .pm = &coh901331_pm_ops, }, .remove = __exit_p(coh901331_remove), - .suspend = coh901331_suspend, - .resume = coh901331_resume, .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-ds1216.c b/drivers/rtc/rtc-ds1216.c index 45cd8c9f5a39..c7702b7269f7 100644 --- a/drivers/rtc/rtc-ds1216.c +++ b/drivers/rtc/rtc-ds1216.c @@ -30,8 +30,6 @@ struct ds1216_regs { struct ds1216_priv { struct rtc_device *rtc; void __iomem *ioaddr; - size_t size; - unsigned long baseaddr; }; static const u8 magic[] = { @@ -144,57 +142,33 @@ static int __init ds1216_rtc_probe(struct platform_device *pdev) { struct resource *res; struct ds1216_priv *priv; - int ret = 0; u8 dummy[8]; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; - priv = kzalloc(sizeof *priv, GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; platform_set_drvdata(pdev, priv); - priv->size = resource_size(res); - if (!request_mem_region(res->start, priv->size, pdev->name)) { - ret = -EBUSY; - goto out; - } - priv->baseaddr = res->start; - priv->ioaddr = ioremap(priv->baseaddr, priv->size); - if (!priv->ioaddr) { - ret = -ENOMEM; - goto out; - } - priv->rtc = rtc_device_register("ds1216", &pdev->dev, - &ds1216_rtc_ops, THIS_MODULE); - if (IS_ERR(priv->rtc)) { - ret = PTR_ERR(priv->rtc); - goto out; - } + priv->ioaddr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->ioaddr)) + return PTR_ERR(priv->ioaddr); + + priv->rtc = devm_rtc_device_register(&pdev->dev, "ds1216", + &ds1216_rtc_ops, THIS_MODULE); + if (IS_ERR(priv->rtc)) + return PTR_ERR(priv->rtc); /* dummy read to get clock into a known state */ ds1216_read(priv->ioaddr, dummy); return 0; - -out: - if (priv->ioaddr) - iounmap(priv->ioaddr); - if (priv->baseaddr) - release_mem_region(priv->baseaddr, priv->size); - kfree(priv); - return ret; } static int __exit ds1216_rtc_remove(struct platform_device *pdev) { - struct ds1216_priv *priv = platform_get_drvdata(pdev); - - rtc_device_unregister(priv->rtc); - iounmap(priv->ioaddr); - release_mem_region(priv->baseaddr, priv->size); - kfree(priv); return 0; } diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index d989412a348a..398c96a98fc4 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c @@ -25,8 +25,6 @@ struct ds1286_priv { struct rtc_device *rtc; u32 __iomem *rtcregs; - size_t size; - unsigned long baseaddr; spinlock_t lock; }; @@ -270,7 +268,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 +278,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); @@ -334,56 +331,30 @@ static int ds1286_probe(struct platform_device *pdev) struct rtc_device *rtc; struct resource *res; struct ds1286_priv *priv; - int ret = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; - priv = kzalloc(sizeof(struct ds1286_priv), GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(struct ds1286_priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->size = resource_size(res); - if (!request_mem_region(res->start, priv->size, pdev->name)) { - ret = -EBUSY; - goto out; - } - priv->baseaddr = res->start; - priv->rtcregs = ioremap(priv->baseaddr, priv->size); - if (!priv->rtcregs) { - ret = -ENOMEM; - goto out; - } + priv->rtcregs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->rtcregs)) + return PTR_ERR(priv->rtcregs); + spin_lock_init(&priv->lock); platform_set_drvdata(pdev, priv); - rtc = rtc_device_register("ds1286", &pdev->dev, - &ds1286_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - goto out; - } + rtc = devm_rtc_device_register(&pdev->dev, "ds1286", &ds1286_ops, + THIS_MODULE); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); priv->rtc = rtc; return 0; - -out: - if (priv->rtc) - rtc_device_unregister(priv->rtc); - if (priv->rtcregs) - iounmap(priv->rtcregs); - if (priv->baseaddr) - release_mem_region(priv->baseaddr, priv->size); - kfree(priv); - return ret; } static int ds1286_remove(struct platform_device *pdev) { - struct ds1286_priv *priv = platform_get_drvdata(pdev); - - rtc_device_unregister(priv->rtc); - iounmap(priv->rtcregs); - release_mem_region(priv->baseaddr, priv->size); - kfree(priv); return 0; } 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-ds1305.c b/drivers/rtc/rtc-ds1305.c index b05a6dc96405..bb5f13f63630 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -619,7 +619,7 @@ static int ds1305_probe(struct spi_device *spi) return -EINVAL; /* set up driver data */ - ds1305 = kzalloc(sizeof *ds1305, GFP_KERNEL); + ds1305 = devm_kzalloc(&spi->dev, sizeof(*ds1305), GFP_KERNEL); if (!ds1305) return -ENOMEM; ds1305->spi = spi; @@ -632,7 +632,7 @@ static int ds1305_probe(struct spi_device *spi) if (status < 0) { dev_dbg(&spi->dev, "can't %s, %d\n", "read", status); - goto fail0; + return status; } dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "read", ds1305->ctrl); @@ -644,8 +644,7 @@ static int ds1305_probe(struct spi_device *spi) */ if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) { dev_dbg(&spi->dev, "RTC chip is not present\n"); - status = -ENODEV; - goto fail0; + return -ENODEV; } if (ds1305->ctrl[2] == 0) dev_dbg(&spi->dev, "chip may not be present\n"); @@ -664,7 +663,7 @@ static int ds1305_probe(struct spi_device *spi) dev_dbg(&spi->dev, "clear WP --> %d\n", status); if (status < 0) - goto fail0; + return status; } /* on DS1305, maybe start oscillator; like most low power @@ -718,7 +717,7 @@ static int ds1305_probe(struct spi_device *spi) if (status < 0) { dev_dbg(&spi->dev, "can't %s, %d\n", "write", status); - goto fail0; + return status; } dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "write", ds1305->ctrl); @@ -730,7 +729,7 @@ static int ds1305_probe(struct spi_device *spi) &value, sizeof value); if (status < 0) { dev_dbg(&spi->dev, "read HOUR --> %d\n", status); - goto fail0; + return status; } ds1305->hr12 = (DS1305_HR_12 & value) != 0; @@ -738,12 +737,12 @@ static int ds1305_probe(struct spi_device *spi) dev_dbg(&spi->dev, "AM/PM\n"); /* register RTC ... from here on, ds1305->ctrl needs locking */ - ds1305->rtc = rtc_device_register("ds1305", &spi->dev, + ds1305->rtc = devm_rtc_device_register(&spi->dev, "ds1305", &ds1305_ops, THIS_MODULE); if (IS_ERR(ds1305->rtc)) { status = PTR_ERR(ds1305->rtc); dev_dbg(&spi->dev, "register rtc --> %d\n", status); - goto fail0; + return status; } /* Maybe set up alarm IRQ; be ready to handle it triggering right @@ -754,12 +753,12 @@ static int ds1305_probe(struct spi_device *spi) */ if (spi->irq) { INIT_WORK(&ds1305->work, ds1305_work); - status = request_irq(spi->irq, ds1305_irq, + status = devm_request_irq(&spi->dev, spi->irq, ds1305_irq, 0, dev_name(&ds1305->rtc->dev), ds1305); if (status < 0) { dev_dbg(&spi->dev, "request_irq %d --> %d\n", spi->irq, status); - goto fail1; + return status; } device_set_wakeup_capable(&spi->dev, 1); @@ -769,18 +768,10 @@ static int ds1305_probe(struct spi_device *spi) status = sysfs_create_bin_file(&spi->dev.kobj, &nvram); if (status < 0) { dev_dbg(&spi->dev, "register nvram --> %d\n", status); - goto fail2; + return status; } return 0; - -fail2: - free_irq(spi->irq, ds1305); -fail1: - rtc_device_unregister(ds1305->rtc); -fail0: - kfree(ds1305); - return status; } static int ds1305_remove(struct spi_device *spi) @@ -792,13 +783,11 @@ static int ds1305_remove(struct spi_device *spi) /* carefully shut down irq and workqueue, if present */ if (spi->irq) { set_bit(FLAG_EXITING, &ds1305->flags); - free_irq(spi->irq, ds1305); + devm_free_irq(&spi->dev, spi->irq, ds1305); cancel_work_sync(&ds1305->work); } - rtc_device_unregister(ds1305->rtc); spi_set_drvdata(spi, NULL); - kfree(ds1305); return 0; } 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..94366e12f40f 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -347,7 +347,7 @@ static int ds1374_probe(struct i2c_client *client, struct ds1374 *ds1374; int ret; - ds1374 = kzalloc(sizeof(struct ds1374), GFP_KERNEL); + ds1374 = devm_kzalloc(&client->dev, sizeof(struct ds1374), GFP_KERNEL); if (!ds1374) return -ENOMEM; @@ -359,36 +359,27 @@ static int ds1374_probe(struct i2c_client *client, ret = ds1374_check_rtc_status(client); if (ret) - goto out_free; + return ret; if (client->irq > 0) { - ret = request_irq(client->irq, ds1374_irq, 0, + ret = devm_request_irq(&client->dev, client->irq, ds1374_irq, 0, "ds1374", client); if (ret) { dev_err(&client->dev, "unable to request IRQ\n"); - goto out_free; + return ret; } device_set_wakeup_capable(&client->dev, 1); } - ds1374->rtc = rtc_device_register(client->name, &client->dev, + ds1374->rtc = devm_rtc_device_register(&client->dev, client->name, &ds1374_rtc_ops, THIS_MODULE); if (IS_ERR(ds1374->rtc)) { - ret = PTR_ERR(ds1374->rtc); dev_err(&client->dev, "unable to register the class device\n"); - goto out_irq; + return PTR_ERR(ds1374->rtc); } return 0; - -out_irq: - if (client->irq > 0) - free_irq(client->irq, client); - -out_free: - kfree(ds1374); - return ret; } static int ds1374_remove(struct i2c_client *client) @@ -400,16 +391,14 @@ static int ds1374_remove(struct i2c_client *client) ds1374->exiting = 1; mutex_unlock(&ds1374->mutex); - free_irq(client->irq, client); + devm_free_irq(&client->dev, client->irq, client); cancel_work_sync(&ds1374->work); } - rtc_device_unregister(ds1374->rtc); - kfree(ds1374); 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 +416,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..289af419dff4 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c @@ -131,26 +131,24 @@ static int ds1390_probe(struct spi_device *spi) spi->bits_per_word = 8; spi_setup(spi); - chip = kzalloc(sizeof *chip, GFP_KERNEL); + chip = devm_kzalloc(&spi->dev, sizeof(*chip), GFP_KERNEL); if (!chip) { 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) { dev_err(&spi->dev, "unable to read device\n"); - kfree(chip); return res; } - chip->rtc = rtc_device_register("ds1390", - &spi->dev, &ds1390_rtc_ops, THIS_MODULE); + chip->rtc = devm_rtc_device_register(&spi->dev, "ds1390", + &ds1390_rtc_ops, THIS_MODULE); if (IS_ERR(chip->rtc)) { dev_err(&spi->dev, "unable to register device\n"); res = PTR_ERR(chip->rtc); - kfree(chip); } return res; @@ -158,11 +156,6 @@ static int ds1390_probe(struct spi_device *spi) static int ds1390_remove(struct spi_device *spi) { - struct ds1390 *chip = spi_get_drvdata(spi); - - rtc_device_unregister(chip->rtc); - kfree(chip); - return 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-ds2404.c b/drivers/rtc/rtc-ds2404.c index b04fc4272fb3..2ca5a23aba8a 100644 --- a/drivers/rtc/rtc-ds2404.c +++ b/drivers/rtc/rtc-ds2404.c @@ -228,7 +228,7 @@ static int rtc_probe(struct platform_device *pdev) struct ds2404 *chip; int retval = -EBUSY; - chip = kzalloc(sizeof(struct ds2404), GFP_KERNEL); + chip = devm_kzalloc(&pdev->dev, sizeof(struct ds2404), GFP_KERNEL); if (!chip) return -ENOMEM; @@ -244,8 +244,8 @@ static int rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, chip); - chip->rtc = rtc_device_register("ds2404", - &pdev->dev, &ds2404_rtc_ops, THIS_MODULE); + chip->rtc = devm_rtc_device_register(&pdev->dev, "ds2404", + &ds2404_rtc_ops, THIS_MODULE); if (IS_ERR(chip->rtc)) { retval = PTR_ERR(chip->rtc); goto err_io; @@ -257,20 +257,14 @@ static int rtc_probe(struct platform_device *pdev) err_io: chip->ops->unmap_io(chip); err_chip: - kfree(chip); return retval; } static int rtc_remove(struct platform_device *dev) { struct ds2404 *chip = platform_get_drvdata(dev); - struct rtc_device *rtc = chip->rtc; - - if (rtc) - rtc_device_unregister(rtc); chip->ops->unmap_io(chip); - kfree(chip); return 0; } diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index db0ca08db315..b83bb5a527f8 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -397,7 +397,7 @@ static int ds3232_probe(struct i2c_client *client, struct ds3232 *ds3232; int ret; - ds3232 = kzalloc(sizeof(struct ds3232), GFP_KERNEL); + ds3232 = devm_kzalloc(&client->dev, sizeof(struct ds3232), GFP_KERNEL); if (!ds3232) return -ENOMEM; @@ -409,34 +409,25 @@ static int ds3232_probe(struct i2c_client *client, ret = ds3232_check_rtc_status(client); if (ret) - goto out_free; + return ret; - ds3232->rtc = rtc_device_register(client->name, &client->dev, + ds3232->rtc = devm_rtc_device_register(&client->dev, client->name, &ds3232_rtc_ops, THIS_MODULE); if (IS_ERR(ds3232->rtc)) { - ret = PTR_ERR(ds3232->rtc); dev_err(&client->dev, "unable to register the class device\n"); - goto out_irq; + return PTR_ERR(ds3232->rtc); } if (client->irq >= 0) { - ret = request_irq(client->irq, ds3232_irq, 0, + ret = devm_request_irq(&client->dev, client->irq, ds3232_irq, 0, "ds3232", client); if (ret) { dev_err(&client->dev, "unable to request IRQ\n"); - goto out_free; + return ret; } } return 0; - -out_irq: - if (client->irq >= 0) - free_irq(client->irq, client); - -out_free: - kfree(ds3232); - return ret; } static int ds3232_remove(struct i2c_client *client) @@ -448,12 +439,10 @@ static int ds3232_remove(struct i2c_client *client) ds3232->exiting = 1; mutex_unlock(&ds3232->mutex); - free_irq(client->irq, client); + devm_free_irq(&client->dev, client->irq, client); cancel_work_sync(&ds3232->work); } - rtc_device_unregister(ds3232->rtc); - kfree(ds3232); 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..2835fb6c1965 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c @@ -358,7 +358,7 @@ static int fm3130_probe(struct i2c_client *client, I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) return -EIO; - fm3130 = kzalloc(sizeof(struct fm3130), GFP_KERNEL); + fm3130 = devm_kzalloc(&client->dev, sizeof(struct fm3130), GFP_KERNEL); if (!fm3130) return -ENOMEM; @@ -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; } @@ -507,7 +507,7 @@ bad_clock: /* We won't bail out here because we just got invalid data. Time setting from u-boot doesn't work anyway */ - fm3130->rtc = rtc_device_register(client->name, &client->dev, + fm3130->rtc = devm_rtc_device_register(&client->dev, client->name, &fm3130_rtc_ops, THIS_MODULE); if (IS_ERR(fm3130->rtc)) { err = PTR_ERR(fm3130->rtc); @@ -517,16 +517,11 @@ bad_clock: } return 0; exit_free: - kfree(fm3130); return err; } static int fm3130_remove(struct i2c_client *client) { - struct fm3130 *fm3130 = i2c_get_clientdata(client); - - rtc_device_unregister(fm3130->rtc); - kfree(fm3130); return 0; } 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-isl12022.c b/drivers/rtc/rtc-isl12022.c index 6b4298ea683d..a1bbbb8de029 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -252,12 +252,11 @@ static int isl12022_probe(struct i2c_client *client, { struct isl12022 *isl12022; - int ret = 0; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; - isl12022 = kzalloc(sizeof(struct isl12022), GFP_KERNEL); + isl12022 = devm_kzalloc(&client->dev, sizeof(struct isl12022), + GFP_KERNEL); if (!isl12022) return -ENOMEM; @@ -265,37 +264,22 @@ static int isl12022_probe(struct i2c_client *client, i2c_set_clientdata(client, isl12022); - isl12022->rtc = rtc_device_register(isl12022_driver.driver.name, - &client->dev, - &isl12022_rtc_ops, - THIS_MODULE); - - if (IS_ERR(isl12022->rtc)) { - ret = PTR_ERR(isl12022->rtc); - goto exit_kfree; - } + isl12022->rtc = devm_rtc_device_register(&client->dev, + isl12022_driver.driver.name, + &isl12022_rtc_ops, THIS_MODULE); + if (IS_ERR(isl12022->rtc)) + return PTR_ERR(isl12022->rtc); return 0; - -exit_kfree: - kfree(isl12022); - - return ret; } static int isl12022_remove(struct i2c_client *client) { - struct isl12022 *isl12022 = i2c_get_clientdata(client); - - rtc_device_unregister(isl12022->rtc); - kfree(isl12022); - return 0; } static const struct i2c_device_id isl12022_id[] = { { "isl12022", 0 }, - { "rtc8564", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, isl12022_id); 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-m41t80.c b/drivers/rtc/rtc-m41t80.c index b885bcd08908..89674b5e6efd 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -637,7 +637,8 @@ static int m41t80_probe(struct i2c_client *client, dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL); + clientdata = devm_kzalloc(&client->dev, sizeof(*clientdata), + GFP_KERNEL); if (!clientdata) { rc = -ENOMEM; goto exit; @@ -646,8 +647,8 @@ static int m41t80_probe(struct i2c_client *client, clientdata->features = id->driver_data; i2c_set_clientdata(client, clientdata); - rtc = rtc_device_register(client->name, &client->dev, - &m41t80_rtc_ops, THIS_MODULE); + rtc = devm_rtc_device_register(&client->dev, client->name, + &m41t80_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { rc = PTR_ERR(rtc); rtc = NULL; @@ -718,26 +719,19 @@ ht_err: goto exit; exit: - if (rtc) - rtc_device_unregister(rtc); - kfree(clientdata); return rc; } static int m41t80_remove(struct i2c_client *client) { +#ifdef CONFIG_RTC_DRV_M41T80_WDT struct m41t80_data *clientdata = i2c_get_clientdata(client); - struct rtc_device *rtc = clientdata->rtc; -#ifdef CONFIG_RTC_DRV_M41T80_WDT if (clientdata->features & M41T80_FEATURE_HT) { misc_deregister(&wdt_dev); unregister_reboot_notifier(&wdt_notifier); } #endif - if (rtc) - rtc_device_unregister(rtc); - kfree(clientdata); 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-m48t35.c b/drivers/rtc/rtc-m48t35.c index 31c9190a1fcb..37444246e5e4 100644 --- a/drivers/rtc/rtc-m48t35.c +++ b/drivers/rtc/rtc-m48t35.c @@ -145,12 +145,11 @@ static int m48t35_probe(struct platform_device *pdev) { struct resource *res; struct m48t35_priv *priv; - int ret = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; - priv = kzalloc(sizeof(struct m48t35_priv), GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(struct m48t35_priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -160,50 +159,29 @@ static int m48t35_probe(struct platform_device *pdev) * conflicts are resolved */ #ifndef CONFIG_SGI_IP27 - if (!request_mem_region(res->start, priv->size, pdev->name)) { - ret = -EBUSY; - goto out; - } + if (!devm_request_mem_region(&pdev->dev, res->start, priv->size, + pdev->name)) + return -EBUSY; #endif priv->baseaddr = res->start; - priv->reg = ioremap(priv->baseaddr, priv->size); - if (!priv->reg) { - ret = -ENOMEM; - goto out; - } + priv->reg = devm_ioremap(&pdev->dev, priv->baseaddr, priv->size); + if (!priv->reg) + return -ENOMEM; spin_lock_init(&priv->lock); platform_set_drvdata(pdev, priv); - priv->rtc = rtc_device_register("m48t35", &pdev->dev, + priv->rtc = devm_rtc_device_register(&pdev->dev, "m48t35", &m48t35_ops, THIS_MODULE); - if (IS_ERR(priv->rtc)) { - ret = PTR_ERR(priv->rtc); - goto out; - } + if (IS_ERR(priv->rtc)) + return PTR_ERR(priv->rtc); return 0; - -out: - if (priv->reg) - iounmap(priv->reg); - if (priv->baseaddr) - release_mem_region(priv->baseaddr, priv->size); - kfree(priv); - return ret; } static int m48t35_remove(struct platform_device *pdev) { - struct m48t35_priv *priv = platform_get_drvdata(pdev); - - rtc_device_unregister(priv->rtc); - iounmap(priv->reg); -#ifndef CONFIG_SGI_IP27 - release_mem_region(priv->baseaddr, priv->size); -#endif - kfree(priv); 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..e3aea00c3145 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c @@ -93,24 +93,24 @@ static int max6902_set_time(struct device *dev, struct rtc_time *dt) dt->tm_year = dt->tm_year + 1900; /* Remove write protection */ - max6902_set_reg(dev, 0xF, 0); + max6902_set_reg(dev, MAX6902_REG_CONTROL, 0); - max6902_set_reg(dev, 0x01, bin2bcd(dt->tm_sec)); - max6902_set_reg(dev, 0x03, bin2bcd(dt->tm_min)); - max6902_set_reg(dev, 0x05, bin2bcd(dt->tm_hour)); + max6902_set_reg(dev, MAX6902_REG_SECONDS, bin2bcd(dt->tm_sec)); + max6902_set_reg(dev, MAX6902_REG_MINUTES, bin2bcd(dt->tm_min)); + max6902_set_reg(dev, MAX6902_REG_HOURS, bin2bcd(dt->tm_hour)); - max6902_set_reg(dev, 0x07, bin2bcd(dt->tm_mday)); - max6902_set_reg(dev, 0x09, bin2bcd(dt->tm_mon + 1)); - max6902_set_reg(dev, 0x0B, bin2bcd(dt->tm_wday)); - max6902_set_reg(dev, 0x0D, bin2bcd(dt->tm_year % 100)); - max6902_set_reg(dev, 0x13, bin2bcd(dt->tm_year / 100)); + max6902_set_reg(dev, MAX6902_REG_DATE, bin2bcd(dt->tm_mday)); + max6902_set_reg(dev, MAX6902_REG_MONTH, bin2bcd(dt->tm_mon + 1)); + max6902_set_reg(dev, MAX6902_REG_DAY, bin2bcd(dt->tm_wday)); + max6902_set_reg(dev, MAX6902_REG_YEAR, bin2bcd(dt->tm_year % 100)); + max6902_set_reg(dev, MAX6902_REG_CENTURY, bin2bcd(dt->tm_year / 100)); /* Compulab used a delay here. However, the datasheet * does not mention a delay being required anywhere... */ /* delay(2000); */ /* Write protect */ - max6902_set_reg(dev, 0xF, 0x80); + max6902_set_reg(dev, MAX6902_REG_CONTROL, 0x80); return 0; } @@ -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..771812d62e6b 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; @@ -513,13 +514,12 @@ static int max77686_rtc_probe(struct platform_device *pdev) info->dev = &pdev->dev; info->max77686 = max77686; info->rtc = max77686->rtc; - info->max77686->rtc_regmap = regmap_init_i2c(info->max77686->rtc, + info->max77686->rtc_regmap = devm_regmap_init_i2c(info->max77686->rtc, &max77686_rtc_regmap_config); if (IS_ERR(info->max77686->rtc_regmap)) { 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-max8925.c b/drivers/rtc/rtc-max8925.c index a0c8265646d2..7c90f4e45e27 100644 --- a/drivers/rtc/rtc-max8925.c +++ b/drivers/rtc/rtc-max8925.c @@ -253,7 +253,8 @@ static int max8925_rtc_probe(struct platform_device *pdev) struct max8925_rtc_info *info; int ret; - info = kzalloc(sizeof(struct max8925_rtc_info), GFP_KERNEL); + info = devm_kzalloc(&pdev->dev, sizeof(struct max8925_rtc_info), + GFP_KERNEL); if (!info) return -ENOMEM; info->chip = chip; @@ -261,12 +262,13 @@ static int max8925_rtc_probe(struct platform_device *pdev) info->dev = &pdev->dev; info->irq = platform_get_irq(pdev, 0); - ret = request_threaded_irq(info->irq, NULL, rtc_update_handler, - IRQF_ONESHOT, "rtc-alarm0", info); + ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, + rtc_update_handler, IRQF_ONESHOT, + "rtc-alarm0", info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq, ret); - goto out_irq; + goto err; } dev_set_drvdata(&pdev->dev, info); @@ -275,32 +277,22 @@ static int max8925_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); - info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, + info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max8925-rtc", &max8925_rtc_ops, THIS_MODULE); ret = PTR_ERR(info->rtc_dev); if (IS_ERR(info->rtc_dev)) { dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); - goto out_rtc; + goto err; } return 0; -out_rtc: +err: platform_set_drvdata(pdev, NULL); - free_irq(info->irq, info); -out_irq: - kfree(info); return ret; } static int max8925_rtc_remove(struct platform_device *pdev) { - struct max8925_rtc_info *info = platform_get_drvdata(pdev); - - if (info) { - free_irq(info->irq, info); - rtc_device_unregister(info->rtc_dev); - kfree(info); - } 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-max8998.c b/drivers/rtc/rtc-max8998.c index 8f234a075e8f..48b6612fae7f 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c @@ -256,7 +256,8 @@ static int max8998_rtc_probe(struct platform_device *pdev) struct max8998_rtc_info *info; int ret; - info = kzalloc(sizeof(struct max8998_rtc_info), GFP_KERNEL); + info = devm_kzalloc(&pdev->dev, sizeof(struct max8998_rtc_info), + GFP_KERNEL); if (!info) return -ENOMEM; @@ -267,7 +268,7 @@ static int max8998_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, info); - info->rtc_dev = rtc_device_register("max8998-rtc", &pdev->dev, + info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max8998-rtc", &max8998_rtc_ops, THIS_MODULE); if (IS_ERR(info->rtc_dev)) { @@ -276,8 +277,8 @@ static int max8998_rtc_probe(struct platform_device *pdev) goto out_rtc; } - ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0, - "rtc-alarm0", info); + ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, + max8998_rtc_alarm_irq, 0, "rtc-alarm0", info); if (ret < 0) dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", @@ -294,20 +295,11 @@ static int max8998_rtc_probe(struct platform_device *pdev) out_rtc: platform_set_drvdata(pdev, NULL); - kfree(info); return ret; } static int max8998_rtc_remove(struct platform_device *pdev) { - struct max8998_rtc_info *info = platform_get_drvdata(pdev); - - if (info) { - free_irq(info->irq, info); - rtc_device_unregister(info->rtc_dev); - kfree(info); - } - return 0; } diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 2643d8874925..7a8ed27a5f2e 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -316,7 +316,7 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) struct mc13xxx *mc13xxx; int rtcrst_pending; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -351,8 +351,8 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) mc13xxx_unlock(mc13xxx); - priv->rtc = rtc_device_register(pdev->name, - &pdev->dev, &mc13xxx_rtc_ops, THIS_MODULE); + priv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, + &mc13xxx_rtc_ops, THIS_MODULE); if (IS_ERR(priv->rtc)) { ret = PTR_ERR(priv->rtc); @@ -372,7 +372,6 @@ err_reset_irq_request: mc13xxx_unlock(mc13xxx); platform_set_drvdata(pdev, NULL); - kfree(priv); } return ret; @@ -384,8 +383,6 @@ static int __exit mc13xxx_rtc_remove(struct platform_device *pdev) mc13xxx_lock(priv->mc13xxx); - rtc_device_unregister(priv->rtc); - mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TODA, priv); mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_1HZ, priv); mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv); @@ -394,8 +391,6 @@ static int __exit mc13xxx_rtc_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - kfree(priv); - return 0; } @@ -420,17 +415,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..771f86a05d14 100644 --- a/drivers/rtc/rtc-msm6242.c +++ b/drivers/rtc/rtc-msm6242.c @@ -194,30 +194,28 @@ static const struct rtc_class_ops msm6242_rtc_ops = { .set_time = msm6242_set_time, }; -static int __init msm6242_rtc_probe(struct platform_device *dev) +static int __init msm6242_rtc_probe(struct platform_device *pdev) { struct resource *res; struct msm6242_priv *priv; struct rtc_device *rtc; int error; - res = platform_get_resource(dev, IORESOURCE_MEM, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->regs = ioremap(res->start, resource_size(res)); - if (!priv->regs) { - error = -ENOMEM; - goto out_free_priv; - } - platform_set_drvdata(dev, priv); + priv->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!priv->regs) + return -ENOMEM; + platform_set_drvdata(pdev, priv); - rtc = rtc_device_register("rtc-msm6242", &dev->dev, &msm6242_rtc_ops, - THIS_MODULE); + rtc = devm_rtc_device_register(&pdev->dev, "rtc-msm6242", + &msm6242_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { error = PTR_ERR(rtc); goto out_unmap; @@ -227,20 +225,12 @@ static int __init msm6242_rtc_probe(struct platform_device *dev) return 0; out_unmap: - platform_set_drvdata(dev, NULL); - iounmap(priv->regs); -out_free_priv: - kfree(priv); + platform_set_drvdata(pdev, NULL); return error; } -static int __exit msm6242_rtc_remove(struct platform_device *dev) +static int __exit msm6242_rtc_remove(struct platform_device *pdev) { - struct msm6242_priv *priv = platform_get_drvdata(dev); - - rtc_device_unregister(priv->rtc); - iounmap(priv->regs); - kfree(priv); return 0; } @@ -252,18 +242,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..f5dfb6e5e7d9 100644 --- a/drivers/rtc/rtc-nuc900.c +++ b/drivers/rtc/rtc-nuc900.c @@ -222,13 +222,13 @@ 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; - int err = 0; - nuc900_rtc = kzalloc(sizeof(struct nuc900_rtc), GFP_KERNEL); + nuc900_rtc = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_rtc), + GFP_KERNEL); if (!nuc900_rtc) { dev_err(&pdev->dev, "kzalloc nuc900_rtc failed\n"); return -ENOMEM; @@ -236,93 +236,51 @@ static int nuc900_rtc_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "platform_get_resource failed\n"); - err = -ENXIO; - goto fail1; + return -ENXIO; } - if (!request_mem_region(res->start, resource_size(res), - pdev->name)) { - dev_err(&pdev->dev, "request_mem_region failed\n"); - err = -EBUSY; - goto fail1; - } - - nuc900_rtc->rtc_reg = ioremap(res->start, resource_size(res)); - if (!nuc900_rtc->rtc_reg) { - dev_err(&pdev->dev, "ioremap rtc_reg failed\n"); - err = -ENOMEM; - goto fail2; - } + nuc900_rtc->rtc_reg = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(nuc900_rtc->rtc_reg)) + return PTR_ERR(nuc900_rtc->rtc_reg); platform_set_drvdata(pdev, nuc900_rtc); - nuc900_rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev, + nuc900_rtc->rtcdev = devm_rtc_device_register(&pdev->dev, pdev->name, &nuc900_rtc_ops, THIS_MODULE); if (IS_ERR(nuc900_rtc->rtcdev)) { dev_err(&pdev->dev, "rtc device register failed\n"); - err = PTR_ERR(nuc900_rtc->rtcdev); - goto fail3; + return PTR_ERR(nuc900_rtc->rtcdev); } __raw_writel(__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_TSSR) | MODE24, nuc900_rtc->rtc_reg + REG_RTC_TSSR); nuc900_rtc->irq_num = platform_get_irq(pdev, 0); - if (request_irq(nuc900_rtc->irq_num, nuc900_rtc_interrupt, - 0, "nuc900rtc", nuc900_rtc)) { + if (devm_request_irq(&pdev->dev, nuc900_rtc->irq_num, + nuc900_rtc_interrupt, 0, "nuc900rtc", nuc900_rtc)) { dev_err(&pdev->dev, "NUC900 RTC request irq failed\n"); - err = -EBUSY; - goto fail4; + return -EBUSY; } return 0; - -fail4: rtc_device_unregister(nuc900_rtc->rtcdev); -fail3: iounmap(nuc900_rtc->rtc_reg); -fail2: release_mem_region(res->start, resource_size(res)); -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; - - free_irq(nuc900_rtc->irq_num, nuc900_rtc); - rtc_device_unregister(nuc900_rtc->rtcdev); - iounmap(nuc900_rtc->rtc_reg); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - - kfree(nuc900_rtc); - platform_set_drvdata(pdev, NULL); return 0; } 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..4e1bdb832e37 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,16 +461,13 @@ 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; } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP static u8 irqstat; -static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) +static int omap_rtc_suspend(struct device *dev) { irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG); @@ -503,34 +475,32 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) * source, and in fact this enable() call is just saving a flag * that's never used... */ - if (device_may_wakeup(&pdev->dev)) + if (device_may_wakeup(dev)) enable_irq_wake(omap_rtc_alarm); else rtc_write(0, OMAP_RTC_INTERRUPTS_REG); /* Disable the clock/module */ - pm_runtime_put_sync(&pdev->dev); + pm_runtime_put_sync(dev); return 0; } -static int omap_rtc_resume(struct platform_device *pdev) +static int omap_rtc_resume(struct device *dev) { /* Enable the clock/module so that we can access the registers */ - pm_runtime_get_sync(&pdev->dev); + pm_runtime_get_sync(dev); - if (device_may_wakeup(&pdev->dev)) + if (device_may_wakeup(dev)) disable_irq_wake(omap_rtc_alarm); else rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG); return 0; } - -#else -#define omap_rtc_suspend NULL -#define omap_rtc_resume NULL #endif +static SIMPLE_DEV_PM_OPS(omap_rtc_pm_ops, omap_rtc_suspend, omap_rtc_resume); + static void omap_rtc_shutdown(struct platform_device *pdev) { rtc_write(0, OMAP_RTC_INTERRUPTS_REG); @@ -539,28 +509,17 @@ static void omap_rtc_shutdown(struct platform_device *pdev) MODULE_ALIAS("platform:omap_rtc"); static struct platform_driver omap_rtc_driver = { .remove = __exit_p(omap_rtc_remove), - .suspend = omap_rtc_suspend, - .resume = omap_rtc_resume, .shutdown = omap_rtc_shutdown, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .pm = &omap_rtc_pm_ops, .of_match_table = of_match_ptr(omap_rtc_of_match), }, .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..539a90b98bc5 100644 --- a/drivers/rtc/rtc-pcap.c +++ b/drivers/rtc/rtc-pcap.c @@ -139,13 +139,14 @@ 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; int err = -ENOMEM; - pcap_rtc = kmalloc(sizeof(struct pcap_rtc), GFP_KERNEL); + pcap_rtc = devm_kzalloc(&pdev->dev, sizeof(struct pcap_rtc), + GFP_KERNEL); if (!pcap_rtc) return err; @@ -153,68 +154,46 @@ static int pcap_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pcap_rtc); - pcap_rtc->rtc = rtc_device_register("pcap", &pdev->dev, - &pcap_rtc_ops, THIS_MODULE); + pcap_rtc->rtc = devm_rtc_device_register(&pdev->dev, "pcap", + &pcap_rtc_ops, THIS_MODULE); if (IS_ERR(pcap_rtc->rtc)) { err = PTR_ERR(pcap_rtc->rtc); - goto fail_rtc; + goto fail; } - timer_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ); alarm_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA); - err = request_irq(timer_irq, pcap_rtc_irq, 0, "RTC Timer", pcap_rtc); + err = devm_request_irq(&pdev->dev, timer_irq, pcap_rtc_irq, 0, + "RTC Timer", pcap_rtc); if (err) - goto fail_timer; + goto fail; - err = request_irq(alarm_irq, pcap_rtc_irq, 0, "RTC Alarm", pcap_rtc); + err = devm_request_irq(&pdev->dev, alarm_irq, pcap_rtc_irq, 0, + "RTC Alarm", pcap_rtc); if (err) - goto fail_alarm; + goto fail; return 0; -fail_alarm: - free_irq(timer_irq, pcap_rtc); -fail_timer: - rtc_device_unregister(pcap_rtc->rtc); -fail_rtc: +fail: platform_set_drvdata(pdev, NULL); - kfree(pcap_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); - - free_irq(pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ), pcap_rtc); - free_irq(pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA), pcap_rtc); - rtc_device_unregister(pcap_rtc->rtc); - kfree(pcap_rtc); - return 0; } 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-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 02b742afa761..796a6c5067dd 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -226,7 +226,8 @@ static int pcf2123_probe(struct spi_device *spi) u8 txbuf[2], rxbuf[2]; int ret, i; - pdata = kzalloc(sizeof(struct pcf2123_plat_data), GFP_KERNEL); + pdata = devm_kzalloc(&spi->dev, sizeof(struct pcf2123_plat_data), + GFP_KERNEL); if (!pdata) return -ENOMEM; spi->dev.platform_data = pdata; @@ -265,6 +266,7 @@ static int pcf2123_probe(struct spi_device *spi) if (!(rxbuf[0] & 0x20)) { dev_err(&spi->dev, "chip not found\n"); + ret = -ENODEV; goto kfree_exit; } @@ -281,7 +283,7 @@ static int pcf2123_probe(struct spi_device *spi) pcf2123_delay_trec(); /* Finalize the initialization */ - rtc = rtc_device_register(pcf2123_driver.driver.name, &spi->dev, + rtc = devm_rtc_device_register(&spi->dev, pcf2123_driver.driver.name, &pcf2123_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { @@ -314,7 +316,6 @@ sysfs_exit: device_remove_file(&spi->dev, &pdata->regs[i].attr); kfree_exit: - kfree(pdata); spi->dev.platform_data = NULL; return ret; } @@ -325,15 +326,10 @@ static int pcf2123_remove(struct spi_device *spi) int i; if (pdata) { - struct rtc_device *rtc = pdata->rtc; - - if (rtc) - rtc_device_unregister(rtc); for (i = 0; i < 16; i++) if (pdata->regs[i].name[0]) device_remove_file(&spi->dev, &pdata->regs[i].attr); - kfree(pdata); } return 0; diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c index e9f3135d305f..e6b6911c8e05 100644 --- a/drivers/rtc/rtc-pcf50633.c +++ b/drivers/rtc/rtc-pcf50633.c @@ -252,20 +252,17 @@ static int pcf50633_rtc_probe(struct platform_device *pdev) { struct pcf50633_rtc *rtc; - rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); if (!rtc) return -ENOMEM; rtc->pcf = dev_to_pcf50633(pdev->dev.parent); platform_set_drvdata(pdev, rtc); - rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev, + rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, "pcf50633-rtc", &pcf50633_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc->rtc_dev)) { - int ret = PTR_ERR(rtc->rtc_dev); - kfree(rtc); - return ret; - } + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM, pcf50633_rtc_irq, rtc); @@ -277,12 +274,8 @@ static int pcf50633_rtc_remove(struct platform_device *pdev) struct pcf50633_rtc *rtc; rtc = platform_get_drvdata(pdev); - pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_ALARM); - rtc_device_unregister(rtc->rtc_dev); - kfree(rtc); - return 0; } 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-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index f7daf18a112e..97b354a26a44 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -245,14 +245,13 @@ static int pcf8563_probe(struct i2c_client *client, { struct pcf8563 *pcf8563; - int err = 0; - dev_dbg(&client->dev, "%s\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; - pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL); + pcf8563 = devm_kzalloc(&client->dev, sizeof(struct pcf8563), + GFP_KERNEL); if (!pcf8563) return -ENOMEM; @@ -260,31 +259,18 @@ static int pcf8563_probe(struct i2c_client *client, i2c_set_clientdata(client, pcf8563); - pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name, - &client->dev, &pcf8563_rtc_ops, THIS_MODULE); + pcf8563->rtc = devm_rtc_device_register(&client->dev, + pcf8563_driver.driver.name, + &pcf8563_rtc_ops, THIS_MODULE); - if (IS_ERR(pcf8563->rtc)) { - err = PTR_ERR(pcf8563->rtc); - goto exit_kfree; - } + if (IS_ERR(pcf8563->rtc)) + return PTR_ERR(pcf8563->rtc); return 0; - -exit_kfree: - kfree(pcf8563); - - return err; } static int pcf8563_remove(struct i2c_client *client) { - struct pcf8563 *pcf8563 = i2c_get_clientdata(client); - - if (pcf8563->rtc) - rtc_device_unregister(pcf8563->rtc); - - kfree(pcf8563); - return 0; } diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 5f97c61247d5..95886dcf4a39 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c @@ -268,39 +268,29 @@ static int pcf8583_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pcf8583 *pcf8583; - int err; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; - pcf8583 = kzalloc(sizeof(struct pcf8583), GFP_KERNEL); + pcf8583 = devm_kzalloc(&client->dev, sizeof(struct pcf8583), + GFP_KERNEL); if (!pcf8583) return -ENOMEM; i2c_set_clientdata(client, pcf8583); - pcf8583->rtc = rtc_device_register(pcf8583_driver.driver.name, - &client->dev, &pcf8583_rtc_ops, THIS_MODULE); + pcf8583->rtc = devm_rtc_device_register(&client->dev, + pcf8583_driver.driver.name, + &pcf8583_rtc_ops, THIS_MODULE); - if (IS_ERR(pcf8583->rtc)) { - err = PTR_ERR(pcf8583->rtc); - goto exit_kfree; - } + if (IS_ERR(pcf8583->rtc)) + return PTR_ERR(pcf8583->rtc); return 0; - -exit_kfree: - kfree(pcf8583); - return err; } static int pcf8583_remove(struct i2c_client *client) { - struct pcf8583 *pcf8583 = i2c_get_clientdata(client); - - if (pcf8583->rtc) - rtc_device_unregister(pcf8583->rtc); - kfree(pcf8583); 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-puv3.c b/drivers/rtc/rtc-puv3.c index 0407e13d4de4..72f437170d2e 100644 --- a/drivers/rtc/rtc-puv3.c +++ b/drivers/rtc/rtc-puv3.c @@ -207,14 +207,14 @@ static const struct rtc_class_ops puv3_rtcops = { .proc = puv3_rtc_proc, }; -static void puv3_rtc_enable(struct platform_device *pdev, int en) +static void puv3_rtc_enable(struct device *dev, int en) { if (!en) { writel(readl(RTC_RTSR) & ~RTC_RTSR_HZE, RTC_RTSR); } else { /* re-enable the device, and check it is ok */ if ((readl(RTC_RTSR) & RTC_RTSR_HZE) == 0) { - dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); + dev_info(dev, "rtc disabled, re-enabling\n"); writel(readl(RTC_RTSR) | RTC_RTSR_HZE, RTC_RTSR); } } @@ -276,7 +276,7 @@ static int puv3_rtc_probe(struct platform_device *pdev) goto err_nores; } - puv3_rtc_enable(pdev, 1); + puv3_rtc_enable(&pdev->dev, 1); /* register RTC and exit */ rtc = rtc_device_register("pkunity", &pdev->dev, &puv3_rtcops, @@ -296,44 +296,41 @@ static int puv3_rtc_probe(struct platform_device *pdev) return 0; err_nortc: - puv3_rtc_enable(pdev, 0); + puv3_rtc_enable(&pdev->dev, 0); release_resource(puv3_rtc_mem); err_nores: return ret; } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP static int ticnt_save; -static int puv3_rtc_suspend(struct platform_device *pdev, pm_message_t state) +static int puv3_rtc_suspend(struct device *dev) { /* save RTAR for anyone using periodic interrupts */ ticnt_save = readl(RTC_RTAR); - puv3_rtc_enable(pdev, 0); + puv3_rtc_enable(dev, 0); return 0; } -static int puv3_rtc_resume(struct platform_device *pdev) +static int puv3_rtc_resume(struct device *dev) { - puv3_rtc_enable(pdev, 1); + puv3_rtc_enable(dev, 1); writel(ticnt_save, RTC_RTAR); return 0; } -#else -#define puv3_rtc_suspend NULL -#define puv3_rtc_resume NULL #endif +static SIMPLE_DEV_PM_OPS(puv3_rtc_pm_ops, puv3_rtc_suspend, puv3_rtc_resume); + static struct platform_driver puv3_rtc_driver = { .probe = puv3_rtc_probe, .remove = puv3_rtc_remove, - .suspend = puv3_rtc_suspend, - .resume = puv3_rtc_resume, .driver = { .name = "PKUnity-v3-RTC", .owner = THIS_MODULE, + .pm = &puv3_rtc_pm_ops, } }; diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index 03c85ee719a7..ed037ae91c5f 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -416,7 +416,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 +434,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..873c689f01c3 100644 --- a/drivers/rtc/rtc-rp5c01.c +++ b/drivers/rtc/rtc-rp5c01.c @@ -230,15 +230,13 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) if (!res) return -ENODEV; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->regs = ioremap(res->start, resource_size(res)); - if (!priv->regs) { - error = -ENOMEM; - goto out_free_priv; - } + priv->regs = devm_ioremap(&dev->dev, res->start, resource_size(res)); + if (!priv->regs) + return -ENOMEM; sysfs_bin_attr_init(&priv->nvram_attr); priv->nvram_attr.attr.name = "nvram"; @@ -251,27 +249,22 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) platform_set_drvdata(dev, priv); - rtc = rtc_device_register("rtc-rp5c01", &dev->dev, &rp5c01_rtc_ops, + rtc = devm_rtc_device_register(&dev->dev, "rtc-rp5c01", &rp5c01_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { error = PTR_ERR(rtc); - goto out_unmap; + goto out; } priv->rtc = rtc; error = sysfs_create_bin_file(&dev->dev.kobj, &priv->nvram_attr); if (error) - goto out_unregister; + goto out; return 0; -out_unregister: - rtc_device_unregister(rtc); -out_unmap: +out: platform_set_drvdata(dev, NULL); - iounmap(priv->regs); -out_free_priv: - kfree(priv); return error; } @@ -280,9 +273,6 @@ static int __exit rp5c01_rtc_remove(struct platform_device *dev) struct rp5c01_priv *priv = platform_get_drvdata(dev); sysfs_remove_bin_file(&dev->dev.kobj, &priv->nvram_attr); - rtc_device_unregister(priv->rtc); - iounmap(priv->regs); - kfree(priv); return 0; } @@ -294,18 +284,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-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index 72ef10be8662..2c37df3586c7 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c @@ -158,7 +158,8 @@ static int rs5c348_probe(struct spi_device *spi) struct rtc_device *rtc; struct rs5c348_plat_data *pdata; - pdata = kzalloc(sizeof(struct rs5c348_plat_data), GFP_KERNEL); + pdata = devm_kzalloc(&spi->dev, sizeof(struct rs5c348_plat_data), + GFP_KERNEL); if (!pdata) return -ENOMEM; spi->dev.platform_data = pdata; @@ -202,7 +203,7 @@ static int rs5c348_probe(struct spi_device *spi) if (ret & RS5C348_BIT_24H) pdata->rtc_24h = 1; - rtc = rtc_device_register(rs5c348_driver.driver.name, &spi->dev, + rtc = devm_rtc_device_register(&spi->dev, rs5c348_driver.driver.name, &rs5c348_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { @@ -214,18 +215,11 @@ static int rs5c348_probe(struct spi_device *spi) return 0; kfree_exit: - kfree(pdata); return ret; } static int rs5c348_remove(struct spi_device *spi) { - struct rs5c348_plat_data *pdata = spi->dev.platform_data; - struct rtc_device *rtc = pdata->rtc; - - if (rtc) - rtc_device_unregister(rtc); - kfree(pdata); return 0; } diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 581739f40097..224d634322b4 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -579,7 +579,9 @@ static int rs5c372_probe(struct i2c_client *client, } } - if (!(rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL))) { + rs5c372 = devm_kzalloc(&client->dev, sizeof(struct rs5c372), + GFP_KERNEL); + if (!rs5c372) { err = -ENOMEM; goto exit; } @@ -594,7 +596,7 @@ static int rs5c372_probe(struct i2c_client *client, err = rs5c_get_regs(rs5c372); if (err < 0) - goto exit_kfree; + goto exit; /* clock may be set for am/pm or 24 hr time */ switch (rs5c372->type) { @@ -617,7 +619,7 @@ static int rs5c372_probe(struct i2c_client *client, break; default: dev_err(&client->dev, "unknown RTC type\n"); - goto exit_kfree; + goto exit; } /* if the oscillator lost power and no other software (like @@ -629,7 +631,7 @@ static int rs5c372_probe(struct i2c_client *client, err = rs5c_oscillator_setup(rs5c372); if (unlikely(err < 0)) { dev_err(&client->dev, "setup error\n"); - goto exit_kfree; + goto exit; } if (rs5c372_get_datetime(client, &tm) < 0) @@ -648,38 +650,28 @@ static int rs5c372_probe(struct i2c_client *client, ); /* REVISIT use client->irq to register alarm irq ... */ - - rs5c372->rtc = rtc_device_register(rs5c372_driver.driver.name, - &client->dev, &rs5c372_rtc_ops, THIS_MODULE); + rs5c372->rtc = devm_rtc_device_register(&client->dev, + rs5c372_driver.driver.name, + &rs5c372_rtc_ops, THIS_MODULE); if (IS_ERR(rs5c372->rtc)) { err = PTR_ERR(rs5c372->rtc); - goto exit_kfree; + goto exit; } err = rs5c_sysfs_register(&client->dev); if (err) - goto exit_devreg; + goto exit; return 0; -exit_devreg: - rtc_device_unregister(rs5c372->rtc); - -exit_kfree: - kfree(rs5c372); - exit: return err; } static int rs5c372_remove(struct i2c_client *client) { - struct rs5c372 *rs5c372 = i2c_get_clientdata(client); - - rtc_device_unregister(rs5c372->rtc); rs5c_sysfs_unregister(&client->dev); - kfree(rs5c372); 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-s35390a.c b/drivers/rtc/rtc-s35390a.c index 8a092325188d..f40afdd0e5f5 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -338,7 +338,8 @@ static int s35390a_probe(struct i2c_client *client, goto exit; } - s35390a = kzalloc(sizeof(struct s35390a), GFP_KERNEL); + s35390a = devm_kzalloc(&client->dev, sizeof(struct s35390a), + GFP_KERNEL); if (!s35390a) { err = -ENOMEM; goto exit; @@ -386,8 +387,9 @@ static int s35390a_probe(struct i2c_client *client, device_set_wakeup_capable(&client->dev, 1); - s35390a->rtc = rtc_device_register(s35390a_driver.driver.name, - &client->dev, &s35390a_rtc_ops, THIS_MODULE); + s35390a->rtc = devm_rtc_device_register(&client->dev, + s35390a_driver.driver.name, + &s35390a_rtc_ops, THIS_MODULE); if (IS_ERR(s35390a->rtc)) { err = PTR_ERR(s35390a->rtc); @@ -399,7 +401,6 @@ exit_dummy: for (i = 1; i < 8; ++i) if (s35390a->client[i]) i2c_unregister_device(s35390a->client[i]); - kfree(s35390a); exit: return err; @@ -408,15 +409,12 @@ exit: static int s35390a_remove(struct i2c_client *client) { unsigned int i; - struct s35390a *s35390a = i2c_get_clientdata(client); + for (i = 1; i < 8; ++i) if (s35390a->client[i]) i2c_unregister_device(s35390a->client[i]); - rtc_device_unregister(s35390a->rtc); - kfree(s35390a); - return 0; } diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index fb994e9ddc15..8e96c00936be 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,13 +422,11 @@ 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); + clk_unprepare(rtc_clk); rtc_clk = NULL; return 0; @@ -498,7 +495,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) return ret; } - clk_enable(rtc_clk); + clk_prepare_enable(rtc_clk); /* check to see if everything is setup correctly */ @@ -511,7 +508,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,23 +571,24 @@ 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); - clk_disable(rtc_clk); + clk_disable_unprepare(rtc_clk); 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 +598,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 +622,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 +630,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 +683,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..00605601dbf7 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -234,14 +234,13 @@ static int sa1100_rtc_probe(struct platform_device *pdev) if (irq_1hz < 0 || irq_alarm < 0) return -ENODEV; - info = kzalloc(sizeof(struct sa1100_rtc), GFP_KERNEL); + info = devm_kzalloc(&pdev->dev, sizeof(struct sa1100_rtc), GFP_KERNEL); if (!info) return -ENOMEM; - info->clk = clk_get(&pdev->dev, NULL); + info->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(info->clk)) { dev_err(&pdev->dev, "failed to find rtc clock source\n"); - ret = PTR_ERR(info->clk); - goto err_clk; + return PTR_ERR(info->clk); } info->irq_1hz = irq_1hz; info->irq_alarm = irq_alarm; @@ -268,8 +267,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); - rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, - THIS_MODULE); + rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &sa1100_rtc_ops, + THIS_MODULE); if (IS_ERR(rtc)) { ret = PTR_ERR(rtc); @@ -306,9 +305,6 @@ err_dev: clk_disable_unprepare(info->clk); err_enable_clk: platform_set_drvdata(pdev, NULL); - clk_put(info->clk); -err_clk: - kfree(info); return ret; } @@ -317,17 +313,14 @@ static int sa1100_rtc_remove(struct platform_device *pdev) struct sa1100_rtc *info = platform_get_drvdata(pdev); if (info) { - rtc_device_unregister(info->rtc); clk_disable_unprepare(info->clk); - clk_put(info->clk); platform_set_drvdata(pdev, NULL); - kfree(info); } 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 +336,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 +355,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..574359c48f65 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); @@ -435,10 +434,10 @@ static int spear_rtc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM - -static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int spear_rtc_suspend(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct spear_rtc_config *config = platform_get_drvdata(pdev); int irq; @@ -454,8 +453,9 @@ static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int spear_rtc_resume(struct platform_device *pdev) +static int spear_rtc_resume(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct spear_rtc_config *config = platform_get_drvdata(pdev); int irq; @@ -473,12 +473,10 @@ static int spear_rtc_resume(struct platform_device *pdev) return 0; } - -#else -#define spear_rtc_suspend NULL -#define spear_rtc_resume NULL #endif +static SIMPLE_DEV_PM_OPS(spear_rtc_pm_ops, spear_rtc_suspend, spear_rtc_resume); + static void spear_rtc_shutdown(struct platform_device *pdev) { struct spear_rtc_config *config = platform_get_drvdata(pdev); @@ -498,11 +496,10 @@ MODULE_DEVICE_TABLE(of, spear_rtc_id_table); static struct platform_driver spear_rtc_driver = { .probe = spear_rtc_probe, .remove = spear_rtc_remove, - .suspend = spear_rtc_suspend, - .resume = spear_rtc_resume, .shutdown = spear_rtc_shutdown, .driver = { .name = "rtc-spear", + .pm = &spear_rtc_pm_ops, .of_match_table = of_match_ptr(spear_rtc_id_table), }, }; 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-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 98f0d3c30738..a9cd26a26dc0 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -227,11 +227,7 @@ static int stmp3xxx_rtc_remove(struct platform_device *pdev) writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, rtc_data->io + STMP3XXX_RTC_CTRL_CLR); - free_irq(rtc_data->irq_alarm, &pdev->dev); - rtc_device_unregister(rtc_data->rtc); platform_set_drvdata(pdev, NULL); - iounmap(rtc_data->io); - kfree(rtc_data); return 0; } @@ -242,22 +238,20 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) struct resource *r; int err; - rtc_data = kzalloc(sizeof *rtc_data, GFP_KERNEL); + rtc_data = devm_kzalloc(&pdev->dev, sizeof(*rtc_data), GFP_KERNEL); if (!rtc_data) return -ENOMEM; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { dev_err(&pdev->dev, "failed to get resource\n"); - err = -ENXIO; - goto out_free; + return -ENXIO; } - rtc_data->io = ioremap(r->start, resource_size(r)); + rtc_data->io = devm_ioremap(&pdev->dev, r->start, resource_size(r)); if (!rtc_data->io) { dev_err(&pdev->dev, "ioremap failed\n"); - err = -EIO; - goto out_free; + return -EIO; } rtc_data->irq_alarm = platform_get_irq(pdev, 0); @@ -265,8 +259,7 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) & STMP3XXX_RTC_STAT_RTC_PRESENT)) { dev_err(&pdev->dev, "no device onboard\n"); - err = -ENODEV; - goto out_remap; + return -ENODEV; } platform_set_drvdata(pdev, rtc_data); @@ -281,43 +274,38 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, rtc_data->io + STMP3XXX_RTC_CTRL_CLR); - rtc_data->rtc = rtc_device_register(pdev->name, &pdev->dev, + rtc_data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &stmp3xxx_rtc_ops, THIS_MODULE); if (IS_ERR(rtc_data->rtc)) { err = PTR_ERR(rtc_data->rtc); - goto out_remap; + goto out; } - err = request_irq(rtc_data->irq_alarm, stmp3xxx_rtc_interrupt, 0, - "RTC alarm", &pdev->dev); + err = devm_request_irq(&pdev->dev, rtc_data->irq_alarm, + stmp3xxx_rtc_interrupt, 0, "RTC alarm", &pdev->dev); if (err) { dev_err(&pdev->dev, "Cannot claim IRQ%d\n", rtc_data->irq_alarm); - goto out_irq_alarm; + goto out; } stmp3xxx_wdt_register(pdev); return 0; -out_irq_alarm: - rtc_device_unregister(rtc_data->rtc); -out_remap: +out: platform_set_drvdata(pdev, NULL); - iounmap(rtc_data->io); -out_free: - kfree(rtc_data); return err; } -#ifdef CONFIG_PM -static int stmp3xxx_rtc_suspend(struct platform_device *dev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int stmp3xxx_rtc_suspend(struct device *dev) { return 0; } -static int stmp3xxx_rtc_resume(struct platform_device *dev) +static int stmp3xxx_rtc_resume(struct device *dev) { - struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(dev); + struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); mxs_reset_block(rtc_data->io); writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | @@ -326,11 +314,11 @@ static int stmp3xxx_rtc_resume(struct platform_device *dev) rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); return 0; } -#else -#define stmp3xxx_rtc_suspend NULL -#define stmp3xxx_rtc_resume NULL #endif +static SIMPLE_DEV_PM_OPS(stmp3xxx_rtc_pm_ops, stmp3xxx_rtc_suspend, + stmp3xxx_rtc_resume); + static const struct of_device_id rtc_dt_ids[] = { { .compatible = "fsl,stmp3xxx-rtc", }, { /* sentinel */ } @@ -340,11 +328,10 @@ MODULE_DEVICE_TABLE(of, rtc_dt_ids); static struct platform_driver stmp3xxx_rtcdrv = { .probe = stmp3xxx_rtc_probe, .remove = stmp3xxx_rtc_remove, - .suspend = stmp3xxx_rtc_suspend, - .resume = stmp3xxx_rtc_resume, .driver = { .name = "stmp3xxx-rtc", .owner = THIS_MODULE, + .pm = &stmp3xxx_rtc_pm_ops, .of_match_table = of_match_ptr(rtc_dt_ids), }, }; 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-twl.c b/drivers/rtc/rtc-twl.c index 8bc6c80b184c..8751a5240c99 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -566,11 +566,10 @@ static void twl_rtc_shutdown(struct platform_device *pdev) mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M); } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP static unsigned char irqstat; -static int twl_rtc_suspend(struct platform_device *pdev, pm_message_t state) +static int twl_rtc_suspend(struct device *dev) { irqstat = rtc_irq_bits; @@ -578,17 +577,15 @@ static int twl_rtc_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int twl_rtc_resume(struct platform_device *pdev) +static int twl_rtc_resume(struct device *dev) { set_rtc_irq_bit(irqstat); return 0; } - -#else -#define twl_rtc_suspend NULL -#define twl_rtc_resume NULL #endif +static SIMPLE_DEV_PM_OPS(twl_rtc_pm_ops, twl_rtc_suspend, twl_rtc_resume); + #ifdef CONFIG_OF static const struct of_device_id twl_rtc_of_match[] = { {.compatible = "ti,twl4030-rtc", }, @@ -603,11 +600,10 @@ static struct platform_driver twl4030rtc_driver = { .probe = twl_rtc_probe, .remove = twl_rtc_remove, .shutdown = twl_rtc_shutdown, - .suspend = twl_rtc_suspend, - .resume = twl_rtc_resume, .driver = { .owner = THIS_MODULE, .name = "twl_rtc", + .pm = &twl_rtc_pm_ops, .of_match_table = of_match_ptr(twl_rtc_of_match), }, }; 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..6e0cba8f47d5 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c @@ -309,7 +309,7 @@ static int rtc_probe(struct platform_device *pdev) int i; int temp; - chip = kzalloc(sizeof *chip, GFP_KERNEL); + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; @@ -353,8 +353,8 @@ static int rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, chip); - chip->rtc = rtc_device_register("v3020", - &pdev->dev, &v3020_rtc_ops, THIS_MODULE); + chip->rtc = devm_rtc_device_register(&pdev->dev, "v3020", + &v3020_rtc_ops, THIS_MODULE); if (IS_ERR(chip->rtc)) { retval = PTR_ERR(chip->rtc); goto err_io; @@ -365,21 +365,14 @@ static int rtc_probe(struct platform_device *pdev) err_io: chip->ops->unmap_io(chip); err_chip: - kfree(chip); - return retval; } static int rtc_remove(struct platform_device *dev) { struct v3020 *chip = platform_get_drvdata(dev); - struct rtc_device *rtc = chip->rtc; - - if (rtc) - rtc_device_unregister(rtc); chip->ops->unmap_io(chip); - kfree(chip); return 0; } 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 d7096ad94d3f..bfda18467ee6 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1732,7 +1732,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 @@ -1744,7 +1744,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) @@ -2380,7 +2380,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/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/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, ®_val); + ret = adp5520_read(data->master, 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, ®); + 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, ®); + 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..f8be90c5dedc 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); @@ -270,27 +270,21 @@ int ili9320_remove(struct ili9320 *ili) } EXPORT_SYMBOL_GPL(ili9320_remove); -#ifdef CONFIG_PM -int ili9320_suspend(struct ili9320 *lcd, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +int ili9320_suspend(struct ili9320 *lcd) { int ret; - dev_dbg(lcd->dev, "%s: event %d\n", __func__, state.event); + ret = ili9320_power(lcd, FB_BLANK_POWERDOWN); - if (state.event == PM_EVENT_SUSPEND) { - ret = ili9320_power(lcd, FB_BLANK_POWERDOWN); - - if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) { - ili9320_write(lcd, ILI9320_POWER1, lcd->power1 | - ILI9320_POWER1_SLP | - ILI9320_POWER1_DSTB); - lcd->initialised = 0; - } - - return ret; + if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) { + ili9320_write(lcd, ILI9320_POWER1, lcd->power1 | + ILI9320_POWER1_SLP | + ILI9320_POWER1_DSTB); + lcd->initialised = 0; } - return 0; + return ret; } EXPORT_SYMBOL_GPL(ili9320_suspend); diff --git a/drivers/video/backlight/ili9320.h b/drivers/video/backlight/ili9320.h index e0db738f7bb9..42329e7aa9a8 100644 --- a/drivers/video/backlight/ili9320.h +++ b/drivers/video/backlight/ili9320.h @@ -76,5 +76,5 @@ extern void ili9320_shutdown(struct ili9320 *lcd); /* PM */ -extern int ili9320_suspend(struct ili9320 *lcd, pm_message_t state); +extern int ili9320_suspend(struct ili9320 *lcd); extern int ili9320_resume(struct ili9320 *lcd); 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..a0e1e02bdc2e 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -14,6 +14,7 @@ #include <linux/i2c.h> #include <linux/backlight.h> #include <linux/err.h> +#include <linux/of.h> #include <linux/platform_data/lp855x.h> #include <linux/pwm.h> @@ -35,10 +36,14 @@ #define LP8557_EPROM_START 0x10 #define LP8557_EPROM_END 0x1E -#define BUF_SIZE 20 #define DEFAULT_BL_NAME "lcd-backlight" #define MAX_BRIGHTNESS 255 +enum lp855x_brightness_ctrl_mode { + PWM_BASED = 1, + REGISTER_BASED, +}; + struct lp855x; /* @@ -58,6 +63,7 @@ struct lp855x_device_config { struct lp855x { const char *chipname; enum lp855x_chip_id chip_id; + enum lp855x_brightness_ctrl_mode mode; struct lp855x_device_config *cfg; struct i2c_client *client; struct backlight_device *bl; @@ -187,7 +193,7 @@ static int lp855x_configure(struct lp855x *lp) if (ret) goto err; - if (pd->load_new_rom_data && pd->size_program) { + if (pd->size_program > 0) { for (i = 0; i < pd->size_program; i++) { addr = pd->rom_data[i].addr; val = pd->rom_data[i].val; @@ -239,18 +245,17 @@ static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br) static int lp855x_bl_update_status(struct backlight_device *bl) { struct lp855x *lp = bl_get_data(bl); - enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode; if (bl->props.state & BL_CORE_SUSPENDED) bl->props.brightness = 0; - if (mode == PWM_BASED) { + if (lp->mode == PWM_BASED) { int br = bl->props.brightness; int max_br = bl->props.max_brightness; lp855x_pwm_ctrl(lp, br, max_br); - } else if (mode == REGISTER_BASED) { + } else if (lp->mode == REGISTER_BASED) { u8 val = bl->props.brightness; lp855x_write_byte(lp, lp->cfg->reg_brightness, val); } @@ -274,7 +279,7 @@ static int lp855x_backlight_register(struct lp855x *lp) struct backlight_device *bl; struct backlight_properties props; struct lp855x_platform_data *pdata = lp->pdata; - char *name = pdata->name ? : DEFAULT_BL_NAME; + const char *name = pdata->name ? : DEFAULT_BL_NAME; props.type = BACKLIGHT_PLATFORM; props.max_brightness = MAX_BRIGHTNESS; @@ -304,22 +309,21 @@ 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, struct device_attribute *attr, char *buf) { struct lp855x *lp = dev_get_drvdata(dev); - enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode; char *strmode = NULL; - if (mode == PWM_BASED) + if (lp->mode == PWM_BASED) strmode = "pwm based"; - else if (mode == REGISTER_BASED) + else if (lp->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); @@ -335,16 +339,71 @@ static const struct attribute_group lp855x_attr_group = { .attrs = lp855x_attributes, }; +#ifdef CONFIG_OF +static int lp855x_parse_dt(struct device *dev, struct device_node *node) +{ + struct lp855x_platform_data *pdata; + int rom_length; + + if (!node) { + dev_err(dev, "no platform data\n"); + return -EINVAL; + } + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + of_property_read_string(node, "bl-name", &pdata->name); + of_property_read_u8(node, "dev-ctrl", &pdata->device_control); + of_property_read_u8(node, "init-brt", &pdata->initial_brightness); + of_property_read_u32(node, "pwm-period", &pdata->period_ns); + + /* Fill ROM platform data if defined */ + rom_length = of_get_child_count(node); + if (rom_length > 0) { + struct lp855x_rom_data *rom; + struct device_node *child; + int i = 0; + + rom = devm_kzalloc(dev, sizeof(*rom) * rom_length, GFP_KERNEL); + if (!rom) + return -ENOMEM; + + for_each_child_of_node(node, child) { + of_property_read_u8(child, "rom-addr", &rom[i].addr); + of_property_read_u8(child, "rom-val", &rom[i].val); + i++; + } + + pdata->size_program = rom_length; + pdata->rom_data = &rom[0]; + } + + dev->platform_data = pdata; + + return 0; +} +#else +static int lp855x_parse_dt(struct device *dev, struct device_node *node) +{ + return -EINVAL; +} +#endif + 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; + struct device_node *node = cl->dev.of_node; int ret; if (!pdata) { - dev_err(&cl->dev, "no platform data supplied\n"); - return -EINVAL; + ret = lp855x_parse_dt(&cl->dev, node); + if (ret < 0) + return ret; + + pdata = cl->dev.platform_data; } if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) @@ -354,7 +413,11 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id) if (!lp) return -ENOMEM; - mode = pdata->mode; + if (pdata->period_ns > 0) + lp->mode = PWM_BASED; + else + lp->mode = REGISTER_BASED; + lp->client = cl; lp->dev = &cl->dev; lp->pdata = pdata; @@ -402,6 +465,17 @@ static int lp855x_remove(struct i2c_client *cl) return 0; } +static const struct of_device_id lp855x_dt_ids[] = { + { .compatible = "ti,lp8550", }, + { .compatible = "ti,lp8551", }, + { .compatible = "ti,lp8552", }, + { .compatible = "ti,lp8553", }, + { .compatible = "ti,lp8556", }, + { .compatible = "ti,lp8557", }, + { } +}; +MODULE_DEVICE_TABLE(of, lp855x_dt_ids); + static const struct i2c_device_id lp855x_ids[] = { {"lp8550", LP8550}, {"lp8551", LP8551}, @@ -416,6 +490,7 @@ MODULE_DEVICE_TABLE(i2c, lp855x_ids); static struct i2c_driver lp855x_driver = { .driver = { .name = "lp855x", + .of_match_table = of_match_ptr(lp855x_dt_ids), }, .probe = lp855x_probe, .remove = lp855x_remove, 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 = <v350qv_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..812e22e35cab 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> @@ -73,27 +71,24 @@ static void omapbl_blank(struct omap_backlight *bl, int mode) } } -#ifdef CONFIG_PM -static int omapbl_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int omapbl_suspend(struct device *dev) { - struct backlight_device *dev = platform_get_drvdata(pdev); - struct omap_backlight *bl = bl_get_data(dev); + struct backlight_device *bl_dev = dev_get_drvdata(dev); + struct omap_backlight *bl = bl_get_data(bl_dev); omapbl_blank(bl, FB_BLANK_POWERDOWN); return 0; } -static int omapbl_resume(struct platform_device *pdev) +static int omapbl_resume(struct device *dev) { - struct backlight_device *dev = platform_get_drvdata(pdev); - struct omap_backlight *bl = bl_get_data(dev); + struct backlight_device *bl_dev = dev_get_drvdata(dev); + struct omap_backlight *bl = bl_get_data(bl_dev); omapbl_blank(bl, bl->powermode); return 0; } -#else -#define omapbl_suspend NULL -#define omapbl_resume NULL #endif static int omapbl_set_power(struct backlight_device *dev, int state) @@ -170,7 +165,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; } @@ -184,13 +179,14 @@ static int omapbl_remove(struct platform_device *pdev) return 0; } +static SIMPLE_DEV_PM_OPS(omapbl_pm_ops, omapbl_suspend, omapbl_resume); + static struct platform_driver omapbl_driver = { .probe = omapbl_probe, .remove = omapbl_remove, - .suspend = omapbl_suspend, - .resume = omapbl_resume, .driver = { .name = "omap-bl", + .pm = &omapbl_pm_ops, }, }; diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c index 17a6b83f97af..056836706708 100644 --- a/drivers/video/backlight/platform_lcd.c +++ b/drivers/video/backlight/platform_lcd.c @@ -86,6 +86,12 @@ static int platform_lcd_probe(struct platform_device *pdev) return -EINVAL; } + if (pdata->probe) { + err = pdata->probe(pdata); + if (err) + return err; + } + plcd = devm_kzalloc(&pdev->dev, sizeof(struct platform_lcd), GFP_KERNEL); if (!plcd) { @@ -121,7 +127,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 +147,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 +164,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/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c index 2326fa810c59..9df66ac68b34 100644 --- a/drivers/video/backlight/tosa_bl.c +++ b/drivers/video/backlight/tosa_bl.c @@ -134,28 +134,27 @@ static int tosa_bl_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM -static int tosa_bl_suspend(struct i2c_client *client, pm_message_t pm) +#ifdef CONFIG_PM_SLEEP +static int tosa_bl_suspend(struct device *dev) { - struct tosa_bl_data *data = i2c_get_clientdata(client); + struct tosa_bl_data *data = dev_get_drvdata(dev); tosa_bl_set_backlight(data, 0); return 0; } -static int tosa_bl_resume(struct i2c_client *client) +static int tosa_bl_resume(struct device *dev) { - struct tosa_bl_data *data = i2c_get_clientdata(client); + struct tosa_bl_data *data = dev_get_drvdata(dev); backlight_update_status(data->bl); return 0; } -#else -#define tosa_bl_suspend NULL -#define tosa_bl_resume NULL #endif +static SIMPLE_DEV_PM_OPS(tosa_bl_pm_ops, tosa_bl_suspend, tosa_bl_resume); + static const struct i2c_device_id tosa_bl_id[] = { { "tosa-bl", 0 }, { }, @@ -165,11 +164,10 @@ static struct i2c_driver tosa_bl_driver = { .driver = { .name = "tosa-bl", .owner = THIS_MODULE, + .pm = &tosa_bl_pm_ops, }, .probe = tosa_bl_probe, .remove = tosa_bl_remove, - .suspend = tosa_bl_suspend, - .resume = tosa_bl_resume, .id_table = tosa_bl_id, }; diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c index 666fe2593ea4..bf081573e5b5 100644 --- a/drivers/video/backlight/tosa_lcd.c +++ b/drivers/video/backlight/tosa_lcd.c @@ -240,19 +240,19 @@ static int tosa_lcd_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_PM -static int tosa_lcd_suspend(struct spi_device *spi, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int tosa_lcd_suspend(struct device *dev) { - struct tosa_lcd_data *data = spi_get_drvdata(spi); + struct tosa_lcd_data *data = dev_get_drvdata(dev); tosa_lcd_tg_off(data); return 0; } -static int tosa_lcd_resume(struct spi_device *spi) +static int tosa_lcd_resume(struct device *dev) { - struct tosa_lcd_data *data = spi_get_drvdata(spi); + struct tosa_lcd_data *data = dev_get_drvdata(dev); tosa_lcd_tg_init(data); if (POWER_IS_ON(data->lcd_power)) @@ -262,20 +262,18 @@ static int tosa_lcd_resume(struct spi_device *spi) return 0; } -#else -#define tosa_lcd_suspend NULL -#define tosa_lcd_resume NULL #endif +static SIMPLE_DEV_PM_OPS(tosa_lcd_pm_ops, tosa_lcd_suspend, tosa_lcd_resume); + static struct spi_driver tosa_lcd_driver = { .driver = { .name = "tosa-lcd", .owner = THIS_MODULE, + .pm = &tosa_lcd_pm_ops, }, .probe = tosa_lcd_probe, .remove = tosa_lcd_remove, - .suspend = tosa_lcd_suspend, - .resume = tosa_lcd_resume, }; module_spi_driver(tosa_lcd_driver); diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c index 70881633b45a..05782312aeb3 100644 --- a/drivers/video/backlight/tps65217_bl.c +++ b/drivers/video/backlight/tps65217_bl.c @@ -245,6 +245,18 @@ tps65217_bl_parse_dt(struct platform_device *pdev) } } + if (!of_property_read_u32(node, "default-brightness", &val)) { + if (val < 0 || + val > 100) { + dev_err(&pdev->dev, + "invalid 'default-brightness' value in the device tree\n"); + err = ERR_PTR(-EINVAL); + goto err; + } + + pdata->dft_brightness = val; + } + of_node_put(node); return pdata; @@ -311,7 +323,8 @@ static int tps65217_bl_probe(struct platform_device *pdev) return PTR_ERR(tps65217_bl->bl); } - tps65217_bl->bl->props.brightness = 0; + tps65217_bl->bl->props.brightness = pdata->dft_brightness; + backlight_update_status(tps65217_bl->bl); platform_set_drvdata(pdev, tps65217_bl); return 0; diff --git a/drivers/video/backlight/vgg2432a4.c b/drivers/video/backlight/vgg2432a4.c index 84d582f591dc..d538947a67d3 100644 --- a/drivers/video/backlight/vgg2432a4.c +++ b/drivers/video/backlight/vgg2432a4.c @@ -205,18 +205,15 @@ static int vgg2432a4_lcd_init(struct ili9320 *lcd, return ret; } -#ifdef CONFIG_PM -static int vgg2432a4_suspend(struct spi_device *spi, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int vgg2432a4_suspend(struct device *dev) { - return ili9320_suspend(spi_get_drvdata(spi), state); + return ili9320_suspend(dev_get_drvdata(dev)); } -static int vgg2432a4_resume(struct spi_device *spi) +static int vgg2432a4_resume(struct device *dev) { - return ili9320_resume(spi_get_drvdata(spi)); + return ili9320_resume(dev_get_drvdata(dev)); } -#else -#define vgg2432a4_suspend NULL -#define vgg2432a4_resume NULL #endif static struct ili9320_client vgg2432a4_client = { @@ -249,16 +246,17 @@ static void vgg2432a4_shutdown(struct spi_device *spi) ili9320_shutdown(spi_get_drvdata(spi)); } +static SIMPLE_DEV_PM_OPS(vgg2432a4_pm_ops, vgg2432a4_suspend, vgg2432a4_resume); + static struct spi_driver vgg2432a4_driver = { .driver = { .name = "VGG2432A4", .owner = THIS_MODULE, + .pm = &vgg2432a4_pm_ops, }, .probe = vgg2432a4_probe, .remove = vgg2432a4_remove, .shutdown = vgg2432a4_shutdown, - .suspend = vgg2432a4_suspend, - .resume = vgg2432a4_resume, }; module_spi_driver(vgg2432a4_driver); 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/fs/fat/dir.c b/fs/fat/dir.c index 165012ef363a..7a6f02caf286 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -964,6 +964,29 @@ int fat_scan(struct inode *dir, const unsigned char *name, } EXPORT_SYMBOL_GPL(fat_scan); +/* + * Scans a directory for a given logstart. + * Returns an error code or zero. + */ +int fat_scan_logstart(struct inode *dir, int i_logstart, + struct fat_slot_info *sinfo) +{ + struct super_block *sb = dir->i_sb; + + sinfo->slot_off = 0; + sinfo->bh = NULL; + while (fat_get_short_entry(dir, &sinfo->slot_off, &sinfo->bh, + &sinfo->de) >= 0) { + if (fat_get_start(MSDOS_SB(sb), sinfo->de) == i_logstart) { + sinfo->slot_off -= sizeof(*sinfo->de); + sinfo->nr_slots = 1; + sinfo->i_pos = fat_make_i_pos(sb, sinfo->bh, sinfo->de); + return 0; + } + } + return -ENOENT; +} + static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots) { struct super_block *sb = dir->i_sb; diff --git a/fs/fat/fat.h b/fs/fat/fat.h index e9cc3f0d58e2..21664fcf3616 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -23,6 +23,9 @@ #define FAT_ERRORS_PANIC 2 /* panic on error */ #define FAT_ERRORS_RO 3 /* remount r/o on error */ +#define FAT_NFS_STALE_RW 1 /* NFS RW support, can cause ESTALE */ +#define FAT_NFS_NOSTALE_RO 2 /* NFS RO support, no ESTALE issue */ + struct fat_mount_options { kuid_t fs_uid; kgid_t fs_gid; @@ -34,6 +37,7 @@ struct fat_mount_options { unsigned short shortname; /* flags for shortname display/create rule */ unsigned char name_check; /* r = relaxed, n = normal, s = strict */ unsigned char errors; /* On error: continue, panic, remount-ro */ + unsigned char nfs; /* NFS support: nostale_ro, stale_rw */ unsigned short allow_utime;/* permission for setting the [am]time */ unsigned quiet:1, /* set = fake successful chmods and chowns */ showexec:1, /* set = only set x bit for com/exe/bat */ @@ -48,8 +52,7 @@ struct fat_mount_options { usefree:1, /* Use free_clusters for FAT32 */ tz_set:1, /* Filesystem timestamps' offset set */ rodir:1, /* allow ATTR_RO for directory */ - discard:1, /* Issue discard requests on deletions */ - nfs:1; /* Do extra work needed for NFS export */ + discard:1; /* Issue discard requests on deletions */ }; #define FAT_HASH_BITS 8 @@ -72,6 +75,7 @@ struct msdos_sb_info { unsigned long root_cluster; /* first cluster of the root directory */ unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */ struct mutex fat_lock; + struct mutex nfs_build_inode_lock; struct mutex s_lock; unsigned int prev_free; /* previously allocated cluster number */ unsigned int free_clusters; /* -1 if undefined */ @@ -215,6 +219,27 @@ static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus) + sbi->data_start; } +static inline void fat_get_blknr_offset(struct msdos_sb_info *sbi, + loff_t i_pos, sector_t *blknr, int *offset) +{ + *blknr = i_pos >> sbi->dir_per_block_bits; + *offset = i_pos & (sbi->dir_per_block - 1); +} + +static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi, + struct inode *inode) +{ + loff_t i_pos; +#if BITS_PER_LONG == 32 + spin_lock(&sbi->inode_hash_lock); +#endif + i_pos = MSDOS_I(inode)->i_pos; +#if BITS_PER_LONG == 32 + spin_unlock(&sbi->inode_hash_lock); +#endif + return i_pos; +} + static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len) { #ifdef __BIG_ENDIAN @@ -271,6 +296,8 @@ extern int fat_dir_empty(struct inode *dir); extern int fat_subdirs(struct inode *dir); extern int fat_scan(struct inode *dir, const unsigned char *name, struct fat_slot_info *sinfo); +extern int fat_scan_logstart(struct inode *dir, int i_logstart, + struct fat_slot_info *sinfo); extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, struct msdos_dir_entry **de); extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts); @@ -348,6 +375,7 @@ extern struct inode *fat_build_inode(struct super_block *sb, extern int fat_sync_inode(struct inode *inode); extern int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, void (*setup)(struct super_block *)); +extern int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de); extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2); @@ -382,12 +410,8 @@ int fat_cache_init(void); void fat_cache_destroy(void); /* fat/nfs.c */ -struct fid; -extern struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid, - int fh_len, int fh_type); -extern struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid, - int fh_len, int fh_type); -extern struct dentry *fat_get_parent(struct dentry *child_dir); +extern const struct export_operations fat_export_ops; +extern const struct export_operations fat_export_ops_nostale; /* helper for printk */ typedef unsigned long long llu; diff --git a/fs/fat/file.c b/fs/fat/file.c index 3978f8ca1823..b0b632e50ddb 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -306,6 +306,11 @@ int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) struct inode *inode = dentry->d_inode; generic_fillattr(inode, stat); stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size; + + if (MSDOS_SB(inode->i_sb)->options.nfs == FAT_NFS_NOSTALE_RO) { + /* Use i_pos for ino. This is used as fileid of nfs. */ + stat->ino = fat_i_pos_read(MSDOS_SB(inode->i_sb), inode); + } return 0; } EXPORT_SYMBOL_GPL(fat_getattr); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index acf6e479b443..4ff901632b26 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -18,7 +18,6 @@ #include <linux/pagemap.h> #include <linux/mpage.h> #include <linux/buffer_head.h> -#include <linux/exportfs.h> #include <linux/mount.h> #include <linux/vfs.h> #include <linux/parser.h> @@ -385,7 +384,7 @@ static int fat_calc_dir_size(struct inode *inode) } /* doesn't deal with root inode */ -static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) +int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) { struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); int error; @@ -444,12 +443,25 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) return 0; } +static inline void fat_lock_build_inode(struct msdos_sb_info *sbi) +{ + if (sbi->options.nfs == FAT_NFS_NOSTALE_RO) + mutex_lock(&sbi->nfs_build_inode_lock); +} + +static inline void fat_unlock_build_inode(struct msdos_sb_info *sbi) +{ + if (sbi->options.nfs == FAT_NFS_NOSTALE_RO) + mutex_unlock(&sbi->nfs_build_inode_lock); +} + struct inode *fat_build_inode(struct super_block *sb, struct msdos_dir_entry *de, loff_t i_pos) { struct inode *inode; int err; + fat_lock_build_inode(MSDOS_SB(sb)); inode = fat_iget(sb, i_pos); if (inode) goto out; @@ -469,6 +481,7 @@ struct inode *fat_build_inode(struct super_block *sb, fat_attach(inode, i_pos); insert_inode_hash(inode); out: + fat_unlock_build_inode(MSDOS_SB(sb)); return inode; } @@ -655,20 +668,6 @@ static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) return 0; } -static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi, - struct inode *inode) -{ - loff_t i_pos; -#if BITS_PER_LONG == 32 - spin_lock(&sbi->inode_hash_lock); -#endif - i_pos = MSDOS_I(inode)->i_pos; -#if BITS_PER_LONG == 32 - spin_unlock(&sbi->inode_hash_lock); -#endif - return i_pos; -} - static int __fat_write_inode(struct inode *inode, int wait) { struct super_block *sb = inode->i_sb; @@ -676,7 +675,8 @@ static int __fat_write_inode(struct inode *inode, int wait) struct buffer_head *bh; struct msdos_dir_entry *raw_entry; loff_t i_pos; - int err; + sector_t blocknr; + int err, offset; if (inode->i_ino == MSDOS_ROOT_INO) return 0; @@ -686,7 +686,8 @@ retry: if (!i_pos) return 0; - bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits); + fat_get_blknr_offset(sbi, i_pos, &blocknr, &offset); + bh = sb_bread(sb, blocknr); if (!bh) { fat_msg(sb, KERN_ERR, "unable to read inode block " "for updating (i_pos %lld)", i_pos); @@ -699,8 +700,7 @@ retry: goto retry; } - raw_entry = &((struct msdos_dir_entry *) (bh->b_data)) - [i_pos & (sbi->dir_per_block - 1)]; + raw_entry = &((struct msdos_dir_entry *) (bh->b_data))[offset]; if (S_ISDIR(inode->i_mode)) raw_entry->size = 0; else @@ -761,12 +761,6 @@ static const struct super_operations fat_sops = { .show_options = fat_show_options, }; -static const struct export_operations fat_export_ops = { - .fh_to_dentry = fat_fh_to_dentry, - .fh_to_parent = fat_fh_to_parent, - .get_parent = fat_get_parent, -}; - static int fat_show_options(struct seq_file *m, struct dentry *root) { struct msdos_sb_info *sbi = MSDOS_SB(root->d_sb); @@ -814,8 +808,6 @@ static int fat_show_options(struct seq_file *m, struct dentry *root) seq_puts(m, ",usefree"); if (opts->quiet) seq_puts(m, ",quiet"); - if (opts->nfs) - seq_puts(m, ",nfs"); if (opts->showexec) seq_puts(m, ",showexec"); if (opts->sys_immutable) @@ -849,6 +841,10 @@ static int fat_show_options(struct seq_file *m, struct dentry *root) seq_puts(m, ",errors=panic"); else seq_puts(m, ",errors=remount-ro"); + if (opts->nfs == FAT_NFS_NOSTALE_RO) + seq_puts(m, ",nfs=nostale_ro"); + else if (opts->nfs) + seq_puts(m, ",nfs=stale_rw"); if (opts->discard) seq_puts(m, ",discard"); @@ -865,7 +861,7 @@ enum { Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset, - Opt_err, + Opt_nfs_stale_rw, Opt_nfs_nostale_ro, Opt_err, }; static const match_table_t fat_tokens = { @@ -895,7 +891,9 @@ static const match_table_t fat_tokens = { {Opt_err_panic, "errors=panic"}, {Opt_err_ro, "errors=remount-ro"}, {Opt_discard, "discard"}, - {Opt_nfs, "nfs"}, + {Opt_nfs_stale_rw, "nfs"}, + {Opt_nfs_stale_rw, "nfs=stale_rw"}, + {Opt_nfs_nostale_ro, "nfs=nostale_ro"}, {Opt_obsolete, "conv=binary"}, {Opt_obsolete, "conv=text"}, {Opt_obsolete, "conv=auto"}, @@ -1092,6 +1090,12 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, case Opt_err_ro: opts->errors = FAT_ERRORS_RO; break; + case Opt_nfs_stale_rw: + opts->nfs = FAT_NFS_STALE_RW; + break; + case Opt_nfs_nostale_ro: + opts->nfs = FAT_NFS_NOSTALE_RO; + break; /* msdos specific */ case Opt_dots: @@ -1150,9 +1154,6 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, case Opt_discard: opts->discard = 1; break; - case Opt_nfs: - opts->nfs = 1; - break; /* obsolete mount options */ case Opt_obsolete: @@ -1183,6 +1184,10 @@ out: opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH); if (opts->unicode_xlate) opts->utf8 = 0; + if (opts->nfs == FAT_NFS_NOSTALE_RO) { + sb->s_flags |= MS_RDONLY; + sb->s_export_op = &fat_export_ops_nostale; + } return 0; } @@ -1193,7 +1198,7 @@ static int fat_read_root(struct inode *inode) struct msdos_sb_info *sbi = MSDOS_SB(sb); int error; - MSDOS_I(inode)->i_pos = 0; + MSDOS_I(inode)->i_pos = MSDOS_ROOT_INO; inode->i_uid = sbi->options.fs_uid; inode->i_gid = sbi->options.fs_gid; inode->i_version++; @@ -1256,6 +1261,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, sb->s_magic = MSDOS_SUPER_MAGIC; sb->s_op = &fat_sops; sb->s_export_op = &fat_export_ops; + mutex_init(&sbi->nfs_build_inode_lock); ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); diff --git a/fs/fat/nfs.c b/fs/fat/nfs.c index 499c10438ca2..93e14933dcb6 100644 --- a/fs/fat/nfs.c +++ b/fs/fat/nfs.c @@ -14,6 +14,18 @@ #include <linux/exportfs.h> #include "fat.h" +struct fat_fid { + u32 i_gen; + u32 i_pos_low; + u16 i_pos_hi; + u16 parent_i_pos_hi; + u32 parent_i_pos_low; + u32 parent_i_gen; +}; + +#define FAT_FID_SIZE_WITHOUT_PARENT 3 +#define FAT_FID_SIZE_WITH_PARENT (sizeof(struct fat_fid)/sizeof(u32)) + /** * Look up a directory inode given its starting cluster. */ @@ -38,63 +50,252 @@ static struct inode *fat_dget(struct super_block *sb, int i_logstart) return inode; } -static struct inode *fat_nfs_get_inode(struct super_block *sb, - u64 ino, u32 generation) +static struct inode *fat_ilookup(struct super_block *sb, u64 ino, loff_t i_pos) { - struct inode *inode; + if (MSDOS_SB(sb)->options.nfs == FAT_NFS_NOSTALE_RO) + return fat_iget(sb, i_pos); - if ((ino < MSDOS_ROOT_INO) || (ino == MSDOS_FSINFO_INO)) - return NULL; + else { + if ((ino < MSDOS_ROOT_INO) || (ino == MSDOS_FSINFO_INO)) + return NULL; + return ilookup(sb, ino); + } +} + +static struct inode *__fat_nfs_get_inode(struct super_block *sb, + u64 ino, u32 generation, loff_t i_pos) +{ + struct inode *inode = fat_ilookup(sb, ino, i_pos); - inode = ilookup(sb, ino); if (inode && generation && (inode->i_generation != generation)) { iput(inode); inode = NULL; } + if (inode == NULL && MSDOS_SB(sb)->options.nfs == FAT_NFS_NOSTALE_RO) { + struct buffer_head *bh = NULL; + struct msdos_dir_entry *de ; + sector_t blocknr; + int offset; + fat_get_blknr_offset(MSDOS_SB(sb), i_pos, &blocknr, &offset); + bh = sb_bread(sb, blocknr); + if (!bh) { + fat_msg(sb, KERN_ERR, + "unable to read block(%llu) for building NFS inode", + (llu)blocknr); + return inode; + } + de = (struct msdos_dir_entry *)bh->b_data; + /* If a file is deleted on server and client is not updated + * yet, we must not build the inode upon a lookup call. + */ + if (IS_FREE(de[offset].name)) + inode = NULL; + else + inode = fat_build_inode(sb, &de[offset], i_pos); + brelse(bh); + } return inode; } +static struct inode *fat_nfs_get_inode(struct super_block *sb, + u64 ino, u32 generation) +{ + + return __fat_nfs_get_inode(sb, ino, generation, 0); +} + +static int +fat_encode_fh_nostale(struct inode *inode, __u32 *fh, int *lenp, + struct inode *parent) +{ + int len = *lenp; + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); + struct fat_fid *fid = (struct fat_fid *) fh; + loff_t i_pos; + int type = FILEID_FAT_WITHOUT_PARENT; + + if (parent) { + if (len < FAT_FID_SIZE_WITH_PARENT) { + *lenp = FAT_FID_SIZE_WITH_PARENT; + return FILEID_INVALID; + } + } else { + if (len < FAT_FID_SIZE_WITHOUT_PARENT) { + *lenp = FAT_FID_SIZE_WITHOUT_PARENT; + return FILEID_INVALID; + } + } + + i_pos = fat_i_pos_read(sbi, inode); + *lenp = FAT_FID_SIZE_WITHOUT_PARENT; + fid->i_gen = inode->i_generation; + fid->i_pos_low = i_pos & 0xFFFFFFFF; + fid->i_pos_hi = (i_pos >> 32) & 0xFFFF; + if (parent) { + i_pos = fat_i_pos_read(sbi, parent); + fid->parent_i_pos_hi = (i_pos >> 32) & 0xFFFF; + fid->parent_i_pos_low = i_pos & 0xFFFFFFFF; + fid->parent_i_gen = parent->i_generation; + type = FILEID_FAT_WITH_PARENT; + *lenp = FAT_FID_SIZE_WITH_PARENT; + } + + return type; +} + /** * Map a NFS file handle to a corresponding dentry. * The dentry may or may not be connected to the filesystem root. */ -struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid, +static struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { return generic_fh_to_dentry(sb, fid, fh_len, fh_type, fat_nfs_get_inode); } +static struct dentry *fat_fh_to_dentry_nostale(struct super_block *sb, + struct fid *fh, int fh_len, + int fh_type) +{ + struct inode *inode = NULL; + struct fat_fid *fid = (struct fat_fid *)fh; + loff_t i_pos; + + switch (fh_type) { + case FILEID_FAT_WITHOUT_PARENT: + if (fh_len < FAT_FID_SIZE_WITHOUT_PARENT) + return NULL; + break; + case FILEID_FAT_WITH_PARENT: + if (fh_len < FAT_FID_SIZE_WITH_PARENT) + return NULL; + break; + default: + return NULL; + } + i_pos = fid->i_pos_hi; + i_pos = (i_pos << 32) | (fid->i_pos_low); + inode = __fat_nfs_get_inode(sb, 0, fid->i_gen, i_pos); + + return d_obtain_alias(inode); +} + /* * Find the parent for a file specified by NFS handle. * This requires that the handle contain the i_ino of the parent. */ -struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid, +static struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { return generic_fh_to_parent(sb, fid, fh_len, fh_type, fat_nfs_get_inode); } +static struct dentry *fat_fh_to_parent_nostale(struct super_block *sb, + struct fid *fh, int fh_len, + int fh_type) +{ + struct inode *inode = NULL; + struct fat_fid *fid = (struct fat_fid *)fh; + loff_t i_pos; + + if (fh_len < FAT_FID_SIZE_WITH_PARENT) + return NULL; + + switch (fh_type) { + case FILEID_FAT_WITH_PARENT: + i_pos = fid->parent_i_pos_hi; + i_pos = (i_pos << 32) | (fid->parent_i_pos_low); + inode = __fat_nfs_get_inode(sb, 0, fid->parent_i_gen, i_pos); + break; + } + + return d_obtain_alias(inode); +} + +/* + * Rebuild the parent for a directory that is not connected + * to the filesystem root + */ +static +struct inode *fat_rebuild_parent(struct super_block *sb, int parent_logstart) +{ + int search_clus, clus_to_match; + struct msdos_dir_entry *de; + struct inode *parent = NULL; + struct inode *dummy_grand_parent = NULL; + struct fat_slot_info sinfo; + struct msdos_sb_info *sbi = MSDOS_SB(sb); + sector_t blknr = fat_clus_to_blknr(sbi, parent_logstart); + struct buffer_head *parent_bh = sb_bread(sb, blknr); + if (!parent_bh) { + fat_msg(sb, KERN_ERR, + "unable to read cluster of parent directory"); + return NULL; + } + + de = (struct msdos_dir_entry *) parent_bh->b_data; + clus_to_match = fat_get_start(sbi, &de[0]); + search_clus = fat_get_start(sbi, &de[1]); + + dummy_grand_parent = fat_dget(sb, search_clus); + if (!dummy_grand_parent) { + dummy_grand_parent = new_inode(sb); + if (!dummy_grand_parent) { + brelse(parent_bh); + return parent; + } + + dummy_grand_parent->i_ino = iunique(sb, MSDOS_ROOT_INO); + fat_fill_inode(dummy_grand_parent, &de[1]); + MSDOS_I(dummy_grand_parent)->i_pos = -1; + } + + if (!fat_scan_logstart(dummy_grand_parent, clus_to_match, &sinfo)) + parent = fat_build_inode(sb, sinfo.de, sinfo.i_pos); + + brelse(parent_bh); + iput(dummy_grand_parent); + + return parent; +} + /* * Find the parent for a directory that is not currently connected to * the filesystem root. * * On entry, the caller holds child_dir->d_inode->i_mutex. */ -struct dentry *fat_get_parent(struct dentry *child_dir) +static struct dentry *fat_get_parent(struct dentry *child_dir) { struct super_block *sb = child_dir->d_sb; struct buffer_head *bh = NULL; struct msdos_dir_entry *de; struct inode *parent_inode = NULL; + struct msdos_sb_info *sbi = MSDOS_SB(sb); if (!fat_get_dotdot_entry(child_dir->d_inode, &bh, &de)) { - int parent_logstart = fat_get_start(MSDOS_SB(sb), de); + int parent_logstart = fat_get_start(sbi, de); parent_inode = fat_dget(sb, parent_logstart); + if (!parent_inode && sbi->options.nfs == FAT_NFS_NOSTALE_RO) + parent_inode = fat_rebuild_parent(sb, parent_logstart); } brelse(bh); return d_obtain_alias(parent_inode); } + +const struct export_operations fat_export_ops = { + .fh_to_dentry = fat_fh_to_dentry, + .fh_to_parent = fat_fh_to_parent, + .get_parent = fat_get_parent, +}; + +const struct export_operations fat_export_ops_nostale = { + .encode_fh = fat_encode_fh_nostale, + .fh_to_dentry = fat_fh_to_dentry_nostale, + .fh_to_parent = fat_fh_to_parent_nostale, + .get_parent = fat_get_parent, +}; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2e27430b9070..417c84877742 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -234,7 +234,6 @@ static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab) { struct idr *stateids = &cl->cl_stateids; - static int min_stateid = 0; struct nfs4_stid *stid; int new_id; @@ -242,7 +241,7 @@ kmem_cache *slab) if (!stid) return NULL; - new_id = idr_alloc(stateids, stid, min_stateid, 0, GFP_KERNEL); + new_id = idr_alloc_cyclic(stateids, stid, 0, 0, GFP_KERNEL); if (new_id < 0) goto out_free; stid->sc_client = cl; @@ -261,10 +260,6 @@ kmem_cache *slab) * amount of time until an id is reused, by ensuring they always * "increase" (mod INT_MAX): */ - - min_stateid = new_id+1; - if (min_stateid == INT_MAX) - min_stateid = 0; return stid; out_free: kfree(stid); diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index e0f7c1241a6a..8562bd3af947 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -359,7 +359,6 @@ static int inotify_find_inode(const char __user *dirname, struct path *path, uns } static int inotify_add_to_idr(struct idr *idr, spinlock_t *idr_lock, - int *last_wd, struct inotify_inode_mark *i_mark) { int ret; @@ -367,11 +366,10 @@ static int inotify_add_to_idr(struct idr *idr, spinlock_t *idr_lock, idr_preload(GFP_KERNEL); spin_lock(idr_lock); - ret = idr_alloc(idr, i_mark, *last_wd + 1, 0, GFP_NOWAIT); + ret = idr_alloc_cyclic(idr, i_mark, 1, 0, GFP_NOWAIT); if (ret >= 0) { /* we added the mark to the idr, take a reference */ i_mark->wd = ret; - *last_wd = i_mark->wd; fsnotify_get_mark(&i_mark->fsn_mark); } @@ -638,8 +636,7 @@ static int inotify_new_watch(struct fsnotify_group *group, if (atomic_read(&group->inotify_data.user->inotify_watches) >= inotify_max_user_watches) goto out_err; - ret = inotify_add_to_idr(idr, idr_lock, &group->inotify_data.last_wd, - tmp_i_mark); + ret = inotify_add_to_idr(idr, idr_lock, tmp_i_mark); if (ret) goto out_err; @@ -697,7 +694,6 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events) spin_lock_init(&group->inotify_data.idr_lock); idr_init(&group->inotify_data.idr); - group->inotify_data.last_wd = 0; group->inotify_data.user = get_current_user(); if (atomic_inc_return(&group->inotify_data.user->inotify_devs) > diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h index 68b162d92254..842de225055f 100644 --- a/include/linux/compiler-gcc4.h +++ b/include/linux/compiler-gcc4.h @@ -13,7 +13,7 @@ #define __must_check __attribute__((warn_unused_result)) #define __compiler_offsetof(a,b) __builtin_offsetof(a,b) -#if GCC_VERSION >= 40100 +#if GCC_VERSION >= 40100 && GCC_VERSION < 40600 # define __compiletime_object_size(obj) __builtin_object_size(obj, 0) #endif diff --git a/include/linux/console.h b/include/linux/console.h index 29680a8cda99..73bab0f58af5 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -141,6 +141,7 @@ struct console { for (con = console_drivers; con != NULL; con = con->next) extern int console_set_on_cmdline; +extern struct console *early_console; extern int add_preferred_console(char *name, int idx, char *options); extern int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options); diff --git a/include/linux/ctype.h b/include/linux/ctype.h index 8acfe312f947..653589e3e30e 100644 --- a/include/linux/ctype.h +++ b/include/linux/ctype.h @@ -61,4 +61,10 @@ static inline char _tolower(const char c) return c | 0x20; } +/* Fast check for octal digit */ +static inline int isodigit(const char c) +{ + return c >= '0' && c <= '7'; +} + #endif diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 5b9b5b317180..41b223a59a63 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -85,6 +85,17 @@ enum fid_type { FILEID_NILFS_WITH_PARENT = 0x62, /* + * 32 bit generation number, 40 bit i_pos. + */ + FILEID_FAT_WITHOUT_PARENT = 0x71, + + /* + * 32 bit generation number, 40 bit i_pos, + * 32 bit parent generation number, 40 bit parent i_pos + */ + FILEID_FAT_WITH_PARENT = 0x72, + + /* * Filesystems must not use 0xff file ID. */ FILEID_INVALID = 0xff, diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index d5b0910d4961..4b2ee8d12f5e 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -157,7 +157,6 @@ struct fsnotify_group { struct inotify_group_private_data { spinlock_t idr_lock; struct idr idr; - u32 last_wd; struct user_struct *user; } inotify_data; #endif diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index dd7c569aacad..661d374aeb2d 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -29,6 +29,10 @@ #ifndef __GENALLOC_H__ #define __GENALLOC_H__ + +struct device; +struct device_node; + /** * Allocation callback function type definition * @map: Pointer to bitmap @@ -105,4 +109,18 @@ extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data); +extern struct gen_pool *devm_gen_pool_create(struct device *dev, + int min_alloc_order, int nid); +extern struct gen_pool *dev_get_gen_pool(struct device *dev); + +#ifdef CONFIG_OF +extern struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index); +#else +static inline struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + return NULL; +} +#endif #endif /* __GENALLOC_H__ */ diff --git a/include/linux/idr.h b/include/linux/idr.h index 2640c7e99e51..a470ac3ef49d 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -42,6 +42,7 @@ struct idr { struct idr_layer *id_free; int layers; /* only valid w/o concurrent changes */ int id_free_cnt; + int cur; /* current pos for cyclic allocation */ spinlock_t lock; }; @@ -75,6 +76,7 @@ struct idr { void *idr_find_slowpath(struct idr *idp, int id); void idr_preload(gfp_t gfp_mask); int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask); +int idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask); int idr_for_each(struct idr *idp, int (*fn)(int id, void *p, void *data), void *data); void *idr_get_next(struct idr *idp, int *nextid); diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h index 290762f93930..29eab2bd3dfa 100644 --- a/include/linux/mfd/tps65217.h +++ b/include/linux/mfd/tps65217.h @@ -228,6 +228,7 @@ enum tps65217_bl_fdim { struct tps65217_bl_pdata { enum tps65217_bl_isel isel; enum tps65217_bl_fdim fdim; + int dft_brightness; }; /** diff --git a/include/linux/net.h b/include/linux/net.h index aa1673160a45..99c9f0c103c2 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -240,8 +240,8 @@ do { \ #define net_dbg_ratelimited(fmt, ...) \ net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__) -#define net_random() random32() -#define net_srandom(seed) srandom32((__force u32)seed) +#define net_random() prandom_u32() +#define net_srandom(seed) prandom_seed((__force u32)(seed)) extern int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t len); diff --git a/include/linux/platform_data/coda.h b/include/linux/platform_data/coda.h new file mode 100644 index 000000000000..6ad4410d9e20 --- /dev/null +++ b/include/linux/platform_data/coda.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2013 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. + */ +#ifndef PLATFORM_CODA_H +#define PLATFORM_CODA_H + +struct device; + +struct coda_platform_data { + struct device *iram_dev; +}; + +#endif diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h index 20ee8b221dbd..ea3200527dd3 100644 --- a/include/linux/platform_data/lp855x.h +++ b/include/linux/platform_data/lp855x.h @@ -69,11 +69,6 @@ enum lp855x_chip_id { LP8557, }; -enum lp855x_brightness_ctrl_mode { - PWM_BASED = 1, - REGISTER_BASED, -}; - enum lp8550_brighntess_source { LP8550_PWM_ONLY, LP8550_I2C_ONLY = 2, @@ -116,24 +111,18 @@ struct lp855x_rom_data { /** * struct lp855x_platform_data * @name : Backlight driver name. If it is not defined, default name is set. - * @mode : brightness control by pwm or lp855x register * @device_control : value of DEVICE CONTROL register * @initial_brightness : initial value of backlight brightness * @period_ns : platform specific pwm period value. unit is nano. Only valid when mode is PWM_BASED. - * @load_new_rom_data : - 0 : use default configuration data - 1 : update values of eeprom or eprom registers on loading driver * @size_program : total size of lp855x_rom_data * @rom_data : list of new eeprom/eprom registers */ struct lp855x_platform_data { - char *name; - enum lp855x_brightness_ctrl_mode mode; + const char *name; u8 device_control; - int initial_brightness; + u8 initial_brightness; unsigned int period_ns; - u8 load_new_rom_data; int size_program; struct lp855x_rom_data *rom_data; }; diff --git a/include/linux/printk.h b/include/linux/printk.h index 822171fcb1c8..4890fe62c011 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -1,6 +1,7 @@ #ifndef __KERNEL_PRINTK__ #define __KERNEL_PRINTK__ +#include <stdarg.h> #include <linux/init.h> #include <linux/kern_levels.h> @@ -95,8 +96,14 @@ int no_printk(const char *fmt, ...) return 0; } +#ifdef CONFIG_EARLY_PRINTK extern asmlinkage __printf(1, 2) void early_printk(const char *fmt, ...); +void early_vprintk(const char *fmt, va_list ap); +#else +static inline __printf(1, 2) __cold +void early_printk(const char *s, ...) { } +#endif #ifdef CONFIG_PRINTK asmlinkage __printf(5, 0) diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 580b24c8b8ca..c2c28975293c 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -133,7 +133,13 @@ extern struct rtc_device *rtc_device_register(const char *name, struct device *dev, const struct rtc_class_ops *ops, struct module *owner); +extern struct rtc_device *devm_rtc_device_register(struct device *dev, + const char *name, + const struct rtc_class_ops *ops, + struct module *owner); extern void rtc_device_unregister(struct rtc_device *rtc); +extern void devm_rtc_device_unregister(struct device *dev, + struct rtc_device *rtc); extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm); extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm); diff --git a/include/trace/events/printk.h b/include/trace/events/printk.h index 94ec79cc011a..c008bc99f9fa 100644 --- a/include/trace/events/printk.h +++ b/include/trace/events/printk.h @@ -6,31 +6,18 @@ #include <linux/tracepoint.h> -TRACE_EVENT_CONDITION(console, - TP_PROTO(const char *log_buf, unsigned start, unsigned end, - unsigned log_buf_len), +TRACE_EVENT(console, + TP_PROTO(const char *text, size_t len), - TP_ARGS(log_buf, start, end, log_buf_len), - - TP_CONDITION(start != end), + TP_ARGS(text, len), TP_STRUCT__entry( - __dynamic_array(char, msg, end - start + 1) + __dynamic_array(char, msg, len + 1) ), TP_fast_assign( - if ((start & (log_buf_len - 1)) > (end & (log_buf_len - 1))) { - memcpy(__get_dynamic_array(msg), - log_buf + (start & (log_buf_len - 1)), - log_buf_len - (start & (log_buf_len - 1))); - memcpy((char *)__get_dynamic_array(msg) + - log_buf_len - (start & (log_buf_len - 1)), - log_buf, end & (log_buf_len - 1)); - } else - memcpy(__get_dynamic_array(msg), - log_buf + (start & (log_buf_len - 1)), - end - start); - ((char *)__get_dynamic_array(msg))[end - start] = 0; + memcpy(__get_dynamic_array(msg), text, len); + ((char *)__get_dynamic_array(msg))[len] = 0; ), TP_printk("%s", __get_str(msg)) diff --git a/include/video/platform_lcd.h b/include/video/platform_lcd.h index ad3bdfe743b2..23864b284147 100644 --- a/include/video/platform_lcd.h +++ b/include/video/platform_lcd.h @@ -15,6 +15,7 @@ struct plat_lcd_data; struct fb_info; struct plat_lcd_data { + int (*probe)(struct plat_lcd_data *); void (*set_power)(struct plat_lcd_data *, unsigned int power); int (*match_fb)(struct plat_lcd_data *, struct fb_info *); }; diff --git a/init/main.c b/init/main.c index 63534a141b4e..ea73e1eb361c 100644 --- a/init/main.c +++ b/init/main.c @@ -9,6 +9,8 @@ * Simplified starting of init: Michael A. Griffith <grif@acm.org> */ +#define DEBUG /* Enable initcall_debug */ + #include <linux/types.h> #include <linux/module.h> #include <linux/proc_fs.h> @@ -174,8 +176,8 @@ static int __init obsolete_checksetup(char *line) if (line[n] == '\0' || line[n] == '=') had_early_param = 1; } else if (!p->setup_func) { - printk(KERN_WARNING "Parameter %s is obsolete," - " ignored\n", p->str); + pr_warn("Parameter %s is obsolete, ignored\n", + p->str); return 1; } else if (p->setup_func(line + n)) return 1; @@ -398,8 +400,7 @@ static int __init do_early_param(char *param, char *val, const char *unused) strcmp(p->str, "earlycon") == 0) ) { if (p->setup_func(val) != 0) - printk(KERN_WARNING - "Malformed early option '%s'\n", param); + pr_warn("Malformed early option '%s'\n", param); } } /* We accept everything at this stage. */ @@ -497,7 +498,7 @@ asmlinkage void __init start_kernel(void) tick_init(); boot_cpu_init(); page_address_init(); - printk(KERN_NOTICE "%s", linux_banner); + pr_notice("%s", linux_banner); setup_arch(&command_line); mm_init_owner(&init_mm, &init_task); mm_init_cpumask(&init_mm); @@ -509,7 +510,7 @@ asmlinkage void __init start_kernel(void) build_all_zonelists(NULL, NULL); page_alloc_init(); - printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); + pr_notice("Kernel command line: %s\n", boot_command_line); parse_early_param(); parse_args("Booting kernel", static_command_line, __start___param, __stop___param - __start___param, @@ -539,11 +540,8 @@ asmlinkage void __init start_kernel(void) * fragile until we cpu_idle() for the first time. */ preempt_disable(); - if (!irqs_disabled()) { - printk(KERN_WARNING "start_kernel(): bug: interrupts were " - "enabled *very* early, fixing it\n"); + if (WARN(!irqs_disabled(), "Interrupts were enabled *very* early, fixing it\n")) local_irq_disable(); - } idr_init_cache(); perf_event_init(); rcu_init(); @@ -558,9 +556,7 @@ asmlinkage void __init start_kernel(void) time_init(); profile_init(); call_function_init(); - if (!irqs_disabled()) - printk(KERN_CRIT "start_kernel(): bug: interrupts were " - "enabled early\n"); + WARN(!irqs_disabled(), "Interrupts were enabled early\n"); early_boot_irqs_disabled = false; local_irq_enable(); @@ -587,8 +583,7 @@ asmlinkage void __init start_kernel(void) #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { - printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - " - "disabling it.\n", + pr_crit("initrd overwritten (0x%08lx < 0x%08lx) - disabling it.\n", page_to_pfn(virt_to_page((void *)initrd_start)), min_low_pfn); initrd_start = 0; @@ -667,14 +662,14 @@ static int __init_or_module do_one_initcall_debug(initcall_t fn) unsigned long long duration; int ret; - printk(KERN_DEBUG "calling %pF @ %i\n", fn, task_pid_nr(current)); + pr_debug("calling %pF @ %i\n", fn, task_pid_nr(current)); calltime = ktime_get(); ret = fn(); rettime = ktime_get(); delta = ktime_sub(rettime, calltime); duration = (unsigned long long) ktime_to_ns(delta) >> 10; - printk(KERN_DEBUG "initcall %pF returned %d after %lld usecs\n", fn, - ret, duration); + pr_debug("initcall %pF returned %d after %lld usecs\n", + fn, ret, duration); return ret; } @@ -702,9 +697,7 @@ int __init_or_module do_one_initcall(initcall_t fn) strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf)); local_irq_enable(); } - if (msgbuf[0]) { - printk("initcall %pF returned with %s\n", fn, msgbuf); - } + WARN(msgbuf[0], "initcall %pF returned with %s\n", fn, msgbuf); return ret; } @@ -832,8 +825,7 @@ static int __ref kernel_init(void *unused) if (ramdisk_execute_command) { if (!run_init_process(ramdisk_execute_command)) return 0; - printk(KERN_WARNING "Failed to execute %s\n", - ramdisk_execute_command); + pr_err("Failed to execute %s\n", ramdisk_execute_command); } /* @@ -845,8 +837,8 @@ static int __ref kernel_init(void *unused) if (execute_command) { if (!run_init_process(execute_command)) return 0; - printk(KERN_WARNING "Failed to execute %s. Attempting " - "defaults...\n", execute_command); + pr_err("Failed to execute %s. Attempting defaults...\n", + execute_command); } if (!run_init_process("/sbin/init") || !run_init_process("/etc/init") || @@ -891,7 +883,7 @@ static noinline void __init kernel_init_freeable(void) /* Open the /dev/console on the rootfs, this should never fail */ if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) - printk(KERN_WARNING "Warning: unable to open an initial console.\n"); + pr_err("Warning: unable to open an initial console.\n"); (void) sys_dup(0); (void) sys_dup(0); diff --git a/kernel/printk.c b/kernel/printk.c index abbdd9e2ac82..376914e2869d 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -49,13 +49,6 @@ #define CREATE_TRACE_POINTS #include <trace/events/printk.h> -/* - * Architectures can override it: - */ -void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...) -{ -} - /* printk's without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL @@ -608,7 +601,8 @@ static unsigned int devkmsg_poll(struct file *file, poll_table *wait) /* return error when data has vanished underneath us */ if (user->seq < log_first_seq) ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI; - ret = POLLIN|POLLRDNORM; + else + ret = POLLIN|POLLRDNORM; } raw_spin_unlock_irq(&logbuf_lock); @@ -1265,7 +1259,7 @@ static void call_console_drivers(int level, const char *text, size_t len) { struct console *con; - trace_console(text, 0, len, len); + trace_console(text, len); if (level >= console_loglevel && !ignore_loglevel) return; @@ -1723,6 +1717,29 @@ static size_t cont_print_text(char *text, size_t size) { return 0; } #endif /* CONFIG_PRINTK */ +#ifdef CONFIG_EARLY_PRINTK +struct console *early_console; + +void early_vprintk(const char *fmt, va_list ap) +{ + if (early_console) { + char buf[512]; + int n = vscnprintf(buf, sizeof(buf), fmt, ap); + + early_console->write(early_console, buf, n); + } +} + +asmlinkage void early_printk(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + early_vprintk(fmt, ap); + va_end(ap); +} +#endif + static int __add_preferred_console(char *name, int idx, char *options, char *brl_options) { diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 5b8ad827fd86..2f8530bc4b17 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -1319,7 +1319,7 @@ static int rcu_gp_init(struct rcu_state *rsp) rnp->grphi, rnp->qsmask); raw_spin_unlock_irq(&rnp->lock); #ifdef CONFIG_PROVE_RCU_DELAY - if ((random32() % (rcu_num_nodes * 8)) == 0) + if ((prandom_u32() % (rcu_num_nodes * 8)) == 0) schedule_timeout_uninterruptible(2); #endif /* #ifdef CONFIG_PROVE_RCU_DELAY */ cond_resched(); diff --git a/kernel/test_kprobes.c b/kernel/test_kprobes.c index f8b11a283171..12d6ebbfdd83 100644 --- a/kernel/test_kprobes.c +++ b/kernel/test_kprobes.c @@ -365,7 +365,7 @@ int init_test_probes(void) target2 = kprobe_target2; do { - rand1 = random32(); + rand1 = prandom_u32(); } while (rand1 <= div_factor); printk(KERN_INFO "Kprobe smoke test started\n"); diff --git a/lib/argv_split.c b/lib/argv_split.c index 1e9a6cbc3689..e927ed0e18a8 100644 --- a/lib/argv_split.c +++ b/lib/argv_split.c @@ -8,23 +8,17 @@ #include <linux/slab.h> #include <linux/export.h> -static const char *skip_arg(const char *cp) -{ - while (*cp && !isspace(*cp)) - cp++; - - return cp; -} - static int count_argc(const char *str) { int count = 0; + bool was_space; - while (*str) { - str = skip_spaces(str); - if (*str) { + for (was_space = true; *str; str++) { + if (isspace(*str)) { + was_space = true; + } else if (was_space) { + was_space = false; count++; - str = skip_arg(str); } } @@ -39,10 +33,8 @@ static int count_argc(const char *str) */ void argv_free(char **argv) { - char **p; - for (p = argv; *p; p++) - kfree(*p); - + argv--; + kfree(argv[0]); kfree(argv); } EXPORT_SYMBOL(argv_free); @@ -59,43 +51,44 @@ EXPORT_SYMBOL(argv_free); * considered to be a single argument separator. The returned array * is always NULL-terminated. Returns NULL on memory allocation * failure. + * + * The source string at `str' may be undergoing concurrent alteration via + * userspace sysctl activity (at least). The argv_split() implementation + * attempts to handle this gracefully by taking a local copy to work on. */ char **argv_split(gfp_t gfp, const char *str, int *argcp) { - int argc = count_argc(str); - char **argv = kzalloc(sizeof(*argv) * (argc+1), gfp); - char **argvp; - - if (argv == NULL) - goto out; - - if (argcp) - *argcp = argc; - - argvp = argv; - - while (*str) { - str = skip_spaces(str); - - if (*str) { - const char *p = str; - char *t; - - str = skip_arg(str); + char *argv_str; + bool was_space; + char **argv, **argv_ret; + int argc; + + argv_str = kstrndup(str, KMALLOC_MAX_SIZE - 1, gfp); + if (!argv_str) + return NULL; + + argc = count_argc(argv_str); + argv = kmalloc(sizeof(*argv) * (argc + 2), gfp); + if (!argv) { + kfree(argv_str); + return NULL; + } - t = kstrndup(p, str-p, gfp); - if (t == NULL) - goto fail; - *argvp++ = t; + *argv = argv_str; + argv_ret = ++argv; + for (was_space = true; *argv_str; argv_str++) { + if (isspace(*argv_str)) { + was_space = true; + *argv_str = 0; + } else if (was_space) { + was_space = false; + *argv++ = argv_str; } } - *argvp = NULL; - - out: - return argv; + *argv = NULL; - fail: - argv_free(argv); - return NULL; + if (argcp) + *argcp = argc; + return argv_ret; } EXPORT_SYMBOL(argv_split); diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 5276b99ca650..46032453abd5 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -281,7 +281,6 @@ static inline int parse_lineno(const char *str, unsigned int *val) * allow the user to express a query which matches a format * containing embedded spaces. */ -#define isodigit(c) ((c) >= '0' && (c) <= '7') static char *unescape(char *str) { char *in = str; diff --git a/lib/fault-inject.c b/lib/fault-inject.c index f7210ad6cffd..c5c7a762b850 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -122,7 +122,7 @@ bool should_fail(struct fault_attr *attr, ssize_t size) return false; } - if (attr->probability <= random32() % 100) + if (attr->probability <= prandom_u32() % 100) return false; if (!fail_stacktrace(attr)) diff --git a/lib/genalloc.c b/lib/genalloc.c index 54920433705a..b35cfa9bc3d4 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -34,6 +34,8 @@ #include <linux/rculist.h> #include <linux/interrupt.h> #include <linux/genalloc.h> +#include <linux/of_address.h> +#include <linux/of_device.h> static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set) { @@ -480,3 +482,82 @@ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, return start_bit; } EXPORT_SYMBOL(gen_pool_best_fit); + +static void devm_gen_pool_release(struct device *dev, void *res) +{ + gen_pool_destroy(*(struct gen_pool **)res); +} + +/** + * devm_gen_pool_create - managed gen_pool_create + * @dev: device that provides the gen_pool + * @min_alloc_order: log base 2 of number of bytes each bitmap bit represents + * @nid: node id of the node the pool structure should be allocated on, or -1 + * + * Create a new special memory pool that can be used to manage special purpose + * memory not managed by the regular kmalloc/kfree interface. The pool will be + * automatically destroyed by the device management code. + */ +struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order, + int nid) +{ + struct gen_pool **ptr, *pool; + + ptr = devres_alloc(devm_gen_pool_release, sizeof(*ptr), GFP_KERNEL); + + pool = gen_pool_create(min_alloc_order, nid); + if (pool) { + *ptr = pool; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return pool; +} + +/** + * dev_get_gen_pool - Obtain the gen_pool (if any) for a device + * @dev: device to retrieve the gen_pool from + * @name: Optional name for the gen_pool, usually NULL + * + * Returns the gen_pool for the device if one is present, or NULL. + */ +struct gen_pool *dev_get_gen_pool(struct device *dev) +{ + struct gen_pool **p = devres_find(dev, devm_gen_pool_release, NULL, + NULL); + + if (!p) + return NULL; + return *p; +} +EXPORT_SYMBOL_GPL(dev_get_gen_pool); + +#ifdef CONFIG_OF +/** + * of_get_named_gen_pool - find a pool by phandle property + * @np: device node + * @propname: property name containing phandle(s) + * @index: index into the phandle array + * + * Returns the pool that contains the chunk starting at the physical + * address of the device tree node pointed at by the phandle property, + * or NULL if not found. + */ +struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + struct platform_device *pdev; + struct device_node *np_pool; + + np_pool = of_parse_phandle(np, propname, index); + if (!np_pool) + return NULL; + pdev = of_find_device_by_node(np_pool); + if (!pdev) + return NULL; + return dev_get_gen_pool(&pdev->dev); +} +EXPORT_SYMBOL_GPL(of_get_named_gen_pool); +#endif /* CONFIG_OF */ diff --git a/lib/idr.c b/lib/idr.c index 322e2816f2fb..cca4b9302a71 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -495,6 +495,33 @@ int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask) } EXPORT_SYMBOL_GPL(idr_alloc); +/** + * idr_alloc_cyclic - allocate new idr entry in a cyclical fashion + * @idr: the (initialized) idr + * @ptr: pointer to be associated with the new id + * @start: the minimum id (inclusive) + * @end: the maximum id (exclusive, <= 0 for max) + * @gfp_mask: memory allocation flags + * + * Essentially the same as idr_alloc, but prefers to allocate progressively + * higher ids if it can. If the "cur" counter wraps, then it will start again + * at the "start" end of the range and allocate one that has already been used. + */ +int idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end, + gfp_t gfp_mask) +{ + int id; + + id = idr_alloc(idr, ptr, max(start, idr->cur), end, gfp_mask); + if (id == -ENOSPC) + id = idr_alloc(idr, ptr, start, end, gfp_mask); + + if (likely(id >= 0)) + idr->cur = id + 1; + return id; +} +EXPORT_SYMBOL(idr_alloc_cyclic); + static void idr_remove_warning(int id) { printk(KERN_WARNING diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c index fc2eeb7cb2ea..1ef4cc344977 100644 --- a/lib/int_sqrt.c +++ b/lib/int_sqrt.c @@ -1,3 +1,9 @@ +/* + * Copyright (C) 2013 Davidlohr Bueso <davidlohr.bueso@hp.com> + * + * Based on the shift-and-subtract algorithm for computing integer + * square root from Guy L. Steele. + */ #include <linux/kernel.h> #include <linux/export.h> @@ -10,23 +16,23 @@ */ unsigned long int_sqrt(unsigned long x) { - unsigned long op, res, one; + unsigned long b, m, y = 0; - op = x; - res = 0; + if (x <= 1) + return x; - one = 1UL << (BITS_PER_LONG - 2); - while (one > op) - one >>= 2; + m = 1UL << (BITS_PER_LONG - 2); + while (m != 0) { + b = y + m; + y >>= 1; - while (one != 0) { - if (op >= res + one) { - op = op - (res + one); - res = res + 2 * one; + if (x >= b) { + x -= b; + y += m; } - res /= 2; - one /= 4; + m >>= 2; } - return res; + + return y; } EXPORT_SYMBOL(int_sqrt); diff --git a/lib/list_sort.c b/lib/list_sort.c index d7325c6b103f..1183fa70a44d 100644 --- a/lib/list_sort.c +++ b/lib/list_sort.c @@ -229,7 +229,7 @@ static int __init list_sort_test(void) goto exit; } /* force some equivalencies */ - el->value = random32() % (TEST_LIST_LEN/3); + el->value = prandom_u32() % (TEST_LIST_LEN / 3); el->serial = i; el->poison1 = TEST_POISON1; el->poison2 = TEST_POISON2; diff --git a/lib/uuid.c b/lib/uuid.c index 52a6fe6387de..398821e4dce1 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -25,13 +25,7 @@ static void __uuid_gen_common(__u8 b[16]) { - int i; - u32 r; - - for (i = 0; i < 4; i++) { - r = random32(); - memcpy(b + i * 4, &r, 4); - } + prandom_bytes(b, 16); /* reversion 0b10 */ b[8] = (b[8] & 0x3F) | 0x80; } diff --git a/mm/swapfile.c b/mm/swapfile.c index a1f7772a01fc..d417efddfe74 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -2120,7 +2120,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) if (p->bdev) { if (blk_queue_nonrot(bdev_get_queue(p->bdev))) { p->flags |= SWP_SOLIDSTATE; - p->cluster_next = 1 + (random32() % p->highest_bit); + p->cluster_next = 1 + (prandom_u32() % p->highest_bit); } if ((swap_flags & SWAP_FLAG_DISCARD) && discard_swap(p) == 0) p->flags |= SWP_DISCARDABLE; diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 6048fc1da1c2..5c217427a669 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2198,7 +2198,7 @@ static inline int f_pick(struct pktgen_dev *pkt_dev) pkt_dev->curfl = 0; /*reset */ } } else { - flow = random32() % pkt_dev->cflows; + flow = prandom_u32() % pkt_dev->cflows; pkt_dev->curfl = flow; if (pkt_dev->flows[flow].count > pkt_dev->lflow) { @@ -2246,7 +2246,7 @@ static void set_cur_queue_map(struct pktgen_dev *pkt_dev) else if (pkt_dev->queue_map_min <= pkt_dev->queue_map_max) { __u16 t; if (pkt_dev->flags & F_QUEUE_MAP_RND) { - t = random32() % + t = prandom_u32() % (pkt_dev->queue_map_max - pkt_dev->queue_map_min + 1) + pkt_dev->queue_map_min; @@ -2278,7 +2278,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) __u32 tmp; if (pkt_dev->flags & F_MACSRC_RND) - mc = random32() % pkt_dev->src_mac_count; + mc = prandom_u32() % pkt_dev->src_mac_count; else { mc = pkt_dev->cur_src_mac_offset++; if (pkt_dev->cur_src_mac_offset >= @@ -2304,7 +2304,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) __u32 tmp; if (pkt_dev->flags & F_MACDST_RND) - mc = random32() % pkt_dev->dst_mac_count; + mc = prandom_u32() % pkt_dev->dst_mac_count; else { mc = pkt_dev->cur_dst_mac_offset++; @@ -2331,21 +2331,21 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) for (i = 0; i < pkt_dev->nr_labels; i++) if (pkt_dev->labels[i] & MPLS_STACK_BOTTOM) pkt_dev->labels[i] = MPLS_STACK_BOTTOM | - ((__force __be32)random32() & + ((__force __be32)prandom_u32() & htonl(0x000fffff)); } if ((pkt_dev->flags & F_VID_RND) && (pkt_dev->vlan_id != 0xffff)) { - pkt_dev->vlan_id = random32() & (4096-1); + pkt_dev->vlan_id = prandom_u32() & (4096 - 1); } if ((pkt_dev->flags & F_SVID_RND) && (pkt_dev->svlan_id != 0xffff)) { - pkt_dev->svlan_id = random32() & (4096 - 1); + pkt_dev->svlan_id = prandom_u32() & (4096 - 1); } if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) { if (pkt_dev->flags & F_UDPSRC_RND) - pkt_dev->cur_udp_src = random32() % + pkt_dev->cur_udp_src = prandom_u32() % (pkt_dev->udp_src_max - pkt_dev->udp_src_min) + pkt_dev->udp_src_min; @@ -2358,7 +2358,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) if (pkt_dev->udp_dst_min < pkt_dev->udp_dst_max) { if (pkt_dev->flags & F_UDPDST_RND) { - pkt_dev->cur_udp_dst = random32() % + pkt_dev->cur_udp_dst = prandom_u32() % (pkt_dev->udp_dst_max - pkt_dev->udp_dst_min) + pkt_dev->udp_dst_min; } else { @@ -2375,7 +2375,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) if (imn < imx) { __u32 t; if (pkt_dev->flags & F_IPSRC_RND) - t = random32() % (imx - imn) + imn; + t = prandom_u32() % (imx - imn) + imn; else { t = ntohl(pkt_dev->cur_saddr); t++; @@ -2396,17 +2396,15 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) __be32 s; if (pkt_dev->flags & F_IPDST_RND) { - t = random32() % (imx - imn) + imn; - s = htonl(t); - - while (ipv4_is_loopback(s) || - ipv4_is_multicast(s) || - ipv4_is_lbcast(s) || - ipv4_is_zeronet(s) || - ipv4_is_local_multicast(s)) { - t = random32() % (imx - imn) + imn; + do { + t = prandom_u32() % + (imx - imn) + imn; s = htonl(t); - } + } while (ipv4_is_loopback(s) || + ipv4_is_multicast(s) || + ipv4_is_lbcast(s) || + ipv4_is_zeronet(s) || + ipv4_is_local_multicast(s)); pkt_dev->cur_daddr = s; } else { t = ntohl(pkt_dev->cur_daddr); @@ -2437,7 +2435,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) for (i = 0; i < 4; i++) { pkt_dev->cur_in6_daddr.s6_addr32[i] = - (((__force __be32)random32() | + (((__force __be32)prandom_u32() | pkt_dev->min_in6_daddr.s6_addr32[i]) & pkt_dev->max_in6_daddr.s6_addr32[i]); } @@ -2447,7 +2445,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) if (pkt_dev->min_pkt_size < pkt_dev->max_pkt_size) { __u32 t; if (pkt_dev->flags & F_TXSIZE_RND) { - t = random32() % + t = prandom_u32() % (pkt_dev->max_pkt_size - pkt_dev->min_pkt_size) + pkt_dev->min_pkt_size; } else { diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index c8e001a9c45b..f84965af4a4e 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -264,7 +264,7 @@ static void death_by_event(unsigned long ul_conntrack) if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) { /* bad luck, let's retry again */ ecache->timeout.expires = jiffies + - (random32() % net->ct.sysctl_events_retry_timeout); + (prandom_u32() % net->ct.sysctl_events_retry_timeout); add_timer(&ecache->timeout); return; } @@ -283,7 +283,7 @@ void nf_ct_dying_timeout(struct nf_conn *ct) /* set a new timer to retry event delivery */ setup_timer(&ecache->timeout, death_by_event, (unsigned long)ct); ecache->timeout.expires = jiffies + - (random32() % net->ct.sysctl_events_retry_timeout); + (prandom_u32() % net->ct.sysctl_events_retry_timeout); add_timer(&ecache->timeout); } EXPORT_SYMBOL_GPL(nf_ct_dying_timeout); diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index cc37dd52ecf9..ef53ab8d0aae 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c @@ -80,7 +80,7 @@ struct choke_sched_data { /* deliver a random number between 0 and N - 1 */ static u32 random_N(unsigned int N) { - return reciprocal_divide(random32(), N); + return reciprocal_divide(prandom_u32(), N); } /* number of elements in queue including holes */ diff --git a/net/sctp/associola.c b/net/sctp/associola.c index d2709e2b7be6..fa261a3594c2 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -66,13 +66,6 @@ static void sctp_assoc_bh_rcv(struct work_struct *work); static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc); static void sctp_assoc_free_asconf_queue(struct sctp_association *asoc); -/* Keep track of the new idr low so that we don't re-use association id - * numbers too fast. It is protected by they idr spin lock is in the - * range of 1 - INT_MAX. - */ -static u32 idr_low = 1; - - /* 1st Level Abstractions. */ /* Initialize a new association from provided memory. */ @@ -1601,13 +1594,8 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp) if (preload) idr_preload(gfp); spin_lock_bh(&sctp_assocs_id_lock); - /* 0 is not a valid id, idr_low is always >= 1 */ - ret = idr_alloc(&sctp_assocs_id, asoc, idr_low, 0, GFP_NOWAIT); - if (ret >= 0) { - idr_low = ret + 1; - if (idr_low == INT_MAX) - idr_low = 1; - } + /* 0 is not a valid assoc_id, must be >= 1 */ + ret = idr_alloc_cyclic(&sctp_assocs_id, asoc, 1, 0, GFP_NOWAIT); spin_unlock_bh(&sctp_assocs_id_lock); if (preload) idr_preload_end(); diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index 88edec929d73..1da52d1406fc 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c @@ -130,8 +130,8 @@ gss_krb5_make_confounder(char *p, u32 conflen) /* initialize to random value */ if (i == 0) { - i = random32(); - i = (i << 32) | random32(); + i = prandom_u32(); + i = (i << 32) | prandom_u32(); } switch (conflen) { diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 25d58e766014..ce2d180d05a4 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -1208,7 +1208,6 @@ EXPORT_SYMBOL_GPL(sunrpc_cache_pipe_upcall); * key and content are both parsed by cache */ -#define isodigit(c) (isdigit(c) && c <= '7') int qword_get(char **bpp, char *dest, int bufsize) { /* return bytes copied, or -1 on error */ diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4de4bc48493b..b954de58304f 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -281,6 +281,7 @@ our $signature_tags = qr{(?xi: Tested-by:| Reviewed-by:| Reported-by:| + Suggested-by:| To:| Cc: )}; @@ -628,6 +629,13 @@ sub sanitise_line { return $res; } +sub get_quoted_string { + my ($line, $rawline) = @_; + + return "" if ($line !~ m/(\"[X]+\")/g); + return substr($rawline, $-[0], $+[0] - $-[0]); +} + sub ctx_statement_block { my ($linenr, $remain, $off) = @_; my $line = $linenr - 1; @@ -1576,7 +1584,8 @@ sub process { # Check for incorrect file permissions if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { my $permhere = $here . "FILE: $realfile\n"; - if ($realfile =~ /(Makefile|Kconfig|\.c|\.h|\.S|\.tmpl)$/) { + if ($realfile !~ m@scripts/@ && + $realfile !~ /\.(py|pl|awk|sh)$/) { ERROR("EXECUTE_PERMISSIONS", "do not set execute permissions for source files\n" . $permhere); } @@ -2514,8 +2523,8 @@ sub process { # check for whitespace before a non-naked semicolon if ($line =~ /^\+.*\S\s+;/) { - CHK("SPACING", - "space prohibited before semicolon\n" . $herecurr); + WARN("SPACING", + "space prohibited before semicolon\n" . $herecurr); } # Check operator spacing. @@ -3221,7 +3230,7 @@ sub process { } # check for unnecessary blank lines around braces - if (($line =~ /^..*}\s*$/ && $prevline =~ /^.\s*$/)) { + if (($line =~ /^.\s*}\s*$/ && $prevline =~ /^.\s*$/)) { CHK("BRACES", "Blank lines aren't necessary before a close brace '}'\n" . $hereprev); } @@ -3373,6 +3382,15 @@ sub process { "struct spinlock should be spinlock_t\n" . $herecurr); } +# check for seq_printf uses that could be seq_puts + if ($line =~ /\bseq_printf\s*\(/) { + my $fmt = get_quoted_string($line, $rawline); + if ($fmt !~ /[^\\]\%/) { + WARN("PREFER_SEQ_PUTS", + "Prefer seq_puts to seq_printf\n" . $herecurr); + } + } + # Check for misused memsets if ($^V && $^V ge 5.10.0 && defined $stat && @@ -3477,6 +3495,13 @@ sub process { "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); } +# check for krealloc arg reuse + if ($^V && $^V ge 5.10.0 && + $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { + WARN("KREALLOC_ARG_REUSE", + "Reusing the krealloc arg is almost always a bug\n" . $herecurr); + } + # check for alloc argument mismatch if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { WARN("ALLOC_ARRAY_ARGS", diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index ce4cc837b748..5e4fb144a04f 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -611,7 +611,7 @@ sub get_maintainers { $hash{$tvi} = $value_pd; } } - } elsif ($type eq 'K') { + } elsif ($type eq 'N') { if ($file =~ m/$value/x) { $hash{$tvi} = 0; } |