diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 21:54:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 21:54:50 -0400 |
commit | dfe2c6dcc8ca2cdc662d7c0473e9811b72ef3370 (patch) | |
tree | 9ed639a08c16322cdf136d576f42df5b97cd1549 /drivers | |
parent | a45d572841a24db02a62cf05e1157c35fdd3705b (diff) | |
parent | 64e455079e1bd7787cc47be30b7f601ce682a5f6 (diff) |
Merge branch 'akpm' (patches from Andrew Morton)
Merge second patch-bomb from Andrew Morton:
- a few hotfixes
- drivers/dma updates
- MAINTAINERS updates
- Quite a lot of lib/ updates
- checkpatch updates
- binfmt updates
- autofs4
- drivers/rtc/
- various small tweaks to less used filesystems
- ipc/ updates
- kernel/watchdog.c changes
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (135 commits)
mm: softdirty: enable write notifications on VMAs after VM_SOFTDIRTY cleared
kernel/param: consolidate __{start,stop}___param[] in <linux/moduleparam.h>
ia64: remove duplicate declarations of __per_cpu_start[] and __per_cpu_end[]
frv: remove unused declarations of __start___ex_table and __stop___ex_table
kvm: ensure hard lockup detection is disabled by default
kernel/watchdog.c: control hard lockup detection default
staging: rtl8192u: use %*pEn to escape buffer
staging: rtl8192e: use %*pEn to escape buffer
staging: wlan-ng: use %*pEhp to print SN
lib80211: remove unused print_ssid()
wireless: hostap: proc: print properly escaped SSID
wireless: ipw2x00: print SSID via %*pE
wireless: libertas: print esaped string via %*pE
lib/vsprintf: add %*pE[achnops] format specifier
lib / string_helpers: introduce string_escape_mem()
lib / string_helpers: refactoring the test suite
lib / string_helpers: move documentation to c-file
include/linux: remove strict_strto* definitions
arch/x86/mm/numa.c: fix boot failure when all nodes are hotpluggable
fs: check bh blocknr earlier when searching lru
...
Diffstat (limited to 'drivers')
44 files changed, 2244 insertions, 849 deletions
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c index 7d6e84a51424..55b83983a9c0 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c | |||
@@ -14,11 +14,14 @@ struct dma_coherent_mem { | |||
14 | int size; | 14 | int size; |
15 | int flags; | 15 | int flags; |
16 | unsigned long *bitmap; | 16 | unsigned long *bitmap; |
17 | spinlock_t spinlock; | ||
17 | }; | 18 | }; |
18 | 19 | ||
19 | int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, | 20 | static int dma_init_coherent_memory(phys_addr_t phys_addr, dma_addr_t device_addr, |
20 | dma_addr_t device_addr, size_t size, int flags) | 21 | size_t size, int flags, |
22 | struct dma_coherent_mem **mem) | ||
21 | { | 23 | { |
24 | struct dma_coherent_mem *dma_mem = NULL; | ||
22 | void __iomem *mem_base = NULL; | 25 | void __iomem *mem_base = NULL; |
23 | int pages = size >> PAGE_SHIFT; | 26 | int pages = size >> PAGE_SHIFT; |
24 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | 27 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); |
@@ -27,40 +30,77 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, | |||
27 | goto out; | 30 | goto out; |
28 | if (!size) | 31 | if (!size) |
29 | goto out; | 32 | goto out; |
30 | if (dev->dma_mem) | ||
31 | goto out; | ||
32 | |||
33 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
34 | 33 | ||
35 | mem_base = ioremap(phys_addr, size); | 34 | mem_base = ioremap(phys_addr, size); |
36 | if (!mem_base) | 35 | if (!mem_base) |
37 | goto out; | 36 | goto out; |
38 | 37 | ||
39 | dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); | 38 | dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); |
40 | if (!dev->dma_mem) | 39 | if (!dma_mem) |
41 | goto out; | 40 | goto out; |
42 | dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | 41 | dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); |
43 | if (!dev->dma_mem->bitmap) | 42 | if (!dma_mem->bitmap) |
44 | goto free1_out; | 43 | goto out; |
44 | |||
45 | dma_mem->virt_base = mem_base; | ||
46 | dma_mem->device_base = device_addr; | ||
47 | dma_mem->pfn_base = PFN_DOWN(phys_addr); | ||
48 | dma_mem->size = pages; | ||
49 | dma_mem->flags = flags; | ||
50 | spin_lock_init(&dma_mem->spinlock); | ||
45 | 51 | ||
46 | dev->dma_mem->virt_base = mem_base; | 52 | *mem = dma_mem; |
47 | dev->dma_mem->device_base = device_addr; | ||
48 | dev->dma_mem->pfn_base = PFN_DOWN(phys_addr); | ||
49 | dev->dma_mem->size = pages; | ||
50 | dev->dma_mem->flags = flags; | ||
51 | 53 | ||
52 | if (flags & DMA_MEMORY_MAP) | 54 | if (flags & DMA_MEMORY_MAP) |
53 | return DMA_MEMORY_MAP; | 55 | return DMA_MEMORY_MAP; |
54 | 56 | ||
55 | return DMA_MEMORY_IO; | 57 | return DMA_MEMORY_IO; |
56 | 58 | ||
57 | free1_out: | 59 | out: |
58 | kfree(dev->dma_mem); | 60 | kfree(dma_mem); |
59 | out: | ||
60 | if (mem_base) | 61 | if (mem_base) |
61 | iounmap(mem_base); | 62 | iounmap(mem_base); |
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
65 | |||
66 | static void dma_release_coherent_memory(struct dma_coherent_mem *mem) | ||
67 | { | ||
68 | if (!mem) | ||
69 | return; | ||
70 | iounmap(mem->virt_base); | ||
71 | kfree(mem->bitmap); | ||
72 | kfree(mem); | ||
73 | } | ||
74 | |||
75 | static int dma_assign_coherent_memory(struct device *dev, | ||
76 | struct dma_coherent_mem *mem) | ||
77 | { | ||
78 | if (dev->dma_mem) | ||
79 | return -EBUSY; | ||
80 | |||
81 | dev->dma_mem = mem; | ||
82 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, | ||
88 | dma_addr_t device_addr, size_t size, int flags) | ||
89 | { | ||
90 | struct dma_coherent_mem *mem; | ||
91 | int ret; | ||
92 | |||
93 | ret = dma_init_coherent_memory(phys_addr, device_addr, size, flags, | ||
94 | &mem); | ||
95 | if (ret == 0) | ||
96 | return 0; | ||
97 | |||
98 | if (dma_assign_coherent_memory(dev, mem) == 0) | ||
99 | return ret; | ||
100 | |||
101 | dma_release_coherent_memory(mem); | ||
102 | return 0; | ||
103 | } | ||
64 | EXPORT_SYMBOL(dma_declare_coherent_memory); | 104 | EXPORT_SYMBOL(dma_declare_coherent_memory); |
65 | 105 | ||
66 | void dma_release_declared_memory(struct device *dev) | 106 | void dma_release_declared_memory(struct device *dev) |
@@ -69,10 +109,8 @@ void dma_release_declared_memory(struct device *dev) | |||
69 | 109 | ||
70 | if (!mem) | 110 | if (!mem) |
71 | return; | 111 | return; |
112 | dma_release_coherent_memory(mem); | ||
72 | dev->dma_mem = NULL; | 113 | dev->dma_mem = NULL; |
73 | iounmap(mem->virt_base); | ||
74 | kfree(mem->bitmap); | ||
75 | kfree(mem); | ||
76 | } | 114 | } |
77 | EXPORT_SYMBOL(dma_release_declared_memory); | 115 | EXPORT_SYMBOL(dma_release_declared_memory); |
78 | 116 | ||
@@ -80,6 +118,7 @@ void *dma_mark_declared_memory_occupied(struct device *dev, | |||
80 | dma_addr_t device_addr, size_t size) | 118 | dma_addr_t device_addr, size_t size) |
81 | { | 119 | { |
82 | struct dma_coherent_mem *mem = dev->dma_mem; | 120 | struct dma_coherent_mem *mem = dev->dma_mem; |
121 | unsigned long flags; | ||
83 | int pos, err; | 122 | int pos, err; |
84 | 123 | ||
85 | size += device_addr & ~PAGE_MASK; | 124 | size += device_addr & ~PAGE_MASK; |
@@ -87,8 +126,11 @@ void *dma_mark_declared_memory_occupied(struct device *dev, | |||
87 | if (!mem) | 126 | if (!mem) |
88 | return ERR_PTR(-EINVAL); | 127 | return ERR_PTR(-EINVAL); |
89 | 128 | ||
129 | spin_lock_irqsave(&mem->spinlock, flags); | ||
90 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; | 130 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; |
91 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(size)); | 131 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(size)); |
132 | spin_unlock_irqrestore(&mem->spinlock, flags); | ||
133 | |||
92 | if (err != 0) | 134 | if (err != 0) |
93 | return ERR_PTR(err); | 135 | return ERR_PTR(err); |
94 | return mem->virt_base + (pos << PAGE_SHIFT); | 136 | return mem->virt_base + (pos << PAGE_SHIFT); |
@@ -115,6 +157,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, | |||
115 | { | 157 | { |
116 | struct dma_coherent_mem *mem; | 158 | struct dma_coherent_mem *mem; |
117 | int order = get_order(size); | 159 | int order = get_order(size); |
160 | unsigned long flags; | ||
118 | int pageno; | 161 | int pageno; |
119 | 162 | ||
120 | if (!dev) | 163 | if (!dev) |
@@ -124,6 +167,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, | |||
124 | return 0; | 167 | return 0; |
125 | 168 | ||
126 | *ret = NULL; | 169 | *ret = NULL; |
170 | spin_lock_irqsave(&mem->spinlock, flags); | ||
127 | 171 | ||
128 | if (unlikely(size > (mem->size << PAGE_SHIFT))) | 172 | if (unlikely(size > (mem->size << PAGE_SHIFT))) |
129 | goto err; | 173 | goto err; |
@@ -138,10 +182,12 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, | |||
138 | *dma_handle = mem->device_base + (pageno << PAGE_SHIFT); | 182 | *dma_handle = mem->device_base + (pageno << PAGE_SHIFT); |
139 | *ret = mem->virt_base + (pageno << PAGE_SHIFT); | 183 | *ret = mem->virt_base + (pageno << PAGE_SHIFT); |
140 | memset(*ret, 0, size); | 184 | memset(*ret, 0, size); |
185 | spin_unlock_irqrestore(&mem->spinlock, flags); | ||
141 | 186 | ||
142 | return 1; | 187 | return 1; |
143 | 188 | ||
144 | err: | 189 | err: |
190 | spin_unlock_irqrestore(&mem->spinlock, flags); | ||
145 | /* | 191 | /* |
146 | * In the case where the allocation can not be satisfied from the | 192 | * In the case where the allocation can not be satisfied from the |
147 | * per-device area, try to fall back to generic memory if the | 193 | * per-device area, try to fall back to generic memory if the |
@@ -171,8 +217,11 @@ int dma_release_from_coherent(struct device *dev, int order, void *vaddr) | |||
171 | if (mem && vaddr >= mem->virt_base && vaddr < | 217 | if (mem && vaddr >= mem->virt_base && vaddr < |
172 | (mem->virt_base + (mem->size << PAGE_SHIFT))) { | 218 | (mem->virt_base + (mem->size << PAGE_SHIFT))) { |
173 | int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; | 219 | int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; |
220 | unsigned long flags; | ||
174 | 221 | ||
222 | spin_lock_irqsave(&mem->spinlock, flags); | ||
175 | bitmap_release_region(mem->bitmap, page, order); | 223 | bitmap_release_region(mem->bitmap, page, order); |
224 | spin_unlock_irqrestore(&mem->spinlock, flags); | ||
176 | return 1; | 225 | return 1; |
177 | } | 226 | } |
178 | return 0; | 227 | return 0; |
@@ -218,3 +267,61 @@ int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma, | |||
218 | return 0; | 267 | return 0; |
219 | } | 268 | } |
220 | EXPORT_SYMBOL(dma_mmap_from_coherent); | 269 | EXPORT_SYMBOL(dma_mmap_from_coherent); |
270 | |||
271 | /* | ||
272 | * Support for reserved memory regions defined in device tree | ||
273 | */ | ||
274 | #ifdef CONFIG_OF_RESERVED_MEM | ||
275 | #include <linux/of.h> | ||
276 | #include <linux/of_fdt.h> | ||
277 | #include <linux/of_reserved_mem.h> | ||
278 | |||
279 | static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev) | ||
280 | { | ||
281 | struct dma_coherent_mem *mem = rmem->priv; | ||
282 | |||
283 | if (!mem && | ||
284 | dma_init_coherent_memory(rmem->base, rmem->base, rmem->size, | ||
285 | DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE, | ||
286 | &mem) != DMA_MEMORY_MAP) { | ||
287 | pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n", | ||
288 | &rmem->base, (unsigned long)rmem->size / SZ_1M); | ||
289 | return -ENODEV; | ||
290 | } | ||
291 | rmem->priv = mem; | ||
292 | dma_assign_coherent_memory(dev, mem); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static void rmem_dma_device_release(struct reserved_mem *rmem, | ||
297 | struct device *dev) | ||
298 | { | ||
299 | dev->dma_mem = NULL; | ||
300 | } | ||
301 | |||
302 | static const struct reserved_mem_ops rmem_dma_ops = { | ||
303 | .device_init = rmem_dma_device_init, | ||
304 | .device_release = rmem_dma_device_release, | ||
305 | }; | ||
306 | |||
307 | static int __init rmem_dma_setup(struct reserved_mem *rmem) | ||
308 | { | ||
309 | unsigned long node = rmem->fdt_node; | ||
310 | |||
311 | if (of_get_flat_dt_prop(node, "reusable", NULL)) | ||
312 | return -EINVAL; | ||
313 | |||
314 | #ifdef CONFIG_ARM | ||
315 | if (!of_get_flat_dt_prop(node, "no-map", NULL)) { | ||
316 | pr_err("Reserved memory: regions without no-map are not yet supported\n"); | ||
317 | return -EINVAL; | ||
318 | } | ||
319 | #endif | ||
320 | |||
321 | rmem->ops = &rmem_dma_ops; | ||
322 | pr_info("Reserved memory: created DMA memory pool at %pa, size %ld MiB\n", | ||
323 | &rmem->base, (unsigned long)rmem->size / SZ_1M); | ||
324 | return 0; | ||
325 | } | ||
326 | RESERVEDMEM_OF_DECLARE(dma, "shared-dma-pool", rmem_dma_setup); | ||
327 | #endif | ||
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 6606abdf880c..473ff4892401 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c | |||
@@ -211,3 +211,69 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages, | |||
211 | { | 211 | { |
212 | return cma_release(dev_get_cma_area(dev), pages, count); | 212 | return cma_release(dev_get_cma_area(dev), pages, count); |
213 | } | 213 | } |
214 | |||
215 | /* | ||
216 | * Support for reserved memory regions defined in device tree | ||
217 | */ | ||
218 | #ifdef CONFIG_OF_RESERVED_MEM | ||
219 | #include <linux/of.h> | ||
220 | #include <linux/of_fdt.h> | ||
221 | #include <linux/of_reserved_mem.h> | ||
222 | |||
223 | #undef pr_fmt | ||
224 | #define pr_fmt(fmt) fmt | ||
225 | |||
226 | static void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev) | ||
227 | { | ||
228 | dev_set_cma_area(dev, rmem->priv); | ||
229 | } | ||
230 | |||
231 | static void rmem_cma_device_release(struct reserved_mem *rmem, | ||
232 | struct device *dev) | ||
233 | { | ||
234 | dev_set_cma_area(dev, NULL); | ||
235 | } | ||
236 | |||
237 | static const struct reserved_mem_ops rmem_cma_ops = { | ||
238 | .device_init = rmem_cma_device_init, | ||
239 | .device_release = rmem_cma_device_release, | ||
240 | }; | ||
241 | |||
242 | static int __init rmem_cma_setup(struct reserved_mem *rmem) | ||
243 | { | ||
244 | phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); | ||
245 | phys_addr_t mask = align - 1; | ||
246 | unsigned long node = rmem->fdt_node; | ||
247 | struct cma *cma; | ||
248 | int err; | ||
249 | |||
250 | if (!of_get_flat_dt_prop(node, "reusable", NULL) || | ||
251 | of_get_flat_dt_prop(node, "no-map", NULL)) | ||
252 | return -EINVAL; | ||
253 | |||
254 | if ((rmem->base & mask) || (rmem->size & mask)) { | ||
255 | pr_err("Reserved memory: incorrect alignment of CMA region\n"); | ||
256 | return -EINVAL; | ||
257 | } | ||
258 | |||
259 | err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma); | ||
260 | if (err) { | ||
261 | pr_err("Reserved memory: unable to setup CMA region\n"); | ||
262 | return err; | ||
263 | } | ||
264 | /* Architecture specific contiguous memory fixup. */ | ||
265 | dma_contiguous_early_fixup(rmem->base, rmem->size); | ||
266 | |||
267 | if (of_get_flat_dt_prop(node, "linux,cma-default", NULL)) | ||
268 | dma_contiguous_set_default(cma); | ||
269 | |||
270 | rmem->ops = &rmem_cma_ops; | ||
271 | rmem->priv = cma; | ||
272 | |||
273 | pr_info("Reserved memory: created CMA memory pool at %pa, size %ld MiB\n", | ||
274 | &rmem->base, (unsigned long)rmem->size / SZ_1M); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup); | ||
279 | #endif | ||
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index cfd3af7b2cbd..84e0590e31dc 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -38,6 +38,15 @@ config COMMON_CLK_MAX77686 | |||
38 | ---help--- | 38 | ---help--- |
39 | This driver supports Maxim 77686 crystal oscillator clock. | 39 | This driver supports Maxim 77686 crystal oscillator clock. |
40 | 40 | ||
41 | config COMMON_CLK_RK808 | ||
42 | tristate "Clock driver for RK808" | ||
43 | depends on MFD_RK808 | ||
44 | ---help--- | ||
45 | This driver supports RK808 crystal oscillator clock. These | ||
46 | multi-function devices have two fixed-rate oscillators, | ||
47 | clocked at 32KHz each. Clkout1 is always on, Clkout2 can off | ||
48 | by control register. | ||
49 | |||
41 | config COMMON_CLK_SI5351 | 50 | config COMMON_CLK_SI5351 |
42 | tristate "Clock driver for SiLabs 5351A/B/C" | 51 | tristate "Clock driver for SiLabs 5351A/B/C" |
43 | depends on I2C | 52 | depends on I2C |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f537a0b1f798..99f53d5f8766 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -28,6 +28,7 @@ obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o | |||
28 | obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o | 28 | obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o |
29 | obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o | 29 | obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o |
30 | obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o | 30 | obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o |
31 | obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o | ||
31 | obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o | 32 | obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o |
32 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o | 33 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o |
33 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o | 34 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o |
diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c new file mode 100644 index 000000000000..83902b9cd49e --- /dev/null +++ b/drivers/clk/clk-rk808.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /* | ||
2 | * Clkout driver for Rockchip RK808 | ||
3 | * | ||
4 | * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd | ||
5 | * | ||
6 | * Author:Chris Zhong <zyw@rock-chips.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/clk.h> | ||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/mfd/rk808.h> | ||
24 | #include <linux/i2c.h> | ||
25 | |||
26 | #define RK808_NR_OUTPUT 2 | ||
27 | |||
28 | struct rk808_clkout { | ||
29 | struct rk808 *rk808; | ||
30 | struct clk_onecell_data clk_data; | ||
31 | struct clk_hw clkout1_hw; | ||
32 | struct clk_hw clkout2_hw; | ||
33 | }; | ||
34 | |||
35 | static unsigned long rk808_clkout_recalc_rate(struct clk_hw *hw, | ||
36 | unsigned long parent_rate) | ||
37 | { | ||
38 | return 32768; | ||
39 | } | ||
40 | |||
41 | static int rk808_clkout2_enable(struct clk_hw *hw, bool enable) | ||
42 | { | ||
43 | struct rk808_clkout *rk808_clkout = container_of(hw, | ||
44 | struct rk808_clkout, | ||
45 | clkout2_hw); | ||
46 | struct rk808 *rk808 = rk808_clkout->rk808; | ||
47 | |||
48 | return regmap_update_bits(rk808->regmap, RK808_CLK32OUT_REG, | ||
49 | CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0); | ||
50 | } | ||
51 | |||
52 | static int rk808_clkout2_prepare(struct clk_hw *hw) | ||
53 | { | ||
54 | return rk808_clkout2_enable(hw, true); | ||
55 | } | ||
56 | |||
57 | static void rk808_clkout2_unprepare(struct clk_hw *hw) | ||
58 | { | ||
59 | rk808_clkout2_enable(hw, false); | ||
60 | } | ||
61 | |||
62 | static int rk808_clkout2_is_prepared(struct clk_hw *hw) | ||
63 | { | ||
64 | struct rk808_clkout *rk808_clkout = container_of(hw, | ||
65 | struct rk808_clkout, | ||
66 | clkout2_hw); | ||
67 | struct rk808 *rk808 = rk808_clkout->rk808; | ||
68 | uint32_t val; | ||
69 | |||
70 | int ret = regmap_read(rk808->regmap, RK808_CLK32OUT_REG, &val); | ||
71 | |||
72 | if (ret < 0) | ||
73 | return ret; | ||
74 | |||
75 | return (val & CLK32KOUT2_EN) ? 1 : 0; | ||
76 | } | ||
77 | |||
78 | static const struct clk_ops rk808_clkout1_ops = { | ||
79 | .recalc_rate = rk808_clkout_recalc_rate, | ||
80 | }; | ||
81 | |||
82 | static const struct clk_ops rk808_clkout2_ops = { | ||
83 | .prepare = rk808_clkout2_prepare, | ||
84 | .unprepare = rk808_clkout2_unprepare, | ||
85 | .is_prepared = rk808_clkout2_is_prepared, | ||
86 | .recalc_rate = rk808_clkout_recalc_rate, | ||
87 | }; | ||
88 | |||
89 | static int rk808_clkout_probe(struct platform_device *pdev) | ||
90 | { | ||
91 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); | ||
92 | struct i2c_client *client = rk808->i2c; | ||
93 | struct device_node *node = client->dev.of_node; | ||
94 | struct clk_init_data init = {}; | ||
95 | struct clk **clk_table; | ||
96 | struct rk808_clkout *rk808_clkout; | ||
97 | |||
98 | rk808_clkout = devm_kzalloc(&client->dev, | ||
99 | sizeof(*rk808_clkout), GFP_KERNEL); | ||
100 | if (!rk808_clkout) | ||
101 | return -ENOMEM; | ||
102 | |||
103 | rk808_clkout->rk808 = rk808; | ||
104 | |||
105 | clk_table = devm_kcalloc(&client->dev, RK808_NR_OUTPUT, | ||
106 | sizeof(struct clk *), GFP_KERNEL); | ||
107 | if (!clk_table) | ||
108 | return -ENOMEM; | ||
109 | |||
110 | init.flags = CLK_IS_ROOT; | ||
111 | init.parent_names = NULL; | ||
112 | init.num_parents = 0; | ||
113 | init.name = "rk808-clkout1"; | ||
114 | init.ops = &rk808_clkout1_ops; | ||
115 | rk808_clkout->clkout1_hw.init = &init; | ||
116 | |||
117 | /* optional override of the clockname */ | ||
118 | of_property_read_string_index(node, "clock-output-names", | ||
119 | 0, &init.name); | ||
120 | |||
121 | clk_table[0] = devm_clk_register(&client->dev, | ||
122 | &rk808_clkout->clkout1_hw); | ||
123 | if (IS_ERR(clk_table[0])) | ||
124 | return PTR_ERR(clk_table[0]); | ||
125 | |||
126 | init.name = "rk808-clkout2"; | ||
127 | init.ops = &rk808_clkout2_ops; | ||
128 | rk808_clkout->clkout2_hw.init = &init; | ||
129 | |||
130 | /* optional override of the clockname */ | ||
131 | of_property_read_string_index(node, "clock-output-names", | ||
132 | 1, &init.name); | ||
133 | |||
134 | clk_table[1] = devm_clk_register(&client->dev, | ||
135 | &rk808_clkout->clkout2_hw); | ||
136 | if (IS_ERR(clk_table[1])) | ||
137 | return PTR_ERR(clk_table[1]); | ||
138 | |||
139 | rk808_clkout->clk_data.clks = clk_table; | ||
140 | rk808_clkout->clk_data.clk_num = RK808_NR_OUTPUT; | ||
141 | |||
142 | return of_clk_add_provider(node, of_clk_src_onecell_get, | ||
143 | &rk808_clkout->clk_data); | ||
144 | } | ||
145 | |||
146 | static int rk808_clkout_remove(struct platform_device *pdev) | ||
147 | { | ||
148 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); | ||
149 | struct i2c_client *client = rk808->i2c; | ||
150 | struct device_node *node = client->dev.of_node; | ||
151 | |||
152 | of_clk_del_provider(node); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static struct platform_driver rk808_clkout_driver = { | ||
158 | .probe = rk808_clkout_probe, | ||
159 | .remove = rk808_clkout_remove, | ||
160 | .driver = { | ||
161 | .name = "rk808-clkout", | ||
162 | }, | ||
163 | }; | ||
164 | |||
165 | module_platform_driver(rk808_clkout_driver); | ||
166 | |||
167 | MODULE_DESCRIPTION("Clkout driver for the rk808 series PMICs"); | ||
168 | MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); | ||
169 | MODULE_LICENSE("GPL"); | ||
170 | MODULE_ALIAS("platform:rk808-clkout"); | ||
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index d28a8c284da9..7206547c13ce 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -3574,7 +3574,7 @@ static int srpt_parse_i_port_id(u8 i_port_id[16], const char *name) | |||
3574 | int ret, rc; | 3574 | int ret, rc; |
3575 | 3575 | ||
3576 | p = name; | 3576 | p = name; |
3577 | if (strnicmp(p, "0x", 2) == 0) | 3577 | if (strncasecmp(p, "0x", 2) == 0) |
3578 | p += 2; | 3578 | p += 2; |
3579 | ret = -EINVAL; | 3579 | ret = -EINVAL; |
3580 | len = strlen(p); | 3580 | len = strlen(p); |
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 8857d5b9be71..ee3434f1e949 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
@@ -812,7 +812,7 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client, | |||
812 | /* if we find something consistent, stay with that assumption | 812 | /* if we find something consistent, stay with that assumption |
813 | * at least M09 won't send 3 bytes here | 813 | * at least M09 won't send 3 bytes here |
814 | */ | 814 | */ |
815 | if (!(strnicmp(rdbuf + 1, "EP0", 3))) { | 815 | if (!(strncasecmp(rdbuf + 1, "EP0", 3))) { |
816 | tsdata->version = M06; | 816 | tsdata->version = M06; |
817 | 817 | ||
818 | /* remove last '$' end marker */ | 818 | /* remove last '$' end marker */ |
diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 31727bf285d0..e2a4f5f415b2 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c | |||
@@ -188,6 +188,7 @@ static void r592_host_reset(struct r592_device *dev) | |||
188 | r592_set_mode(dev, dev->parallel_mode); | 188 | r592_set_mode(dev, dev->parallel_mode); |
189 | } | 189 | } |
190 | 190 | ||
191 | #ifdef CONFIG_PM_SLEEP | ||
191 | /* Disable all hardware interrupts */ | 192 | /* Disable all hardware interrupts */ |
192 | static void r592_clear_interrupts(struct r592_device *dev) | 193 | static void r592_clear_interrupts(struct r592_device *dev) |
193 | { | 194 | { |
@@ -195,6 +196,7 @@ static void r592_clear_interrupts(struct r592_device *dev) | |||
195 | r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_ACK_MASK); | 196 | r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_ACK_MASK); |
196 | r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_EN_MASK); | 197 | r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_EN_MASK); |
197 | } | 198 | } |
199 | #endif | ||
198 | 200 | ||
199 | /* Tests if there is an CRC error */ | 201 | /* Tests if there is an CRC error */ |
200 | static int r592_test_io_error(struct r592_device *dev) | 202 | static int r592_test_io_error(struct r592_device *dev) |
diff --git a/drivers/misc/altera-stapl/altera.c b/drivers/misc/altera-stapl/altera.c index 24272e022bec..bca2630d006f 100644 --- a/drivers/misc/altera-stapl/altera.c +++ b/drivers/misc/altera-stapl/altera.c | |||
@@ -454,7 +454,7 @@ exit_done: | |||
454 | 454 | ||
455 | name = &p[str_table + name_id]; | 455 | name = &p[str_table + name_id]; |
456 | 456 | ||
457 | if (strnicmp(aconf->action, name, strlen(name)) == 0) { | 457 | if (strncasecmp(aconf->action, name, strlen(name)) == 0) { |
458 | action_found = 1; | 458 | action_found = 1; |
459 | current_proc = | 459 | current_proc = |
460 | get_unaligned_be32(&p[action_table + | 460 | get_unaligned_be32(&p[action_table + |
@@ -2176,7 +2176,7 @@ static int altera_get_note(u8 *p, s32 program_size, | |||
2176 | key_ptr = &p[note_strings + | 2176 | key_ptr = &p[note_strings + |
2177 | get_unaligned_be32( | 2177 | get_unaligned_be32( |
2178 | &p[note_table + (8 * i)])]; | 2178 | &p[note_table + (8 * i)])]; |
2179 | if ((strnicmp(key, key_ptr, strlen(key_ptr)) == 0) && | 2179 | if ((strncasecmp(key, key_ptr, strlen(key_ptr)) == 0) && |
2180 | (key != NULL)) { | 2180 | (key != NULL)) { |
2181 | status = 0; | 2181 | status = 0; |
2182 | 2182 | ||
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index 8efd17c52f65..dd84557cf957 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c | |||
@@ -168,7 +168,6 @@ static int prism2_bss_list_proc_show(struct seq_file *m, void *v) | |||
168 | local_info_t *local = m->private; | 168 | local_info_t *local = m->private; |
169 | struct list_head *ptr = v; | 169 | struct list_head *ptr = v; |
170 | struct hostap_bss_info *bss; | 170 | struct hostap_bss_info *bss; |
171 | int i; | ||
172 | 171 | ||
173 | if (ptr == &local->bss_list) { | 172 | if (ptr == &local->bss_list) { |
174 | seq_printf(m, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t" | 173 | seq_printf(m, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t" |
@@ -181,9 +180,7 @@ static int prism2_bss_list_proc_show(struct seq_file *m, void *v) | |||
181 | bss->bssid, bss->last_update, | 180 | bss->bssid, bss->last_update, |
182 | bss->count, bss->capab_info); | 181 | bss->count, bss->capab_info); |
183 | 182 | ||
184 | for (i = 0; i < bss->ssid_len; i++) | 183 | seq_printf(m, "%*pE", (int)bss->ssid_len, bss->ssid); |
185 | seq_putc(m,bss->ssid[i] >= 32 && bss->ssid[i] < 127 ? | ||
186 | bss->ssid[i] : '_'); | ||
187 | 184 | ||
188 | seq_putc(m, '\t'); | 185 | seq_putc(m, '\t'); |
189 | seq_printf(m, "%*phN", (int)bss->ssid_len, bss->ssid); | 186 | seq_printf(m, "%*phN", (int)bss->ssid_len, bss->ssid); |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index c3d726f334e3..6fabea0309dd 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -2005,7 +2005,6 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) | |||
2005 | u32 chan; | 2005 | u32 chan; |
2006 | char *txratename; | 2006 | char *txratename; |
2007 | u8 bssid[ETH_ALEN]; | 2007 | u8 bssid[ETH_ALEN]; |
2008 | DECLARE_SSID_BUF(ssid); | ||
2009 | 2008 | ||
2010 | /* | 2009 | /* |
2011 | * TBD: BSSID is usually 00:00:00:00:00:00 here and not | 2010 | * TBD: BSSID is usually 00:00:00:00:00:00 here and not |
@@ -2067,8 +2066,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) | |||
2067 | break; | 2066 | break; |
2068 | } | 2067 | } |
2069 | 2068 | ||
2070 | IPW_DEBUG_INFO("%s: Associated with '%s' at %s, channel %d (BSSID=%pM)\n", | 2069 | IPW_DEBUG_INFO("%s: Associated with '%*pE' at %s, channel %d (BSSID=%pM)\n", |
2071 | priv->net_dev->name, print_ssid(ssid, essid, essid_len), | 2070 | priv->net_dev->name, essid_len, essid, |
2072 | txratename, chan, bssid); | 2071 | txratename, chan, bssid); |
2073 | 2072 | ||
2074 | /* now we copy read ssid into dev */ | 2073 | /* now we copy read ssid into dev */ |
@@ -2095,9 +2094,8 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, | |||
2095 | .host_command_length = ssid_len | 2094 | .host_command_length = ssid_len |
2096 | }; | 2095 | }; |
2097 | int err; | 2096 | int err; |
2098 | DECLARE_SSID_BUF(ssid); | ||
2099 | 2097 | ||
2100 | IPW_DEBUG_HC("SSID: '%s'\n", print_ssid(ssid, essid, ssid_len)); | 2098 | IPW_DEBUG_HC("SSID: '%*pE'\n", ssid_len, essid); |
2101 | 2099 | ||
2102 | if (ssid_len) | 2100 | if (ssid_len) |
2103 | memcpy(cmd.host_command_parameters, essid, ssid_len); | 2101 | memcpy(cmd.host_command_parameters, essid, ssid_len); |
@@ -2138,11 +2136,8 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, | |||
2138 | 2136 | ||
2139 | static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status) | 2137 | static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status) |
2140 | { | 2138 | { |
2141 | DECLARE_SSID_BUF(ssid); | ||
2142 | |||
2143 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | 2139 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, |
2144 | "disassociated: '%s' %pM\n", | 2140 | "disassociated: '%*pE' %pM\n", priv->essid_len, priv->essid, |
2145 | print_ssid(ssid, priv->essid, priv->essid_len), | ||
2146 | priv->bssid); | 2141 | priv->bssid); |
2147 | 2142 | ||
2148 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); | 2143 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); |
@@ -6975,7 +6970,6 @@ static int ipw2100_wx_set_essid(struct net_device *dev, | |||
6975 | char *essid = ""; /* ANY */ | 6970 | char *essid = ""; /* ANY */ |
6976 | int length = 0; | 6971 | int length = 0; |
6977 | int err = 0; | 6972 | int err = 0; |
6978 | DECLARE_SSID_BUF(ssid); | ||
6979 | 6973 | ||
6980 | mutex_lock(&priv->action_mutex); | 6974 | mutex_lock(&priv->action_mutex); |
6981 | if (!(priv->status & STATUS_INITIALIZED)) { | 6975 | if (!(priv->status & STATUS_INITIALIZED)) { |
@@ -7005,8 +6999,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev, | |||
7005 | goto done; | 6999 | goto done; |
7006 | } | 7000 | } |
7007 | 7001 | ||
7008 | IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", | 7002 | IPW_DEBUG_WX("Setting ESSID: '%*pE' (%d)\n", length, essid, length); |
7009 | print_ssid(ssid, essid, length), length); | ||
7010 | 7003 | ||
7011 | priv->essid_len = length; | 7004 | priv->essid_len = length; |
7012 | memcpy(priv->essid, essid, priv->essid_len); | 7005 | memcpy(priv->essid, essid, priv->essid_len); |
@@ -7027,13 +7020,12 @@ static int ipw2100_wx_get_essid(struct net_device *dev, | |||
7027 | */ | 7020 | */ |
7028 | 7021 | ||
7029 | struct ipw2100_priv *priv = libipw_priv(dev); | 7022 | struct ipw2100_priv *priv = libipw_priv(dev); |
7030 | DECLARE_SSID_BUF(ssid); | ||
7031 | 7023 | ||
7032 | /* If we are associated, trying to associate, or have a statically | 7024 | /* If we are associated, trying to associate, or have a statically |
7033 | * configured ESSID then return that; otherwise return ANY */ | 7025 | * configured ESSID then return that; otherwise return ANY */ |
7034 | if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) { | 7026 | if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) { |
7035 | IPW_DEBUG_WX("Getting essid: '%s'\n", | 7027 | IPW_DEBUG_WX("Getting essid: '%*pE'\n", |
7036 | print_ssid(ssid, priv->essid, priv->essid_len)); | 7028 | priv->essid_len, priv->essid); |
7037 | memcpy(extra, priv->essid, priv->essid_len); | 7029 | memcpy(extra, priv->essid, priv->essid_len); |
7038 | wrqu->essid.length = priv->essid_len; | 7030 | wrqu->essid.length = priv->essid_len; |
7039 | wrqu->essid.flags = 1; /* active */ | 7031 | wrqu->essid.flags = 1; /* active */ |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index f0c3c77a48d3..edc344334a75 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -4496,7 +4496,6 @@ static void handle_scan_event(struct ipw_priv *priv) | |||
4496 | static void ipw_rx_notification(struct ipw_priv *priv, | 4496 | static void ipw_rx_notification(struct ipw_priv *priv, |
4497 | struct ipw_rx_notification *notif) | 4497 | struct ipw_rx_notification *notif) |
4498 | { | 4498 | { |
4499 | DECLARE_SSID_BUF(ssid); | ||
4500 | u16 size = le16_to_cpu(notif->size); | 4499 | u16 size = le16_to_cpu(notif->size); |
4501 | 4500 | ||
4502 | IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size); | 4501 | IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size); |
@@ -4509,9 +4508,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4509 | case CMAS_ASSOCIATED:{ | 4508 | case CMAS_ASSOCIATED:{ |
4510 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | 4509 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
4511 | IPW_DL_ASSOC, | 4510 | IPW_DL_ASSOC, |
4512 | "associated: '%s' %pM\n", | 4511 | "associated: '%*pE' %pM\n", |
4513 | print_ssid(ssid, priv->essid, | 4512 | priv->essid_len, priv->essid, |
4514 | priv->essid_len), | ||
4515 | priv->bssid); | 4513 | priv->bssid); |
4516 | 4514 | ||
4517 | switch (priv->ieee->iw_mode) { | 4515 | switch (priv->ieee->iw_mode) { |
@@ -4585,14 +4583,9 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4585 | IPW_DEBUG(IPW_DL_NOTIF | | 4583 | IPW_DEBUG(IPW_DL_NOTIF | |
4586 | IPW_DL_STATE | | 4584 | IPW_DL_STATE | |
4587 | IPW_DL_ASSOC, | 4585 | IPW_DL_ASSOC, |
4588 | "deauthenticated: '%s' " | 4586 | "deauthenticated: '%*pE' %pM: (0x%04X) - %s\n", |
4589 | "%pM" | 4587 | priv->essid_len, |
4590 | ": (0x%04X) - %s\n", | 4588 | priv->essid, |
4591 | print_ssid(ssid, | ||
4592 | priv-> | ||
4593 | essid, | ||
4594 | priv-> | ||
4595 | essid_len), | ||
4596 | priv->bssid, | 4589 | priv->bssid, |
4597 | le16_to_cpu(auth->status), | 4590 | le16_to_cpu(auth->status), |
4598 | ipw_get_status_code | 4591 | ipw_get_status_code |
@@ -4610,9 +4603,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4610 | 4603 | ||
4611 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | 4604 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
4612 | IPW_DL_ASSOC, | 4605 | IPW_DL_ASSOC, |
4613 | "authenticated: '%s' %pM\n", | 4606 | "authenticated: '%*pE' %pM\n", |
4614 | print_ssid(ssid, priv->essid, | 4607 | priv->essid_len, priv->essid, |
4615 | priv->essid_len), | ||
4616 | priv->bssid); | 4608 | priv->bssid); |
4617 | break; | 4609 | break; |
4618 | } | 4610 | } |
@@ -4638,9 +4630,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4638 | 4630 | ||
4639 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | 4631 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
4640 | IPW_DL_ASSOC, | 4632 | IPW_DL_ASSOC, |
4641 | "disassociated: '%s' %pM\n", | 4633 | "disassociated: '%*pE' %pM\n", |
4642 | print_ssid(ssid, priv->essid, | 4634 | priv->essid_len, priv->essid, |
4643 | priv->essid_len), | ||
4644 | priv->bssid); | 4635 | priv->bssid); |
4645 | 4636 | ||
4646 | priv->status &= | 4637 | priv->status &= |
@@ -4676,9 +4667,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4676 | switch (auth->state) { | 4667 | switch (auth->state) { |
4677 | case CMAS_AUTHENTICATED: | 4668 | case CMAS_AUTHENTICATED: |
4678 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, | 4669 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, |
4679 | "authenticated: '%s' %pM\n", | 4670 | "authenticated: '%*pE' %pM\n", |
4680 | print_ssid(ssid, priv->essid, | 4671 | priv->essid_len, priv->essid, |
4681 | priv->essid_len), | ||
4682 | priv->bssid); | 4672 | priv->bssid); |
4683 | priv->status |= STATUS_AUTH; | 4673 | priv->status |= STATUS_AUTH; |
4684 | break; | 4674 | break; |
@@ -4695,9 +4685,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4695 | } | 4685 | } |
4696 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | 4686 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
4697 | IPW_DL_ASSOC, | 4687 | IPW_DL_ASSOC, |
4698 | "deauthenticated: '%s' %pM\n", | 4688 | "deauthenticated: '%*pE' %pM\n", |
4699 | print_ssid(ssid, priv->essid, | 4689 | priv->essid_len, priv->essid, |
4700 | priv->essid_len), | ||
4701 | priv->bssid); | 4690 | priv->bssid); |
4702 | 4691 | ||
4703 | priv->status &= ~(STATUS_ASSOCIATING | | 4692 | priv->status &= ~(STATUS_ASSOCIATING | |
@@ -5516,16 +5505,13 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5516 | int roaming) | 5505 | int roaming) |
5517 | { | 5506 | { |
5518 | struct ipw_supported_rates rates; | 5507 | struct ipw_supported_rates rates; |
5519 | DECLARE_SSID_BUF(ssid); | ||
5520 | 5508 | ||
5521 | /* Verify that this network's capability is compatible with the | 5509 | /* Verify that this network's capability is compatible with the |
5522 | * current mode (AdHoc or Infrastructure) */ | 5510 | * current mode (AdHoc or Infrastructure) */ |
5523 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC && | 5511 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC && |
5524 | !(network->capability & WLAN_CAPABILITY_IBSS))) { | 5512 | !(network->capability & WLAN_CAPABILITY_IBSS))) { |
5525 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded due to " | 5513 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded due to capability mismatch.\n", |
5526 | "capability mismatch.\n", | 5514 | network->ssid_len, network->ssid, |
5527 | print_ssid(ssid, network->ssid, | ||
5528 | network->ssid_len), | ||
5529 | network->bssid); | 5515 | network->bssid); |
5530 | return 0; | 5516 | return 0; |
5531 | } | 5517 | } |
@@ -5536,10 +5522,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5536 | if ((network->ssid_len != match->network->ssid_len) || | 5522 | if ((network->ssid_len != match->network->ssid_len) || |
5537 | memcmp(network->ssid, match->network->ssid, | 5523 | memcmp(network->ssid, match->network->ssid, |
5538 | network->ssid_len)) { | 5524 | network->ssid_len)) { |
5539 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5525 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of non-network ESSID.\n", |
5540 | "because of non-network ESSID.\n", | 5526 | network->ssid_len, network->ssid, |
5541 | print_ssid(ssid, network->ssid, | ||
5542 | network->ssid_len), | ||
5543 | network->bssid); | 5527 | network->bssid); |
5544 | return 0; | 5528 | return 0; |
5545 | } | 5529 | } |
@@ -5550,17 +5534,10 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5550 | ((network->ssid_len != priv->essid_len) || | 5534 | ((network->ssid_len != priv->essid_len) || |
5551 | memcmp(network->ssid, priv->essid, | 5535 | memcmp(network->ssid, priv->essid, |
5552 | min(network->ssid_len, priv->essid_len)))) { | 5536 | min(network->ssid_len, priv->essid_len)))) { |
5553 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 5537 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n", |
5554 | 5538 | network->ssid_len, network->ssid, | |
5555 | strlcpy(escaped, | 5539 | network->bssid, priv->essid_len, |
5556 | print_ssid(ssid, network->ssid, | 5540 | priv->essid); |
5557 | network->ssid_len), | ||
5558 | sizeof(escaped)); | ||
5559 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | ||
5560 | "because of ESSID mismatch: '%s'.\n", | ||
5561 | escaped, network->bssid, | ||
5562 | print_ssid(ssid, priv->essid, | ||
5563 | priv->essid_len)); | ||
5564 | return 0; | 5541 | return 0; |
5565 | } | 5542 | } |
5566 | } | 5543 | } |
@@ -5569,26 +5546,20 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5569 | * testing everything else. */ | 5546 | * testing everything else. */ |
5570 | 5547 | ||
5571 | if (network->time_stamp[0] < match->network->time_stamp[0]) { | 5548 | if (network->time_stamp[0] < match->network->time_stamp[0]) { |
5572 | IPW_DEBUG_MERGE("Network '%s excluded because newer than " | 5549 | IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n", |
5573 | "current network.\n", | 5550 | match->network->ssid_len, match->network->ssid); |
5574 | print_ssid(ssid, match->network->ssid, | ||
5575 | match->network->ssid_len)); | ||
5576 | return 0; | 5551 | return 0; |
5577 | } else if (network->time_stamp[1] < match->network->time_stamp[1]) { | 5552 | } else if (network->time_stamp[1] < match->network->time_stamp[1]) { |
5578 | IPW_DEBUG_MERGE("Network '%s excluded because newer than " | 5553 | IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n", |
5579 | "current network.\n", | 5554 | match->network->ssid_len, match->network->ssid); |
5580 | print_ssid(ssid, match->network->ssid, | ||
5581 | match->network->ssid_len)); | ||
5582 | return 0; | 5555 | return 0; |
5583 | } | 5556 | } |
5584 | 5557 | ||
5585 | /* Now go through and see if the requested network is valid... */ | 5558 | /* Now go through and see if the requested network is valid... */ |
5586 | if (priv->ieee->scan_age != 0 && | 5559 | if (priv->ieee->scan_age != 0 && |
5587 | time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { | 5560 | time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { |
5588 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5561 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of age: %ums.\n", |
5589 | "because of age: %ums.\n", | 5562 | network->ssid_len, network->ssid, |
5590 | print_ssid(ssid, network->ssid, | ||
5591 | network->ssid_len), | ||
5592 | network->bssid, | 5563 | network->bssid, |
5593 | jiffies_to_msecs(jiffies - | 5564 | jiffies_to_msecs(jiffies - |
5594 | network->last_scanned)); | 5565 | network->last_scanned)); |
@@ -5597,10 +5568,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5597 | 5568 | ||
5598 | if ((priv->config & CFG_STATIC_CHANNEL) && | 5569 | if ((priv->config & CFG_STATIC_CHANNEL) && |
5599 | (network->channel != priv->channel)) { | 5570 | (network->channel != priv->channel)) { |
5600 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5571 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n", |
5601 | "because of channel mismatch: %d != %d.\n", | 5572 | network->ssid_len, network->ssid, |
5602 | print_ssid(ssid, network->ssid, | ||
5603 | network->ssid_len), | ||
5604 | network->bssid, | 5573 | network->bssid, |
5605 | network->channel, priv->channel); | 5574 | network->channel, priv->channel); |
5606 | return 0; | 5575 | return 0; |
@@ -5609,10 +5578,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5609 | /* Verify privacy compatibility */ | 5578 | /* Verify privacy compatibility */ |
5610 | if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != | 5579 | if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != |
5611 | ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { | 5580 | ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { |
5612 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5581 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n", |
5613 | "because of privacy mismatch: %s != %s.\n", | 5582 | network->ssid_len, network->ssid, |
5614 | print_ssid(ssid, network->ssid, | ||
5615 | network->ssid_len), | ||
5616 | network->bssid, | 5583 | network->bssid, |
5617 | priv-> | 5584 | priv-> |
5618 | capability & CAP_PRIVACY_ON ? "on" : "off", | 5585 | capability & CAP_PRIVACY_ON ? "on" : "off", |
@@ -5623,22 +5590,16 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5623 | } | 5590 | } |
5624 | 5591 | ||
5625 | if (ether_addr_equal(network->bssid, priv->bssid)) { | 5592 | if (ether_addr_equal(network->bssid, priv->bssid)) { |
5626 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5593 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of the same BSSID match: %pM.\n", |
5627 | "because of the same BSSID match: %pM" | 5594 | network->ssid_len, network->ssid, |
5628 | ".\n", print_ssid(ssid, network->ssid, | 5595 | network->bssid, priv->bssid); |
5629 | network->ssid_len), | ||
5630 | network->bssid, | ||
5631 | priv->bssid); | ||
5632 | return 0; | 5596 | return 0; |
5633 | } | 5597 | } |
5634 | 5598 | ||
5635 | /* Filter out any incompatible freq / mode combinations */ | 5599 | /* Filter out any incompatible freq / mode combinations */ |
5636 | if (!libipw_is_valid_mode(priv->ieee, network->mode)) { | 5600 | if (!libipw_is_valid_mode(priv->ieee, network->mode)) { |
5637 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5601 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n", |
5638 | "because of invalid frequency/mode " | 5602 | network->ssid_len, network->ssid, |
5639 | "combination.\n", | ||
5640 | print_ssid(ssid, network->ssid, | ||
5641 | network->ssid_len), | ||
5642 | network->bssid); | 5603 | network->bssid); |
5643 | return 0; | 5604 | return 0; |
5644 | } | 5605 | } |
@@ -5646,20 +5607,15 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5646 | /* Ensure that the rates supported by the driver are compatible with | 5607 | /* Ensure that the rates supported by the driver are compatible with |
5647 | * this AP, including verification of basic rates (mandatory) */ | 5608 | * this AP, including verification of basic rates (mandatory) */ |
5648 | if (!ipw_compatible_rates(priv, network, &rates)) { | 5609 | if (!ipw_compatible_rates(priv, network, &rates)) { |
5649 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5610 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n", |
5650 | "because configured rate mask excludes " | 5611 | network->ssid_len, network->ssid, |
5651 | "AP mandatory rate.\n", | ||
5652 | print_ssid(ssid, network->ssid, | ||
5653 | network->ssid_len), | ||
5654 | network->bssid); | 5612 | network->bssid); |
5655 | return 0; | 5613 | return 0; |
5656 | } | 5614 | } |
5657 | 5615 | ||
5658 | if (rates.num_rates == 0) { | 5616 | if (rates.num_rates == 0) { |
5659 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5617 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of no compatible rates.\n", |
5660 | "because of no compatible rates.\n", | 5618 | network->ssid_len, network->ssid, |
5661 | print_ssid(ssid, network->ssid, | ||
5662 | network->ssid_len), | ||
5663 | network->bssid); | 5619 | network->bssid); |
5664 | return 0; | 5620 | return 0; |
5665 | } | 5621 | } |
@@ -5671,16 +5627,14 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5671 | /* Set up 'new' AP to this network */ | 5627 | /* Set up 'new' AP to this network */ |
5672 | ipw_copy_rates(&match->rates, &rates); | 5628 | ipw_copy_rates(&match->rates, &rates); |
5673 | match->network = network; | 5629 | match->network = network; |
5674 | IPW_DEBUG_MERGE("Network '%s (%pM)' is a viable match.\n", | 5630 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' is a viable match.\n", |
5675 | print_ssid(ssid, network->ssid, network->ssid_len), | 5631 | network->ssid_len, network->ssid, network->bssid); |
5676 | network->bssid); | ||
5677 | 5632 | ||
5678 | return 1; | 5633 | return 1; |
5679 | } | 5634 | } |
5680 | 5635 | ||
5681 | static void ipw_merge_adhoc_network(struct work_struct *work) | 5636 | static void ipw_merge_adhoc_network(struct work_struct *work) |
5682 | { | 5637 | { |
5683 | DECLARE_SSID_BUF(ssid); | ||
5684 | struct ipw_priv *priv = | 5638 | struct ipw_priv *priv = |
5685 | container_of(work, struct ipw_priv, merge_networks); | 5639 | container_of(work, struct ipw_priv, merge_networks); |
5686 | struct libipw_network *network = NULL; | 5640 | struct libipw_network *network = NULL; |
@@ -5710,9 +5664,8 @@ static void ipw_merge_adhoc_network(struct work_struct *work) | |||
5710 | 5664 | ||
5711 | mutex_lock(&priv->mutex); | 5665 | mutex_lock(&priv->mutex); |
5712 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { | 5666 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { |
5713 | IPW_DEBUG_MERGE("remove network %s\n", | 5667 | IPW_DEBUG_MERGE("remove network %*pE\n", |
5714 | print_ssid(ssid, priv->essid, | 5668 | priv->essid_len, priv->essid); |
5715 | priv->essid_len)); | ||
5716 | ipw_remove_current_network(priv); | 5669 | ipw_remove_current_network(priv); |
5717 | } | 5670 | } |
5718 | 5671 | ||
@@ -5728,7 +5681,6 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5728 | struct libipw_network *network, int roaming) | 5681 | struct libipw_network *network, int roaming) |
5729 | { | 5682 | { |
5730 | struct ipw_supported_rates rates; | 5683 | struct ipw_supported_rates rates; |
5731 | DECLARE_SSID_BUF(ssid); | ||
5732 | 5684 | ||
5733 | /* Verify that this network's capability is compatible with the | 5685 | /* Verify that this network's capability is compatible with the |
5734 | * current mode (AdHoc or Infrastructure) */ | 5686 | * current mode (AdHoc or Infrastructure) */ |
@@ -5736,10 +5688,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5736 | !(network->capability & WLAN_CAPABILITY_ESS)) || | 5688 | !(network->capability & WLAN_CAPABILITY_ESS)) || |
5737 | (priv->ieee->iw_mode == IW_MODE_ADHOC && | 5689 | (priv->ieee->iw_mode == IW_MODE_ADHOC && |
5738 | !(network->capability & WLAN_CAPABILITY_IBSS))) { | 5690 | !(network->capability & WLAN_CAPABILITY_IBSS))) { |
5739 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded due to " | 5691 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded due to capability mismatch.\n", |
5740 | "capability mismatch.\n", | 5692 | network->ssid_len, network->ssid, |
5741 | print_ssid(ssid, network->ssid, | ||
5742 | network->ssid_len), | ||
5743 | network->bssid); | 5693 | network->bssid); |
5744 | return 0; | 5694 | return 0; |
5745 | } | 5695 | } |
@@ -5750,10 +5700,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5750 | if ((network->ssid_len != match->network->ssid_len) || | 5700 | if ((network->ssid_len != match->network->ssid_len) || |
5751 | memcmp(network->ssid, match->network->ssid, | 5701 | memcmp(network->ssid, match->network->ssid, |
5752 | network->ssid_len)) { | 5702 | network->ssid_len)) { |
5753 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5703 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of non-network ESSID.\n", |
5754 | "because of non-network ESSID.\n", | 5704 | network->ssid_len, network->ssid, |
5755 | print_ssid(ssid, network->ssid, | ||
5756 | network->ssid_len), | ||
5757 | network->bssid); | 5705 | network->bssid); |
5758 | return 0; | 5706 | return 0; |
5759 | } | 5707 | } |
@@ -5764,16 +5712,10 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5764 | ((network->ssid_len != priv->essid_len) || | 5712 | ((network->ssid_len != priv->essid_len) || |
5765 | memcmp(network->ssid, priv->essid, | 5713 | memcmp(network->ssid, priv->essid, |
5766 | min(network->ssid_len, priv->essid_len)))) { | 5714 | min(network->ssid_len, priv->essid_len)))) { |
5767 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 5715 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n", |
5768 | strlcpy(escaped, | 5716 | network->ssid_len, network->ssid, |
5769 | print_ssid(ssid, network->ssid, | 5717 | network->bssid, priv->essid_len, |
5770 | network->ssid_len), | 5718 | priv->essid); |
5771 | sizeof(escaped)); | ||
5772 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | ||
5773 | "because of ESSID mismatch: '%s'.\n", | ||
5774 | escaped, network->bssid, | ||
5775 | print_ssid(ssid, priv->essid, | ||
5776 | priv->essid_len)); | ||
5777 | return 0; | 5719 | return 0; |
5778 | } | 5720 | } |
5779 | } | 5721 | } |
@@ -5781,16 +5723,10 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5781 | /* If the old network rate is better than this one, don't bother | 5723 | /* If the old network rate is better than this one, don't bother |
5782 | * testing everything else. */ | 5724 | * testing everything else. */ |
5783 | if (match->network && match->network->stats.rssi > network->stats.rssi) { | 5725 | if (match->network && match->network->stats.rssi > network->stats.rssi) { |
5784 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 5726 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because '%*pE (%pM)' has a stronger signal.\n", |
5785 | strlcpy(escaped, | 5727 | network->ssid_len, network->ssid, |
5786 | print_ssid(ssid, network->ssid, network->ssid_len), | 5728 | network->bssid, match->network->ssid_len, |
5787 | sizeof(escaped)); | 5729 | match->network->ssid, match->network->bssid); |
5788 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because " | ||
5789 | "'%s (%pM)' has a stronger signal.\n", | ||
5790 | escaped, network->bssid, | ||
5791 | print_ssid(ssid, match->network->ssid, | ||
5792 | match->network->ssid_len), | ||
5793 | match->network->bssid); | ||
5794 | return 0; | 5730 | return 0; |
5795 | } | 5731 | } |
5796 | 5732 | ||
@@ -5798,11 +5734,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5798 | * last 3 seconds, do not try and associate again... */ | 5734 | * last 3 seconds, do not try and associate again... */ |
5799 | if (network->last_associate && | 5735 | if (network->last_associate && |
5800 | time_after(network->last_associate + (HZ * 3UL), jiffies)) { | 5736 | time_after(network->last_associate + (HZ * 3UL), jiffies)) { |
5801 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5737 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of storming (%ums since last assoc attempt).\n", |
5802 | "because of storming (%ums since last " | 5738 | network->ssid_len, network->ssid, |
5803 | "assoc attempt).\n", | ||
5804 | print_ssid(ssid, network->ssid, | ||
5805 | network->ssid_len), | ||
5806 | network->bssid, | 5739 | network->bssid, |
5807 | jiffies_to_msecs(jiffies - | 5740 | jiffies_to_msecs(jiffies - |
5808 | network->last_associate)); | 5741 | network->last_associate)); |
@@ -5812,10 +5745,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5812 | /* Now go through and see if the requested network is valid... */ | 5745 | /* Now go through and see if the requested network is valid... */ |
5813 | if (priv->ieee->scan_age != 0 && | 5746 | if (priv->ieee->scan_age != 0 && |
5814 | time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { | 5747 | time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { |
5815 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5748 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of age: %ums.\n", |
5816 | "because of age: %ums.\n", | 5749 | network->ssid_len, network->ssid, |
5817 | print_ssid(ssid, network->ssid, | ||
5818 | network->ssid_len), | ||
5819 | network->bssid, | 5750 | network->bssid, |
5820 | jiffies_to_msecs(jiffies - | 5751 | jiffies_to_msecs(jiffies - |
5821 | network->last_scanned)); | 5752 | network->last_scanned)); |
@@ -5824,10 +5755,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5824 | 5755 | ||
5825 | if ((priv->config & CFG_STATIC_CHANNEL) && | 5756 | if ((priv->config & CFG_STATIC_CHANNEL) && |
5826 | (network->channel != priv->channel)) { | 5757 | (network->channel != priv->channel)) { |
5827 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5758 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n", |
5828 | "because of channel mismatch: %d != %d.\n", | 5759 | network->ssid_len, network->ssid, |
5829 | print_ssid(ssid, network->ssid, | ||
5830 | network->ssid_len), | ||
5831 | network->bssid, | 5760 | network->bssid, |
5832 | network->channel, priv->channel); | 5761 | network->channel, priv->channel); |
5833 | return 0; | 5762 | return 0; |
@@ -5836,10 +5765,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5836 | /* Verify privacy compatibility */ | 5765 | /* Verify privacy compatibility */ |
5837 | if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != | 5766 | if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != |
5838 | ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { | 5767 | ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { |
5839 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5768 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n", |
5840 | "because of privacy mismatch: %s != %s.\n", | 5769 | network->ssid_len, network->ssid, |
5841 | print_ssid(ssid, network->ssid, | ||
5842 | network->ssid_len), | ||
5843 | network->bssid, | 5770 | network->bssid, |
5844 | priv->capability & CAP_PRIVACY_ON ? "on" : | 5771 | priv->capability & CAP_PRIVACY_ON ? "on" : |
5845 | "off", | 5772 | "off", |
@@ -5850,31 +5777,24 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5850 | 5777 | ||
5851 | if ((priv->config & CFG_STATIC_BSSID) && | 5778 | if ((priv->config & CFG_STATIC_BSSID) && |
5852 | !ether_addr_equal(network->bssid, priv->bssid)) { | 5779 | !ether_addr_equal(network->bssid, priv->bssid)) { |
5853 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5780 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of BSSID mismatch: %pM.\n", |
5854 | "because of BSSID mismatch: %pM.\n", | 5781 | network->ssid_len, network->ssid, |
5855 | print_ssid(ssid, network->ssid, | ||
5856 | network->ssid_len), | ||
5857 | network->bssid, priv->bssid); | 5782 | network->bssid, priv->bssid); |
5858 | return 0; | 5783 | return 0; |
5859 | } | 5784 | } |
5860 | 5785 | ||
5861 | /* Filter out any incompatible freq / mode combinations */ | 5786 | /* Filter out any incompatible freq / mode combinations */ |
5862 | if (!libipw_is_valid_mode(priv->ieee, network->mode)) { | 5787 | if (!libipw_is_valid_mode(priv->ieee, network->mode)) { |
5863 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5788 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n", |
5864 | "because of invalid frequency/mode " | 5789 | network->ssid_len, network->ssid, |
5865 | "combination.\n", | ||
5866 | print_ssid(ssid, network->ssid, | ||
5867 | network->ssid_len), | ||
5868 | network->bssid); | 5790 | network->bssid); |
5869 | return 0; | 5791 | return 0; |
5870 | } | 5792 | } |
5871 | 5793 | ||
5872 | /* Filter out invalid channel in current GEO */ | 5794 | /* Filter out invalid channel in current GEO */ |
5873 | if (!libipw_is_valid_channel(priv->ieee, network->channel)) { | 5795 | if (!libipw_is_valid_channel(priv->ieee, network->channel)) { |
5874 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5796 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid channel in current GEO\n", |
5875 | "because of invalid channel in current GEO\n", | 5797 | network->ssid_len, network->ssid, |
5876 | print_ssid(ssid, network->ssid, | ||
5877 | network->ssid_len), | ||
5878 | network->bssid); | 5798 | network->bssid); |
5879 | return 0; | 5799 | return 0; |
5880 | } | 5800 | } |
@@ -5882,20 +5802,15 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5882 | /* Ensure that the rates supported by the driver are compatible with | 5802 | /* Ensure that the rates supported by the driver are compatible with |
5883 | * this AP, including verification of basic rates (mandatory) */ | 5803 | * this AP, including verification of basic rates (mandatory) */ |
5884 | if (!ipw_compatible_rates(priv, network, &rates)) { | 5804 | if (!ipw_compatible_rates(priv, network, &rates)) { |
5885 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5805 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n", |
5886 | "because configured rate mask excludes " | 5806 | network->ssid_len, network->ssid, |
5887 | "AP mandatory rate.\n", | ||
5888 | print_ssid(ssid, network->ssid, | ||
5889 | network->ssid_len), | ||
5890 | network->bssid); | 5807 | network->bssid); |
5891 | return 0; | 5808 | return 0; |
5892 | } | 5809 | } |
5893 | 5810 | ||
5894 | if (rates.num_rates == 0) { | 5811 | if (rates.num_rates == 0) { |
5895 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5812 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of no compatible rates.\n", |
5896 | "because of no compatible rates.\n", | 5813 | network->ssid_len, network->ssid, |
5897 | print_ssid(ssid, network->ssid, | ||
5898 | network->ssid_len), | ||
5899 | network->bssid); | 5814 | network->bssid); |
5900 | return 0; | 5815 | return 0; |
5901 | } | 5816 | } |
@@ -5908,9 +5823,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5908 | ipw_copy_rates(&match->rates, &rates); | 5823 | ipw_copy_rates(&match->rates, &rates); |
5909 | match->network = network; | 5824 | match->network = network; |
5910 | 5825 | ||
5911 | IPW_DEBUG_ASSOC("Network '%s (%pM)' is a viable match.\n", | 5826 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' is a viable match.\n", |
5912 | print_ssid(ssid, network->ssid, network->ssid_len), | 5827 | network->ssid_len, network->ssid, network->bssid); |
5913 | network->bssid); | ||
5914 | 5828 | ||
5915 | return 1; | 5829 | return 1; |
5916 | } | 5830 | } |
@@ -6152,7 +6066,6 @@ static void ipw_bg_adhoc_check(struct work_struct *work) | |||
6152 | 6066 | ||
6153 | static void ipw_debug_config(struct ipw_priv *priv) | 6067 | static void ipw_debug_config(struct ipw_priv *priv) |
6154 | { | 6068 | { |
6155 | DECLARE_SSID_BUF(ssid); | ||
6156 | IPW_DEBUG_INFO("Scan completed, no valid APs matched " | 6069 | IPW_DEBUG_INFO("Scan completed, no valid APs matched " |
6157 | "[CFG 0x%08X]\n", priv->config); | 6070 | "[CFG 0x%08X]\n", priv->config); |
6158 | if (priv->config & CFG_STATIC_CHANNEL) | 6071 | if (priv->config & CFG_STATIC_CHANNEL) |
@@ -6160,8 +6073,8 @@ static void ipw_debug_config(struct ipw_priv *priv) | |||
6160 | else | 6073 | else |
6161 | IPW_DEBUG_INFO("Channel unlocked.\n"); | 6074 | IPW_DEBUG_INFO("Channel unlocked.\n"); |
6162 | if (priv->config & CFG_STATIC_ESSID) | 6075 | if (priv->config & CFG_STATIC_ESSID) |
6163 | IPW_DEBUG_INFO("ESSID locked to '%s'\n", | 6076 | IPW_DEBUG_INFO("ESSID locked to '%*pE'\n", |
6164 | print_ssid(ssid, priv->essid, priv->essid_len)); | 6077 | priv->essid_len, priv->essid); |
6165 | else | 6078 | else |
6166 | IPW_DEBUG_INFO("ESSID unlocked.\n"); | 6079 | IPW_DEBUG_INFO("ESSID unlocked.\n"); |
6167 | if (priv->config & CFG_STATIC_BSSID) | 6080 | if (priv->config & CFG_STATIC_BSSID) |
@@ -7385,7 +7298,6 @@ static int ipw_associate_network(struct ipw_priv *priv, | |||
7385 | struct ipw_supported_rates *rates, int roaming) | 7298 | struct ipw_supported_rates *rates, int roaming) |
7386 | { | 7299 | { |
7387 | int err; | 7300 | int err; |
7388 | DECLARE_SSID_BUF(ssid); | ||
7389 | 7301 | ||
7390 | if (priv->config & CFG_FIXED_RATE) | 7302 | if (priv->config & CFG_FIXED_RATE) |
7391 | ipw_set_fixed_rate(priv, network->mode); | 7303 | ipw_set_fixed_rate(priv, network->mode); |
@@ -7451,10 +7363,9 @@ static int ipw_associate_network(struct ipw_priv *priv, | |||
7451 | priv->assoc_request.capability &= | 7363 | priv->assoc_request.capability &= |
7452 | ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); | 7364 | ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); |
7453 | 7365 | ||
7454 | IPW_DEBUG_ASSOC("%ssociation attempt: '%s', channel %d, " | 7366 | IPW_DEBUG_ASSOC("%ssociation attempt: '%*pE', channel %d, 802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n", |
7455 | "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n", | ||
7456 | roaming ? "Rea" : "A", | 7367 | roaming ? "Rea" : "A", |
7457 | print_ssid(ssid, priv->essid, priv->essid_len), | 7368 | priv->essid_len, priv->essid, |
7458 | network->channel, | 7369 | network->channel, |
7459 | ipw_modes[priv->assoc_request.ieee_mode], | 7370 | ipw_modes[priv->assoc_request.ieee_mode], |
7460 | rates->num_rates, | 7371 | rates->num_rates, |
@@ -7553,9 +7464,8 @@ static int ipw_associate_network(struct ipw_priv *priv, | |||
7553 | return err; | 7464 | return err; |
7554 | } | 7465 | } |
7555 | 7466 | ||
7556 | IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM\n", | 7467 | IPW_DEBUG(IPW_DL_STATE, "associating: '%*pE' %pM\n", |
7557 | print_ssid(ssid, priv->essid, priv->essid_len), | 7468 | priv->essid_len, priv->essid, priv->bssid); |
7558 | priv->bssid); | ||
7559 | 7469 | ||
7560 | return 0; | 7470 | return 0; |
7561 | } | 7471 | } |
@@ -7645,7 +7555,6 @@ static int ipw_associate(void *data) | |||
7645 | struct ipw_supported_rates *rates; | 7555 | struct ipw_supported_rates *rates; |
7646 | struct list_head *element; | 7556 | struct list_head *element; |
7647 | unsigned long flags; | 7557 | unsigned long flags; |
7648 | DECLARE_SSID_BUF(ssid); | ||
7649 | 7558 | ||
7650 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { | 7559 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { |
7651 | IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n"); | 7560 | IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n"); |
@@ -7704,10 +7613,8 @@ static int ipw_associate(void *data) | |||
7704 | /* If there are no more slots, expire the oldest */ | 7613 | /* If there are no more slots, expire the oldest */ |
7705 | list_del(&oldest->list); | 7614 | list_del(&oldest->list); |
7706 | target = oldest; | 7615 | target = oldest; |
7707 | IPW_DEBUG_ASSOC("Expired '%s' (%pM) from " | 7616 | IPW_DEBUG_ASSOC("Expired '%*pE' (%pM) from network list.\n", |
7708 | "network list.\n", | 7617 | target->ssid_len, target->ssid, |
7709 | print_ssid(ssid, target->ssid, | ||
7710 | target->ssid_len), | ||
7711 | target->bssid); | 7618 | target->bssid); |
7712 | list_add_tail(&target->list, | 7619 | list_add_tail(&target->list, |
7713 | &priv->ieee->network_free_list); | 7620 | &priv->ieee->network_free_list); |
@@ -9093,7 +9000,6 @@ static int ipw_wx_set_essid(struct net_device *dev, | |||
9093 | { | 9000 | { |
9094 | struct ipw_priv *priv = libipw_priv(dev); | 9001 | struct ipw_priv *priv = libipw_priv(dev); |
9095 | int length; | 9002 | int length; |
9096 | DECLARE_SSID_BUF(ssid); | ||
9097 | 9003 | ||
9098 | mutex_lock(&priv->mutex); | 9004 | mutex_lock(&priv->mutex); |
9099 | 9005 | ||
@@ -9118,8 +9024,7 @@ static int ipw_wx_set_essid(struct net_device *dev, | |||
9118 | return 0; | 9024 | return 0; |
9119 | } | 9025 | } |
9120 | 9026 | ||
9121 | IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", | 9027 | IPW_DEBUG_WX("Setting ESSID: '%*pE' (%d)\n", length, extra, length); |
9122 | print_ssid(ssid, extra, length), length); | ||
9123 | 9028 | ||
9124 | priv->essid_len = length; | 9029 | priv->essid_len = length; |
9125 | memcpy(priv->essid, extra, priv->essid_len); | 9030 | memcpy(priv->essid, extra, priv->essid_len); |
@@ -9138,15 +9043,14 @@ static int ipw_wx_get_essid(struct net_device *dev, | |||
9138 | union iwreq_data *wrqu, char *extra) | 9043 | union iwreq_data *wrqu, char *extra) |
9139 | { | 9044 | { |
9140 | struct ipw_priv *priv = libipw_priv(dev); | 9045 | struct ipw_priv *priv = libipw_priv(dev); |
9141 | DECLARE_SSID_BUF(ssid); | ||
9142 | 9046 | ||
9143 | /* If we are associated, trying to associate, or have a statically | 9047 | /* If we are associated, trying to associate, or have a statically |
9144 | * configured ESSID then return that; otherwise return ANY */ | 9048 | * configured ESSID then return that; otherwise return ANY */ |
9145 | mutex_lock(&priv->mutex); | 9049 | mutex_lock(&priv->mutex); |
9146 | if (priv->config & CFG_STATIC_ESSID || | 9050 | if (priv->config & CFG_STATIC_ESSID || |
9147 | priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { | 9051 | priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { |
9148 | IPW_DEBUG_WX("Getting essid: '%s'\n", | 9052 | IPW_DEBUG_WX("Getting essid: '%*pE'\n", |
9149 | print_ssid(ssid, priv->essid, priv->essid_len)); | 9053 | priv->essid_len, priv->essid); |
9150 | memcpy(extra, priv->essid, priv->essid_len); | 9054 | memcpy(extra, priv->essid, priv->essid_len); |
9151 | wrqu->essid.length = priv->essid_len; | 9055 | wrqu->essid.length = priv->essid_len; |
9152 | wrqu->essid.flags = 1; /* active */ | 9056 | wrqu->essid.flags = 1; /* active */ |
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index a586a85bfcfe..2d66984079bb 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c | |||
@@ -1120,7 +1120,6 @@ static int libipw_parse_info_param(struct libipw_info_element | |||
1120 | *info_element, u16 length, | 1120 | *info_element, u16 length, |
1121 | struct libipw_network *network) | 1121 | struct libipw_network *network) |
1122 | { | 1122 | { |
1123 | DECLARE_SSID_BUF(ssid); | ||
1124 | u8 i; | 1123 | u8 i; |
1125 | #ifdef CONFIG_LIBIPW_DEBUG | 1124 | #ifdef CONFIG_LIBIPW_DEBUG |
1126 | char rates_str[64]; | 1125 | char rates_str[64]; |
@@ -1151,10 +1150,9 @@ static int libipw_parse_info_param(struct libipw_info_element | |||
1151 | memset(network->ssid + network->ssid_len, 0, | 1150 | memset(network->ssid + network->ssid_len, 0, |
1152 | IW_ESSID_MAX_SIZE - network->ssid_len); | 1151 | IW_ESSID_MAX_SIZE - network->ssid_len); |
1153 | 1152 | ||
1154 | LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%s' len=%d.\n", | 1153 | LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%*pE' len=%d.\n", |
1155 | print_ssid(ssid, network->ssid, | 1154 | network->ssid_len, network->ssid, |
1156 | network->ssid_len), | 1155 | network->ssid_len); |
1157 | network->ssid_len); | ||
1158 | break; | 1156 | break; |
1159 | 1157 | ||
1160 | case WLAN_EID_SUPP_RATES: | 1158 | case WLAN_EID_SUPP_RATES: |
@@ -1399,8 +1397,6 @@ static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_r | |||
1399 | struct libipw_network *network, | 1397 | struct libipw_network *network, |
1400 | struct libipw_rx_stats *stats) | 1398 | struct libipw_rx_stats *stats) |
1401 | { | 1399 | { |
1402 | DECLARE_SSID_BUF(ssid); | ||
1403 | |||
1404 | network->qos_data.active = 0; | 1400 | network->qos_data.active = 0; |
1405 | network->qos_data.supported = 0; | 1401 | network->qos_data.supported = 0; |
1406 | network->qos_data.param_count = 0; | 1402 | network->qos_data.param_count = 0; |
@@ -1447,11 +1443,9 @@ static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_r | |||
1447 | } | 1443 | } |
1448 | 1444 | ||
1449 | if (network->mode == 0) { | 1445 | if (network->mode == 0) { |
1450 | LIBIPW_DEBUG_SCAN("Filtered out '%s (%pM)' " | 1446 | LIBIPW_DEBUG_SCAN("Filtered out '%*pE (%pM)' network.\n", |
1451 | "network.\n", | 1447 | network->ssid_len, network->ssid, |
1452 | print_ssid(ssid, network->ssid, | 1448 | network->bssid); |
1453 | network->ssid_len), | ||
1454 | network->bssid); | ||
1455 | return 1; | 1449 | return 1; |
1456 | } | 1450 | } |
1457 | 1451 | ||
@@ -1563,11 +1557,9 @@ static void libipw_process_probe_response(struct libipw_device | |||
1563 | struct libipw_info_element *info_element = beacon->info_element; | 1557 | struct libipw_info_element *info_element = beacon->info_element; |
1564 | #endif | 1558 | #endif |
1565 | unsigned long flags; | 1559 | unsigned long flags; |
1566 | DECLARE_SSID_BUF(ssid); | ||
1567 | 1560 | ||
1568 | LIBIPW_DEBUG_SCAN("'%s' (%pM" | 1561 | LIBIPW_DEBUG_SCAN("'%*pE' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", |
1569 | "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", | 1562 | info_element->len, info_element->data, |
1570 | print_ssid(ssid, info_element->data, info_element->len), | ||
1571 | beacon->header.addr3, | 1563 | beacon->header.addr3, |
1572 | (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0', | 1564 | (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0', |
1573 | (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0', | 1565 | (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0', |
@@ -1587,12 +1579,11 @@ static void libipw_process_probe_response(struct libipw_device | |||
1587 | (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0'); | 1579 | (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0'); |
1588 | 1580 | ||
1589 | if (libipw_network_init(ieee, beacon, &network, stats)) { | 1581 | if (libipw_network_init(ieee, beacon, &network, stats)) { |
1590 | LIBIPW_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n", | 1582 | LIBIPW_DEBUG_SCAN("Dropped '%*pE' (%pM) via %s.\n", |
1591 | print_ssid(ssid, info_element->data, | 1583 | info_element->len, info_element->data, |
1592 | info_element->len), | 1584 | beacon->header.addr3, |
1593 | beacon->header.addr3, | 1585 | is_beacon(beacon->header.frame_ctl) ? |
1594 | is_beacon(beacon->header.frame_ctl) ? | 1586 | "BEACON" : "PROBE RESPONSE"); |
1595 | "BEACON" : "PROBE RESPONSE"); | ||
1596 | return; | 1587 | return; |
1597 | } | 1588 | } |
1598 | 1589 | ||
@@ -1624,11 +1615,9 @@ static void libipw_process_probe_response(struct libipw_device | |||
1624 | /* If there are no more slots, expire the oldest */ | 1615 | /* If there are no more slots, expire the oldest */ |
1625 | list_del(&oldest->list); | 1616 | list_del(&oldest->list); |
1626 | target = oldest; | 1617 | target = oldest; |
1627 | LIBIPW_DEBUG_SCAN("Expired '%s' (%pM) from " | 1618 | LIBIPW_DEBUG_SCAN("Expired '%*pE' (%pM) from network list.\n", |
1628 | "network list.\n", | 1619 | target->ssid_len, target->ssid, |
1629 | print_ssid(ssid, target->ssid, | 1620 | target->bssid); |
1630 | target->ssid_len), | ||
1631 | target->bssid); | ||
1632 | libipw_network_reset(target); | 1621 | libipw_network_reset(target); |
1633 | } else { | 1622 | } else { |
1634 | /* Otherwise just pull from the free list */ | 1623 | /* Otherwise just pull from the free list */ |
@@ -1638,23 +1627,21 @@ static void libipw_process_probe_response(struct libipw_device | |||
1638 | } | 1627 | } |
1639 | 1628 | ||
1640 | #ifdef CONFIG_LIBIPW_DEBUG | 1629 | #ifdef CONFIG_LIBIPW_DEBUG |
1641 | LIBIPW_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n", | 1630 | LIBIPW_DEBUG_SCAN("Adding '%*pE' (%pM) via %s.\n", |
1642 | print_ssid(ssid, network.ssid, | 1631 | network.ssid_len, network.ssid, |
1643 | network.ssid_len), | 1632 | network.bssid, |
1644 | network.bssid, | 1633 | is_beacon(beacon->header.frame_ctl) ? |
1645 | is_beacon(beacon->header.frame_ctl) ? | 1634 | "BEACON" : "PROBE RESPONSE"); |
1646 | "BEACON" : "PROBE RESPONSE"); | ||
1647 | #endif | 1635 | #endif |
1648 | memcpy(target, &network, sizeof(*target)); | 1636 | memcpy(target, &network, sizeof(*target)); |
1649 | network.ibss_dfs = NULL; | 1637 | network.ibss_dfs = NULL; |
1650 | list_add_tail(&target->list, &ieee->network_list); | 1638 | list_add_tail(&target->list, &ieee->network_list); |
1651 | } else { | 1639 | } else { |
1652 | LIBIPW_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", | 1640 | LIBIPW_DEBUG_SCAN("Updating '%*pE' (%pM) via %s.\n", |
1653 | print_ssid(ssid, target->ssid, | 1641 | target->ssid_len, target->ssid, |
1654 | target->ssid_len), | 1642 | target->bssid, |
1655 | target->bssid, | 1643 | is_beacon(beacon->header.frame_ctl) ? |
1656 | is_beacon(beacon->header.frame_ctl) ? | 1644 | "BEACON" : "PROBE RESPONSE"); |
1657 | "BEACON" : "PROBE RESPONSE"); | ||
1658 | update_network(target, &network); | 1645 | update_network(target, &network); |
1659 | network.ibss_dfs = NULL; | 1646 | network.ibss_dfs = NULL; |
1660 | } | 1647 | } |
diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c index 54aba4744438..dd29f46d086b 100644 --- a/drivers/net/wireless/ipw2x00/libipw_wx.c +++ b/drivers/net/wireless/ipw2x00/libipw_wx.c | |||
@@ -272,7 +272,6 @@ int libipw_wx_get_scan(struct libipw_device *ieee, | |||
272 | char *ev = extra; | 272 | char *ev = extra; |
273 | char *stop = ev + wrqu->data.length; | 273 | char *stop = ev + wrqu->data.length; |
274 | int i = 0; | 274 | int i = 0; |
275 | DECLARE_SSID_BUF(ssid); | ||
276 | 275 | ||
277 | LIBIPW_DEBUG_WX("Getting scan\n"); | 276 | LIBIPW_DEBUG_WX("Getting scan\n"); |
278 | 277 | ||
@@ -290,12 +289,10 @@ int libipw_wx_get_scan(struct libipw_device *ieee, | |||
290 | ev = libipw_translate_scan(ieee, ev, stop, network, | 289 | ev = libipw_translate_scan(ieee, ev, stop, network, |
291 | info); | 290 | info); |
292 | else { | 291 | else { |
293 | LIBIPW_DEBUG_SCAN("Not showing network '%s (" | 292 | LIBIPW_DEBUG_SCAN("Not showing network '%*pE (%pM)' due to age (%ums).\n", |
294 | "%pM)' due to age (%ums).\n", | 293 | network->ssid_len, network->ssid, |
295 | print_ssid(ssid, network->ssid, | 294 | network->bssid, |
296 | network->ssid_len), | 295 | elapsed_jiffies_msecs( |
297 | network->bssid, | ||
298 | elapsed_jiffies_msecs( | ||
299 | network->last_scanned)); | 296 | network->last_scanned)); |
300 | } | 297 | } |
301 | } | 298 | } |
@@ -322,7 +319,6 @@ int libipw_wx_set_encode(struct libipw_device *ieee, | |||
322 | int i, key, key_provided, len; | 319 | int i, key, key_provided, len; |
323 | struct lib80211_crypt_data **crypt; | 320 | struct lib80211_crypt_data **crypt; |
324 | int host_crypto = ieee->host_encrypt || ieee->host_decrypt; | 321 | int host_crypto = ieee->host_encrypt || ieee->host_decrypt; |
325 | DECLARE_SSID_BUF(ssid); | ||
326 | 322 | ||
327 | LIBIPW_DEBUG_WX("SET_ENCODE\n"); | 323 | LIBIPW_DEBUG_WX("SET_ENCODE\n"); |
328 | 324 | ||
@@ -417,8 +413,8 @@ int libipw_wx_set_encode(struct libipw_device *ieee, | |||
417 | if (len > erq->length) | 413 | if (len > erq->length) |
418 | memset(sec.keys[key] + erq->length, 0, | 414 | memset(sec.keys[key] + erq->length, 0, |
419 | len - erq->length); | 415 | len - erq->length); |
420 | LIBIPW_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n", | 416 | LIBIPW_DEBUG_WX("Setting key %d to '%*pE' (%d:%d bytes)\n", |
421 | key, print_ssid(ssid, sec.keys[key], len), | 417 | key, len, sec.keys[key], |
422 | erq->length, len); | 418 | erq->length, len); |
423 | sec.key_sizes[key] = len; | 419 | sec.key_sizes[key] = len; |
424 | if (*crypt) | 420 | if (*crypt) |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 818b1edaaa9a..34f09ef90bb3 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -590,7 +590,6 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
590 | int chan_no = -1; | 590 | int chan_no = -1; |
591 | const u8 *ssid = NULL; | 591 | const u8 *ssid = NULL; |
592 | u8 ssid_len = 0; | 592 | u8 ssid_len = 0; |
593 | DECLARE_SSID_BUF(ssid_buf); | ||
594 | 593 | ||
595 | int len = get_unaligned_le16(pos); | 594 | int len = get_unaligned_le16(pos); |
596 | pos += 2; | 595 | pos += 2; |
@@ -644,10 +643,8 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
644 | struct ieee80211_channel *channel = | 643 | struct ieee80211_channel *channel = |
645 | ieee80211_get_channel(wiphy, freq); | 644 | ieee80211_get_channel(wiphy, freq); |
646 | 645 | ||
647 | lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %s, " | 646 | lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %*pE, %d dBm\n", |
648 | "%d dBm\n", | 647 | bssid, capa, chan_no, ssid_len, ssid, |
649 | bssid, capa, chan_no, | ||
650 | print_ssid(ssid_buf, ssid, ssid_len), | ||
651 | LBS_SCAN_RSSI_TO_MBM(rssi)/100); | 648 | LBS_SCAN_RSSI_TO_MBM(rssi)/100); |
652 | 649 | ||
653 | if (channel && | 650 | if (channel && |
@@ -1984,7 +1981,6 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev, | |||
1984 | struct lbs_private *priv = wiphy_priv(wiphy); | 1981 | struct lbs_private *priv = wiphy_priv(wiphy); |
1985 | int ret = 0; | 1982 | int ret = 0; |
1986 | struct cfg80211_bss *bss; | 1983 | struct cfg80211_bss *bss; |
1987 | DECLARE_SSID_BUF(ssid_buf); | ||
1988 | 1984 | ||
1989 | if (dev == priv->mesh_dev) | 1985 | if (dev == priv->mesh_dev) |
1990 | return -EOPNOTSUPP; | 1986 | return -EOPNOTSUPP; |
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 01a67f62696f..d0c881dd5846 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c | |||
@@ -93,7 +93,6 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, | |||
93 | { | 93 | { |
94 | struct cmd_ds_mesh_config cmd; | 94 | struct cmd_ds_mesh_config cmd; |
95 | struct mrvl_meshie *ie; | 95 | struct mrvl_meshie *ie; |
96 | DECLARE_SSID_BUF(ssid); | ||
97 | 96 | ||
98 | memset(&cmd, 0, sizeof(cmd)); | 97 | memset(&cmd, 0, sizeof(cmd)); |
99 | cmd.channel = cpu_to_le16(chan); | 98 | cmd.channel = cpu_to_le16(chan); |
@@ -122,9 +121,9 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, | |||
122 | default: | 121 | default: |
123 | return -1; | 122 | return -1; |
124 | } | 123 | } |
125 | lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n", | 124 | lbs_deb_cmd("mesh config action %d type %x channel %d SSID %*pE\n", |
126 | action, priv->mesh_tlv, chan, | 125 | action, priv->mesh_tlv, chan, priv->mesh_ssid_len, |
127 | print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len)); | 126 | priv->mesh_ssid); |
128 | 127 | ||
129 | return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv); | 128 | return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv); |
130 | } | 129 | } |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index f959978c7aac..cf0f89364d44 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -8878,13 +8878,13 @@ static int __must_check __init get_thinkpad_model_data( | |||
8878 | } | 8878 | } |
8879 | 8879 | ||
8880 | s = dmi_get_system_info(DMI_PRODUCT_VERSION); | 8880 | s = dmi_get_system_info(DMI_PRODUCT_VERSION); |
8881 | if (s && !(strnicmp(s, "ThinkPad", 8) && strnicmp(s, "Lenovo", 6))) { | 8881 | if (s && !(strncasecmp(s, "ThinkPad", 8) && strncasecmp(s, "Lenovo", 6))) { |
8882 | tp->model_str = kstrdup(s, GFP_KERNEL); | 8882 | tp->model_str = kstrdup(s, GFP_KERNEL); |
8883 | if (!tp->model_str) | 8883 | if (!tp->model_str) |
8884 | return -ENOMEM; | 8884 | return -ENOMEM; |
8885 | } else { | 8885 | } else { |
8886 | s = dmi_get_system_info(DMI_BIOS_VENDOR); | 8886 | s = dmi_get_system_info(DMI_BIOS_VENDOR); |
8887 | if (s && !(strnicmp(s, "Lenovo", 6))) { | 8887 | if (s && !(strncasecmp(s, "Lenovo", 6))) { |
8888 | tp->model_str = kstrdup(s, GFP_KERNEL); | 8888 | tp->model_str = kstrdup(s, GFP_KERNEL); |
8889 | if (!tp->model_str) | 8889 | if (!tp->model_str) |
8890 | return -ENOMEM; | 8890 | return -ENOMEM; |
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index e6c403be09a9..4b6808ff0e5d 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -346,41 +346,41 @@ static ssize_t resources_store(struct device *dmdev, | |||
346 | } | 346 | } |
347 | 347 | ||
348 | buf = skip_spaces(buf); | 348 | buf = skip_spaces(buf); |
349 | if (!strnicmp(buf, "disable", 7)) { | 349 | if (!strncasecmp(buf, "disable", 7)) { |
350 | retval = pnp_disable_dev(dev); | 350 | retval = pnp_disable_dev(dev); |
351 | goto done; | 351 | goto done; |
352 | } | 352 | } |
353 | if (!strnicmp(buf, "activate", 8)) { | 353 | if (!strncasecmp(buf, "activate", 8)) { |
354 | retval = pnp_activate_dev(dev); | 354 | retval = pnp_activate_dev(dev); |
355 | goto done; | 355 | goto done; |
356 | } | 356 | } |
357 | if (!strnicmp(buf, "fill", 4)) { | 357 | if (!strncasecmp(buf, "fill", 4)) { |
358 | if (dev->active) | 358 | if (dev->active) |
359 | goto done; | 359 | goto done; |
360 | retval = pnp_auto_config_dev(dev); | 360 | retval = pnp_auto_config_dev(dev); |
361 | goto done; | 361 | goto done; |
362 | } | 362 | } |
363 | if (!strnicmp(buf, "auto", 4)) { | 363 | if (!strncasecmp(buf, "auto", 4)) { |
364 | if (dev->active) | 364 | if (dev->active) |
365 | goto done; | 365 | goto done; |
366 | pnp_init_resources(dev); | 366 | pnp_init_resources(dev); |
367 | retval = pnp_auto_config_dev(dev); | 367 | retval = pnp_auto_config_dev(dev); |
368 | goto done; | 368 | goto done; |
369 | } | 369 | } |
370 | if (!strnicmp(buf, "clear", 5)) { | 370 | if (!strncasecmp(buf, "clear", 5)) { |
371 | if (dev->active) | 371 | if (dev->active) |
372 | goto done; | 372 | goto done; |
373 | pnp_init_resources(dev); | 373 | pnp_init_resources(dev); |
374 | goto done; | 374 | goto done; |
375 | } | 375 | } |
376 | if (!strnicmp(buf, "get", 3)) { | 376 | if (!strncasecmp(buf, "get", 3)) { |
377 | mutex_lock(&pnp_res_mutex); | 377 | mutex_lock(&pnp_res_mutex); |
378 | if (pnp_can_read(dev)) | 378 | if (pnp_can_read(dev)) |
379 | dev->protocol->get(dev); | 379 | dev->protocol->get(dev); |
380 | mutex_unlock(&pnp_res_mutex); | 380 | mutex_unlock(&pnp_res_mutex); |
381 | goto done; | 381 | goto done; |
382 | } | 382 | } |
383 | if (!strnicmp(buf, "set", 3)) { | 383 | if (!strncasecmp(buf, "set", 3)) { |
384 | resource_size_t start; | 384 | resource_size_t start; |
385 | resource_size_t end; | 385 | resource_size_t end; |
386 | unsigned long flags; | 386 | unsigned long flags; |
@@ -392,31 +392,31 @@ static ssize_t resources_store(struct device *dmdev, | |||
392 | mutex_lock(&pnp_res_mutex); | 392 | mutex_lock(&pnp_res_mutex); |
393 | while (1) { | 393 | while (1) { |
394 | buf = skip_spaces(buf); | 394 | buf = skip_spaces(buf); |
395 | if (!strnicmp(buf, "io", 2)) { | 395 | if (!strncasecmp(buf, "io", 2)) { |
396 | buf = pnp_get_resource_value(buf + 2, | 396 | buf = pnp_get_resource_value(buf + 2, |
397 | IORESOURCE_IO, | 397 | IORESOURCE_IO, |
398 | &start, &end, | 398 | &start, &end, |
399 | &flags); | 399 | &flags); |
400 | pnp_add_io_resource(dev, start, end, flags); | 400 | pnp_add_io_resource(dev, start, end, flags); |
401 | } else if (!strnicmp(buf, "mem", 3)) { | 401 | } else if (!strncasecmp(buf, "mem", 3)) { |
402 | buf = pnp_get_resource_value(buf + 3, | 402 | buf = pnp_get_resource_value(buf + 3, |
403 | IORESOURCE_MEM, | 403 | IORESOURCE_MEM, |
404 | &start, &end, | 404 | &start, &end, |
405 | &flags); | 405 | &flags); |
406 | pnp_add_mem_resource(dev, start, end, flags); | 406 | pnp_add_mem_resource(dev, start, end, flags); |
407 | } else if (!strnicmp(buf, "irq", 3)) { | 407 | } else if (!strncasecmp(buf, "irq", 3)) { |
408 | buf = pnp_get_resource_value(buf + 3, | 408 | buf = pnp_get_resource_value(buf + 3, |
409 | IORESOURCE_IRQ, | 409 | IORESOURCE_IRQ, |
410 | &start, NULL, | 410 | &start, NULL, |
411 | &flags); | 411 | &flags); |
412 | pnp_add_irq_resource(dev, start, flags); | 412 | pnp_add_irq_resource(dev, start, flags); |
413 | } else if (!strnicmp(buf, "dma", 3)) { | 413 | } else if (!strncasecmp(buf, "dma", 3)) { |
414 | buf = pnp_get_resource_value(buf + 3, | 414 | buf = pnp_get_resource_value(buf + 3, |
415 | IORESOURCE_DMA, | 415 | IORESOURCE_DMA, |
416 | &start, NULL, | 416 | &start, NULL, |
417 | &flags); | 417 | &flags); |
418 | pnp_add_dma_resource(dev, start, flags); | 418 | pnp_add_dma_resource(dev, start, flags); |
419 | } else if (!strnicmp(buf, "bus", 3)) { | 419 | } else if (!strncasecmp(buf, "bus", 3)) { |
420 | buf = pnp_get_resource_value(buf + 3, | 420 | buf = pnp_get_resource_value(buf + 3, |
421 | IORESOURCE_BUS, | 421 | IORESOURCE_BUS, |
422 | &start, &end, | 422 | &start, &end, |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 1bea0fc43464..8cd0beebdc3f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -288,6 +288,26 @@ config RTC_DRV_MAX77686 | |||
288 | This driver can also be built as a module. If so, the module | 288 | This driver can also be built as a module. If so, the module |
289 | will be called rtc-max77686. | 289 | will be called rtc-max77686. |
290 | 290 | ||
291 | config RTC_DRV_RK808 | ||
292 | tristate "Rockchip RK808 RTC" | ||
293 | depends on MFD_RK808 | ||
294 | help | ||
295 | If you say yes here you will get support for the | ||
296 | RTC of RK808 PMIC. | ||
297 | |||
298 | This driver can also be built as a module. If so, the module | ||
299 | will be called rk808-rtc. | ||
300 | |||
301 | config RTC_DRV_MAX77802 | ||
302 | tristate "Maxim 77802 RTC" | ||
303 | depends on MFD_MAX77686 | ||
304 | help | ||
305 | If you say yes here you will get support for the | ||
306 | RTC of Maxim MAX77802 PMIC. | ||
307 | |||
308 | This driver can also be built as a module. If so, the module | ||
309 | will be called rtc-max77802. | ||
310 | |||
291 | config RTC_DRV_RS5C372 | 311 | config RTC_DRV_RS5C372 |
292 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" | 312 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" |
293 | help | 313 | help |
@@ -732,6 +752,7 @@ config RTC_DRV_DS1216 | |||
732 | 752 | ||
733 | config RTC_DRV_DS1286 | 753 | config RTC_DRV_DS1286 |
734 | tristate "Dallas DS1286" | 754 | tristate "Dallas DS1286" |
755 | depends on HAS_IOMEM | ||
735 | help | 756 | help |
736 | If you say yes here you get support for the Dallas DS1286 RTC chips. | 757 | If you say yes here you get support for the Dallas DS1286 RTC chips. |
737 | 758 | ||
@@ -743,6 +764,7 @@ config RTC_DRV_DS1302 | |||
743 | 764 | ||
744 | config RTC_DRV_DS1511 | 765 | config RTC_DRV_DS1511 |
745 | tristate "Dallas DS1511" | 766 | tristate "Dallas DS1511" |
767 | depends on HAS_IOMEM | ||
746 | help | 768 | help |
747 | If you say yes here you get support for the | 769 | If you say yes here you get support for the |
748 | Dallas DS1511 timekeeping/watchdog chip. | 770 | Dallas DS1511 timekeeping/watchdog chip. |
@@ -752,6 +774,7 @@ config RTC_DRV_DS1511 | |||
752 | 774 | ||
753 | config RTC_DRV_DS1553 | 775 | config RTC_DRV_DS1553 |
754 | tristate "Maxim/Dallas DS1553" | 776 | tristate "Maxim/Dallas DS1553" |
777 | depends on HAS_IOMEM | ||
755 | help | 778 | help |
756 | If you say yes here you get support for the | 779 | If you say yes here you get support for the |
757 | Maxim/Dallas DS1553 timekeeping chip. | 780 | Maxim/Dallas DS1553 timekeeping chip. |
@@ -761,6 +784,7 @@ config RTC_DRV_DS1553 | |||
761 | 784 | ||
762 | config RTC_DRV_DS1742 | 785 | config RTC_DRV_DS1742 |
763 | tristate "Maxim/Dallas DS1742/1743" | 786 | tristate "Maxim/Dallas DS1742/1743" |
787 | depends on HAS_IOMEM | ||
764 | help | 788 | help |
765 | If you say yes here you get support for the | 789 | If you say yes here you get support for the |
766 | Maxim/Dallas DS1742/1743 timekeeping chip. | 790 | Maxim/Dallas DS1742/1743 timekeeping chip. |
@@ -816,6 +840,7 @@ config RTC_DRV_EFI | |||
816 | 840 | ||
817 | config RTC_DRV_STK17TA8 | 841 | config RTC_DRV_STK17TA8 |
818 | tristate "Simtek STK17TA8" | 842 | tristate "Simtek STK17TA8" |
843 | depends on HAS_IOMEM | ||
819 | help | 844 | help |
820 | If you say yes here you get support for the | 845 | If you say yes here you get support for the |
821 | Simtek STK17TA8 timekeeping chip. | 846 | Simtek STK17TA8 timekeeping chip. |
@@ -834,6 +859,7 @@ config RTC_DRV_M48T86 | |||
834 | 859 | ||
835 | config RTC_DRV_M48T35 | 860 | config RTC_DRV_M48T35 |
836 | tristate "ST M48T35" | 861 | tristate "ST M48T35" |
862 | depends on HAS_IOMEM | ||
837 | help | 863 | help |
838 | If you say Y here you will get support for the | 864 | If you say Y here you will get support for the |
839 | ST M48T35 RTC chip. | 865 | ST M48T35 RTC chip. |
@@ -843,6 +869,7 @@ config RTC_DRV_M48T35 | |||
843 | 869 | ||
844 | config RTC_DRV_M48T59 | 870 | config RTC_DRV_M48T59 |
845 | tristate "ST M48T59/M48T08/M48T02" | 871 | tristate "ST M48T59/M48T08/M48T02" |
872 | depends on HAS_IOMEM | ||
846 | help | 873 | help |
847 | If you say Y here you will get support for the | 874 | If you say Y here you will get support for the |
848 | ST M48T59 RTC chip and compatible ST M48T08 and M48T02. | 875 | ST M48T59 RTC chip and compatible ST M48T08 and M48T02. |
@@ -855,6 +882,7 @@ config RTC_DRV_M48T59 | |||
855 | 882 | ||
856 | config RTC_DRV_MSM6242 | 883 | config RTC_DRV_MSM6242 |
857 | tristate "Oki MSM6242" | 884 | tristate "Oki MSM6242" |
885 | depends on HAS_IOMEM | ||
858 | help | 886 | help |
859 | If you say yes here you get support for the Oki MSM6242 | 887 | If you say yes here you get support for the Oki MSM6242 |
860 | timekeeping chip. It is used in some Amiga models (e.g. A2000). | 888 | timekeeping chip. It is used in some Amiga models (e.g. A2000). |
@@ -864,6 +892,7 @@ config RTC_DRV_MSM6242 | |||
864 | 892 | ||
865 | config RTC_DRV_BQ4802 | 893 | config RTC_DRV_BQ4802 |
866 | tristate "TI BQ4802" | 894 | tristate "TI BQ4802" |
895 | depends on HAS_IOMEM | ||
867 | help | 896 | help |
868 | If you say Y here you will get support for the TI | 897 | If you say Y here you will get support for the TI |
869 | BQ4802 RTC chip. | 898 | BQ4802 RTC chip. |
@@ -873,6 +902,7 @@ config RTC_DRV_BQ4802 | |||
873 | 902 | ||
874 | config RTC_DRV_RP5C01 | 903 | config RTC_DRV_RP5C01 |
875 | tristate "Ricoh RP5C01" | 904 | tristate "Ricoh RP5C01" |
905 | depends on HAS_IOMEM | ||
876 | help | 906 | help |
877 | If you say yes here you get support for the Ricoh RP5C01 | 907 | If you say yes here you get support for the Ricoh RP5C01 |
878 | timekeeping chip. It is used in some Amiga models (e.g. A3000 | 908 | timekeeping chip. It is used in some Amiga models (e.g. A3000 |
@@ -1374,6 +1404,7 @@ config RTC_DRV_MOXART | |||
1374 | 1404 | ||
1375 | config RTC_DRV_XGENE | 1405 | config RTC_DRV_XGENE |
1376 | tristate "APM X-Gene RTC" | 1406 | tristate "APM X-Gene RTC" |
1407 | depends on HAS_IOMEM | ||
1377 | help | 1408 | help |
1378 | If you say yes here you get support for the APM X-Gene SoC real time | 1409 | If you say yes here you get support for the APM X-Gene SoC real time |
1379 | clock. | 1410 | clock. |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 9055b7dd3dc5..b188323c096a 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -85,6 +85,7 @@ obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o | |||
85 | obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o | 85 | obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o |
86 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 86 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
87 | obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o | 87 | obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o |
88 | obj-$(CONFIG_RTC_DRV_MAX77802) += rtc-max77802.o | ||
88 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o | 89 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o |
89 | obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o | 90 | obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o |
90 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o | 91 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o |
@@ -109,6 +110,7 @@ obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o | |||
109 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o | 110 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o |
110 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 111 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
111 | obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o | 112 | obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o |
113 | obj-$(CONFIG_RTC_DRV_RK808) += rtc-rk808.o | ||
112 | obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o | 114 | obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o |
113 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 115 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
114 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 116 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index c74bf0dc52cc..314129e66d6e 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c | |||
@@ -2,10 +2,14 @@ | |||
2 | * Driver for TI BQ32000 RTC. | 2 | * Driver for TI BQ32000 RTC. |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Semihalf. | 4 | * Copyright (C) 2009 Semihalf. |
5 | * Copyright (C) 2014 Pavel Machek <pavel@denx.de> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | * | ||
11 | * You can get hardware description at | ||
12 | * http://www.ti.com/lit/ds/symlink/bq32000.pdf | ||
9 | */ | 13 | */ |
10 | 14 | ||
11 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -27,6 +31,10 @@ | |||
27 | #define BQ32K_CENT 0x40 /* Century flag */ | 31 | #define BQ32K_CENT 0x40 /* Century flag */ |
28 | #define BQ32K_CENT_EN 0x80 /* Century flag enable bit */ | 32 | #define BQ32K_CENT_EN 0x80 /* Century flag enable bit */ |
29 | 33 | ||
34 | #define BQ32K_CALIBRATION 0x07 /* CAL_CFG1, calibration and control */ | ||
35 | #define BQ32K_TCH2 0x08 /* Trickle charge enable */ | ||
36 | #define BQ32K_CFG2 0x09 /* Trickle charger control */ | ||
37 | |||
30 | struct bq32k_regs { | 38 | struct bq32k_regs { |
31 | uint8_t seconds; | 39 | uint8_t seconds; |
32 | uint8_t minutes; | 40 | uint8_t minutes; |
@@ -122,6 +130,57 @@ static const struct rtc_class_ops bq32k_rtc_ops = { | |||
122 | .set_time = bq32k_rtc_set_time, | 130 | .set_time = bq32k_rtc_set_time, |
123 | }; | 131 | }; |
124 | 132 | ||
133 | static int trickle_charger_of_init(struct device *dev, struct device_node *node) | ||
134 | { | ||
135 | unsigned char reg; | ||
136 | int error; | ||
137 | u32 ohms = 0; | ||
138 | |||
139 | if (of_property_read_u32(node, "trickle-resistor-ohms" , &ohms)) | ||
140 | return 0; | ||
141 | |||
142 | switch (ohms) { | ||
143 | case 180+940: | ||
144 | /* | ||
145 | * TCHE[3:0] == 0x05, TCH2 == 1, TCFE == 0 (charging | ||
146 | * over diode and 940ohm resistor) | ||
147 | */ | ||
148 | |||
149 | if (of_property_read_bool(node, "trickle-diode-disable")) { | ||
150 | dev_err(dev, "diode and resistor mismatch\n"); | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | reg = 0x05; | ||
154 | break; | ||
155 | |||
156 | case 180+20000: | ||
157 | /* diode disabled */ | ||
158 | |||
159 | if (!of_property_read_bool(node, "trickle-diode-disable")) { | ||
160 | dev_err(dev, "bq32k: diode and resistor mismatch\n"); | ||
161 | return -EINVAL; | ||
162 | } | ||
163 | reg = 0x25; | ||
164 | break; | ||
165 | |||
166 | default: | ||
167 | dev_err(dev, "invalid resistor value (%d)\n", ohms); | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | error = bq32k_write(dev, ®, BQ32K_CFG2, 1); | ||
172 | if (error) | ||
173 | return error; | ||
174 | |||
175 | reg = 0x20; | ||
176 | error = bq32k_write(dev, ®, BQ32K_TCH2, 1); | ||
177 | if (error) | ||
178 | return error; | ||
179 | |||
180 | dev_info(dev, "Enabled trickle RTC battery charge.\n"); | ||
181 | return 0; | ||
182 | } | ||
183 | |||
125 | static int bq32k_probe(struct i2c_client *client, | 184 | static int bq32k_probe(struct i2c_client *client, |
126 | const struct i2c_device_id *id) | 185 | const struct i2c_device_id *id) |
127 | { | 186 | { |
@@ -153,6 +212,9 @@ static int bq32k_probe(struct i2c_client *client, | |||
153 | if (error) | 212 | if (error) |
154 | return error; | 213 | return error; |
155 | 214 | ||
215 | if (client && client->dev.of_node) | ||
216 | trickle_charger_of_init(dev, client->dev.of_node); | ||
217 | |||
156 | rtc = devm_rtc_device_register(&client->dev, bq32k_driver.driver.name, | 218 | rtc = devm_rtc_device_register(&client->dev, bq32k_driver.driver.name, |
157 | &bq32k_rtc_ops, THIS_MODULE); | 219 | &bq32k_rtc_ops, THIS_MODULE); |
158 | if (IS_ERR(rtc)) | 220 | if (IS_ERR(rtc)) |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index b0e4a3eb33c7..5b2e76159b41 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -856,7 +856,7 @@ static void __exit cmos_do_remove(struct device *dev) | |||
856 | cmos->dev = NULL; | 856 | cmos->dev = NULL; |
857 | } | 857 | } |
858 | 858 | ||
859 | #ifdef CONFIG_PM_SLEEP | 859 | #ifdef CONFIG_PM |
860 | 860 | ||
861 | static int cmos_suspend(struct device *dev) | 861 | static int cmos_suspend(struct device *dev) |
862 | { | 862 | { |
@@ -907,6 +907,8 @@ static inline int cmos_poweroff(struct device *dev) | |||
907 | return cmos_suspend(dev); | 907 | return cmos_suspend(dev); |
908 | } | 908 | } |
909 | 909 | ||
910 | #ifdef CONFIG_PM_SLEEP | ||
911 | |||
910 | static int cmos_resume(struct device *dev) | 912 | static int cmos_resume(struct device *dev) |
911 | { | 913 | { |
912 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 914 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
@@ -954,6 +956,7 @@ static int cmos_resume(struct device *dev) | |||
954 | return 0; | 956 | return 0; |
955 | } | 957 | } |
956 | 958 | ||
959 | #endif | ||
957 | #else | 960 | #else |
958 | 961 | ||
959 | static inline int cmos_poweroff(struct device *dev) | 962 | static inline int cmos_poweroff(struct device *dev) |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index f03d5ba96db1..bb43cf703efc 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -126,9 +126,14 @@ struct chip_desc { | |||
126 | u16 nvram_offset; | 126 | u16 nvram_offset; |
127 | u16 nvram_size; | 127 | u16 nvram_size; |
128 | u16 trickle_charger_reg; | 128 | u16 trickle_charger_reg; |
129 | u8 trickle_charger_setup; | ||
130 | u8 (*do_trickle_setup)(struct i2c_client *, uint32_t, bool); | ||
129 | }; | 131 | }; |
130 | 132 | ||
131 | static const struct chip_desc chips[last_ds_type] = { | 133 | static u8 do_trickle_setup_ds1339(struct i2c_client *, |
134 | uint32_t ohms, bool diode); | ||
135 | |||
136 | static struct chip_desc chips[last_ds_type] = { | ||
132 | [ds_1307] = { | 137 | [ds_1307] = { |
133 | .nvram_offset = 8, | 138 | .nvram_offset = 8, |
134 | .nvram_size = 56, | 139 | .nvram_size = 56, |
@@ -143,6 +148,7 @@ static const struct chip_desc chips[last_ds_type] = { | |||
143 | [ds_1339] = { | 148 | [ds_1339] = { |
144 | .alarm = 1, | 149 | .alarm = 1, |
145 | .trickle_charger_reg = 0x10, | 150 | .trickle_charger_reg = 0x10, |
151 | .do_trickle_setup = &do_trickle_setup_ds1339, | ||
146 | }, | 152 | }, |
147 | [ds_1340] = { | 153 | [ds_1340] = { |
148 | .trickle_charger_reg = 0x08, | 154 | .trickle_charger_reg = 0x08, |
@@ -833,15 +839,58 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, | |||
833 | return count; | 839 | return count; |
834 | } | 840 | } |
835 | 841 | ||
842 | |||
836 | /*----------------------------------------------------------------------*/ | 843 | /*----------------------------------------------------------------------*/ |
837 | 844 | ||
845 | static u8 do_trickle_setup_ds1339(struct i2c_client *client, | ||
846 | uint32_t ohms, bool diode) | ||
847 | { | ||
848 | u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE : | ||
849 | DS1307_TRICKLE_CHARGER_NO_DIODE; | ||
850 | |||
851 | switch (ohms) { | ||
852 | case 250: | ||
853 | setup |= DS1307_TRICKLE_CHARGER_250_OHM; | ||
854 | break; | ||
855 | case 2000: | ||
856 | setup |= DS1307_TRICKLE_CHARGER_2K_OHM; | ||
857 | break; | ||
858 | case 4000: | ||
859 | setup |= DS1307_TRICKLE_CHARGER_4K_OHM; | ||
860 | break; | ||
861 | default: | ||
862 | dev_warn(&client->dev, | ||
863 | "Unsupported ohm value %u in dt\n", ohms); | ||
864 | return 0; | ||
865 | } | ||
866 | return setup; | ||
867 | } | ||
868 | |||
869 | static void ds1307_trickle_of_init(struct i2c_client *client, | ||
870 | struct chip_desc *chip) | ||
871 | { | ||
872 | uint32_t ohms = 0; | ||
873 | bool diode = true; | ||
874 | |||
875 | if (!chip->do_trickle_setup) | ||
876 | goto out; | ||
877 | if (of_property_read_u32(client->dev.of_node, "trickle-resistor-ohms" , &ohms)) | ||
878 | goto out; | ||
879 | if (of_property_read_bool(client->dev.of_node, "trickle-diode-disable")) | ||
880 | diode = false; | ||
881 | chip->trickle_charger_setup = chip->do_trickle_setup(client, | ||
882 | ohms, diode); | ||
883 | out: | ||
884 | return; | ||
885 | } | ||
886 | |||
838 | static int ds1307_probe(struct i2c_client *client, | 887 | static int ds1307_probe(struct i2c_client *client, |
839 | const struct i2c_device_id *id) | 888 | const struct i2c_device_id *id) |
840 | { | 889 | { |
841 | struct ds1307 *ds1307; | 890 | struct ds1307 *ds1307; |
842 | int err = -ENODEV; | 891 | int err = -ENODEV; |
843 | int tmp; | 892 | int tmp; |
844 | const struct chip_desc *chip = &chips[id->driver_data]; | 893 | struct chip_desc *chip = &chips[id->driver_data]; |
845 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 894 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
846 | bool want_irq = false; | 895 | bool want_irq = false; |
847 | unsigned char *buf; | 896 | unsigned char *buf; |
@@ -866,9 +915,19 @@ static int ds1307_probe(struct i2c_client *client, | |||
866 | ds1307->client = client; | 915 | ds1307->client = client; |
867 | ds1307->type = id->driver_data; | 916 | ds1307->type = id->driver_data; |
868 | 917 | ||
869 | if (pdata && pdata->trickle_charger_setup && chip->trickle_charger_reg) | 918 | if (!pdata && client->dev.of_node) |
919 | ds1307_trickle_of_init(client, chip); | ||
920 | else if (pdata && pdata->trickle_charger_setup) | ||
921 | chip->trickle_charger_setup = pdata->trickle_charger_setup; | ||
922 | |||
923 | if (chip->trickle_charger_setup && chip->trickle_charger_reg) { | ||
924 | dev_dbg(&client->dev, "writing trickle charger info 0x%x to 0x%x\n", | ||
925 | DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup, | ||
926 | chip->trickle_charger_reg); | ||
870 | i2c_smbus_write_byte_data(client, chip->trickle_charger_reg, | 927 | i2c_smbus_write_byte_data(client, chip->trickle_charger_reg, |
871 | DS13XX_TRICKLE_CHARGER_MAGIC | pdata->trickle_charger_setup); | 928 | DS13XX_TRICKLE_CHARGER_MAGIC | |
929 | chip->trickle_charger_setup); | ||
930 | } | ||
872 | 931 | ||
873 | buf = ds1307->regs; | 932 | buf = ds1307->regs; |
874 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { | 933 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { |
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index aa55f081c505..ee3ba7e6b45e 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c | |||
@@ -274,7 +274,7 @@ static int isl12022_probe(struct i2c_client *client, | |||
274 | } | 274 | } |
275 | 275 | ||
276 | #ifdef CONFIG_OF | 276 | #ifdef CONFIG_OF |
277 | static struct of_device_id isl12022_dt_match[] = { | 277 | static const struct of_device_id isl12022_dt_match[] = { |
278 | { .compatible = "isl,isl12022" }, | 278 | { .compatible = "isl,isl12022" }, |
279 | { }, | 279 | { }, |
280 | }; | 280 | }; |
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index d20a7f0786eb..cf73e969c8cc 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c | |||
@@ -32,15 +32,6 @@ | |||
32 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) | 32 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) |
33 | #define RTC_RBUDR_SHIFT 4 | 33 | #define RTC_RBUDR_SHIFT 4 |
34 | #define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) | 34 | #define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) |
35 | /* WTSR and SMPL Register */ | ||
36 | #define WTSRT_SHIFT 0 | ||
37 | #define SMPLT_SHIFT 2 | ||
38 | #define WTSR_EN_SHIFT 6 | ||
39 | #define SMPL_EN_SHIFT 7 | ||
40 | #define WTSRT_MASK (3 << WTSRT_SHIFT) | ||
41 | #define SMPLT_MASK (3 << SMPLT_SHIFT) | ||
42 | #define WTSR_EN_MASK (1 << WTSR_EN_SHIFT) | ||
43 | #define SMPL_EN_MASK (1 << SMPL_EN_SHIFT) | ||
44 | /* RTC Hour register */ | 35 | /* RTC Hour register */ |
45 | #define HOUR_PM_SHIFT 6 | 36 | #define HOUR_PM_SHIFT 6 |
46 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) | 37 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) |
@@ -49,7 +40,6 @@ | |||
49 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) | 40 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) |
50 | 41 | ||
51 | #define MAX77686_RTC_UPDATE_DELAY 16 | 42 | #define MAX77686_RTC_UPDATE_DELAY 16 |
52 | #undef MAX77686_RTC_WTSR_SMPL | ||
53 | 43 | ||
54 | enum { | 44 | enum { |
55 | RTC_SEC = 0, | 45 | RTC_SEC = 0, |
@@ -80,16 +70,6 @@ enum MAX77686_RTC_OP { | |||
80 | MAX77686_RTC_READ, | 70 | MAX77686_RTC_READ, |
81 | }; | 71 | }; |
82 | 72 | ||
83 | static inline int max77686_rtc_calculate_wday(u8 shifted) | ||
84 | { | ||
85 | int counter = -1; | ||
86 | while (shifted) { | ||
87 | shifted >>= 1; | ||
88 | counter++; | ||
89 | } | ||
90 | return counter; | ||
91 | } | ||
92 | |||
93 | static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, | 73 | static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, |
94 | int rtc_24hr_mode) | 74 | int rtc_24hr_mode) |
95 | { | 75 | { |
@@ -103,7 +83,8 @@ static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, | |||
103 | tm->tm_hour += 12; | 83 | tm->tm_hour += 12; |
104 | } | 84 | } |
105 | 85 | ||
106 | tm->tm_wday = max77686_rtc_calculate_wday(data[RTC_WEEKDAY] & 0x7f); | 86 | /* Only a single bit is set in data[], so fls() would be equivalent */ |
87 | tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f) - 1; | ||
107 | tm->tm_mday = data[RTC_DATE] & 0x1f; | 88 | tm->tm_mday = data[RTC_DATE] & 0x1f; |
108 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; | 89 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; |
109 | tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; | 90 | tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; |
@@ -412,64 +393,6 @@ static const struct rtc_class_ops max77686_rtc_ops = { | |||
412 | .alarm_irq_enable = max77686_rtc_alarm_irq_enable, | 393 | .alarm_irq_enable = max77686_rtc_alarm_irq_enable, |
413 | }; | 394 | }; |
414 | 395 | ||
415 | #ifdef MAX77686_RTC_WTSR_SMPL | ||
416 | static void max77686_rtc_enable_wtsr(struct max77686_rtc_info *info, bool enable) | ||
417 | { | ||
418 | int ret; | ||
419 | unsigned int val, mask; | ||
420 | |||
421 | if (enable) | ||
422 | val = (1 << WTSR_EN_SHIFT) | (3 << WTSRT_SHIFT); | ||
423 | else | ||
424 | val = 0; | ||
425 | |||
426 | mask = WTSR_EN_MASK | WTSRT_MASK; | ||
427 | |||
428 | dev_info(info->dev, "%s: %s WTSR\n", __func__, | ||
429 | enable ? "enable" : "disable"); | ||
430 | |||
431 | ret = regmap_update_bits(info->max77686->rtc_regmap, | ||
432 | MAX77686_WTSR_SMPL_CNTL, mask, val); | ||
433 | if (ret < 0) { | ||
434 | dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n", | ||
435 | __func__, ret); | ||
436 | return; | ||
437 | } | ||
438 | |||
439 | max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
440 | } | ||
441 | |||
442 | static void max77686_rtc_enable_smpl(struct max77686_rtc_info *info, bool enable) | ||
443 | { | ||
444 | int ret; | ||
445 | unsigned int val, mask; | ||
446 | |||
447 | if (enable) | ||
448 | val = (1 << SMPL_EN_SHIFT) | (0 << SMPLT_SHIFT); | ||
449 | else | ||
450 | val = 0; | ||
451 | |||
452 | mask = SMPL_EN_MASK | SMPLT_MASK; | ||
453 | |||
454 | dev_info(info->dev, "%s: %s SMPL\n", __func__, | ||
455 | enable ? "enable" : "disable"); | ||
456 | |||
457 | ret = regmap_update_bits(info->max77686->rtc_regmap, | ||
458 | MAX77686_WTSR_SMPL_CNTL, mask, val); | ||
459 | if (ret < 0) { | ||
460 | dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n", | ||
461 | __func__, ret); | ||
462 | return; | ||
463 | } | ||
464 | |||
465 | max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
466 | |||
467 | val = 0; | ||
468 | regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val); | ||
469 | dev_info(info->dev, "%s: WTSR_SMPL(0x%02x)\n", __func__, val); | ||
470 | } | ||
471 | #endif /* MAX77686_RTC_WTSR_SMPL */ | ||
472 | |||
473 | static int max77686_rtc_init_reg(struct max77686_rtc_info *info) | 396 | static int max77686_rtc_init_reg(struct max77686_rtc_info *info) |
474 | { | 397 | { |
475 | u8 data[2]; | 398 | u8 data[2]; |
@@ -519,19 +442,12 @@ static int max77686_rtc_probe(struct platform_device *pdev) | |||
519 | goto err_rtc; | 442 | goto err_rtc; |
520 | } | 443 | } |
521 | 444 | ||
522 | #ifdef MAX77686_RTC_WTSR_SMPL | ||
523 | max77686_rtc_enable_wtsr(info, true); | ||
524 | max77686_rtc_enable_smpl(info, true); | ||
525 | #endif | ||
526 | |||
527 | device_init_wakeup(&pdev->dev, 1); | 445 | device_init_wakeup(&pdev->dev, 1); |
528 | 446 | ||
529 | info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc", | 447 | info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc", |
530 | &max77686_rtc_ops, THIS_MODULE); | 448 | &max77686_rtc_ops, THIS_MODULE); |
531 | 449 | ||
532 | if (IS_ERR(info->rtc_dev)) { | 450 | if (IS_ERR(info->rtc_dev)) { |
533 | dev_info(&pdev->dev, "%s: fail\n", __func__); | ||
534 | |||
535 | ret = PTR_ERR(info->rtc_dev); | 451 | ret = PTR_ERR(info->rtc_dev); |
536 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | 452 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); |
537 | if (ret == 0) | 453 | if (ret == 0) |
@@ -539,6 +455,12 @@ static int max77686_rtc_probe(struct platform_device *pdev) | |||
539 | goto err_rtc; | 455 | goto err_rtc; |
540 | } | 456 | } |
541 | 457 | ||
458 | if (!max77686->rtc_irq_data) { | ||
459 | ret = -EINVAL; | ||
460 | dev_err(&pdev->dev, "%s: no RTC regmap IRQ chip\n", __func__); | ||
461 | goto err_rtc; | ||
462 | } | ||
463 | |||
542 | info->virq = regmap_irq_get_virq(max77686->rtc_irq_data, | 464 | info->virq = regmap_irq_get_virq(max77686->rtc_irq_data, |
543 | MAX77686_RTCIRQ_RTCA1); | 465 | MAX77686_RTCIRQ_RTCA1); |
544 | if (!info->virq) { | 466 | if (!info->virq) { |
@@ -556,33 +478,33 @@ err_rtc: | |||
556 | return ret; | 478 | return ret; |
557 | } | 479 | } |
558 | 480 | ||
559 | static void max77686_rtc_shutdown(struct platform_device *pdev) | 481 | #ifdef CONFIG_PM_SLEEP |
482 | static int max77686_rtc_suspend(struct device *dev) | ||
560 | { | 483 | { |
561 | #ifdef MAX77686_RTC_WTSR_SMPL | 484 | if (device_may_wakeup(dev)) { |
562 | struct max77686_rtc_info *info = platform_get_drvdata(pdev); | 485 | struct max77686_rtc_info *info = dev_get_drvdata(dev); |
563 | int i; | 486 | |
564 | u8 val = 0; | 487 | return enable_irq_wake(info->virq); |
565 | |||
566 | for (i = 0; i < 3; i++) { | ||
567 | max77686_rtc_enable_wtsr(info, false); | ||
568 | regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val); | ||
569 | dev_info(info->dev, "%s: WTSR_SMPL reg(0x%02x)\n", __func__, | ||
570 | val); | ||
571 | if (val & WTSR_EN_MASK) { | ||
572 | dev_emerg(info->dev, "%s: fail to disable WTSR\n", | ||
573 | __func__); | ||
574 | } else { | ||
575 | dev_info(info->dev, "%s: success to disable WTSR\n", | ||
576 | __func__); | ||
577 | break; | ||
578 | } | ||
579 | } | 488 | } |
580 | 489 | ||
581 | /* Disable SMPL when power off */ | 490 | return 0; |
582 | max77686_rtc_enable_smpl(info, false); | ||
583 | #endif /* MAX77686_RTC_WTSR_SMPL */ | ||
584 | } | 491 | } |
585 | 492 | ||
493 | static int max77686_rtc_resume(struct device *dev) | ||
494 | { | ||
495 | if (device_may_wakeup(dev)) { | ||
496 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
497 | |||
498 | return disable_irq_wake(info->virq); | ||
499 | } | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | #endif | ||
504 | |||
505 | static SIMPLE_DEV_PM_OPS(max77686_rtc_pm_ops, | ||
506 | max77686_rtc_suspend, max77686_rtc_resume); | ||
507 | |||
586 | static const struct platform_device_id rtc_id[] = { | 508 | static const struct platform_device_id rtc_id[] = { |
587 | { "max77686-rtc", 0 }, | 509 | { "max77686-rtc", 0 }, |
588 | {}, | 510 | {}, |
@@ -592,9 +514,9 @@ static struct platform_driver max77686_rtc_driver = { | |||
592 | .driver = { | 514 | .driver = { |
593 | .name = "max77686-rtc", | 515 | .name = "max77686-rtc", |
594 | .owner = THIS_MODULE, | 516 | .owner = THIS_MODULE, |
517 | .pm = &max77686_rtc_pm_ops, | ||
595 | }, | 518 | }, |
596 | .probe = max77686_rtc_probe, | 519 | .probe = max77686_rtc_probe, |
597 | .shutdown = max77686_rtc_shutdown, | ||
598 | .id_table = rtc_id, | 520 | .id_table = rtc_id, |
599 | }; | 521 | }; |
600 | 522 | ||
diff --git a/drivers/rtc/rtc-max77802.c b/drivers/rtc/rtc-max77802.c new file mode 100644 index 000000000000..566471335b33 --- /dev/null +++ b/drivers/rtc/rtc-max77802.c | |||
@@ -0,0 +1,502 @@ | |||
1 | /* | ||
2 | * RTC driver for Maxim MAX77802 | ||
3 | * | ||
4 | * Copyright (C) 2013 Google, Inc | ||
5 | * | ||
6 | * Copyright (C) 2012 Samsung Electronics Co.Ltd | ||
7 | * | ||
8 | * based on rtc-max8997.c | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/slab.h> | ||
18 | #include <linux/rtc.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/mutex.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/mfd/max77686-private.h> | ||
24 | #include <linux/irqdomain.h> | ||
25 | #include <linux/regmap.h> | ||
26 | |||
27 | /* RTC Control Register */ | ||
28 | #define BCD_EN_SHIFT 0 | ||
29 | #define BCD_EN_MASK (1 << BCD_EN_SHIFT) | ||
30 | #define MODEL24_SHIFT 1 | ||
31 | #define MODEL24_MASK (1 << MODEL24_SHIFT) | ||
32 | /* RTC Update Register1 */ | ||
33 | #define RTC_UDR_SHIFT 0 | ||
34 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) | ||
35 | #define RTC_RBUDR_SHIFT 4 | ||
36 | #define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) | ||
37 | /* RTC Hour register */ | ||
38 | #define HOUR_PM_SHIFT 6 | ||
39 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) | ||
40 | /* RTC Alarm Enable */ | ||
41 | #define ALARM_ENABLE_SHIFT 7 | ||
42 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) | ||
43 | |||
44 | /* For the RTCAE1 register, we write this value to enable the alarm */ | ||
45 | #define ALARM_ENABLE_VALUE 0x77 | ||
46 | |||
47 | #define MAX77802_RTC_UPDATE_DELAY_US 200 | ||
48 | |||
49 | enum { | ||
50 | RTC_SEC = 0, | ||
51 | RTC_MIN, | ||
52 | RTC_HOUR, | ||
53 | RTC_WEEKDAY, | ||
54 | RTC_MONTH, | ||
55 | RTC_YEAR, | ||
56 | RTC_DATE, | ||
57 | RTC_NR_TIME | ||
58 | }; | ||
59 | |||
60 | struct max77802_rtc_info { | ||
61 | struct device *dev; | ||
62 | struct max77686_dev *max77802; | ||
63 | struct i2c_client *rtc; | ||
64 | struct rtc_device *rtc_dev; | ||
65 | struct mutex lock; | ||
66 | |||
67 | struct regmap *regmap; | ||
68 | |||
69 | int virq; | ||
70 | int rtc_24hr_mode; | ||
71 | }; | ||
72 | |||
73 | enum MAX77802_RTC_OP { | ||
74 | MAX77802_RTC_WRITE, | ||
75 | MAX77802_RTC_READ, | ||
76 | }; | ||
77 | |||
78 | static void max77802_rtc_data_to_tm(u8 *data, struct rtc_time *tm, | ||
79 | int rtc_24hr_mode) | ||
80 | { | ||
81 | tm->tm_sec = data[RTC_SEC] & 0xff; | ||
82 | tm->tm_min = data[RTC_MIN] & 0xff; | ||
83 | if (rtc_24hr_mode) | ||
84 | tm->tm_hour = data[RTC_HOUR] & 0x1f; | ||
85 | else { | ||
86 | tm->tm_hour = data[RTC_HOUR] & 0x0f; | ||
87 | if (data[RTC_HOUR] & HOUR_PM_MASK) | ||
88 | tm->tm_hour += 12; | ||
89 | } | ||
90 | |||
91 | /* Only a single bit is set in data[], so fls() would be equivalent */ | ||
92 | tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0xff) - 1; | ||
93 | tm->tm_mday = data[RTC_DATE] & 0x1f; | ||
94 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; | ||
95 | |||
96 | tm->tm_year = data[RTC_YEAR] & 0xff; | ||
97 | tm->tm_yday = 0; | ||
98 | tm->tm_isdst = 0; | ||
99 | } | ||
100 | |||
101 | static int max77802_rtc_tm_to_data(struct rtc_time *tm, u8 *data) | ||
102 | { | ||
103 | data[RTC_SEC] = tm->tm_sec; | ||
104 | data[RTC_MIN] = tm->tm_min; | ||
105 | data[RTC_HOUR] = tm->tm_hour; | ||
106 | data[RTC_WEEKDAY] = 1 << tm->tm_wday; | ||
107 | data[RTC_DATE] = tm->tm_mday; | ||
108 | data[RTC_MONTH] = tm->tm_mon + 1; | ||
109 | data[RTC_YEAR] = tm->tm_year; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int max77802_rtc_update(struct max77802_rtc_info *info, | ||
115 | enum MAX77802_RTC_OP op) | ||
116 | { | ||
117 | int ret; | ||
118 | unsigned int data; | ||
119 | |||
120 | if (op == MAX77802_RTC_WRITE) | ||
121 | data = 1 << RTC_UDR_SHIFT; | ||
122 | else | ||
123 | data = 1 << RTC_RBUDR_SHIFT; | ||
124 | |||
125 | ret = regmap_update_bits(info->max77802->regmap, | ||
126 | MAX77802_RTC_UPDATE0, data, data); | ||
127 | if (ret < 0) | ||
128 | dev_err(info->dev, "%s: fail to write update reg(ret=%d, data=0x%x)\n", | ||
129 | __func__, ret, data); | ||
130 | else { | ||
131 | /* Minimum delay required before RTC update. */ | ||
132 | usleep_range(MAX77802_RTC_UPDATE_DELAY_US, | ||
133 | MAX77802_RTC_UPDATE_DELAY_US * 2); | ||
134 | } | ||
135 | |||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | static int max77802_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
140 | { | ||
141 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
142 | u8 data[RTC_NR_TIME]; | ||
143 | int ret; | ||
144 | |||
145 | mutex_lock(&info->lock); | ||
146 | |||
147 | ret = max77802_rtc_update(info, MAX77802_RTC_READ); | ||
148 | if (ret < 0) | ||
149 | goto out; | ||
150 | |||
151 | ret = regmap_bulk_read(info->max77802->regmap, | ||
152 | MAX77802_RTC_SEC, data, RTC_NR_TIME); | ||
153 | if (ret < 0) { | ||
154 | dev_err(info->dev, "%s: fail to read time reg(%d)\n", __func__, | ||
155 | ret); | ||
156 | goto out; | ||
157 | } | ||
158 | |||
159 | max77802_rtc_data_to_tm(data, tm, info->rtc_24hr_mode); | ||
160 | |||
161 | ret = rtc_valid_tm(tm); | ||
162 | |||
163 | out: | ||
164 | mutex_unlock(&info->lock); | ||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | static int max77802_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
169 | { | ||
170 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
171 | u8 data[RTC_NR_TIME]; | ||
172 | int ret; | ||
173 | |||
174 | ret = max77802_rtc_tm_to_data(tm, data); | ||
175 | if (ret < 0) | ||
176 | return ret; | ||
177 | |||
178 | mutex_lock(&info->lock); | ||
179 | |||
180 | ret = regmap_bulk_write(info->max77802->regmap, | ||
181 | MAX77802_RTC_SEC, data, RTC_NR_TIME); | ||
182 | if (ret < 0) { | ||
183 | dev_err(info->dev, "%s: fail to write time reg(%d)\n", __func__, | ||
184 | ret); | ||
185 | goto out; | ||
186 | } | ||
187 | |||
188 | ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); | ||
189 | |||
190 | out: | ||
191 | mutex_unlock(&info->lock); | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static int max77802_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
196 | { | ||
197 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
198 | u8 data[RTC_NR_TIME]; | ||
199 | unsigned int val; | ||
200 | int ret; | ||
201 | |||
202 | mutex_lock(&info->lock); | ||
203 | |||
204 | ret = max77802_rtc_update(info, MAX77802_RTC_READ); | ||
205 | if (ret < 0) | ||
206 | goto out; | ||
207 | |||
208 | ret = regmap_bulk_read(info->max77802->regmap, | ||
209 | MAX77802_ALARM1_SEC, data, RTC_NR_TIME); | ||
210 | if (ret < 0) { | ||
211 | dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n", | ||
212 | __func__, __LINE__, ret); | ||
213 | goto out; | ||
214 | } | ||
215 | |||
216 | max77802_rtc_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); | ||
217 | |||
218 | alrm->enabled = 0; | ||
219 | ret = regmap_read(info->max77802->regmap, | ||
220 | MAX77802_RTC_AE1, &val); | ||
221 | if (ret < 0) { | ||
222 | dev_err(info->dev, "%s:%d fail to read alarm enable(%d)\n", | ||
223 | __func__, __LINE__, ret); | ||
224 | goto out; | ||
225 | } | ||
226 | if (val) | ||
227 | alrm->enabled = 1; | ||
228 | |||
229 | alrm->pending = 0; | ||
230 | ret = regmap_read(info->max77802->regmap, MAX77802_REG_STATUS2, &val); | ||
231 | if (ret < 0) { | ||
232 | dev_err(info->dev, "%s:%d fail to read status2 reg(%d)\n", | ||
233 | __func__, __LINE__, ret); | ||
234 | goto out; | ||
235 | } | ||
236 | |||
237 | if (val & (1 << 2)) /* RTCA1 */ | ||
238 | alrm->pending = 1; | ||
239 | |||
240 | out: | ||
241 | mutex_unlock(&info->lock); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static int max77802_rtc_stop_alarm(struct max77802_rtc_info *info) | ||
246 | { | ||
247 | int ret; | ||
248 | |||
249 | if (!mutex_is_locked(&info->lock)) | ||
250 | dev_warn(info->dev, "%s: should have mutex locked\n", __func__); | ||
251 | |||
252 | ret = max77802_rtc_update(info, MAX77802_RTC_READ); | ||
253 | if (ret < 0) | ||
254 | goto out; | ||
255 | |||
256 | ret = regmap_write(info->max77802->regmap, | ||
257 | MAX77802_RTC_AE1, 0); | ||
258 | if (ret < 0) { | ||
259 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
260 | __func__, ret); | ||
261 | goto out; | ||
262 | } | ||
263 | |||
264 | ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); | ||
265 | out: | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | static int max77802_rtc_start_alarm(struct max77802_rtc_info *info) | ||
270 | { | ||
271 | int ret; | ||
272 | |||
273 | if (!mutex_is_locked(&info->lock)) | ||
274 | dev_warn(info->dev, "%s: should have mutex locked\n", | ||
275 | __func__); | ||
276 | |||
277 | ret = max77802_rtc_update(info, MAX77802_RTC_READ); | ||
278 | if (ret < 0) | ||
279 | goto out; | ||
280 | |||
281 | ret = regmap_write(info->max77802->regmap, | ||
282 | MAX77802_RTC_AE1, | ||
283 | ALARM_ENABLE_VALUE); | ||
284 | |||
285 | if (ret < 0) { | ||
286 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", | ||
287 | __func__, ret); | ||
288 | goto out; | ||
289 | } | ||
290 | |||
291 | ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); | ||
292 | out: | ||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | static int max77802_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
297 | { | ||
298 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
299 | u8 data[RTC_NR_TIME]; | ||
300 | int ret; | ||
301 | |||
302 | ret = max77802_rtc_tm_to_data(&alrm->time, data); | ||
303 | if (ret < 0) | ||
304 | return ret; | ||
305 | |||
306 | mutex_lock(&info->lock); | ||
307 | |||
308 | ret = max77802_rtc_stop_alarm(info); | ||
309 | if (ret < 0) | ||
310 | goto out; | ||
311 | |||
312 | ret = regmap_bulk_write(info->max77802->regmap, | ||
313 | MAX77802_ALARM1_SEC, data, RTC_NR_TIME); | ||
314 | |||
315 | if (ret < 0) { | ||
316 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
317 | __func__, ret); | ||
318 | goto out; | ||
319 | } | ||
320 | |||
321 | ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); | ||
322 | if (ret < 0) | ||
323 | goto out; | ||
324 | |||
325 | if (alrm->enabled) | ||
326 | ret = max77802_rtc_start_alarm(info); | ||
327 | out: | ||
328 | mutex_unlock(&info->lock); | ||
329 | return ret; | ||
330 | } | ||
331 | |||
332 | static int max77802_rtc_alarm_irq_enable(struct device *dev, | ||
333 | unsigned int enabled) | ||
334 | { | ||
335 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
336 | int ret; | ||
337 | |||
338 | mutex_lock(&info->lock); | ||
339 | if (enabled) | ||
340 | ret = max77802_rtc_start_alarm(info); | ||
341 | else | ||
342 | ret = max77802_rtc_stop_alarm(info); | ||
343 | mutex_unlock(&info->lock); | ||
344 | |||
345 | return ret; | ||
346 | } | ||
347 | |||
348 | static irqreturn_t max77802_rtc_alarm_irq(int irq, void *data) | ||
349 | { | ||
350 | struct max77802_rtc_info *info = data; | ||
351 | |||
352 | dev_dbg(info->dev, "%s:irq(%d)\n", __func__, irq); | ||
353 | |||
354 | rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); | ||
355 | |||
356 | return IRQ_HANDLED; | ||
357 | } | ||
358 | |||
359 | static const struct rtc_class_ops max77802_rtc_ops = { | ||
360 | .read_time = max77802_rtc_read_time, | ||
361 | .set_time = max77802_rtc_set_time, | ||
362 | .read_alarm = max77802_rtc_read_alarm, | ||
363 | .set_alarm = max77802_rtc_set_alarm, | ||
364 | .alarm_irq_enable = max77802_rtc_alarm_irq_enable, | ||
365 | }; | ||
366 | |||
367 | static int max77802_rtc_init_reg(struct max77802_rtc_info *info) | ||
368 | { | ||
369 | u8 data[2]; | ||
370 | int ret; | ||
371 | |||
372 | max77802_rtc_update(info, MAX77802_RTC_READ); | ||
373 | |||
374 | /* Set RTC control register : Binary mode, 24hour mdoe */ | ||
375 | data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
376 | data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
377 | |||
378 | info->rtc_24hr_mode = 1; | ||
379 | |||
380 | ret = regmap_bulk_write(info->max77802->regmap, | ||
381 | MAX77802_RTC_CONTROLM, data, ARRAY_SIZE(data)); | ||
382 | if (ret < 0) { | ||
383 | dev_err(info->dev, "%s: fail to write controlm reg(%d)\n", | ||
384 | __func__, ret); | ||
385 | return ret; | ||
386 | } | ||
387 | |||
388 | ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); | ||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | static int max77802_rtc_probe(struct platform_device *pdev) | ||
393 | { | ||
394 | struct max77686_dev *max77802 = dev_get_drvdata(pdev->dev.parent); | ||
395 | struct max77802_rtc_info *info; | ||
396 | int ret; | ||
397 | |||
398 | dev_dbg(&pdev->dev, "%s\n", __func__); | ||
399 | |||
400 | info = devm_kzalloc(&pdev->dev, sizeof(struct max77802_rtc_info), | ||
401 | GFP_KERNEL); | ||
402 | if (!info) | ||
403 | return -ENOMEM; | ||
404 | |||
405 | mutex_init(&info->lock); | ||
406 | info->dev = &pdev->dev; | ||
407 | info->max77802 = max77802; | ||
408 | info->rtc = max77802->i2c; | ||
409 | |||
410 | platform_set_drvdata(pdev, info); | ||
411 | |||
412 | ret = max77802_rtc_init_reg(info); | ||
413 | |||
414 | if (ret < 0) { | ||
415 | dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret); | ||
416 | return ret; | ||
417 | } | ||
418 | |||
419 | device_init_wakeup(&pdev->dev, 1); | ||
420 | |||
421 | info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77802-rtc", | ||
422 | &max77802_rtc_ops, THIS_MODULE); | ||
423 | |||
424 | if (IS_ERR(info->rtc_dev)) { | ||
425 | ret = PTR_ERR(info->rtc_dev); | ||
426 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
427 | if (ret == 0) | ||
428 | ret = -EINVAL; | ||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | if (!max77802->rtc_irq_data) { | ||
433 | dev_err(&pdev->dev, "No RTC regmap IRQ chip\n"); | ||
434 | return -EINVAL; | ||
435 | } | ||
436 | |||
437 | info->virq = regmap_irq_get_virq(max77802->rtc_irq_data, | ||
438 | MAX77686_RTCIRQ_RTCA1); | ||
439 | |||
440 | if (info->virq <= 0) { | ||
441 | dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n", | ||
442 | MAX77686_RTCIRQ_RTCA1); | ||
443 | return -EINVAL; | ||
444 | } | ||
445 | |||
446 | ret = devm_request_threaded_irq(&pdev->dev, info->virq, NULL, | ||
447 | max77802_rtc_alarm_irq, 0, "rtc-alarm1", | ||
448 | info); | ||
449 | if (ret < 0) | ||
450 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", | ||
451 | info->virq, ret); | ||
452 | |||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | #ifdef CONFIG_PM_SLEEP | ||
457 | static int max77802_rtc_suspend(struct device *dev) | ||
458 | { | ||
459 | if (device_may_wakeup(dev)) { | ||
460 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
461 | |||
462 | return enable_irq_wake(info->virq); | ||
463 | } | ||
464 | |||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static int max77802_rtc_resume(struct device *dev) | ||
469 | { | ||
470 | if (device_may_wakeup(dev)) { | ||
471 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
472 | |||
473 | return disable_irq_wake(info->virq); | ||
474 | } | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | #endif | ||
479 | |||
480 | static SIMPLE_DEV_PM_OPS(max77802_rtc_pm_ops, | ||
481 | max77802_rtc_suspend, max77802_rtc_resume); | ||
482 | |||
483 | static const struct platform_device_id rtc_id[] = { | ||
484 | { "max77802-rtc", 0 }, | ||
485 | {}, | ||
486 | }; | ||
487 | |||
488 | static struct platform_driver max77802_rtc_driver = { | ||
489 | .driver = { | ||
490 | .name = "max77802-rtc", | ||
491 | .owner = THIS_MODULE, | ||
492 | .pm = &max77802_rtc_pm_ops, | ||
493 | }, | ||
494 | .probe = max77802_rtc_probe, | ||
495 | .id_table = rtc_id, | ||
496 | }; | ||
497 | |||
498 | module_platform_driver(max77802_rtc_driver); | ||
499 | |||
500 | MODULE_DESCRIPTION("Maxim MAX77802 RTC driver"); | ||
501 | MODULE_AUTHOR("Simon Glass <sjg@chromium.org>"); | ||
502 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index dc4f14255cc3..3b965ad6f4d5 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c | |||
@@ -401,7 +401,7 @@ static int mpc5121_rtc_remove(struct platform_device *op) | |||
401 | } | 401 | } |
402 | 402 | ||
403 | #ifdef CONFIG_OF | 403 | #ifdef CONFIG_OF |
404 | static struct of_device_id mpc5121_rtc_match[] = { | 404 | static const struct of_device_id mpc5121_rtc_match[] = { |
405 | { .compatible = "fsl,mpc5121-rtc", }, | 405 | { .compatible = "fsl,mpc5121-rtc", }, |
406 | { .compatible = "fsl,mpc5200-rtc", }, | 406 | { .compatible = "fsl,mpc5200-rtc", }, |
407 | {}, | 407 | {}, |
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 5a197d9dc7e7..c2ef0a22ee94 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -167,8 +167,8 @@ static irqreturn_t pcf8563_irq(int irq, void *dev_id) | |||
167 | char pending; | 167 | char pending; |
168 | 168 | ||
169 | err = pcf8563_get_alarm_mode(pcf8563->client, NULL, &pending); | 169 | err = pcf8563_get_alarm_mode(pcf8563->client, NULL, &pending); |
170 | if (err < 0) | 170 | if (err) |
171 | return err; | 171 | return IRQ_NONE; |
172 | 172 | ||
173 | if (pending) { | 173 | if (pending) { |
174 | rtc_update_irq(pcf8563->rtc, 1, RTC_IRQF | RTC_AF); | 174 | rtc_update_irq(pcf8563->rtc, 1, RTC_IRQF | RTC_AF); |
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index c2639845186b..5911a6dca291 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
@@ -176,7 +176,11 @@ static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
176 | { | 176 | { |
177 | struct i2c_client *client = to_i2c_client(dev); | 177 | struct i2c_client *client = to_i2c_client(dev); |
178 | unsigned char ctrl, year[2]; | 178 | unsigned char ctrl, year[2]; |
179 | struct rtc_mem mem = { CMOS_YEAR, sizeof(year), year }; | 179 | struct rtc_mem mem = { |
180 | .loc = CMOS_YEAR, | ||
181 | .nr = sizeof(year), | ||
182 | .data = year | ||
183 | }; | ||
180 | int real_year, year_offset, err; | 184 | int real_year, year_offset, err; |
181 | 185 | ||
182 | /* | 186 | /* |
@@ -222,8 +226,16 @@ static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
222 | { | 226 | { |
223 | struct i2c_client *client = to_i2c_client(dev); | 227 | struct i2c_client *client = to_i2c_client(dev); |
224 | unsigned char year[2], chk; | 228 | unsigned char year[2], chk; |
225 | struct rtc_mem cmos_year = { CMOS_YEAR, sizeof(year), year }; | 229 | struct rtc_mem cmos_year = { |
226 | struct rtc_mem cmos_check = { CMOS_CHECKSUM, 1, &chk }; | 230 | .loc = CMOS_YEAR, |
231 | .nr = sizeof(year), | ||
232 | .data = year | ||
233 | }; | ||
234 | struct rtc_mem cmos_check = { | ||
235 | .loc = CMOS_CHECKSUM, | ||
236 | .nr = 1, | ||
237 | .data = &chk | ||
238 | }; | ||
227 | unsigned int proper_year = tm->tm_year + 1900; | 239 | unsigned int proper_year = tm->tm_year + 1900; |
228 | int ret; | 240 | int ret; |
229 | 241 | ||
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c new file mode 100644 index 000000000000..df42257668ac --- /dev/null +++ b/drivers/rtc/rtc-rk808.c | |||
@@ -0,0 +1,414 @@ | |||
1 | /* | ||
2 | * RTC driver for Rockchip RK808 | ||
3 | * | ||
4 | * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd | ||
5 | * | ||
6 | * Author: Chris Zhong <zyw@rock-chips.com> | ||
7 | * Author: Zhang Qing <zhangqing@rock-chips.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms and conditions of the GNU General Public License, | ||
11 | * version 2, as published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/rtc.h> | ||
22 | #include <linux/bcd.h> | ||
23 | #include <linux/mfd/rk808.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/i2c.h> | ||
26 | |||
27 | /* RTC_CTRL_REG bitfields */ | ||
28 | #define BIT_RTC_CTRL_REG_STOP_RTC_M BIT(0) | ||
29 | |||
30 | /* RK808 has a shadowed register for saving a "frozen" RTC time. | ||
31 | * When user setting "GET_TIME" to 1, the time will save in this shadowed | ||
32 | * register. If set "READSEL" to 1, user read rtc time register, actually | ||
33 | * get the time of that moment. If we need the real time, clr this bit. | ||
34 | */ | ||
35 | #define BIT_RTC_CTRL_REG_RTC_GET_TIME BIT(6) | ||
36 | #define BIT_RTC_CTRL_REG_RTC_READSEL_M BIT(7) | ||
37 | #define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M BIT(3) | ||
38 | #define RTC_STATUS_MASK 0xFE | ||
39 | |||
40 | #define SECONDS_REG_MSK 0x7F | ||
41 | #define MINUTES_REG_MAK 0x7F | ||
42 | #define HOURS_REG_MSK 0x3F | ||
43 | #define DAYS_REG_MSK 0x3F | ||
44 | #define MONTHS_REG_MSK 0x1F | ||
45 | #define YEARS_REG_MSK 0xFF | ||
46 | #define WEEKS_REG_MSK 0x7 | ||
47 | |||
48 | /* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */ | ||
49 | |||
50 | #define NUM_TIME_REGS (RK808_WEEKS_REG - RK808_SECONDS_REG + 1) | ||
51 | #define NUM_ALARM_REGS (RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1) | ||
52 | |||
53 | struct rk808_rtc { | ||
54 | struct rk808 *rk808; | ||
55 | struct rtc_device *rtc; | ||
56 | int irq; | ||
57 | }; | ||
58 | |||
59 | /* Read current time and date in RTC */ | ||
60 | static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) | ||
61 | { | ||
62 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); | ||
63 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
64 | u8 rtc_data[NUM_TIME_REGS]; | ||
65 | int ret; | ||
66 | |||
67 | /* Force an update of the shadowed registers right now */ | ||
68 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | ||
69 | BIT_RTC_CTRL_REG_RTC_GET_TIME, | ||
70 | 0); | ||
71 | if (ret) { | ||
72 | dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret); | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | ||
77 | BIT_RTC_CTRL_REG_RTC_GET_TIME, | ||
78 | BIT_RTC_CTRL_REG_RTC_GET_TIME); | ||
79 | if (ret) { | ||
80 | dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG, | ||
85 | rtc_data, NUM_TIME_REGS); | ||
86 | if (ret) { | ||
87 | dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret); | ||
88 | return ret; | ||
89 | } | ||
90 | |||
91 | tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK); | ||
92 | tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK); | ||
93 | tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK); | ||
94 | tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK); | ||
95 | tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1; | ||
96 | tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100; | ||
97 | tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK); | ||
98 | dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | ||
99 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | ||
100 | tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec); | ||
101 | |||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | /* Set current time and date in RTC */ | ||
106 | static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
107 | { | ||
108 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); | ||
109 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
110 | u8 rtc_data[NUM_TIME_REGS]; | ||
111 | int ret; | ||
112 | |||
113 | rtc_data[0] = bin2bcd(tm->tm_sec); | ||
114 | rtc_data[1] = bin2bcd(tm->tm_min); | ||
115 | rtc_data[2] = bin2bcd(tm->tm_hour); | ||
116 | rtc_data[3] = bin2bcd(tm->tm_mday); | ||
117 | rtc_data[4] = bin2bcd(tm->tm_mon + 1); | ||
118 | rtc_data[5] = bin2bcd(tm->tm_year - 100); | ||
119 | rtc_data[6] = bin2bcd(tm->tm_wday); | ||
120 | dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | ||
121 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | ||
122 | tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec); | ||
123 | |||
124 | /* Stop RTC while updating the RTC registers */ | ||
125 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | ||
126 | BIT_RTC_CTRL_REG_STOP_RTC_M, | ||
127 | BIT_RTC_CTRL_REG_STOP_RTC_M); | ||
128 | if (ret) { | ||
129 | dev_err(dev, "Failed to update RTC control: %d\n", ret); | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG, | ||
134 | rtc_data, NUM_TIME_REGS); | ||
135 | if (ret) { | ||
136 | dev_err(dev, "Failed to bull write rtc_data: %d\n", ret); | ||
137 | return ret; | ||
138 | } | ||
139 | /* Start RTC again */ | ||
140 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | ||
141 | BIT_RTC_CTRL_REG_STOP_RTC_M, 0); | ||
142 | if (ret) { | ||
143 | dev_err(dev, "Failed to update RTC control: %d\n", ret); | ||
144 | return ret; | ||
145 | } | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | /* Read alarm time and date in RTC */ | ||
150 | static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
151 | { | ||
152 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); | ||
153 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
154 | u8 alrm_data[NUM_ALARM_REGS]; | ||
155 | uint32_t int_reg; | ||
156 | int ret; | ||
157 | |||
158 | ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG, | ||
159 | alrm_data, NUM_ALARM_REGS); | ||
160 | |||
161 | alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK); | ||
162 | alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK); | ||
163 | alrm->time.tm_hour = bcd2bin(alrm_data[2] & HOURS_REG_MSK); | ||
164 | alrm->time.tm_mday = bcd2bin(alrm_data[3] & DAYS_REG_MSK); | ||
165 | alrm->time.tm_mon = (bcd2bin(alrm_data[4] & MONTHS_REG_MSK)) - 1; | ||
166 | alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100; | ||
167 | |||
168 | ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg); | ||
169 | if (ret) { | ||
170 | dev_err(dev, "Failed to read RTC INT REG: %d\n", ret); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | dev_dbg(dev, "alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | ||
175 | 1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, | ||
176 | alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, | ||
177 | alrm->time.tm_min, alrm->time.tm_sec); | ||
178 | |||
179 | alrm->enabled = (int_reg & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M) ? 1 : 0; | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc) | ||
185 | { | ||
186 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
187 | int ret; | ||
188 | |||
189 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG, | ||
190 | BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0); | ||
191 | |||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc) | ||
196 | { | ||
197 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
198 | int ret; | ||
199 | |||
200 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG, | ||
201 | BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, | ||
202 | BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); | ||
203 | |||
204 | return ret; | ||
205 | } | ||
206 | |||
207 | static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
208 | { | ||
209 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); | ||
210 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
211 | u8 alrm_data[NUM_ALARM_REGS]; | ||
212 | int ret; | ||
213 | |||
214 | ret = rk808_rtc_stop_alarm(rk808_rtc); | ||
215 | if (ret) { | ||
216 | dev_err(dev, "Failed to stop alarm: %d\n", ret); | ||
217 | return ret; | ||
218 | } | ||
219 | dev_dbg(dev, "alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | ||
220 | 1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, | ||
221 | alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, | ||
222 | alrm->time.tm_min, alrm->time.tm_sec); | ||
223 | |||
224 | alrm_data[0] = bin2bcd(alrm->time.tm_sec); | ||
225 | alrm_data[1] = bin2bcd(alrm->time.tm_min); | ||
226 | alrm_data[2] = bin2bcd(alrm->time.tm_hour); | ||
227 | alrm_data[3] = bin2bcd(alrm->time.tm_mday); | ||
228 | alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1); | ||
229 | alrm_data[5] = bin2bcd(alrm->time.tm_year - 100); | ||
230 | |||
231 | ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG, | ||
232 | alrm_data, NUM_ALARM_REGS); | ||
233 | if (ret) { | ||
234 | dev_err(dev, "Failed to bulk write: %d\n", ret); | ||
235 | return ret; | ||
236 | } | ||
237 | if (alrm->enabled) { | ||
238 | ret = rk808_rtc_start_alarm(rk808_rtc); | ||
239 | if (ret) { | ||
240 | dev_err(dev, "Failed to start alarm: %d\n", ret); | ||
241 | return ret; | ||
242 | } | ||
243 | } | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int rk808_rtc_alarm_irq_enable(struct device *dev, | ||
248 | unsigned int enabled) | ||
249 | { | ||
250 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); | ||
251 | |||
252 | if (enabled) | ||
253 | return rk808_rtc_start_alarm(rk808_rtc); | ||
254 | |||
255 | return rk808_rtc_stop_alarm(rk808_rtc); | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * We will just handle setting the frequency and make use the framework for | ||
260 | * reading the periodic interupts. | ||
261 | * | ||
262 | * @freq: Current periodic IRQ freq: | ||
263 | * bit 0: every second | ||
264 | * bit 1: every minute | ||
265 | * bit 2: every hour | ||
266 | * bit 3: every day | ||
267 | */ | ||
268 | static irqreturn_t rk808_alarm_irq(int irq, void *data) | ||
269 | { | ||
270 | struct rk808_rtc *rk808_rtc = data; | ||
271 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
272 | struct i2c_client *client = rk808->i2c; | ||
273 | int ret; | ||
274 | |||
275 | ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG, | ||
276 | RTC_STATUS_MASK); | ||
277 | if (ret) { | ||
278 | dev_err(&client->dev, | ||
279 | "%s:Failed to update RTC status: %d\n", __func__, ret); | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
284 | dev_dbg(&client->dev, | ||
285 | "%s:irq=%d\n", __func__, irq); | ||
286 | return IRQ_HANDLED; | ||
287 | } | ||
288 | |||
289 | static const struct rtc_class_ops rk808_rtc_ops = { | ||
290 | .read_time = rk808_rtc_readtime, | ||
291 | .set_time = rk808_rtc_set_time, | ||
292 | .read_alarm = rk808_rtc_readalarm, | ||
293 | .set_alarm = rk808_rtc_setalarm, | ||
294 | .alarm_irq_enable = rk808_rtc_alarm_irq_enable, | ||
295 | }; | ||
296 | |||
297 | #ifdef CONFIG_PM_SLEEP | ||
298 | /* Turn off the alarm if it should not be a wake source. */ | ||
299 | static int rk808_rtc_suspend(struct device *dev) | ||
300 | { | ||
301 | struct platform_device *pdev = to_platform_device(dev); | ||
302 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev); | ||
303 | |||
304 | if (device_may_wakeup(dev)) | ||
305 | enable_irq_wake(rk808_rtc->irq); | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | /* Enable the alarm if it should be enabled (in case it was disabled to | ||
311 | * prevent use as a wake source). | ||
312 | */ | ||
313 | static int rk808_rtc_resume(struct device *dev) | ||
314 | { | ||
315 | struct platform_device *pdev = to_platform_device(dev); | ||
316 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev); | ||
317 | |||
318 | if (device_may_wakeup(dev)) | ||
319 | disable_irq_wake(rk808_rtc->irq); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | #endif | ||
324 | |||
325 | static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops, | ||
326 | rk808_rtc_suspend, rk808_rtc_resume); | ||
327 | |||
328 | static int rk808_rtc_probe(struct platform_device *pdev) | ||
329 | { | ||
330 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); | ||
331 | struct rk808_rtc *rk808_rtc; | ||
332 | struct rtc_time tm; | ||
333 | int ret; | ||
334 | |||
335 | rk808_rtc = devm_kzalloc(&pdev->dev, sizeof(*rk808_rtc), GFP_KERNEL); | ||
336 | if (rk808_rtc == NULL) | ||
337 | return -ENOMEM; | ||
338 | |||
339 | platform_set_drvdata(pdev, rk808_rtc); | ||
340 | rk808_rtc->rk808 = rk808; | ||
341 | |||
342 | /* start rtc running by default, and use shadowed timer. */ | ||
343 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | ||
344 | BIT_RTC_CTRL_REG_STOP_RTC_M | | ||
345 | BIT_RTC_CTRL_REG_RTC_READSEL_M, | ||
346 | BIT_RTC_CTRL_REG_RTC_READSEL_M); | ||
347 | if (ret) { | ||
348 | dev_err(&pdev->dev, | ||
349 | "Failed to update RTC control: %d\n", ret); | ||
350 | return ret; | ||
351 | } | ||
352 | |||
353 | ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG, | ||
354 | RTC_STATUS_MASK); | ||
355 | if (ret) { | ||
356 | dev_err(&pdev->dev, | ||
357 | "Failed to write RTC status: %d\n", ret); | ||
358 | return ret; | ||
359 | } | ||
360 | |||
361 | /* set init time */ | ||
362 | ret = rk808_rtc_readtime(&pdev->dev, &tm); | ||
363 | if (ret) { | ||
364 | dev_err(&pdev->dev, "Failed to read RTC time\n"); | ||
365 | return ret; | ||
366 | } | ||
367 | ret = rtc_valid_tm(&tm); | ||
368 | if (ret) | ||
369 | dev_warn(&pdev->dev, "invalid date/time\n"); | ||
370 | |||
371 | device_init_wakeup(&pdev->dev, 1); | ||
372 | |||
373 | rk808_rtc->rtc = devm_rtc_device_register(&pdev->dev, "rk808-rtc", | ||
374 | &rk808_rtc_ops, THIS_MODULE); | ||
375 | if (IS_ERR(rk808_rtc->rtc)) { | ||
376 | ret = PTR_ERR(rk808_rtc->rtc); | ||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | rk808_rtc->irq = platform_get_irq(pdev, 0); | ||
381 | if (rk808_rtc->irq < 0) { | ||
382 | if (rk808_rtc->irq != -EPROBE_DEFER) | ||
383 | dev_err(&pdev->dev, "Wake up is not possible as irq = %d\n", | ||
384 | rk808_rtc->irq); | ||
385 | return rk808_rtc->irq; | ||
386 | } | ||
387 | |||
388 | /* request alarm irq of rk808 */ | ||
389 | ret = devm_request_threaded_irq(&pdev->dev, rk808_rtc->irq, NULL, | ||
390 | rk808_alarm_irq, 0, | ||
391 | "RTC alarm", rk808_rtc); | ||
392 | if (ret) { | ||
393 | dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", | ||
394 | rk808_rtc->irq, ret); | ||
395 | } | ||
396 | |||
397 | return ret; | ||
398 | } | ||
399 | |||
400 | static struct platform_driver rk808_rtc_driver = { | ||
401 | .probe = rk808_rtc_probe, | ||
402 | .driver = { | ||
403 | .name = "rk808-rtc", | ||
404 | .pm = &rk808_rtc_pm_ops, | ||
405 | }, | ||
406 | }; | ||
407 | |||
408 | module_platform_driver(rk808_rtc_driver); | ||
409 | |||
410 | MODULE_DESCRIPTION("RTC driver for the rk808 series PMICs"); | ||
411 | MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); | ||
412 | MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); | ||
413 | MODULE_LICENSE("GPL"); | ||
414 | MODULE_ALIAS("platform:rk808-rtc"); | ||
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index ccf54f06396b..28871cd7e3b5 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -142,12 +142,11 @@ static int rs5c_get_regs(struct rs5c372 *rs5c) | |||
142 | } | 142 | } |
143 | 143 | ||
144 | dev_dbg(&client->dev, | 144 | dev_dbg(&client->dev, |
145 | "%02x %02x %02x (%02x) %02x %02x %02x (%02x), " | 145 | "%3ph (%02x) %3ph (%02x), %3ph, %3ph; %02x %02x\n", |
146 | "%02x %02x %02x, %02x %02x %02x; %02x %02x\n", | 146 | rs5c->regs + 0, rs5c->regs[3], |
147 | rs5c->regs[0], rs5c->regs[1], rs5c->regs[2], rs5c->regs[3], | 147 | rs5c->regs + 4, rs5c->regs[7], |
148 | rs5c->regs[4], rs5c->regs[5], rs5c->regs[6], rs5c->regs[7], | 148 | rs5c->regs + 8, rs5c->regs + 11, |
149 | rs5c->regs[8], rs5c->regs[9], rs5c->regs[10], rs5c->regs[11], | 149 | rs5c->regs[14], rs5c->regs[15]); |
150 | rs5c->regs[12], rs5c->regs[13], rs5c->regs[14], rs5c->regs[15]); | ||
151 | 150 | ||
152 | return 0; | 151 | return 0; |
153 | } | 152 | } |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 4958a363b2c7..a6b1252c9941 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -32,155 +32,150 @@ | |||
32 | #include <asm/irq.h> | 32 | #include <asm/irq.h> |
33 | #include "rtc-s3c.h" | 33 | #include "rtc-s3c.h" |
34 | 34 | ||
35 | enum s3c_cpu_type { | 35 | struct s3c_rtc { |
36 | TYPE_S3C2410, | 36 | struct device *dev; |
37 | TYPE_S3C2416, | 37 | struct rtc_device *rtc; |
38 | TYPE_S3C2443, | ||
39 | TYPE_S3C64XX, | ||
40 | }; | ||
41 | 38 | ||
42 | struct s3c_rtc_drv_data { | 39 | void __iomem *base; |
43 | int cpu_type; | 40 | struct clk *rtc_clk; |
44 | }; | 41 | struct clk *rtc_src_clk; |
42 | bool enabled; | ||
43 | |||
44 | struct s3c_rtc_data *data; | ||
45 | 45 | ||
46 | /* I have yet to find an S3C implementation with more than one | 46 | int irq_alarm; |
47 | * of these rtc blocks in */ | 47 | int irq_tick; |
48 | 48 | ||
49 | static struct clk *rtc_clk; | 49 | spinlock_t pie_lock; |
50 | static void __iomem *s3c_rtc_base; | 50 | spinlock_t alarm_clk_lock; |
51 | static int s3c_rtc_alarmno; | ||
52 | static int s3c_rtc_tickno; | ||
53 | static enum s3c_cpu_type s3c_rtc_cpu_type; | ||
54 | 51 | ||
55 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); | 52 | int ticnt_save, ticnt_en_save; |
53 | bool wake_en; | ||
54 | }; | ||
55 | |||
56 | struct s3c_rtc_data { | ||
57 | int max_user_freq; | ||
58 | bool needs_src_clk; | ||
59 | |||
60 | void (*irq_handler) (struct s3c_rtc *info, int mask); | ||
61 | void (*set_freq) (struct s3c_rtc *info, int freq); | ||
62 | void (*enable_tick) (struct s3c_rtc *info, struct seq_file *seq); | ||
63 | void (*select_tick_clk) (struct s3c_rtc *info); | ||
64 | void (*save_tick_cnt) (struct s3c_rtc *info); | ||
65 | void (*restore_tick_cnt) (struct s3c_rtc *info); | ||
66 | void (*enable) (struct s3c_rtc *info); | ||
67 | void (*disable) (struct s3c_rtc *info); | ||
68 | }; | ||
56 | 69 | ||
57 | static void s3c_rtc_alarm_clk_enable(bool enable) | 70 | static void s3c_rtc_alarm_clk_enable(struct s3c_rtc *info, bool enable) |
58 | { | 71 | { |
59 | static DEFINE_SPINLOCK(s3c_rtc_alarm_clk_lock); | ||
60 | static bool alarm_clk_enabled; | ||
61 | unsigned long irq_flags; | 72 | unsigned long irq_flags; |
62 | 73 | ||
63 | spin_lock_irqsave(&s3c_rtc_alarm_clk_lock, irq_flags); | 74 | spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); |
64 | if (enable) { | 75 | if (enable) { |
65 | if (!alarm_clk_enabled) { | 76 | if (!info->enabled) { |
66 | clk_enable(rtc_clk); | 77 | clk_enable(info->rtc_clk); |
67 | alarm_clk_enabled = true; | 78 | if (info->data->needs_src_clk) |
79 | clk_enable(info->rtc_src_clk); | ||
80 | info->enabled = true; | ||
68 | } | 81 | } |
69 | } else { | 82 | } else { |
70 | if (alarm_clk_enabled) { | 83 | if (info->enabled) { |
71 | clk_disable(rtc_clk); | 84 | if (info->data->needs_src_clk) |
72 | alarm_clk_enabled = false; | 85 | clk_disable(info->rtc_src_clk); |
86 | clk_disable(info->rtc_clk); | ||
87 | info->enabled = false; | ||
73 | } | 88 | } |
74 | } | 89 | } |
75 | spin_unlock_irqrestore(&s3c_rtc_alarm_clk_lock, irq_flags); | 90 | spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); |
76 | } | 91 | } |
77 | 92 | ||
78 | /* IRQ Handlers */ | 93 | /* IRQ Handlers */ |
79 | 94 | static irqreturn_t s3c_rtc_tickirq(int irq, void *id) | |
80 | static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) | ||
81 | { | 95 | { |
82 | struct rtc_device *rdev = id; | 96 | struct s3c_rtc *info = (struct s3c_rtc *)id; |
83 | |||
84 | clk_enable(rtc_clk); | ||
85 | rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); | ||
86 | |||
87 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | ||
88 | writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP); | ||
89 | |||
90 | clk_disable(rtc_clk); | ||
91 | 97 | ||
92 | s3c_rtc_alarm_clk_enable(false); | 98 | if (info->data->irq_handler) |
99 | info->data->irq_handler(info, S3C2410_INTP_TIC); | ||
93 | 100 | ||
94 | return IRQ_HANDLED; | 101 | return IRQ_HANDLED; |
95 | } | 102 | } |
96 | 103 | ||
97 | static irqreturn_t s3c_rtc_tickirq(int irq, void *id) | 104 | static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) |
98 | { | 105 | { |
99 | struct rtc_device *rdev = id; | 106 | struct s3c_rtc *info = (struct s3c_rtc *)id; |
100 | 107 | ||
101 | clk_enable(rtc_clk); | 108 | if (info->data->irq_handler) |
102 | rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); | 109 | info->data->irq_handler(info, S3C2410_INTP_ALM); |
103 | 110 | ||
104 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | ||
105 | writeb(S3C2410_INTP_TIC, s3c_rtc_base + S3C2410_INTP); | ||
106 | |||
107 | clk_disable(rtc_clk); | ||
108 | return IRQ_HANDLED; | 111 | return IRQ_HANDLED; |
109 | } | 112 | } |
110 | 113 | ||
111 | /* Update control registers */ | 114 | /* Update control registers */ |
112 | static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) | 115 | static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) |
113 | { | 116 | { |
117 | struct s3c_rtc *info = dev_get_drvdata(dev); | ||
114 | unsigned int tmp; | 118 | unsigned int tmp; |
115 | 119 | ||
116 | dev_dbg(dev, "%s: aie=%d\n", __func__, enabled); | 120 | dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled); |
117 | 121 | ||
118 | clk_enable(rtc_clk); | 122 | clk_enable(info->rtc_clk); |
119 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | 123 | if (info->data->needs_src_clk) |
124 | clk_enable(info->rtc_src_clk); | ||
125 | tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | ||
120 | 126 | ||
121 | if (enabled) | 127 | if (enabled) |
122 | tmp |= S3C2410_RTCALM_ALMEN; | 128 | tmp |= S3C2410_RTCALM_ALMEN; |
123 | 129 | ||
124 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); | 130 | writeb(tmp, info->base + S3C2410_RTCALM); |
125 | clk_disable(rtc_clk); | 131 | if (info->data->needs_src_clk) |
132 | clk_disable(info->rtc_src_clk); | ||
133 | clk_disable(info->rtc_clk); | ||
126 | 134 | ||
127 | s3c_rtc_alarm_clk_enable(enabled); | 135 | s3c_rtc_alarm_clk_enable(info, enabled); |
128 | 136 | ||
129 | return 0; | 137 | return 0; |
130 | } | 138 | } |
131 | 139 | ||
132 | static int s3c_rtc_setfreq(struct device *dev, int freq) | 140 | /* Set RTC frequency */ |
141 | static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq) | ||
133 | { | 142 | { |
134 | struct platform_device *pdev = to_platform_device(dev); | ||
135 | struct rtc_device *rtc_dev = platform_get_drvdata(pdev); | ||
136 | unsigned int tmp = 0; | ||
137 | int val; | ||
138 | |||
139 | if (!is_power_of_2(freq)) | 143 | if (!is_power_of_2(freq)) |
140 | return -EINVAL; | 144 | return -EINVAL; |
141 | 145 | ||
142 | clk_enable(rtc_clk); | 146 | clk_enable(info->rtc_clk); |
143 | spin_lock_irq(&s3c_rtc_pie_lock); | 147 | if (info->data->needs_src_clk) |
148 | clk_enable(info->rtc_src_clk); | ||
149 | spin_lock_irq(&info->pie_lock); | ||
144 | 150 | ||
145 | if (s3c_rtc_cpu_type != TYPE_S3C64XX) { | 151 | if (info->data->set_freq) |
146 | tmp = readb(s3c_rtc_base + S3C2410_TICNT); | 152 | info->data->set_freq(info, freq); |
147 | tmp &= S3C2410_TICNT_ENABLE; | ||
148 | } | ||
149 | 153 | ||
150 | val = (rtc_dev->max_user_freq / freq) - 1; | 154 | spin_unlock_irq(&info->pie_lock); |
151 | 155 | if (info->data->needs_src_clk) | |
152 | if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { | 156 | clk_disable(info->rtc_src_clk); |
153 | tmp |= S3C2443_TICNT_PART(val); | 157 | clk_disable(info->rtc_clk); |
154 | writel(S3C2443_TICNT1_PART(val), s3c_rtc_base + S3C2443_TICNT1); | ||
155 | |||
156 | if (s3c_rtc_cpu_type == TYPE_S3C2416) | ||
157 | writel(S3C2416_TICNT2_PART(val), s3c_rtc_base + S3C2416_TICNT2); | ||
158 | } else { | ||
159 | tmp |= val; | ||
160 | } | ||
161 | |||
162 | writel(tmp, s3c_rtc_base + S3C2410_TICNT); | ||
163 | spin_unlock_irq(&s3c_rtc_pie_lock); | ||
164 | clk_disable(rtc_clk); | ||
165 | 158 | ||
166 | return 0; | 159 | return 0; |
167 | } | 160 | } |
168 | 161 | ||
169 | /* Time read/write */ | 162 | /* Time read/write */ |
170 | |||
171 | static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | 163 | static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) |
172 | { | 164 | { |
165 | struct s3c_rtc *info = dev_get_drvdata(dev); | ||
173 | unsigned int have_retried = 0; | 166 | unsigned int have_retried = 0; |
174 | void __iomem *base = s3c_rtc_base; | ||
175 | 167 | ||
176 | clk_enable(rtc_clk); | 168 | clk_enable(info->rtc_clk); |
169 | if (info->data->needs_src_clk) | ||
170 | clk_enable(info->rtc_src_clk); | ||
171 | |||
177 | retry_get_time: | 172 | retry_get_time: |
178 | rtc_tm->tm_min = readb(base + S3C2410_RTCMIN); | 173 | rtc_tm->tm_min = readb(info->base + S3C2410_RTCMIN); |
179 | rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR); | 174 | rtc_tm->tm_hour = readb(info->base + S3C2410_RTCHOUR); |
180 | rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE); | 175 | rtc_tm->tm_mday = readb(info->base + S3C2410_RTCDATE); |
181 | rtc_tm->tm_mon = readb(base + S3C2410_RTCMON); | 176 | rtc_tm->tm_mon = readb(info->base + S3C2410_RTCMON); |
182 | rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR); | 177 | rtc_tm->tm_year = readb(info->base + S3C2410_RTCYEAR); |
183 | rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC); | 178 | rtc_tm->tm_sec = readb(info->base + S3C2410_RTCSEC); |
184 | 179 | ||
185 | /* the only way to work out whether the system was mid-update | 180 | /* the only way to work out whether the system was mid-update |
186 | * when we read it is to check the second counter, and if it | 181 | * when we read it is to check the second counter, and if it |
@@ -207,13 +202,16 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
207 | 202 | ||
208 | rtc_tm->tm_mon -= 1; | 203 | rtc_tm->tm_mon -= 1; |
209 | 204 | ||
210 | clk_disable(rtc_clk); | 205 | if (info->data->needs_src_clk) |
206 | clk_disable(info->rtc_src_clk); | ||
207 | clk_disable(info->rtc_clk); | ||
208 | |||
211 | return rtc_valid_tm(rtc_tm); | 209 | return rtc_valid_tm(rtc_tm); |
212 | } | 210 | } |
213 | 211 | ||
214 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | 212 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) |
215 | { | 213 | { |
216 | void __iomem *base = s3c_rtc_base; | 214 | struct s3c_rtc *info = dev_get_drvdata(dev); |
217 | int year = tm->tm_year - 100; | 215 | int year = tm->tm_year - 100; |
218 | 216 | ||
219 | dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n", | 217 | dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n", |
@@ -227,33 +225,42 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
227 | return -EINVAL; | 225 | return -EINVAL; |
228 | } | 226 | } |
229 | 227 | ||
230 | clk_enable(rtc_clk); | 228 | clk_enable(info->rtc_clk); |
231 | writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); | 229 | if (info->data->needs_src_clk) |
232 | writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); | 230 | clk_enable(info->rtc_src_clk); |
233 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); | 231 | |
234 | writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE); | 232 | writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_RTCSEC); |
235 | writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON); | 233 | writeb(bin2bcd(tm->tm_min), info->base + S3C2410_RTCMIN); |
236 | writeb(bin2bcd(year), base + S3C2410_RTCYEAR); | 234 | writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_RTCHOUR); |
237 | clk_disable(rtc_clk); | 235 | writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_RTCDATE); |
236 | writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_RTCMON); | ||
237 | writeb(bin2bcd(year), info->base + S3C2410_RTCYEAR); | ||
238 | |||
239 | if (info->data->needs_src_clk) | ||
240 | clk_disable(info->rtc_src_clk); | ||
241 | clk_disable(info->rtc_clk); | ||
238 | 242 | ||
239 | return 0; | 243 | return 0; |
240 | } | 244 | } |
241 | 245 | ||
242 | static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | 246 | static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) |
243 | { | 247 | { |
248 | struct s3c_rtc *info = dev_get_drvdata(dev); | ||
244 | struct rtc_time *alm_tm = &alrm->time; | 249 | struct rtc_time *alm_tm = &alrm->time; |
245 | void __iomem *base = s3c_rtc_base; | ||
246 | unsigned int alm_en; | 250 | unsigned int alm_en; |
247 | 251 | ||
248 | clk_enable(rtc_clk); | 252 | clk_enable(info->rtc_clk); |
249 | alm_tm->tm_sec = readb(base + S3C2410_ALMSEC); | 253 | if (info->data->needs_src_clk) |
250 | alm_tm->tm_min = readb(base + S3C2410_ALMMIN); | 254 | clk_enable(info->rtc_src_clk); |
251 | alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR); | ||
252 | alm_tm->tm_mon = readb(base + S3C2410_ALMMON); | ||
253 | alm_tm->tm_mday = readb(base + S3C2410_ALMDATE); | ||
254 | alm_tm->tm_year = readb(base + S3C2410_ALMYEAR); | ||
255 | 255 | ||
256 | alm_en = readb(base + S3C2410_RTCALM); | 256 | alm_tm->tm_sec = readb(info->base + S3C2410_ALMSEC); |
257 | alm_tm->tm_min = readb(info->base + S3C2410_ALMMIN); | ||
258 | alm_tm->tm_hour = readb(info->base + S3C2410_ALMHOUR); | ||
259 | alm_tm->tm_mon = readb(info->base + S3C2410_ALMMON); | ||
260 | alm_tm->tm_mday = readb(info->base + S3C2410_ALMDATE); | ||
261 | alm_tm->tm_year = readb(info->base + S3C2410_ALMYEAR); | ||
262 | |||
263 | alm_en = readb(info->base + S3C2410_RTCALM); | ||
257 | 264 | ||
258 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; | 265 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; |
259 | 266 | ||
@@ -297,65 +304,74 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
297 | else | 304 | else |
298 | alm_tm->tm_year = -1; | 305 | alm_tm->tm_year = -1; |
299 | 306 | ||
300 | clk_disable(rtc_clk); | 307 | if (info->data->needs_src_clk) |
308 | clk_disable(info->rtc_src_clk); | ||
309 | clk_disable(info->rtc_clk); | ||
310 | |||
301 | return 0; | 311 | return 0; |
302 | } | 312 | } |
303 | 313 | ||
304 | static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | 314 | static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) |
305 | { | 315 | { |
316 | struct s3c_rtc *info = dev_get_drvdata(dev); | ||
306 | struct rtc_time *tm = &alrm->time; | 317 | struct rtc_time *tm = &alrm->time; |
307 | void __iomem *base = s3c_rtc_base; | ||
308 | unsigned int alrm_en; | 318 | unsigned int alrm_en; |
309 | 319 | ||
310 | clk_enable(rtc_clk); | 320 | clk_enable(info->rtc_clk); |
321 | if (info->data->needs_src_clk) | ||
322 | clk_enable(info->rtc_src_clk); | ||
323 | |||
311 | dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", | 324 | dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", |
312 | alrm->enabled, | 325 | alrm->enabled, |
313 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | 326 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, |
314 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 327 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
315 | 328 | ||
316 | alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; | 329 | alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; |
317 | writeb(0x00, base + S3C2410_RTCALM); | 330 | writeb(0x00, info->base + S3C2410_RTCALM); |
318 | 331 | ||
319 | if (tm->tm_sec < 60 && tm->tm_sec >= 0) { | 332 | if (tm->tm_sec < 60 && tm->tm_sec >= 0) { |
320 | alrm_en |= S3C2410_RTCALM_SECEN; | 333 | alrm_en |= S3C2410_RTCALM_SECEN; |
321 | writeb(bin2bcd(tm->tm_sec), base + S3C2410_ALMSEC); | 334 | writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_ALMSEC); |
322 | } | 335 | } |
323 | 336 | ||
324 | if (tm->tm_min < 60 && tm->tm_min >= 0) { | 337 | if (tm->tm_min < 60 && tm->tm_min >= 0) { |
325 | alrm_en |= S3C2410_RTCALM_MINEN; | 338 | alrm_en |= S3C2410_RTCALM_MINEN; |
326 | writeb(bin2bcd(tm->tm_min), base + S3C2410_ALMMIN); | 339 | writeb(bin2bcd(tm->tm_min), info->base + S3C2410_ALMMIN); |
327 | } | 340 | } |
328 | 341 | ||
329 | if (tm->tm_hour < 24 && tm->tm_hour >= 0) { | 342 | if (tm->tm_hour < 24 && tm->tm_hour >= 0) { |
330 | alrm_en |= S3C2410_RTCALM_HOUREN; | 343 | alrm_en |= S3C2410_RTCALM_HOUREN; |
331 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR); | 344 | writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_ALMHOUR); |
332 | } | 345 | } |
333 | 346 | ||
334 | dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en); | 347 | dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en); |
335 | 348 | ||
336 | writeb(alrm_en, base + S3C2410_RTCALM); | 349 | writeb(alrm_en, info->base + S3C2410_RTCALM); |
337 | 350 | ||
338 | s3c_rtc_setaie(dev, alrm->enabled); | 351 | s3c_rtc_setaie(dev, alrm->enabled); |
339 | 352 | ||
340 | clk_disable(rtc_clk); | 353 | if (info->data->needs_src_clk) |
354 | clk_disable(info->rtc_src_clk); | ||
355 | clk_disable(info->rtc_clk); | ||
356 | |||
341 | return 0; | 357 | return 0; |
342 | } | 358 | } |
343 | 359 | ||
344 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | 360 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) |
345 | { | 361 | { |
346 | unsigned int ticnt; | 362 | struct s3c_rtc *info = dev_get_drvdata(dev); |
347 | 363 | ||
348 | clk_enable(rtc_clk); | 364 | clk_enable(info->rtc_clk); |
349 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 365 | if (info->data->needs_src_clk) |
350 | ticnt = readw(s3c_rtc_base + S3C2410_RTCCON); | 366 | clk_enable(info->rtc_src_clk); |
351 | ticnt &= S3C64XX_RTCCON_TICEN; | 367 | |
352 | } else { | 368 | if (info->data->enable_tick) |
353 | ticnt = readb(s3c_rtc_base + S3C2410_TICNT); | 369 | info->data->enable_tick(info, seq); |
354 | ticnt &= S3C2410_TICNT_ENABLE; | 370 | |
355 | } | 371 | if (info->data->needs_src_clk) |
372 | clk_disable(info->rtc_src_clk); | ||
373 | clk_disable(info->rtc_clk); | ||
356 | 374 | ||
357 | seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); | ||
358 | clk_disable(rtc_clk); | ||
359 | return 0; | 375 | return 0; |
360 | } | 376 | } |
361 | 377 | ||
@@ -368,152 +384,199 @@ static const struct rtc_class_ops s3c_rtcops = { | |||
368 | .alarm_irq_enable = s3c_rtc_setaie, | 384 | .alarm_irq_enable = s3c_rtc_setaie, |
369 | }; | 385 | }; |
370 | 386 | ||
371 | static void s3c_rtc_enable(struct platform_device *pdev, int en) | 387 | static void s3c24xx_rtc_enable(struct s3c_rtc *info) |
372 | { | 388 | { |
373 | void __iomem *base = s3c_rtc_base; | 389 | unsigned int con, tmp; |
374 | unsigned int tmp; | ||
375 | 390 | ||
376 | if (s3c_rtc_base == NULL) | 391 | clk_enable(info->rtc_clk); |
377 | return; | 392 | if (info->data->needs_src_clk) |
378 | 393 | clk_enable(info->rtc_src_clk); | |
379 | clk_enable(rtc_clk); | ||
380 | if (!en) { | ||
381 | tmp = readw(base + S3C2410_RTCCON); | ||
382 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | ||
383 | tmp &= ~S3C64XX_RTCCON_TICEN; | ||
384 | tmp &= ~S3C2410_RTCCON_RTCEN; | ||
385 | writew(tmp, base + S3C2410_RTCCON); | ||
386 | |||
387 | if (s3c_rtc_cpu_type != TYPE_S3C64XX) { | ||
388 | tmp = readb(base + S3C2410_TICNT); | ||
389 | tmp &= ~S3C2410_TICNT_ENABLE; | ||
390 | writeb(tmp, base + S3C2410_TICNT); | ||
391 | } | ||
392 | } else { | ||
393 | /* re-enable the device, and check it is ok */ | ||
394 | 394 | ||
395 | if ((readw(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0) { | 395 | con = readw(info->base + S3C2410_RTCCON); |
396 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); | 396 | /* re-enable the device, and check it is ok */ |
397 | if ((con & S3C2410_RTCCON_RTCEN) == 0) { | ||
398 | dev_info(info->dev, "rtc disabled, re-enabling\n"); | ||
397 | 399 | ||
398 | tmp = readw(base + S3C2410_RTCCON); | 400 | tmp = readw(info->base + S3C2410_RTCCON); |
399 | writew(tmp | S3C2410_RTCCON_RTCEN, | 401 | writew(tmp | S3C2410_RTCCON_RTCEN, |
400 | base + S3C2410_RTCCON); | 402 | info->base + S3C2410_RTCCON); |
401 | } | 403 | } |
402 | 404 | ||
403 | if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)) { | 405 | if (con & S3C2410_RTCCON_CNTSEL) { |
404 | dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); | 406 | dev_info(info->dev, "removing RTCCON_CNTSEL\n"); |
405 | 407 | ||
406 | tmp = readw(base + S3C2410_RTCCON); | 408 | tmp = readw(info->base + S3C2410_RTCCON); |
407 | writew(tmp & ~S3C2410_RTCCON_CNTSEL, | 409 | writew(tmp & ~S3C2410_RTCCON_CNTSEL, |
408 | base + S3C2410_RTCCON); | 410 | info->base + S3C2410_RTCCON); |
409 | } | 411 | } |
410 | 412 | ||
411 | if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)) { | 413 | if (con & S3C2410_RTCCON_CLKRST) { |
412 | dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); | 414 | dev_info(info->dev, "removing RTCCON_CLKRST\n"); |
413 | 415 | ||
414 | tmp = readw(base + S3C2410_RTCCON); | 416 | tmp = readw(info->base + S3C2410_RTCCON); |
415 | writew(tmp & ~S3C2410_RTCCON_CLKRST, | 417 | writew(tmp & ~S3C2410_RTCCON_CLKRST, |
416 | base + S3C2410_RTCCON); | 418 | info->base + S3C2410_RTCCON); |
417 | } | ||
418 | } | 419 | } |
419 | clk_disable(rtc_clk); | 420 | |
421 | if (info->data->needs_src_clk) | ||
422 | clk_disable(info->rtc_src_clk); | ||
423 | clk_disable(info->rtc_clk); | ||
420 | } | 424 | } |
421 | 425 | ||
422 | static int s3c_rtc_remove(struct platform_device *dev) | 426 | static void s3c24xx_rtc_disable(struct s3c_rtc *info) |
423 | { | 427 | { |
424 | s3c_rtc_setaie(&dev->dev, 0); | 428 | unsigned int con; |
429 | |||
430 | clk_enable(info->rtc_clk); | ||
431 | if (info->data->needs_src_clk) | ||
432 | clk_enable(info->rtc_src_clk); | ||
433 | |||
434 | con = readw(info->base + S3C2410_RTCCON); | ||
435 | con &= ~S3C2410_RTCCON_RTCEN; | ||
436 | writew(con, info->base + S3C2410_RTCCON); | ||
425 | 437 | ||
426 | clk_unprepare(rtc_clk); | 438 | con = readb(info->base + S3C2410_TICNT); |
427 | rtc_clk = NULL; | 439 | con &= ~S3C2410_TICNT_ENABLE; |
440 | writeb(con, info->base + S3C2410_TICNT); | ||
441 | |||
442 | if (info->data->needs_src_clk) | ||
443 | clk_disable(info->rtc_src_clk); | ||
444 | clk_disable(info->rtc_clk); | ||
445 | } | ||
446 | |||
447 | static void s3c6410_rtc_disable(struct s3c_rtc *info) | ||
448 | { | ||
449 | unsigned int con; | ||
450 | |||
451 | clk_enable(info->rtc_clk); | ||
452 | if (info->data->needs_src_clk) | ||
453 | clk_enable(info->rtc_src_clk); | ||
454 | |||
455 | con = readw(info->base + S3C2410_RTCCON); | ||
456 | con &= ~S3C64XX_RTCCON_TICEN; | ||
457 | con &= ~S3C2410_RTCCON_RTCEN; | ||
458 | writew(con, info->base + S3C2410_RTCCON); | ||
459 | |||
460 | if (info->data->needs_src_clk) | ||
461 | clk_disable(info->rtc_src_clk); | ||
462 | clk_disable(info->rtc_clk); | ||
463 | } | ||
464 | |||
465 | static int s3c_rtc_remove(struct platform_device *pdev) | ||
466 | { | ||
467 | struct s3c_rtc *info = platform_get_drvdata(pdev); | ||
468 | |||
469 | s3c_rtc_setaie(info->dev, 0); | ||
470 | |||
471 | clk_unprepare(info->rtc_clk); | ||
472 | info->rtc_clk = NULL; | ||
428 | 473 | ||
429 | return 0; | 474 | return 0; |
430 | } | 475 | } |
431 | 476 | ||
432 | static const struct of_device_id s3c_rtc_dt_match[]; | 477 | static const struct of_device_id s3c_rtc_dt_match[]; |
433 | 478 | ||
434 | static inline int s3c_rtc_get_driver_data(struct platform_device *pdev) | 479 | static struct s3c_rtc_data *s3c_rtc_get_data(struct platform_device *pdev) |
435 | { | 480 | { |
436 | #ifdef CONFIG_OF | 481 | const struct of_device_id *match; |
437 | struct s3c_rtc_drv_data *data; | 482 | |
438 | if (pdev->dev.of_node) { | 483 | match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); |
439 | const struct of_device_id *match; | 484 | return (struct s3c_rtc_data *)match->data; |
440 | match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); | ||
441 | data = (struct s3c_rtc_drv_data *) match->data; | ||
442 | return data->cpu_type; | ||
443 | } | ||
444 | #endif | ||
445 | return platform_get_device_id(pdev)->driver_data; | ||
446 | } | 485 | } |
447 | 486 | ||
448 | static int s3c_rtc_probe(struct platform_device *pdev) | 487 | static int s3c_rtc_probe(struct platform_device *pdev) |
449 | { | 488 | { |
450 | struct rtc_device *rtc; | 489 | struct s3c_rtc *info = NULL; |
451 | struct rtc_time rtc_tm; | 490 | struct rtc_time rtc_tm; |
452 | struct resource *res; | 491 | struct resource *res; |
453 | int ret; | 492 | int ret; |
454 | int tmp; | ||
455 | 493 | ||
456 | dev_dbg(&pdev->dev, "%s: probe=%p\n", __func__, pdev); | 494 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
495 | if (!info) | ||
496 | return -ENOMEM; | ||
457 | 497 | ||
458 | /* find the IRQs */ | 498 | /* find the IRQs */ |
459 | 499 | info->irq_tick = platform_get_irq(pdev, 1); | |
460 | s3c_rtc_tickno = platform_get_irq(pdev, 1); | 500 | if (info->irq_tick < 0) { |
461 | if (s3c_rtc_tickno < 0) { | ||
462 | dev_err(&pdev->dev, "no irq for rtc tick\n"); | 501 | dev_err(&pdev->dev, "no irq for rtc tick\n"); |
463 | return s3c_rtc_tickno; | 502 | return info->irq_tick; |
503 | } | ||
504 | |||
505 | info->dev = &pdev->dev; | ||
506 | info->data = s3c_rtc_get_data(pdev); | ||
507 | if (!info->data) { | ||
508 | dev_err(&pdev->dev, "failed getting s3c_rtc_data\n"); | ||
509 | return -EINVAL; | ||
464 | } | 510 | } |
511 | spin_lock_init(&info->pie_lock); | ||
512 | spin_lock_init(&info->alarm_clk_lock); | ||
513 | |||
514 | platform_set_drvdata(pdev, info); | ||
465 | 515 | ||
466 | s3c_rtc_alarmno = platform_get_irq(pdev, 0); | 516 | info->irq_alarm = platform_get_irq(pdev, 0); |
467 | if (s3c_rtc_alarmno < 0) { | 517 | if (info->irq_alarm < 0) { |
468 | dev_err(&pdev->dev, "no irq for alarm\n"); | 518 | dev_err(&pdev->dev, "no irq for alarm\n"); |
469 | return s3c_rtc_alarmno; | 519 | return info->irq_alarm; |
470 | } | 520 | } |
471 | 521 | ||
472 | dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n", | 522 | dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n", |
473 | s3c_rtc_tickno, s3c_rtc_alarmno); | 523 | info->irq_tick, info->irq_alarm); |
474 | 524 | ||
475 | /* get the memory region */ | 525 | /* get the memory region */ |
476 | |||
477 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 526 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
478 | s3c_rtc_base = devm_ioremap_resource(&pdev->dev, res); | 527 | info->base = devm_ioremap_resource(&pdev->dev, res); |
479 | if (IS_ERR(s3c_rtc_base)) | 528 | if (IS_ERR(info->base)) |
480 | return PTR_ERR(s3c_rtc_base); | 529 | return PTR_ERR(info->base); |
481 | 530 | ||
482 | rtc_clk = devm_clk_get(&pdev->dev, "rtc"); | 531 | info->rtc_clk = devm_clk_get(&pdev->dev, "rtc"); |
483 | if (IS_ERR(rtc_clk)) { | 532 | if (IS_ERR(info->rtc_clk)) { |
484 | dev_err(&pdev->dev, "failed to find rtc clock source\n"); | 533 | dev_err(&pdev->dev, "failed to find rtc clock\n"); |
485 | ret = PTR_ERR(rtc_clk); | 534 | return PTR_ERR(info->rtc_clk); |
486 | rtc_clk = NULL; | ||
487 | return ret; | ||
488 | } | 535 | } |
536 | clk_prepare_enable(info->rtc_clk); | ||
489 | 537 | ||
490 | clk_prepare_enable(rtc_clk); | 538 | info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src"); |
539 | if (IS_ERR(info->rtc_src_clk)) { | ||
540 | dev_err(&pdev->dev, "failed to find rtc source clock\n"); | ||
541 | return PTR_ERR(info->rtc_src_clk); | ||
542 | } | ||
543 | clk_prepare_enable(info->rtc_src_clk); | ||
491 | 544 | ||
492 | /* check to see if everything is setup correctly */ | ||
493 | 545 | ||
494 | s3c_rtc_enable(pdev, 1); | 546 | /* check to see if everything is setup correctly */ |
547 | if (info->data->enable) | ||
548 | info->data->enable(info); | ||
495 | 549 | ||
496 | dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", | 550 | dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", |
497 | readw(s3c_rtc_base + S3C2410_RTCCON)); | 551 | readw(info->base + S3C2410_RTCCON)); |
498 | 552 | ||
499 | device_init_wakeup(&pdev->dev, 1); | 553 | device_init_wakeup(&pdev->dev, 1); |
500 | 554 | ||
501 | /* register RTC and exit */ | 555 | /* register RTC and exit */ |
502 | 556 | info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, | |
503 | rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, | ||
504 | THIS_MODULE); | 557 | THIS_MODULE); |
505 | 558 | if (IS_ERR(info->rtc)) { | |
506 | if (IS_ERR(rtc)) { | ||
507 | dev_err(&pdev->dev, "cannot attach rtc\n"); | 559 | dev_err(&pdev->dev, "cannot attach rtc\n"); |
508 | ret = PTR_ERR(rtc); | 560 | ret = PTR_ERR(info->rtc); |
509 | goto err_nortc; | 561 | goto err_nortc; |
510 | } | 562 | } |
511 | 563 | ||
512 | s3c_rtc_cpu_type = s3c_rtc_get_driver_data(pdev); | 564 | ret = devm_request_irq(&pdev->dev, info->irq_alarm, s3c_rtc_alarmirq, |
565 | 0, "s3c2410-rtc alarm", info); | ||
566 | if (ret) { | ||
567 | dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_alarm, ret); | ||
568 | goto err_nortc; | ||
569 | } | ||
513 | 570 | ||
514 | /* Check RTC Time */ | 571 | ret = devm_request_irq(&pdev->dev, info->irq_tick, s3c_rtc_tickirq, |
572 | 0, "s3c2410-rtc tick", info); | ||
573 | if (ret) { | ||
574 | dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_tick, ret); | ||
575 | goto err_nortc; | ||
576 | } | ||
515 | 577 | ||
516 | s3c_rtc_gettime(NULL, &rtc_tm); | 578 | /* Check RTC Time */ |
579 | s3c_rtc_gettime(&pdev->dev, &rtc_tm); | ||
517 | 580 | ||
518 | if (rtc_valid_tm(&rtc_tm)) { | 581 | if (rtc_valid_tm(&rtc_tm)) { |
519 | rtc_tm.tm_year = 100; | 582 | rtc_tm.tm_year = 100; |
@@ -523,163 +586,312 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
523 | rtc_tm.tm_min = 0; | 586 | rtc_tm.tm_min = 0; |
524 | rtc_tm.tm_sec = 0; | 587 | rtc_tm.tm_sec = 0; |
525 | 588 | ||
526 | s3c_rtc_settime(NULL, &rtc_tm); | 589 | s3c_rtc_settime(&pdev->dev, &rtc_tm); |
527 | 590 | ||
528 | dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); | 591 | dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); |
529 | } | 592 | } |
530 | 593 | ||
531 | if (s3c_rtc_cpu_type != TYPE_S3C2410) | 594 | if (info->data->select_tick_clk) |
532 | rtc->max_user_freq = 32768; | 595 | info->data->select_tick_clk(info); |
533 | else | ||
534 | rtc->max_user_freq = 128; | ||
535 | |||
536 | if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { | ||
537 | tmp = readw(s3c_rtc_base + S3C2410_RTCCON); | ||
538 | tmp |= S3C2443_RTCCON_TICSEL; | ||
539 | writew(tmp, s3c_rtc_base + S3C2410_RTCCON); | ||
540 | } | ||
541 | 596 | ||
542 | platform_set_drvdata(pdev, rtc); | 597 | s3c_rtc_setfreq(info, 1); |
543 | 598 | ||
544 | s3c_rtc_setfreq(&pdev->dev, 1); | 599 | if (info->data->needs_src_clk) |
545 | 600 | clk_disable(info->rtc_src_clk); | |
546 | ret = devm_request_irq(&pdev->dev, s3c_rtc_alarmno, s3c_rtc_alarmirq, | 601 | clk_disable(info->rtc_clk); |
547 | 0, "s3c2410-rtc alarm", rtc); | ||
548 | if (ret) { | ||
549 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); | ||
550 | goto err_nortc; | ||
551 | } | ||
552 | |||
553 | ret = devm_request_irq(&pdev->dev, s3c_rtc_tickno, s3c_rtc_tickirq, | ||
554 | 0, "s3c2410-rtc tick", rtc); | ||
555 | if (ret) { | ||
556 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); | ||
557 | goto err_nortc; | ||
558 | } | ||
559 | |||
560 | clk_disable(rtc_clk); | ||
561 | 602 | ||
562 | return 0; | 603 | return 0; |
563 | 604 | ||
564 | err_nortc: | 605 | err_nortc: |
565 | s3c_rtc_enable(pdev, 0); | 606 | if (info->data->disable) |
566 | clk_disable_unprepare(rtc_clk); | 607 | info->data->disable(info); |
608 | clk_disable_unprepare(info->rtc_clk); | ||
567 | 609 | ||
568 | return ret; | 610 | return ret; |
569 | } | 611 | } |
570 | 612 | ||
571 | #ifdef CONFIG_PM_SLEEP | 613 | #ifdef CONFIG_PM_SLEEP |
572 | /* RTC Power management control */ | ||
573 | |||
574 | static int ticnt_save, ticnt_en_save; | ||
575 | static bool wake_en; | ||
576 | 614 | ||
577 | static int s3c_rtc_suspend(struct device *dev) | 615 | static int s3c_rtc_suspend(struct device *dev) |
578 | { | 616 | { |
579 | struct platform_device *pdev = to_platform_device(dev); | 617 | struct s3c_rtc *info = dev_get_drvdata(dev); |
618 | |||
619 | clk_enable(info->rtc_clk); | ||
620 | if (info->data->needs_src_clk) | ||
621 | clk_enable(info->rtc_src_clk); | ||
580 | 622 | ||
581 | clk_enable(rtc_clk); | ||
582 | /* save TICNT for anyone using periodic interrupts */ | 623 | /* save TICNT for anyone using periodic interrupts */ |
583 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 624 | if (info->data->save_tick_cnt) |
584 | ticnt_en_save = readw(s3c_rtc_base + S3C2410_RTCCON); | 625 | info->data->save_tick_cnt(info); |
585 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; | 626 | |
586 | ticnt_save = readl(s3c_rtc_base + S3C2410_TICNT); | 627 | if (info->data->disable) |
587 | } else { | 628 | info->data->disable(info); |
588 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); | ||
589 | } | ||
590 | s3c_rtc_enable(pdev, 0); | ||
591 | 629 | ||
592 | if (device_may_wakeup(dev) && !wake_en) { | 630 | if (device_may_wakeup(dev) && !info->wake_en) { |
593 | if (enable_irq_wake(s3c_rtc_alarmno) == 0) | 631 | if (enable_irq_wake(info->irq_alarm) == 0) |
594 | wake_en = true; | 632 | info->wake_en = true; |
595 | else | 633 | else |
596 | dev_err(dev, "enable_irq_wake failed\n"); | 634 | dev_err(dev, "enable_irq_wake failed\n"); |
597 | } | 635 | } |
598 | clk_disable(rtc_clk); | 636 | |
637 | if (info->data->needs_src_clk) | ||
638 | clk_disable(info->rtc_src_clk); | ||
639 | clk_disable(info->rtc_clk); | ||
599 | 640 | ||
600 | return 0; | 641 | return 0; |
601 | } | 642 | } |
602 | 643 | ||
603 | static int s3c_rtc_resume(struct device *dev) | 644 | static int s3c_rtc_resume(struct device *dev) |
604 | { | 645 | { |
605 | struct platform_device *pdev = to_platform_device(dev); | 646 | struct s3c_rtc *info = dev_get_drvdata(dev); |
606 | unsigned int tmp; | ||
607 | 647 | ||
608 | clk_enable(rtc_clk); | 648 | clk_enable(info->rtc_clk); |
609 | s3c_rtc_enable(pdev, 1); | 649 | if (info->data->needs_src_clk) |
610 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 650 | clk_enable(info->rtc_src_clk); |
611 | writel(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | ||
612 | if (ticnt_en_save) { | ||
613 | tmp = readw(s3c_rtc_base + S3C2410_RTCCON); | ||
614 | writew(tmp | ticnt_en_save, | ||
615 | s3c_rtc_base + S3C2410_RTCCON); | ||
616 | } | ||
617 | } else { | ||
618 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | ||
619 | } | ||
620 | 651 | ||
621 | if (device_may_wakeup(dev) && wake_en) { | 652 | if (info->data->enable) |
622 | disable_irq_wake(s3c_rtc_alarmno); | 653 | info->data->enable(info); |
623 | wake_en = false; | 654 | |
655 | if (info->data->restore_tick_cnt) | ||
656 | info->data->restore_tick_cnt(info); | ||
657 | |||
658 | if (device_may_wakeup(dev) && info->wake_en) { | ||
659 | disable_irq_wake(info->irq_alarm); | ||
660 | info->wake_en = false; | ||
624 | } | 661 | } |
625 | clk_disable(rtc_clk); | 662 | |
663 | if (info->data->needs_src_clk) | ||
664 | clk_disable(info->rtc_src_clk); | ||
665 | clk_disable(info->rtc_clk); | ||
626 | 666 | ||
627 | return 0; | 667 | return 0; |
628 | } | 668 | } |
629 | #endif | 669 | #endif |
630 | |||
631 | static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); | 670 | static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); |
632 | 671 | ||
633 | #ifdef CONFIG_OF | 672 | static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask) |
634 | static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = { | 673 | { |
635 | [TYPE_S3C2410] = { TYPE_S3C2410 }, | 674 | clk_enable(info->rtc_clk); |
636 | [TYPE_S3C2416] = { TYPE_S3C2416 }, | 675 | if (info->data->needs_src_clk) |
637 | [TYPE_S3C2443] = { TYPE_S3C2443 }, | 676 | clk_enable(info->rtc_src_clk); |
638 | [TYPE_S3C64XX] = { TYPE_S3C64XX }, | 677 | rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); |
678 | if (info->data->needs_src_clk) | ||
679 | clk_disable(info->rtc_src_clk); | ||
680 | clk_disable(info->rtc_clk); | ||
681 | |||
682 | s3c_rtc_alarm_clk_enable(info, false); | ||
683 | } | ||
684 | |||
685 | static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask) | ||
686 | { | ||
687 | clk_enable(info->rtc_clk); | ||
688 | if (info->data->needs_src_clk) | ||
689 | clk_enable(info->rtc_src_clk); | ||
690 | rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); | ||
691 | writeb(mask, info->base + S3C2410_INTP); | ||
692 | if (info->data->needs_src_clk) | ||
693 | clk_disable(info->rtc_src_clk); | ||
694 | clk_disable(info->rtc_clk); | ||
695 | |||
696 | s3c_rtc_alarm_clk_enable(info, false); | ||
697 | } | ||
698 | |||
699 | static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq) | ||
700 | { | ||
701 | unsigned int tmp = 0; | ||
702 | int val; | ||
703 | |||
704 | tmp = readb(info->base + S3C2410_TICNT); | ||
705 | tmp &= S3C2410_TICNT_ENABLE; | ||
706 | |||
707 | val = (info->rtc->max_user_freq / freq) - 1; | ||
708 | tmp |= val; | ||
709 | |||
710 | writel(tmp, info->base + S3C2410_TICNT); | ||
711 | } | ||
712 | |||
713 | static void s3c2416_rtc_setfreq(struct s3c_rtc *info, int freq) | ||
714 | { | ||
715 | unsigned int tmp = 0; | ||
716 | int val; | ||
717 | |||
718 | tmp = readb(info->base + S3C2410_TICNT); | ||
719 | tmp &= S3C2410_TICNT_ENABLE; | ||
720 | |||
721 | val = (info->rtc->max_user_freq / freq) - 1; | ||
722 | |||
723 | tmp |= S3C2443_TICNT_PART(val); | ||
724 | writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1); | ||
725 | |||
726 | writel(S3C2416_TICNT2_PART(val), info->base + S3C2416_TICNT2); | ||
727 | |||
728 | writel(tmp, info->base + S3C2410_TICNT); | ||
729 | } | ||
730 | |||
731 | static void s3c2443_rtc_setfreq(struct s3c_rtc *info, int freq) | ||
732 | { | ||
733 | unsigned int tmp = 0; | ||
734 | int val; | ||
735 | |||
736 | tmp = readb(info->base + S3C2410_TICNT); | ||
737 | tmp &= S3C2410_TICNT_ENABLE; | ||
738 | |||
739 | val = (info->rtc->max_user_freq / freq) - 1; | ||
740 | |||
741 | tmp |= S3C2443_TICNT_PART(val); | ||
742 | writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1); | ||
743 | |||
744 | writel(tmp, info->base + S3C2410_TICNT); | ||
745 | } | ||
746 | |||
747 | static void s3c6410_rtc_setfreq(struct s3c_rtc *info, int freq) | ||
748 | { | ||
749 | int val; | ||
750 | |||
751 | val = (info->rtc->max_user_freq / freq) - 1; | ||
752 | writel(val, info->base + S3C2410_TICNT); | ||
753 | } | ||
754 | |||
755 | static void s3c24xx_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq) | ||
756 | { | ||
757 | unsigned int ticnt; | ||
758 | |||
759 | ticnt = readb(info->base + S3C2410_TICNT); | ||
760 | ticnt &= S3C2410_TICNT_ENABLE; | ||
761 | |||
762 | seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); | ||
763 | } | ||
764 | |||
765 | static void s3c2416_rtc_select_tick_clk(struct s3c_rtc *info) | ||
766 | { | ||
767 | unsigned int con; | ||
768 | |||
769 | con = readw(info->base + S3C2410_RTCCON); | ||
770 | con |= S3C2443_RTCCON_TICSEL; | ||
771 | writew(con, info->base + S3C2410_RTCCON); | ||
772 | } | ||
773 | |||
774 | static void s3c6410_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq) | ||
775 | { | ||
776 | unsigned int ticnt; | ||
777 | |||
778 | ticnt = readw(info->base + S3C2410_RTCCON); | ||
779 | ticnt &= S3C64XX_RTCCON_TICEN; | ||
780 | |||
781 | seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); | ||
782 | } | ||
783 | |||
784 | static void s3c24xx_rtc_save_tick_cnt(struct s3c_rtc *info) | ||
785 | { | ||
786 | info->ticnt_save = readb(info->base + S3C2410_TICNT); | ||
787 | } | ||
788 | |||
789 | static void s3c24xx_rtc_restore_tick_cnt(struct s3c_rtc *info) | ||
790 | { | ||
791 | writeb(info->ticnt_save, info->base + S3C2410_TICNT); | ||
792 | } | ||
793 | |||
794 | static void s3c6410_rtc_save_tick_cnt(struct s3c_rtc *info) | ||
795 | { | ||
796 | info->ticnt_en_save = readw(info->base + S3C2410_RTCCON); | ||
797 | info->ticnt_en_save &= S3C64XX_RTCCON_TICEN; | ||
798 | info->ticnt_save = readl(info->base + S3C2410_TICNT); | ||
799 | } | ||
800 | |||
801 | static void s3c6410_rtc_restore_tick_cnt(struct s3c_rtc *info) | ||
802 | { | ||
803 | unsigned int con; | ||
804 | |||
805 | writel(info->ticnt_save, info->base + S3C2410_TICNT); | ||
806 | if (info->ticnt_en_save) { | ||
807 | con = readw(info->base + S3C2410_RTCCON); | ||
808 | writew(con | info->ticnt_en_save, | ||
809 | info->base + S3C2410_RTCCON); | ||
810 | } | ||
811 | } | ||
812 | |||
813 | static struct s3c_rtc_data const s3c2410_rtc_data = { | ||
814 | .max_user_freq = 128, | ||
815 | .irq_handler = s3c24xx_rtc_irq, | ||
816 | .set_freq = s3c2410_rtc_setfreq, | ||
817 | .enable_tick = s3c24xx_rtc_enable_tick, | ||
818 | .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, | ||
819 | .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, | ||
820 | .enable = s3c24xx_rtc_enable, | ||
821 | .disable = s3c24xx_rtc_disable, | ||
822 | }; | ||
823 | |||
824 | static struct s3c_rtc_data const s3c2416_rtc_data = { | ||
825 | .max_user_freq = 32768, | ||
826 | .irq_handler = s3c24xx_rtc_irq, | ||
827 | .set_freq = s3c2416_rtc_setfreq, | ||
828 | .enable_tick = s3c24xx_rtc_enable_tick, | ||
829 | .select_tick_clk = s3c2416_rtc_select_tick_clk, | ||
830 | .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, | ||
831 | .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, | ||
832 | .enable = s3c24xx_rtc_enable, | ||
833 | .disable = s3c24xx_rtc_disable, | ||
834 | }; | ||
835 | |||
836 | static struct s3c_rtc_data const s3c2443_rtc_data = { | ||
837 | .max_user_freq = 32768, | ||
838 | .irq_handler = s3c24xx_rtc_irq, | ||
839 | .set_freq = s3c2443_rtc_setfreq, | ||
840 | .enable_tick = s3c24xx_rtc_enable_tick, | ||
841 | .select_tick_clk = s3c2416_rtc_select_tick_clk, | ||
842 | .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, | ||
843 | .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, | ||
844 | .enable = s3c24xx_rtc_enable, | ||
845 | .disable = s3c24xx_rtc_disable, | ||
846 | }; | ||
847 | |||
848 | static struct s3c_rtc_data const s3c6410_rtc_data = { | ||
849 | .max_user_freq = 32768, | ||
850 | .irq_handler = s3c6410_rtc_irq, | ||
851 | .set_freq = s3c6410_rtc_setfreq, | ||
852 | .enable_tick = s3c6410_rtc_enable_tick, | ||
853 | .save_tick_cnt = s3c6410_rtc_save_tick_cnt, | ||
854 | .restore_tick_cnt = s3c6410_rtc_restore_tick_cnt, | ||
855 | .enable = s3c24xx_rtc_enable, | ||
856 | .disable = s3c6410_rtc_disable, | ||
857 | }; | ||
858 | |||
859 | static struct s3c_rtc_data const exynos3250_rtc_data = { | ||
860 | .max_user_freq = 32768, | ||
861 | .needs_src_clk = true, | ||
862 | .irq_handler = s3c6410_rtc_irq, | ||
863 | .set_freq = s3c6410_rtc_setfreq, | ||
864 | .enable_tick = s3c6410_rtc_enable_tick, | ||
865 | .save_tick_cnt = s3c6410_rtc_save_tick_cnt, | ||
866 | .restore_tick_cnt = s3c6410_rtc_restore_tick_cnt, | ||
867 | .enable = s3c24xx_rtc_enable, | ||
868 | .disable = s3c6410_rtc_disable, | ||
639 | }; | 869 | }; |
640 | 870 | ||
641 | static const struct of_device_id s3c_rtc_dt_match[] = { | 871 | static const struct of_device_id s3c_rtc_dt_match[] = { |
642 | { | 872 | { |
643 | .compatible = "samsung,s3c2410-rtc", | 873 | .compatible = "samsung,s3c2410-rtc", |
644 | .data = &s3c_rtc_drv_data_array[TYPE_S3C2410], | 874 | .data = (void *)&s3c2410_rtc_data, |
645 | }, { | 875 | }, { |
646 | .compatible = "samsung,s3c2416-rtc", | 876 | .compatible = "samsung,s3c2416-rtc", |
647 | .data = &s3c_rtc_drv_data_array[TYPE_S3C2416], | 877 | .data = (void *)&s3c2416_rtc_data, |
648 | }, { | 878 | }, { |
649 | .compatible = "samsung,s3c2443-rtc", | 879 | .compatible = "samsung,s3c2443-rtc", |
650 | .data = &s3c_rtc_drv_data_array[TYPE_S3C2443], | 880 | .data = (void *)&s3c2443_rtc_data, |
651 | }, { | 881 | }, { |
652 | .compatible = "samsung,s3c6410-rtc", | 882 | .compatible = "samsung,s3c6410-rtc", |
653 | .data = &s3c_rtc_drv_data_array[TYPE_S3C64XX], | 883 | .data = (void *)&s3c6410_rtc_data, |
654 | }, | ||
655 | {}, | ||
656 | }; | ||
657 | MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); | ||
658 | #endif | ||
659 | |||
660 | static struct platform_device_id s3c_rtc_driver_ids[] = { | ||
661 | { | ||
662 | .name = "s3c2410-rtc", | ||
663 | .driver_data = TYPE_S3C2410, | ||
664 | }, { | ||
665 | .name = "s3c2416-rtc", | ||
666 | .driver_data = TYPE_S3C2416, | ||
667 | }, { | ||
668 | .name = "s3c2443-rtc", | ||
669 | .driver_data = TYPE_S3C2443, | ||
670 | }, { | 884 | }, { |
671 | .name = "s3c64xx-rtc", | 885 | .compatible = "samsung,exynos3250-rtc", |
672 | .driver_data = TYPE_S3C64XX, | 886 | .data = (void *)&exynos3250_rtc_data, |
673 | }, | 887 | }, |
674 | { } | 888 | { /* sentinel */ }, |
675 | }; | 889 | }; |
676 | 890 | MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); | |
677 | MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); | ||
678 | 891 | ||
679 | static struct platform_driver s3c_rtc_driver = { | 892 | static struct platform_driver s3c_rtc_driver = { |
680 | .probe = s3c_rtc_probe, | 893 | .probe = s3c_rtc_probe, |
681 | .remove = s3c_rtc_remove, | 894 | .remove = s3c_rtc_remove, |
682 | .id_table = s3c_rtc_driver_ids, | ||
683 | .driver = { | 895 | .driver = { |
684 | .name = "s3c-rtc", | 896 | .name = "s3c-rtc", |
685 | .owner = THIS_MODULE, | 897 | .owner = THIS_MODULE, |
@@ -687,7 +899,6 @@ static struct platform_driver s3c_rtc_driver = { | |||
687 | .of_match_table = of_match_ptr(s3c_rtc_dt_match), | 899 | .of_match_table = of_match_ptr(s3c_rtc_dt_match), |
688 | }, | 900 | }, |
689 | }; | 901 | }; |
690 | |||
691 | module_platform_driver(s3c_rtc_driver); | 902 | module_platform_driver(s3c_rtc_driver); |
692 | 903 | ||
693 | MODULE_DESCRIPTION("Samsung S3C RTC Driver"); | 904 | MODULE_DESCRIPTION("Samsung S3C RTC Driver"); |
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index d497aa05a72f..c692dfebd0ba 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c | |||
@@ -257,11 +257,11 @@ static ssize_t chp_status_write(struct device *dev, | |||
257 | if (!num_args) | 257 | if (!num_args) |
258 | return count; | 258 | return count; |
259 | 259 | ||
260 | if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) { | 260 | if (!strncasecmp(cmd, "on", 2) || !strcmp(cmd, "1")) { |
261 | mutex_lock(&cp->lock); | 261 | mutex_lock(&cp->lock); |
262 | error = s390_vary_chpid(cp->chpid, 1); | 262 | error = s390_vary_chpid(cp->chpid, 1); |
263 | mutex_unlock(&cp->lock); | 263 | mutex_unlock(&cp->lock); |
264 | } else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) { | 264 | } else if (!strncasecmp(cmd, "off", 3) || !strcmp(cmd, "0")) { |
265 | mutex_lock(&cp->lock); | 265 | mutex_lock(&cp->lock); |
266 | error = s390_vary_chpid(cp->chpid, 0); | 266 | error = s390_vary_chpid(cp->chpid, 0); |
267 | mutex_unlock(&cp->lock); | 267 | mutex_unlock(&cp->lock); |
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 52a216f21ae5..e5afc3884d74 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c | |||
@@ -528,7 +528,7 @@ ips_setup(char *ips_str) | |||
528 | * Update the variables | 528 | * Update the variables |
529 | */ | 529 | */ |
530 | for (i = 0; i < ARRAY_SIZE(options); i++) { | 530 | for (i = 0; i < ARRAY_SIZE(options); i++) { |
531 | if (strnicmp | 531 | if (strncasecmp |
532 | (key, options[i].option_name, | 532 | (key, options[i].option_name, |
533 | strlen(options[i].option_name)) == 0) { | 533 | strlen(options[i].option_name)) == 0) { |
534 | if (value) | 534 | if (value) |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 2b6d447ad6d6..238e06f13b8a 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -3371,7 +3371,7 @@ static ssize_t opts_store(struct device_driver *ddp, const char *buf, | |||
3371 | char work[20]; | 3371 | char work[20]; |
3372 | 3372 | ||
3373 | if (1 == sscanf(buf, "%10s", work)) { | 3373 | if (1 == sscanf(buf, "%10s", work)) { |
3374 | if (0 == strnicmp(work,"0x", 2)) { | 3374 | if (0 == strncasecmp(work,"0x", 2)) { |
3375 | if (1 == sscanf(&work[2], "%x", &opts)) | 3375 | if (1 == sscanf(&work[2], "%x", &opts)) |
3376 | goto opts_done; | 3376 | goto opts_done; |
3377 | } else { | 3377 | } else { |
diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index 1718229f6278..d9d55d12fd5f 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c | |||
@@ -79,7 +79,7 @@ int rtw_android_cmdstr_to_num(char *cmdstr) | |||
79 | { | 79 | { |
80 | int cmd_num; | 80 | int cmd_num; |
81 | for (cmd_num = 0; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++) | 81 | for (cmd_num = 0; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++) |
82 | if (0 == strnicmp(cmdstr , android_wifi_cmd_str[cmd_num], | 82 | if (0 == strncasecmp(cmdstr , android_wifi_cmd_str[cmd_num], |
83 | strlen(android_wifi_cmd_str[cmd_num]))) | 83 | strlen(android_wifi_cmd_str[cmd_num]))) |
84 | break; | 84 | break; |
85 | return cmd_num; | 85 | return cmd_num; |
diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 91d35df286c3..2d82f8993ea1 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h | |||
@@ -2957,25 +2957,13 @@ extern inline int rtllib_get_scans(struct rtllib_device *ieee) | |||
2957 | static inline const char *escape_essid(const char *essid, u8 essid_len) | 2957 | static inline const char *escape_essid(const char *essid, u8 essid_len) |
2958 | { | 2958 | { |
2959 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 2959 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; |
2960 | const char *s = essid; | ||
2961 | char *d = escaped; | ||
2962 | 2960 | ||
2963 | if (rtllib_is_empty_essid(essid, essid_len)) { | 2961 | if (rtllib_is_empty_essid(essid, essid_len)) { |
2964 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); | 2962 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); |
2965 | return escaped; | 2963 | return escaped; |
2966 | } | 2964 | } |
2967 | 2965 | ||
2968 | essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); | 2966 | snprintf(escaped, sizeof(escaped), "%*pEn", essid_len, essid); |
2969 | while (essid_len--) { | ||
2970 | if (*s == '\0') { | ||
2971 | *d++ = '\\'; | ||
2972 | *d++ = '0'; | ||
2973 | s++; | ||
2974 | } else { | ||
2975 | *d++ = *s++; | ||
2976 | } | ||
2977 | } | ||
2978 | *d = '\0'; | ||
2979 | return escaped; | 2967 | return escaped; |
2980 | } | 2968 | } |
2981 | 2969 | ||
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 9ecfa4a2421d..b44aa17d30a7 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h | |||
@@ -2593,25 +2593,13 @@ static inline int ieee80211_get_scans(struct ieee80211_device *ieee) | |||
2593 | 2593 | ||
2594 | static inline const char *escape_essid(const char *essid, u8 essid_len) { | 2594 | static inline const char *escape_essid(const char *essid, u8 essid_len) { |
2595 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 2595 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; |
2596 | const char *s = essid; | ||
2597 | char *d = escaped; | ||
2598 | 2596 | ||
2599 | if (ieee80211_is_empty_essid(essid, essid_len)) { | 2597 | if (ieee80211_is_empty_essid(essid, essid_len)) { |
2600 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); | 2598 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); |
2601 | return escaped; | 2599 | return escaped; |
2602 | } | 2600 | } |
2603 | 2601 | ||
2604 | essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); | 2602 | snprintf(escaped, sizeof(escaped), "%*pEn", essid_len, essid); |
2605 | while (essid_len--) { | ||
2606 | if (*s == '\0') { | ||
2607 | *d++ = '\\'; | ||
2608 | *d++ = '0'; | ||
2609 | s++; | ||
2610 | } else { | ||
2611 | *d++ = *s++; | ||
2612 | } | ||
2613 | } | ||
2614 | *d = '\0'; | ||
2615 | return escaped; | 2603 | return escaped; |
2616 | } | 2604 | } |
2617 | 2605 | ||
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 799ce8aa70ef..df577dfe7ffb 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c | |||
@@ -60,7 +60,6 @@ | |||
60 | #include <linux/netdevice.h> | 60 | #include <linux/netdevice.h> |
61 | #include <linux/workqueue.h> | 61 | #include <linux/workqueue.h> |
62 | #include <linux/byteorder/generic.h> | 62 | #include <linux/byteorder/generic.h> |
63 | #include <linux/ctype.h> | ||
64 | 63 | ||
65 | #include <linux/io.h> | 64 | #include <linux/io.h> |
66 | #include <linux/delay.h> | 65 | #include <linux/delay.h> |
@@ -81,27 +80,6 @@ | |||
81 | #include "hfa384x.h" | 80 | #include "hfa384x.h" |
82 | #include "prism2mgmt.h" | 81 | #include "prism2mgmt.h" |
83 | 82 | ||
84 | /* Create a string of printable chars from something that might not be */ | ||
85 | /* It's recommended that the str be 4*len + 1 bytes long */ | ||
86 | #define wlan_mkprintstr(buf, buflen, str, strlen) \ | ||
87 | { \ | ||
88 | int i = 0; \ | ||
89 | int j = 0; \ | ||
90 | memset(str, 0, (strlen)); \ | ||
91 | for (i = 0; i < (buflen); i++) { \ | ||
92 | if (isprint((buf)[i])) { \ | ||
93 | (str)[j] = (buf)[i]; \ | ||
94 | j++; \ | ||
95 | } else { \ | ||
96 | (str)[j] = '\\'; \ | ||
97 | (str)[j+1] = 'x'; \ | ||
98 | (str)[j+2] = hex_asc_hi((buf)[i]); \ | ||
99 | (str)[j+3] = hex_asc_lo((buf)[i]); \ | ||
100 | j += 4; \ | ||
101 | } \ | ||
102 | } \ | ||
103 | } | ||
104 | |||
105 | static char *dev_info = "prism2_usb"; | 83 | static char *dev_info = "prism2_usb"; |
106 | static wlandevice_t *create_wlan(void); | 84 | static wlandevice_t *create_wlan(void); |
107 | 85 | ||
@@ -607,7 +585,6 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev) | |||
607 | hfa384x_t *hw = (hfa384x_t *) wlandev->priv; | 585 | hfa384x_t *hw = (hfa384x_t *) wlandev->priv; |
608 | u16 temp; | 586 | u16 temp; |
609 | u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN]; | 587 | u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN]; |
610 | char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1]; | ||
611 | 588 | ||
612 | /* Collect version and compatibility info */ | 589 | /* Collect version and compatibility info */ |
613 | /* Some are critical, some are not */ | 590 | /* Some are critical, some are not */ |
@@ -862,9 +839,8 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev) | |||
862 | result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, | 839 | result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, |
863 | snum, HFA384x_RID_NICSERIALNUMBER_LEN); | 840 | snum, HFA384x_RID_NICSERIALNUMBER_LEN); |
864 | if (!result) { | 841 | if (!result) { |
865 | wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN, | 842 | netdev_info(wlandev->netdev, "Prism2 card SN: %*pEhp\n", |
866 | pstr, sizeof(pstr)); | 843 | HFA384x_RID_NICSERIALNUMBER_LEN, snum); |
867 | netdev_info(wlandev->netdev, "Prism2 card SN: %s\n", pstr); | ||
868 | } else { | 844 | } else { |
869 | netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n"); | 845 | netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n"); |
870 | goto failed; | 846 | goto failed; |
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 71b0ec0c370d..1e23f4f8d2c2 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c | |||
@@ -66,7 +66,7 @@ static struct thermal_governor *__find_governor(const char *name) | |||
66 | return def_governor; | 66 | return def_governor; |
67 | 67 | ||
68 | list_for_each_entry(pos, &thermal_governor_list, governor_list) | 68 | list_for_each_entry(pos, &thermal_governor_list, governor_list) |
69 | if (!strnicmp(name, pos->name, THERMAL_NAME_LENGTH)) | 69 | if (!strncasecmp(name, pos->name, THERMAL_NAME_LENGTH)) |
70 | return pos; | 70 | return pos; |
71 | 71 | ||
72 | return NULL; | 72 | return NULL; |
@@ -104,7 +104,7 @@ int thermal_register_governor(struct thermal_governor *governor) | |||
104 | 104 | ||
105 | name = pos->tzp->governor_name; | 105 | name = pos->tzp->governor_name; |
106 | 106 | ||
107 | if (!strnicmp(name, governor->name, THERMAL_NAME_LENGTH)) | 107 | if (!strncasecmp(name, governor->name, THERMAL_NAME_LENGTH)) |
108 | pos->governor = governor; | 108 | pos->governor = governor; |
109 | } | 109 | } |
110 | 110 | ||
@@ -129,7 +129,7 @@ void thermal_unregister_governor(struct thermal_governor *governor) | |||
129 | mutex_lock(&thermal_list_lock); | 129 | mutex_lock(&thermal_list_lock); |
130 | 130 | ||
131 | list_for_each_entry(pos, &thermal_tz_list, node) { | 131 | list_for_each_entry(pos, &thermal_tz_list, node) { |
132 | if (!strnicmp(pos->governor->name, governor->name, | 132 | if (!strncasecmp(pos->governor->name, governor->name, |
133 | THERMAL_NAME_LENGTH)) | 133 | THERMAL_NAME_LENGTH)) |
134 | pos->governor = NULL; | 134 | pos->governor = NULL; |
135 | } | 135 | } |
@@ -1665,7 +1665,7 @@ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name) | |||
1665 | 1665 | ||
1666 | mutex_lock(&thermal_list_lock); | 1666 | mutex_lock(&thermal_list_lock); |
1667 | list_for_each_entry(pos, &thermal_tz_list, node) | 1667 | list_for_each_entry(pos, &thermal_tz_list, node) |
1668 | if (!strnicmp(name, pos->type, THERMAL_NAME_LENGTH)) { | 1668 | if (!strncasecmp(name, pos->type, THERMAL_NAME_LENGTH)) { |
1669 | found++; | 1669 | found++; |
1670 | ref = pos; | 1670 | ref = pos; |
1671 | } | 1671 | } |
diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index 167cffff3d4e..7c74f58fc101 100644 --- a/drivers/video/fbdev/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c | |||
@@ -1001,7 +1001,7 @@ static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val, | |||
1001 | 1001 | ||
1002 | for (i = 0 ; i < size ; i++ ) { | 1002 | for (i = 0 ; i < size ; i++ ) { |
1003 | if (s != NULL) { | 1003 | if (s != NULL) { |
1004 | if (!strnicmp(p[i].name, s, strlen(s))) | 1004 | if (!strncasecmp(p[i].name, s, strlen(s))) |
1005 | return p[i].val; | 1005 | return p[i].val; |
1006 | } else { | 1006 | } else { |
1007 | if (p[i].val == val) | 1007 | if (p[i].val == val) |
diff --git a/drivers/video/fbdev/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c index 43c63a4f3178..e350eb57f11d 100644 --- a/drivers/video/fbdev/s3c2410fb.c +++ b/drivers/video/fbdev/s3c2410fb.c | |||
@@ -601,12 +601,12 @@ static int s3c2410fb_debug_store(struct device *dev, | |||
601 | if (len < 1) | 601 | if (len < 1) |
602 | return -EINVAL; | 602 | return -EINVAL; |
603 | 603 | ||
604 | if (strnicmp(buf, "on", 2) == 0 || | 604 | if (strncasecmp(buf, "on", 2) == 0 || |
605 | strnicmp(buf, "1", 1) == 0) { | 605 | strncasecmp(buf, "1", 1) == 0) { |
606 | debug = 1; | 606 | debug = 1; |
607 | dev_dbg(dev, "s3c2410fb: Debug On"); | 607 | dev_dbg(dev, "s3c2410fb: Debug On"); |
608 | } else if (strnicmp(buf, "off", 3) == 0 || | 608 | } else if (strncasecmp(buf, "off", 3) == 0 || |
609 | strnicmp(buf, "0", 1) == 0) { | 609 | strncasecmp(buf, "0", 1) == 0) { |
610 | debug = 0; | 610 | debug = 0; |
611 | dev_dbg(dev, "s3c2410fb: Debug Off"); | 611 | dev_dbg(dev, "s3c2410fb: Debug Off"); |
612 | } else { | 612 | } else { |
diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c index 3f12a2dd959a..4f5cf035ac3c 100644 --- a/drivers/video/fbdev/sis/sis_main.c +++ b/drivers/video/fbdev/sis/sis_main.c | |||
@@ -162,7 +162,7 @@ static void sisfb_search_mode(char *name, bool quiet) | |||
162 | return; | 162 | return; |
163 | } | 163 | } |
164 | 164 | ||
165 | if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { | 165 | if(!strncasecmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { |
166 | if(!quiet) | 166 | if(!quiet) |
167 | printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); | 167 | printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); |
168 | 168 | ||
@@ -201,7 +201,7 @@ static void sisfb_search_mode(char *name, bool quiet) | |||
201 | 201 | ||
202 | i = 0; j = 0; | 202 | i = 0; j = 0; |
203 | while(sisbios_mode[i].mode_no[0] != 0) { | 203 | while(sisbios_mode[i].mode_no[0] != 0) { |
204 | if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) { | 204 | if(!strncasecmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) { |
205 | if(sisfb_fstn) { | 205 | if(sisfb_fstn) { |
206 | if(sisbios_mode[i-1].mode_no[1] == 0x50 || | 206 | if(sisbios_mode[i-1].mode_no[1] == 0x50 || |
207 | sisbios_mode[i-1].mode_no[1] == 0x56 || | 207 | sisbios_mode[i-1].mode_no[1] == 0x56 || |
@@ -262,7 +262,7 @@ sisfb_search_crt2type(const char *name) | |||
262 | if(name == NULL) return; | 262 | if(name == NULL) return; |
263 | 263 | ||
264 | while(sis_crt2type[i].type_no != -1) { | 264 | while(sis_crt2type[i].type_no != -1) { |
265 | if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) { | 265 | if(!strncasecmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) { |
266 | sisfb_crt2type = sis_crt2type[i].type_no; | 266 | sisfb_crt2type = sis_crt2type[i].type_no; |
267 | sisfb_tvplug = sis_crt2type[i].tvplug_no; | 267 | sisfb_tvplug = sis_crt2type[i].tvplug_no; |
268 | sisfb_crt2flags = sis_crt2type[i].flags; | 268 | sisfb_crt2flags = sis_crt2type[i].flags; |
@@ -289,7 +289,7 @@ sisfb_search_tvstd(const char *name) | |||
289 | return; | 289 | return; |
290 | 290 | ||
291 | while(sis_tvtype[i].type_no != -1) { | 291 | while(sis_tvtype[i].type_no != -1) { |
292 | if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) { | 292 | if(!strncasecmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) { |
293 | sisfb_tvstd = sis_tvtype[i].type_no; | 293 | sisfb_tvstd = sis_tvtype[i].type_no; |
294 | break; | 294 | break; |
295 | } | 295 | } |
@@ -308,12 +308,12 @@ sisfb_search_specialtiming(const char *name) | |||
308 | if(name == NULL) | 308 | if(name == NULL) |
309 | return; | 309 | return; |
310 | 310 | ||
311 | if(!strnicmp(name, "none", 4)) { | 311 | if(!strncasecmp(name, "none", 4)) { |
312 | sisfb_specialtiming = CUT_FORCENONE; | 312 | sisfb_specialtiming = CUT_FORCENONE; |
313 | printk(KERN_DEBUG "sisfb: Special timing disabled\n"); | 313 | printk(KERN_DEBUG "sisfb: Special timing disabled\n"); |
314 | } else { | 314 | } else { |
315 | while(mycustomttable[i].chipID != 0) { | 315 | while(mycustomttable[i].chipID != 0) { |
316 | if(!strnicmp(name,mycustomttable[i].optionName, | 316 | if(!strncasecmp(name,mycustomttable[i].optionName, |
317 | strlen(mycustomttable[i].optionName))) { | 317 | strlen(mycustomttable[i].optionName))) { |
318 | sisfb_specialtiming = mycustomttable[i].SpecialID; | 318 | sisfb_specialtiming = mycustomttable[i].SpecialID; |
319 | found = true; | 319 | found = true; |
@@ -3952,68 +3952,68 @@ static int __init sisfb_setup(char *options) | |||
3952 | 3952 | ||
3953 | if(!(*this_opt)) continue; | 3953 | if(!(*this_opt)) continue; |
3954 | 3954 | ||
3955 | if(!strnicmp(this_opt, "off", 3)) { | 3955 | if(!strncasecmp(this_opt, "off", 3)) { |
3956 | sisfb_off = 1; | 3956 | sisfb_off = 1; |
3957 | } else if(!strnicmp(this_opt, "forcecrt2type:", 14)) { | 3957 | } else if(!strncasecmp(this_opt, "forcecrt2type:", 14)) { |
3958 | /* Need to check crt2 type first for fstn/dstn */ | 3958 | /* Need to check crt2 type first for fstn/dstn */ |
3959 | sisfb_search_crt2type(this_opt + 14); | 3959 | sisfb_search_crt2type(this_opt + 14); |
3960 | } else if(!strnicmp(this_opt, "tvmode:",7)) { | 3960 | } else if(!strncasecmp(this_opt, "tvmode:",7)) { |
3961 | sisfb_search_tvstd(this_opt + 7); | 3961 | sisfb_search_tvstd(this_opt + 7); |
3962 | } else if(!strnicmp(this_opt, "tvstandard:",11)) { | 3962 | } else if(!strncasecmp(this_opt, "tvstandard:",11)) { |
3963 | sisfb_search_tvstd(this_opt + 11); | 3963 | sisfb_search_tvstd(this_opt + 11); |
3964 | } else if(!strnicmp(this_opt, "mode:", 5)) { | 3964 | } else if(!strncasecmp(this_opt, "mode:", 5)) { |
3965 | sisfb_search_mode(this_opt + 5, false); | 3965 | sisfb_search_mode(this_opt + 5, false); |
3966 | } else if(!strnicmp(this_opt, "vesa:", 5)) { | 3966 | } else if(!strncasecmp(this_opt, "vesa:", 5)) { |
3967 | sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false); | 3967 | sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false); |
3968 | } else if(!strnicmp(this_opt, "rate:", 5)) { | 3968 | } else if(!strncasecmp(this_opt, "rate:", 5)) { |
3969 | sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); | 3969 | sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); |
3970 | } else if(!strnicmp(this_opt, "forcecrt1:", 10)) { | 3970 | } else if(!strncasecmp(this_opt, "forcecrt1:", 10)) { |
3971 | sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0); | 3971 | sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0); |
3972 | } else if(!strnicmp(this_opt, "mem:",4)) { | 3972 | } else if(!strncasecmp(this_opt, "mem:",4)) { |
3973 | sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0); | 3973 | sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0); |
3974 | } else if(!strnicmp(this_opt, "pdc:", 4)) { | 3974 | } else if(!strncasecmp(this_opt, "pdc:", 4)) { |
3975 | sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0); | 3975 | sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0); |
3976 | } else if(!strnicmp(this_opt, "pdc1:", 5)) { | 3976 | } else if(!strncasecmp(this_opt, "pdc1:", 5)) { |
3977 | sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0); | 3977 | sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0); |
3978 | } else if(!strnicmp(this_opt, "noaccel", 7)) { | 3978 | } else if(!strncasecmp(this_opt, "noaccel", 7)) { |
3979 | sisfb_accel = 0; | 3979 | sisfb_accel = 0; |
3980 | } else if(!strnicmp(this_opt, "accel", 5)) { | 3980 | } else if(!strncasecmp(this_opt, "accel", 5)) { |
3981 | sisfb_accel = -1; | 3981 | sisfb_accel = -1; |
3982 | } else if(!strnicmp(this_opt, "noypan", 6)) { | 3982 | } else if(!strncasecmp(this_opt, "noypan", 6)) { |
3983 | sisfb_ypan = 0; | 3983 | sisfb_ypan = 0; |
3984 | } else if(!strnicmp(this_opt, "ypan", 4)) { | 3984 | } else if(!strncasecmp(this_opt, "ypan", 4)) { |
3985 | sisfb_ypan = -1; | 3985 | sisfb_ypan = -1; |
3986 | } else if(!strnicmp(this_opt, "nomax", 5)) { | 3986 | } else if(!strncasecmp(this_opt, "nomax", 5)) { |
3987 | sisfb_max = 0; | 3987 | sisfb_max = 0; |
3988 | } else if(!strnicmp(this_opt, "max", 3)) { | 3988 | } else if(!strncasecmp(this_opt, "max", 3)) { |
3989 | sisfb_max = -1; | 3989 | sisfb_max = -1; |
3990 | } else if(!strnicmp(this_opt, "userom:", 7)) { | 3990 | } else if(!strncasecmp(this_opt, "userom:", 7)) { |
3991 | sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0); | 3991 | sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0); |
3992 | } else if(!strnicmp(this_opt, "useoem:", 7)) { | 3992 | } else if(!strncasecmp(this_opt, "useoem:", 7)) { |
3993 | sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); | 3993 | sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); |
3994 | } else if(!strnicmp(this_opt, "nocrt2rate", 10)) { | 3994 | } else if(!strncasecmp(this_opt, "nocrt2rate", 10)) { |
3995 | sisfb_nocrt2rate = 1; | 3995 | sisfb_nocrt2rate = 1; |
3996 | } else if(!strnicmp(this_opt, "scalelcd:", 9)) { | 3996 | } else if(!strncasecmp(this_opt, "scalelcd:", 9)) { |
3997 | unsigned long temp = 2; | 3997 | unsigned long temp = 2; |
3998 | temp = simple_strtoul(this_opt + 9, NULL, 0); | 3998 | temp = simple_strtoul(this_opt + 9, NULL, 0); |
3999 | if((temp == 0) || (temp == 1)) { | 3999 | if((temp == 0) || (temp == 1)) { |
4000 | sisfb_scalelcd = temp ^ 1; | 4000 | sisfb_scalelcd = temp ^ 1; |
4001 | } | 4001 | } |
4002 | } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) { | 4002 | } else if(!strncasecmp(this_opt, "tvxposoffset:", 13)) { |
4003 | int temp = 0; | 4003 | int temp = 0; |
4004 | temp = (int)simple_strtol(this_opt + 13, NULL, 0); | 4004 | temp = (int)simple_strtol(this_opt + 13, NULL, 0); |
4005 | if((temp >= -32) && (temp <= 32)) { | 4005 | if((temp >= -32) && (temp <= 32)) { |
4006 | sisfb_tvxposoffset = temp; | 4006 | sisfb_tvxposoffset = temp; |
4007 | } | 4007 | } |
4008 | } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) { | 4008 | } else if(!strncasecmp(this_opt, "tvyposoffset:", 13)) { |
4009 | int temp = 0; | 4009 | int temp = 0; |
4010 | temp = (int)simple_strtol(this_opt + 13, NULL, 0); | 4010 | temp = (int)simple_strtol(this_opt + 13, NULL, 0); |
4011 | if((temp >= -32) && (temp <= 32)) { | 4011 | if((temp >= -32) && (temp <= 32)) { |
4012 | sisfb_tvyposoffset = temp; | 4012 | sisfb_tvyposoffset = temp; |
4013 | } | 4013 | } |
4014 | } else if(!strnicmp(this_opt, "specialtiming:", 14)) { | 4014 | } else if(!strncasecmp(this_opt, "specialtiming:", 14)) { |
4015 | sisfb_search_specialtiming(this_opt + 14); | 4015 | sisfb_search_specialtiming(this_opt + 14); |
4016 | } else if(!strnicmp(this_opt, "lvdshl:", 7)) { | 4016 | } else if(!strncasecmp(this_opt, "lvdshl:", 7)) { |
4017 | int temp = 4; | 4017 | int temp = 4; |
4018 | temp = simple_strtoul(this_opt + 7, NULL, 0); | 4018 | temp = simple_strtoul(this_opt + 7, NULL, 0); |
4019 | if((temp >= 0) && (temp <= 3)) { | 4019 | if((temp >= 0) && (temp <= 3)) { |
@@ -4022,9 +4022,9 @@ static int __init sisfb_setup(char *options) | |||
4022 | } else if(this_opt[0] >= '0' && this_opt[0] <= '9') { | 4022 | } else if(this_opt[0] >= '0' && this_opt[0] <= '9') { |
4023 | sisfb_search_mode(this_opt, true); | 4023 | sisfb_search_mode(this_opt, true); |
4024 | #if !defined(__i386__) && !defined(__x86_64__) | 4024 | #if !defined(__i386__) && !defined(__x86_64__) |
4025 | } else if(!strnicmp(this_opt, "resetcard", 9)) { | 4025 | } else if(!strncasecmp(this_opt, "resetcard", 9)) { |
4026 | sisfb_resetcard = 1; | 4026 | sisfb_resetcard = 1; |
4027 | } else if(!strnicmp(this_opt, "videoram:", 9)) { | 4027 | } else if(!strncasecmp(this_opt, "videoram:", 9)) { |
4028 | sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0); | 4028 | sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0); |
4029 | #endif | 4029 | #endif |
4030 | } else { | 4030 | } else { |
diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c index c2c8eb668784..9e74e8fbe074 100644 --- a/drivers/video/fbdev/sm501fb.c +++ b/drivers/video/fbdev/sm501fb.c | |||
@@ -1187,9 +1187,9 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev, | |||
1187 | if (len < 1) | 1187 | if (len < 1) |
1188 | return -EINVAL; | 1188 | return -EINVAL; |
1189 | 1189 | ||
1190 | if (strnicmp(buf, "crt", 3) == 0) | 1190 | if (strncasecmp(buf, "crt", 3) == 0) |
1191 | head = HEAD_CRT; | 1191 | head = HEAD_CRT; |
1192 | else if (strnicmp(buf, "panel", 5) == 0) | 1192 | else if (strncasecmp(buf, "panel", 5) == 0) |
1193 | head = HEAD_PANEL; | 1193 | head = HEAD_PANEL; |
1194 | else | 1194 | else |
1195 | return -EINVAL; | 1195 | return -EINVAL; |