diff options
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 7d6e84a5142..55b83983a9c 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c @@ -14,11 +14,14 @@ struct dma_coherent_mem { int size; int flags; unsigned long *bitmap; + spinlock_t spinlock; }; -int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, - dma_addr_t device_addr, size_t size, int flags) +static int dma_init_coherent_memory(phys_addr_t phys_addr, dma_addr_t device_addr, + size_t size, int flags, + struct dma_coherent_mem **mem) { + struct dma_coherent_mem *dma_mem = NULL; void __iomem *mem_base = NULL; int pages = size >> PAGE_SHIFT; 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, goto out; if (!size) goto out; - if (dev->dma_mem) - goto out; - - /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ mem_base = ioremap(phys_addr, size); if (!mem_base) goto out; - dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); - if (!dev->dma_mem) + dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); + if (!dma_mem) goto out; - dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); - if (!dev->dma_mem->bitmap) - goto free1_out; + dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); + if (!dma_mem->bitmap) + goto out; + + dma_mem->virt_base = mem_base; + dma_mem->device_base = device_addr; + dma_mem->pfn_base = PFN_DOWN(phys_addr); + dma_mem->size = pages; + dma_mem->flags = flags; + spin_lock_init(&dma_mem->spinlock); - dev->dma_mem->virt_base = mem_base; - dev->dma_mem->device_base = device_addr; - dev->dma_mem->pfn_base = PFN_DOWN(phys_addr); - dev->dma_mem->size = pages; - dev->dma_mem->flags = flags; + *mem = dma_mem; if (flags & DMA_MEMORY_MAP) return DMA_MEMORY_MAP; return DMA_MEMORY_IO; - free1_out: - kfree(dev->dma_mem); - out: +out: + kfree(dma_mem); if (mem_base) iounmap(mem_base); return 0; } + +static void dma_release_coherent_memory(struct dma_coherent_mem *mem) +{ + if (!mem) + return; + iounmap(mem->virt_base); + kfree(mem->bitmap); + kfree(mem); +} + +static int dma_assign_coherent_memory(struct device *dev, + struct dma_coherent_mem *mem) +{ + if (dev->dma_mem) + return -EBUSY; + + dev->dma_mem = mem; + /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ + + return 0; +} + +int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, + dma_addr_t device_addr, size_t size, int flags) +{ + struct dma_coherent_mem *mem; + int ret; + + ret = dma_init_coherent_memory(phys_addr, device_addr, size, flags, + &mem); + if (ret == 0) + return 0; + + if (dma_assign_coherent_memory(dev, mem) == 0) + return ret; + + dma_release_coherent_memory(mem); + return 0; +} EXPORT_SYMBOL(dma_declare_coherent_memory); void dma_release_declared_memory(struct device *dev) @@ -69,10 +109,8 @@ void dma_release_declared_memory(struct device *dev) if (!mem) return; + dma_release_coherent_memory(mem); dev->dma_mem = NULL; - iounmap(mem->virt_base); - kfree(mem->bitmap); - kfree(mem); } EXPORT_SYMBOL(dma_release_declared_memory); @@ -80,6 +118,7 @@ void *dma_mark_declared_memory_occupied(struct device *dev, dma_addr_t device_addr, size_t size) { struct dma_coherent_mem *mem = dev->dma_mem; + unsigned long flags; int pos, err; size += device_addr & ~PAGE_MASK; @@ -87,8 +126,11 @@ void *dma_mark_declared_memory_occupied(struct device *dev, if (!mem) return ERR_PTR(-EINVAL); + spin_lock_irqsave(&mem->spinlock, flags); pos = (device_addr - mem->device_base) >> PAGE_SHIFT; err = bitmap_allocate_region(mem->bitmap, pos, get_order(size)); + spin_unlock_irqrestore(&mem->spinlock, flags); + if (err != 0) return ERR_PTR(err); return mem->virt_base + (pos << PAGE_SHIFT); @@ -115,6 +157,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, { struct dma_coherent_mem *mem; int order = get_order(size); + unsigned long flags; int pageno; if (!dev) @@ -124,6 +167,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, return 0; *ret = NULL; + spin_lock_irqsave(&mem->spinlock, flags); if (unlikely(size > (mem->size << PAGE_SHIFT))) goto err; @@ -138,10 +182,12 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, *dma_handle = mem->device_base + (pageno << PAGE_SHIFT); *ret = mem->virt_base + (pageno << PAGE_SHIFT); memset(*ret, 0, size); + spin_unlock_irqrestore(&mem->spinlock, flags); return 1; err: + spin_unlock_irqrestore(&mem->spinlock, flags); /* * In the case where the allocation can not be satisfied from the * 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) if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; + unsigned long flags; + spin_lock_irqsave(&mem->spinlock, flags); bitmap_release_region(mem->bitmap, page, order); + spin_unlock_irqrestore(&mem->spinlock, flags); return 1; } return 0; @@ -218,3 +267,61 @@ int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma, return 0; } EXPORT_SYMBOL(dma_mmap_from_coherent); + +/* + * Support for reserved memory regions defined in device tree + */ +#ifdef CONFIG_OF_RESERVED_MEM +#include <linux/of.h> +#include <linux/of_fdt.h> +#include <linux/of_reserved_mem.h> + +static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev) +{ + struct dma_coherent_mem *mem = rmem->priv; + + if (!mem && + dma_init_coherent_memory(rmem->base, rmem->base, rmem->size, + DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE, + &mem) != DMA_MEMORY_MAP) { + pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n", + &rmem->base, (unsigned long)rmem->size / SZ_1M); + return -ENODEV; + } + rmem->priv = mem; + dma_assign_coherent_memory(dev, mem); + return 0; +} + +static void rmem_dma_device_release(struct reserved_mem *rmem, + struct device *dev) +{ + dev->dma_mem = NULL; +} + +static const struct reserved_mem_ops rmem_dma_ops = { + .device_init = rmem_dma_device_init, + .device_release = rmem_dma_device_release, +}; + +static int __init rmem_dma_setup(struct reserved_mem *rmem) +{ + unsigned long node = rmem->fdt_node; + + if (of_get_flat_dt_prop(node, "reusable", NULL)) + return -EINVAL; + +#ifdef CONFIG_ARM + if (!of_get_flat_dt_prop(node, "no-map", NULL)) { + pr_err("Reserved memory: regions without no-map are not yet supported\n"); + return -EINVAL; + } +#endif + + rmem->ops = &rmem_dma_ops; + pr_info("Reserved memory: created DMA memory pool at %pa, size %ld MiB\n", + &rmem->base, (unsigned long)rmem->size / SZ_1M); + return 0; +} +RESERVEDMEM_OF_DECLARE(dma, "shared-dma-pool", rmem_dma_setup); +#endif diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 6606abdf880..473ff489240 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, { return cma_release(dev_get_cma_area(dev), pages, count); } + +/* + * Support for reserved memory regions defined in device tree + */ +#ifdef CONFIG_OF_RESERVED_MEM +#include <linux/of.h> +#include <linux/of_fdt.h> +#include <linux/of_reserved_mem.h> + +#undef pr_fmt +#define pr_fmt(fmt) fmt + +static void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev) +{ + dev_set_cma_area(dev, rmem->priv); +} + +static void rmem_cma_device_release(struct reserved_mem *rmem, + struct device *dev) +{ + dev_set_cma_area(dev, NULL); +} + +static const struct reserved_mem_ops rmem_cma_ops = { + .device_init = rmem_cma_device_init, + .device_release = rmem_cma_device_release, +}; + +static int __init rmem_cma_setup(struct reserved_mem *rmem) +{ + phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); + phys_addr_t mask = align - 1; + unsigned long node = rmem->fdt_node; + struct cma *cma; + int err; + + if (!of_get_flat_dt_prop(node, "reusable", NULL) || + of_get_flat_dt_prop(node, "no-map", NULL)) + return -EINVAL; + + if ((rmem->base & mask) || (rmem->size & mask)) { + pr_err("Reserved memory: incorrect alignment of CMA region\n"); + return -EINVAL; + } + + err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma); + if (err) { + pr_err("Reserved memory: unable to setup CMA region\n"); + return err; + } + /* Architecture specific contiguous memory fixup. */ + dma_contiguous_early_fixup(rmem->base, rmem->size); + + if (of_get_flat_dt_prop(node, "linux,cma-default", NULL)) + dma_contiguous_set_default(cma); + + rmem->ops = &rmem_cma_ops; + rmem->priv = cma; + + pr_info("Reserved memory: created CMA memory pool at %pa, size %ld MiB\n", + &rmem->base, (unsigned long)rmem->size / SZ_1M); + + return 0; +} +RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup); +#endif diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index cfd3af7b2cb..84e0590e31d 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -38,6 +38,15 @@ config COMMON_CLK_MAX77686 ---help--- This driver supports Maxim 77686 crystal oscillator clock. +config COMMON_CLK_RK808 + tristate "Clock driver for RK808" + depends on MFD_RK808 + ---help--- + This driver supports RK808 crystal oscillator clock. These + multi-function devices have two fixed-rate oscillators, + clocked at 32KHz each. Clkout1 is always on, Clkout2 can off + by control register. + config COMMON_CLK_SI5351 tristate "Clock driver for SiLabs 5351A/B/C" depends on I2C diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f537a0b1f79..99f53d5f876 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o +obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o 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 00000000000..83902b9cd49 --- /dev/null +++ b/drivers/clk/clk-rk808.c @@ -0,0 +1,170 @@ +/* + * Clkout driver for Rockchip RK808 + * + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd + * + * Author:Chris Zhong <zyw@rock-chips.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/platform_device.h> +#include <linux/mfd/rk808.h> +#include <linux/i2c.h> + +#define RK808_NR_OUTPUT 2 + +struct rk808_clkout { + struct rk808 *rk808; + struct clk_onecell_data clk_data; + struct clk_hw clkout1_hw; + struct clk_hw clkout2_hw; +}; + +static unsigned long rk808_clkout_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return 32768; +} + +static int rk808_clkout2_enable(struct clk_hw *hw, bool enable) +{ + struct rk808_clkout *rk808_clkout = container_of(hw, + struct rk808_clkout, + clkout2_hw); + struct rk808 *rk808 = rk808_clkout->rk808; + + return regmap_update_bits(rk808->regmap, RK808_CLK32OUT_REG, + CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0); +} + +static int rk808_clkout2_prepare(struct clk_hw *hw) +{ + return rk808_clkout2_enable(hw, true); +} + +static void rk808_clkout2_unprepare(struct clk_hw *hw) +{ + rk808_clkout2_enable(hw, false); +} + +static int rk808_clkout2_is_prepared(struct clk_hw *hw) +{ + struct rk808_clkout *rk808_clkout = container_of(hw, + struct rk808_clkout, + clkout2_hw); + struct rk808 *rk808 = rk808_clkout->rk808; + uint32_t val; + + int ret = regmap_read(rk808->regmap, RK808_CLK32OUT_REG, &val); + + if (ret < 0) + return ret; + + return (val & CLK32KOUT2_EN) ? 1 : 0; +} + +static const struct clk_ops rk808_clkout1_ops = { + .recalc_rate = rk808_clkout_recalc_rate, +}; + +static const struct clk_ops rk808_clkout2_ops = { + .prepare = rk808_clkout2_prepare, + .unprepare = rk808_clkout2_unprepare, + .is_prepared = rk808_clkout2_is_prepared, + .recalc_rate = rk808_clkout_recalc_rate, +}; + +static int rk808_clkout_probe(struct platform_device *pdev) +{ + struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); + struct i2c_client *client = rk808->i2c; + struct device_node *node = client->dev.of_node; + struct clk_init_data init = {}; + struct clk **clk_table; + struct rk808_clkout *rk808_clkout; + + rk808_clkout = devm_kzalloc(&client->dev, + sizeof(*rk808_clkout), GFP_KERNEL); + if (!rk808_clkout) + return -ENOMEM; + + rk808_clkout->rk808 = rk808; + + clk_table = devm_kcalloc(&client->dev, RK808_NR_OUTPUT, + sizeof(struct clk *), GFP_KERNEL); + if (!clk_table) + return -ENOMEM; + + init.flags = CLK_IS_ROOT; + init.parent_names = NULL; + init.num_parents = 0; + init.name = "rk808-clkout1"; + init.ops = &rk808_clkout1_ops; + rk808_clkout->clkout1_hw.init = &init; + + /* optional override of the clockname */ + of_property_read_string_index(node, "clock-output-names", + 0, &init.name); + + clk_table[0] = devm_clk_register(&client->dev, + &rk808_clkout->clkout1_hw); + if (IS_ERR(clk_table[0])) + return PTR_ERR(clk_table[0]); + + init.name = "rk808-clkout2"; + init.ops = &rk808_clkout2_ops; + rk808_clkout->clkout2_hw.init = &init; + + /* optional override of the clockname */ + of_property_read_string_index(node, "clock-output-names", + 1, &init.name); + + clk_table[1] = devm_clk_register(&client->dev, + &rk808_clkout->clkout2_hw); + if (IS_ERR(clk_table[1])) + return PTR_ERR(clk_table[1]); + + rk808_clkout->clk_data.clks = clk_table; + rk808_clkout->clk_data.clk_num = RK808_NR_OUTPUT; + + return of_clk_add_provider(node, of_clk_src_onecell_get, + &rk808_clkout->clk_data); +} + +static int rk808_clkout_remove(struct platform_device *pdev) +{ + struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); + struct i2c_client *client = rk808->i2c; + struct device_node *node = client->dev.of_node; + + of_clk_del_provider(node); + + return 0; +} + +static struct platform_driver rk808_clkout_driver = { + .probe = rk808_clkout_probe, + .remove = rk808_clkout_remove, + .driver = { + .name = "rk808-clkout", + }, +}; + +module_platform_driver(rk808_clkout_driver); + +MODULE_DESCRIPTION("Clkout driver for the rk808 series PMICs"); +MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:rk808-clkout"); diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index d28a8c284da..7206547c13c 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) int ret, rc; p = name; - if (strnicmp(p, "0x", 2) == 0) + if (strncasecmp(p, "0x", 2) == 0) p += 2; ret = -EINVAL; len = strlen(p); diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 8857d5b9be7..ee3434f1e94 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, /* if we find something consistent, stay with that assumption * at least M09 won't send 3 bytes here */ - if (!(strnicmp(rdbuf + 1, "EP0", 3))) { + if (!(strncasecmp(rdbuf + 1, "EP0", 3))) { tsdata->version = M06; /* remove last '$' end marker */ diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 31727bf285d..e2a4f5f415b 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) r592_set_mode(dev, dev->parallel_mode); } +#ifdef CONFIG_PM_SLEEP /* Disable all hardware interrupts */ static void r592_clear_interrupts(struct r592_device *dev) { @@ -195,6 +196,7 @@ static void r592_clear_interrupts(struct r592_device *dev) r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_ACK_MASK); r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_EN_MASK); } +#endif /* Tests if there is an CRC error */ 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 24272e022be..bca2630d006 100644 --- a/drivers/misc/altera-stapl/altera.c +++ b/drivers/misc/altera-stapl/altera.c @@ -454,7 +454,7 @@ exit_done: name = &p[str_table + name_id]; - if (strnicmp(aconf->action, name, strlen(name)) == 0) { + if (strncasecmp(aconf->action, name, strlen(name)) == 0) { action_found = 1; current_proc = get_unaligned_be32(&p[action_table + @@ -2176,7 +2176,7 @@ static int altera_get_note(u8 *p, s32 program_size, key_ptr = &p[note_strings + get_unaligned_be32( &p[note_table + (8 * i)])]; - if ((strnicmp(key, key_ptr, strlen(key_ptr)) == 0) && + if ((strncasecmp(key, key_ptr, strlen(key_ptr)) == 0) && (key != NULL)) { status = 0; diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index 8efd17c52f6..dd84557cf95 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) local_info_t *local = m->private; struct list_head *ptr = v; struct hostap_bss_info *bss; - int i; if (ptr == &local->bss_list) { 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) bss->bssid, bss->last_update, bss->count, bss->capab_info); - for (i = 0; i < bss->ssid_len; i++) - seq_putc(m,bss->ssid[i] >= 32 && bss->ssid[i] < 127 ? - bss->ssid[i] : '_'); + seq_printf(m, "%*pE", (int)bss->ssid_len, bss->ssid); seq_putc(m, '\t'); 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 c3d726f334e..6fabea0309d 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) u32 chan; char *txratename; u8 bssid[ETH_ALEN]; - DECLARE_SSID_BUF(ssid); /* * 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) break; } - IPW_DEBUG_INFO("%s: Associated with '%s' at %s, channel %d (BSSID=%pM)\n", - priv->net_dev->name, print_ssid(ssid, essid, essid_len), + IPW_DEBUG_INFO("%s: Associated with '%*pE' at %s, channel %d (BSSID=%pM)\n", + priv->net_dev->name, essid_len, essid, txratename, chan, bssid); /* now we copy read ssid into dev */ @@ -2095,9 +2094,8 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, .host_command_length = ssid_len }; int err; - DECLARE_SSID_BUF(ssid); - IPW_DEBUG_HC("SSID: '%s'\n", print_ssid(ssid, essid, ssid_len)); + IPW_DEBUG_HC("SSID: '%*pE'\n", ssid_len, essid); if (ssid_len) memcpy(cmd.host_command_parameters, essid, ssid_len); @@ -2138,11 +2136,8 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status) { - DECLARE_SSID_BUF(ssid); - IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "disassociated: '%s' %pM\n", - print_ssid(ssid, priv->essid, priv->essid_len), + "disassociated: '%*pE' %pM\n", priv->essid_len, priv->essid, priv->bssid); priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); @@ -6975,7 +6970,6 @@ static int ipw2100_wx_set_essid(struct net_device *dev, char *essid = ""; /* ANY */ int length = 0; int err = 0; - DECLARE_SSID_BUF(ssid); mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { @@ -7005,8 +6999,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev, goto done; } - IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", - print_ssid(ssid, essid, length), length); + IPW_DEBUG_WX("Setting ESSID: '%*pE' (%d)\n", length, essid, length); priv->essid_len = length; memcpy(priv->essid, essid, priv->essid_len); @@ -7027,13 +7020,12 @@ static int ipw2100_wx_get_essid(struct net_device *dev, */ struct ipw2100_priv *priv = libipw_priv(dev); - DECLARE_SSID_BUF(ssid); /* If we are associated, trying to associate, or have a statically * configured ESSID then return that; otherwise return ANY */ if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) { - IPW_DEBUG_WX("Getting essid: '%s'\n", - print_ssid(ssid, priv->essid, priv->essid_len)); + IPW_DEBUG_WX("Getting essid: '%*pE'\n", + priv->essid_len, priv->essid); memcpy(extra, priv->essid, priv->essid_len); wrqu->essid.length = priv->essid_len; wrqu->essid.flags = 1; /* active */ diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index f0c3c77a48d..edc344334a7 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) static void ipw_rx_notification(struct ipw_priv *priv, struct ipw_rx_notification *notif) { - DECLARE_SSID_BUF(ssid); u16 size = le16_to_cpu(notif->size); IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size); @@ -4509,9 +4508,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, case CMAS_ASSOCIATED:{ IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "associated: '%s' %pM\n", - print_ssid(ssid, priv->essid, - priv->essid_len), + "associated: '%*pE' %pM\n", + priv->essid_len, priv->essid, priv->bssid); switch (priv->ieee->iw_mode) { @@ -4585,14 +4583,9 @@ static void ipw_rx_notification(struct ipw_priv *priv, IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "deauthenticated: '%s' " - "%pM" - ": (0x%04X) - %s\n", - print_ssid(ssid, - priv-> - essid, - priv-> - essid_len), + "deauthenticated: '%*pE' %pM: (0x%04X) - %s\n", + priv->essid_len, + priv->essid, priv->bssid, le16_to_cpu(auth->status), ipw_get_status_code @@ -4610,9 +4603,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "authenticated: '%s' %pM\n", - print_ssid(ssid, priv->essid, - priv->essid_len), + "authenticated: '%*pE' %pM\n", + priv->essid_len, priv->essid, priv->bssid); break; } @@ -4638,9 +4630,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "disassociated: '%s' %pM\n", - print_ssid(ssid, priv->essid, - priv->essid_len), + "disassociated: '%*pE' %pM\n", + priv->essid_len, priv->essid, priv->bssid); priv->status &= @@ -4676,9 +4667,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, switch (auth->state) { case CMAS_AUTHENTICATED: IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, - "authenticated: '%s' %pM\n", - print_ssid(ssid, priv->essid, - priv->essid_len), + "authenticated: '%*pE' %pM\n", + priv->essid_len, priv->essid, priv->bssid); priv->status |= STATUS_AUTH; break; @@ -4695,9 +4685,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, } IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "deauthenticated: '%s' %pM\n", - print_ssid(ssid, priv->essid, - priv->essid_len), + "deauthenticated: '%*pE' %pM\n", + priv->essid_len, priv->essid, priv->bssid); priv->status &= ~(STATUS_ASSOCIATING | @@ -5516,16 +5505,13 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, int roaming) { struct ipw_supported_rates rates; - DECLARE_SSID_BUF(ssid); /* Verify that this network's capability is compatible with the * current mode (AdHoc or Infrastructure) */ if ((priv->ieee->iw_mode == IW_MODE_ADHOC && !(network->capability & WLAN_CAPABILITY_IBSS))) { - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded due to " - "capability mismatch.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded due to capability mismatch.\n", + network->ssid_len, network->ssid, network->bssid); return 0; } @@ -5536,10 +5522,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, if ((network->ssid_len != match->network->ssid_len) || memcmp(network->ssid, match->network->ssid, network->ssid_len)) { - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " - "because of non-network ESSID.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of non-network ESSID.\n", + network->ssid_len, network->ssid, network->bssid); return 0; } @@ -5550,17 +5534,10 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, ((network->ssid_len != priv->essid_len) || memcmp(network->ssid, priv->essid, min(network->ssid_len, priv->essid_len)))) { - char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - - strlcpy(escaped, - print_ssid(ssid, network->ssid, - network->ssid_len), - sizeof(escaped)); - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " - "because of ESSID mismatch: '%s'.\n", - escaped, network->bssid, - print_ssid(ssid, priv->essid, - priv->essid_len)); + IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n", + network->ssid_len, network->ssid, + network->bssid, priv->essid_len, + priv->essid); return 0; } } @@ -5569,26 +5546,20 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, * testing everything else. */ if (network->time_stamp[0] < match->network->time_stamp[0]) { - IPW_DEBUG_MERGE("Network '%s excluded because newer than " - "current network.\n", - print_ssid(ssid, match->network->ssid, - match->network->ssid_len)); + IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n", + match->network->ssid_len, match->network->ssid); return 0; } else if (network->time_stamp[1] < match->network->time_stamp[1]) { - IPW_DEBUG_MERGE("Network '%s excluded because newer than " - "current network.\n", - print_ssid(ssid, match->network->ssid, - match->network->ssid_len)); + IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n", + match->network->ssid_len, match->network->ssid); return 0; } /* Now go through and see if the requested network is valid... */ if (priv->ieee->scan_age != 0 && time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " - "because of age: %ums.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of age: %ums.\n", + network->ssid_len, network->ssid, network->bssid, jiffies_to_msecs(jiffies - network->last_scanned)); @@ -5597,10 +5568,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, if ((priv->config & CFG_STATIC_CHANNEL) && (network->channel != priv->channel)) { - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " - "because of channel mismatch: %d != %d.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n", + network->ssid_len, network->ssid, network->bssid, network->channel, priv->channel); return 0; @@ -5609,10 +5578,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, /* Verify privacy compatibility */ if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " - "because of privacy mismatch: %s != %s.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n", + network->ssid_len, network->ssid, network->bssid, priv-> capability & CAP_PRIVACY_ON ? "on" : "off", @@ -5623,22 +5590,16 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, } if (ether_addr_equal(network->bssid, priv->bssid)) { - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " - "because of the same BSSID match: %pM" - ".\n", print_ssid(ssid, network->ssid, - network->ssid_len), - network->bssid, - priv->bssid); + IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of the same BSSID match: %pM.\n", + network->ssid_len, network->ssid, + network->bssid, priv->bssid); return 0; } /* Filter out any incompatible freq / mode combinations */ if (!libipw_is_valid_mode(priv->ieee, network->mode)) { - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " - "because of invalid frequency/mode " - "combination.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n", + network->ssid_len, network->ssid, network->bssid); return 0; } @@ -5646,20 +5607,15 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, /* Ensure that the rates supported by the driver are compatible with * this AP, including verification of basic rates (mandatory) */ if (!ipw_compatible_rates(priv, network, &rates)) { - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " - "because configured rate mask excludes " - "AP mandatory rate.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n", + network->ssid_len, network->ssid, network->bssid); return 0; } if (rates.num_rates == 0) { - IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " - "because of no compatible rates.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of no compatible rates.\n", + network->ssid_len, network->ssid, network->bssid); return 0; } @@ -5671,16 +5627,14 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, /* Set up 'new' AP to this network */ ipw_copy_rates(&match->rates, &rates); match->network = network; - IPW_DEBUG_MERGE("Network '%s (%pM)' is a viable match.\n", - print_ssid(ssid, network->ssid, network->ssid_len), - network->bssid); + IPW_DEBUG_MERGE("Network '%*pE (%pM)' is a viable match.\n", + network->ssid_len, network->ssid, network->bssid); return 1; } static void ipw_merge_adhoc_network(struct work_struct *work) { - DECLARE_SSID_BUF(ssid); struct ipw_priv *priv = container_of(work, struct ipw_priv, merge_networks); struct libipw_network *network = NULL; @@ -5710,9 +5664,8 @@ static void ipw_merge_adhoc_network(struct work_struct *work) mutex_lock(&priv->mutex); if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { - IPW_DEBUG_MERGE("remove network %s\n", - print_ssid(ssid, priv->essid, - priv->essid_len)); + IPW_DEBUG_MERGE("remove network %*pE\n", + priv->essid_len, priv->essid); ipw_remove_current_network(priv); } @@ -5728,7 +5681,6 @@ static int ipw_best_network(struct ipw_priv *priv, struct libipw_network *network, int roaming) { struct ipw_supported_rates rates; - DECLARE_SSID_BUF(ssid); /* Verify that this network's capability is compatible with the * current mode (AdHoc or Infrastructure) */ @@ -5736,10 +5688,8 @@ static int ipw_best_network(struct ipw_priv *priv, !(network->capability & WLAN_CAPABILITY_ESS)) || (priv->ieee->iw_mode == IW_MODE_ADHOC && !(network->capability & WLAN_CAPABILITY_IBSS))) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded due to " - "capability mismatch.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded due to capability mismatch.\n", + network->ssid_len, network->ssid, network->bssid); return 0; } @@ -5750,10 +5700,8 @@ static int ipw_best_network(struct ipw_priv *priv, if ((network->ssid_len != match->network->ssid_len) || memcmp(network->ssid, match->network->ssid, network->ssid_len)) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because of non-network ESSID.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of non-network ESSID.\n", + network->ssid_len, network->ssid, network->bssid); return 0; } @@ -5764,16 +5712,10 @@ static int ipw_best_network(struct ipw_priv *priv, ((network->ssid_len != priv->essid_len) || memcmp(network->ssid, priv->essid, min(network->ssid_len, priv->essid_len)))) { - char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - strlcpy(escaped, - print_ssid(ssid, network->ssid, - network->ssid_len), - sizeof(escaped)); - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because of ESSID mismatch: '%s'.\n", - escaped, network->bssid, - print_ssid(ssid, priv->essid, - priv->essid_len)); + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n", + network->ssid_len, network->ssid, + network->bssid, priv->essid_len, + priv->essid); return 0; } } @@ -5781,16 +5723,10 @@ static int ipw_best_network(struct ipw_priv *priv, /* If the old network rate is better than this one, don't bother * testing everything else. */ if (match->network && match->network->stats.rssi > network->stats.rssi) { - char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - strlcpy(escaped, - print_ssid(ssid, network->ssid, network->ssid_len), - sizeof(escaped)); - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because " - "'%s (%pM)' has a stronger signal.\n", - escaped, network->bssid, - print_ssid(ssid, match->network->ssid, - match->network->ssid_len), - match->network->bssid); + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because '%*pE (%pM)' has a stronger signal.\n", + network->ssid_len, network->ssid, + network->bssid, match->network->ssid_len, + match->network->ssid, match->network->bssid); return 0; } @@ -5798,11 +5734,8 @@ static int ipw_best_network(struct ipw_priv *priv, * last 3 seconds, do not try and associate again... */ if (network->last_associate && time_after(network->last_associate + (HZ * 3UL), jiffies)) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because of storming (%ums since last " - "assoc attempt).\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of storming (%ums since last assoc attempt).\n", + network->ssid_len, network->ssid, network->bssid, jiffies_to_msecs(jiffies - network->last_associate)); @@ -5812,10 +5745,8 @@ static int ipw_best_network(struct ipw_priv *priv, /* Now go through and see if the requested network is valid... */ if (priv->ieee->scan_age != 0 && time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because of age: %ums.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of age: %ums.\n", + network->ssid_len, network->ssid, network->bssid, jiffies_to_msecs(jiffies - network->last_scanned)); @@ -5824,10 +5755,8 @@ static int ipw_best_network(struct ipw_priv *priv, if ((priv->config & CFG_STATIC_CHANNEL) && (network->channel != priv->channel)) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because of channel mismatch: %d != %d.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n", + network->ssid_len, network->ssid, network->bssid, network->channel, priv->channel); return 0; @@ -5836,10 +5765,8 @@ static int ipw_best_network(struct ipw_priv *priv, /* Verify privacy compatibility */ if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because of privacy mismatch: %s != %s.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n", + network->ssid_len, network->ssid, network->bssid, priv->capability & CAP_PRIVACY_ON ? "on" : "off", @@ -5850,31 +5777,24 @@ static int ipw_best_network(struct ipw_priv *priv, if ((priv->config & CFG_STATIC_BSSID) && !ether_addr_equal(network->bssid, priv->bssid)) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because of BSSID mismatch: %pM.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of BSSID mismatch: %pM.\n", + network->ssid_len, network->ssid, network->bssid, priv->bssid); return 0; } /* Filter out any incompatible freq / mode combinations */ if (!libipw_is_valid_mode(priv->ieee, network->mode)) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because of invalid frequency/mode " - "combination.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n", + network->ssid_len, network->ssid, network->bssid); return 0; } /* Filter out invalid channel in current GEO */ if (!libipw_is_valid_channel(priv->ieee, network->channel)) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because of invalid channel in current GEO\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid channel in current GEO\n", + network->ssid_len, network->ssid, network->bssid); return 0; } @@ -5882,20 +5802,15 @@ static int ipw_best_network(struct ipw_priv *priv, /* Ensure that the rates supported by the driver are compatible with * this AP, including verification of basic rates (mandatory) */ if (!ipw_compatible_rates(priv, network, &rates)) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because configured rate mask excludes " - "AP mandatory rate.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n", + network->ssid_len, network->ssid, network->bssid); return 0; } if (rates.num_rates == 0) { - IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " - "because of no compatible rates.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of no compatible rates.\n", + network->ssid_len, network->ssid, network->bssid); return 0; } @@ -5908,9 +5823,8 @@ static int ipw_best_network(struct ipw_priv *priv, ipw_copy_rates(&match->rates, &rates); match->network = network; - IPW_DEBUG_ASSOC("Network '%s (%pM)' is a viable match.\n", - print_ssid(ssid, network->ssid, network->ssid_len), - network->bssid); + IPW_DEBUG_ASSOC("Network '%*pE (%pM)' is a viable match.\n", + network->ssid_len, network->ssid, network->bssid); return 1; } @@ -6152,7 +6066,6 @@ static void ipw_bg_adhoc_check(struct work_struct *work) static void ipw_debug_config(struct ipw_priv *priv) { - DECLARE_SSID_BUF(ssid); IPW_DEBUG_INFO("Scan completed, no valid APs matched " "[CFG 0x%08X]\n", priv->config); if (priv->config & CFG_STATIC_CHANNEL) @@ -6160,8 +6073,8 @@ static void ipw_debug_config(struct ipw_priv *priv) else IPW_DEBUG_INFO("Channel unlocked.\n"); if (priv->config & CFG_STATIC_ESSID) - IPW_DEBUG_INFO("ESSID locked to '%s'\n", - print_ssid(ssid, priv->essid, priv->essid_len)); + IPW_DEBUG_INFO("ESSID locked to '%*pE'\n", + priv->essid_len, priv->essid); else IPW_DEBUG_INFO("ESSID unlocked.\n"); if (priv->config & CFG_STATIC_BSSID) @@ -7385,7 +7298,6 @@ static int ipw_associate_network(struct ipw_priv *priv, struct ipw_supported_rates *rates, int roaming) { int err; - DECLARE_SSID_BUF(ssid); if (priv->config & CFG_FIXED_RATE) ipw_set_fixed_rate(priv, network->mode); @@ -7451,10 +7363,9 @@ static int ipw_associate_network(struct ipw_priv *priv, priv->assoc_request.capability &= ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); - IPW_DEBUG_ASSOC("%ssociation attempt: '%s', channel %d, " - "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n", + IPW_DEBUG_ASSOC("%ssociation attempt: '%*pE', channel %d, 802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n", roaming ? "Rea" : "A", - print_ssid(ssid, priv->essid, priv->essid_len), + priv->essid_len, priv->essid, network->channel, ipw_modes[priv->assoc_request.ieee_mode], rates->num_rates, @@ -7553,9 +7464,8 @@ static int ipw_associate_network(struct ipw_priv *priv, return err; } - IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM\n", - print_ssid(ssid, priv->essid, priv->essid_len), - priv->bssid); + IPW_DEBUG(IPW_DL_STATE, "associating: '%*pE' %pM\n", + priv->essid_len, priv->essid, priv->bssid); return 0; } @@ -7645,7 +7555,6 @@ static int ipw_associate(void *data) struct ipw_supported_rates *rates; struct list_head *element; unsigned long flags; - DECLARE_SSID_BUF(ssid); if (priv->ieee->iw_mode == IW_MODE_MONITOR) { IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n"); @@ -7704,10 +7613,8 @@ static int ipw_associate(void *data) /* If there are no more slots, expire the oldest */ list_del(&oldest->list); target = oldest; - IPW_DEBUG_ASSOC("Expired '%s' (%pM) from " - "network list.\n", - print_ssid(ssid, target->ssid, - target->ssid_len), + IPW_DEBUG_ASSOC("Expired '%*pE' (%pM) from network list.\n", + target->ssid_len, target->ssid, target->bssid); list_add_tail(&target->list, &priv->ieee->network_free_list); @@ -9093,7 +9000,6 @@ static int ipw_wx_set_essid(struct net_device *dev, { struct ipw_priv *priv = libipw_priv(dev); int length; - DECLARE_SSID_BUF(ssid); mutex_lock(&priv->mutex); @@ -9118,8 +9024,7 @@ static int ipw_wx_set_essid(struct net_device *dev, return 0; } - IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", - print_ssid(ssid, extra, length), length); + IPW_DEBUG_WX("Setting ESSID: '%*pE' (%d)\n", length, extra, length); priv->essid_len = length; memcpy(priv->essid, extra, priv->essid_len); @@ -9138,15 +9043,14 @@ static int ipw_wx_get_essid(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = libipw_priv(dev); - DECLARE_SSID_BUF(ssid); /* If we are associated, trying to associate, or have a statically * configured ESSID then return that; otherwise return ANY */ mutex_lock(&priv->mutex); if (priv->config & CFG_STATIC_ESSID || priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { - IPW_DEBUG_WX("Getting essid: '%s'\n", - print_ssid(ssid, priv->essid, priv->essid_len)); + IPW_DEBUG_WX("Getting essid: '%*pE'\n", + priv->essid_len, priv->essid); memcpy(extra, priv->essid, priv->essid_len); wrqu->essid.length = priv->essid_len; wrqu->essid.flags = 1; /* active */ diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index a586a85bfcf..2d66984079b 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 *info_element, u16 length, struct libipw_network *network) { - DECLARE_SSID_BUF(ssid); u8 i; #ifdef CONFIG_LIBIPW_DEBUG char rates_str[64]; @@ -1151,10 +1150,9 @@ static int libipw_parse_info_param(struct libipw_info_element memset(network->ssid + network->ssid_len, 0, IW_ESSID_MAX_SIZE - network->ssid_len); - LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%s' len=%d.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), - network->ssid_len); + LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%*pE' len=%d.\n", + network->ssid_len, network->ssid, + network->ssid_len); break; case WLAN_EID_SUPP_RATES: @@ -1399,8 +1397,6 @@ static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_r struct libipw_network *network, struct libipw_rx_stats *stats) { - DECLARE_SSID_BUF(ssid); - network->qos_data.active = 0; network->qos_data.supported = 0; network->qos_data.param_count = 0; @@ -1447,11 +1443,9 @@ static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_r } if (network->mode == 0) { - LIBIPW_DEBUG_SCAN("Filtered out '%s (%pM)' " - "network.\n", - print_ssid(ssid, network->ssid, - network->ssid_len), - network->bssid); + LIBIPW_DEBUG_SCAN("Filtered out '%*pE (%pM)' network.\n", + network->ssid_len, network->ssid, + network->bssid); return 1; } @@ -1563,11 +1557,9 @@ static void libipw_process_probe_response(struct libipw_device struct libipw_info_element *info_element = beacon->info_element; #endif unsigned long flags; - DECLARE_SSID_BUF(ssid); - LIBIPW_DEBUG_SCAN("'%s' (%pM" - "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", - print_ssid(ssid, info_element->data, info_element->len), + LIBIPW_DEBUG_SCAN("'%*pE' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", + info_element->len, info_element->data, beacon->header.addr3, (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0', (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0', @@ -1587,12 +1579,11 @@ static void libipw_process_probe_response(struct libipw_device (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0'); if (libipw_network_init(ieee, beacon, &network, stats)) { - LIBIPW_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n", - print_ssid(ssid, info_element->data, - info_element->len), - beacon->header.addr3, - is_beacon(beacon->header.frame_ctl) ? - "BEACON" : "PROBE RESPONSE"); + LIBIPW_DEBUG_SCAN("Dropped '%*pE' (%pM) via %s.\n", + info_element->len, info_element->data, + beacon->header.addr3, + is_beacon(beacon->header.frame_ctl) ? + "BEACON" : "PROBE RESPONSE"); return; } @@ -1624,11 +1615,9 @@ static void libipw_process_probe_response(struct libipw_device /* If there are no more slots, expire the oldest */ list_del(&oldest->list); target = oldest; - LIBIPW_DEBUG_SCAN("Expired '%s' (%pM) from " - "network list.\n", - print_ssid(ssid, target->ssid, - target->ssid_len), - target->bssid); + LIBIPW_DEBUG_SCAN("Expired '%*pE' (%pM) from network list.\n", + target->ssid_len, target->ssid, + target->bssid); libipw_network_reset(target); } else { /* Otherwise just pull from the free list */ @@ -1638,23 +1627,21 @@ static void libipw_process_probe_response(struct libipw_device } #ifdef CONFIG_LIBIPW_DEBUG - LIBIPW_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n", - print_ssid(ssid, network.ssid, - network.ssid_len), - network.bssid, - is_beacon(beacon->header.frame_ctl) ? - "BEACON" : "PROBE RESPONSE"); + LIBIPW_DEBUG_SCAN("Adding '%*pE' (%pM) via %s.\n", + network.ssid_len, network.ssid, + network.bssid, + is_beacon(beacon->header.frame_ctl) ? + "BEACON" : "PROBE RESPONSE"); #endif memcpy(target, &network, sizeof(*target)); network.ibss_dfs = NULL; list_add_tail(&target->list, &ieee->network_list); } else { - LIBIPW_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", - print_ssid(ssid, target->ssid, - target->ssid_len), - target->bssid, - is_beacon(beacon->header.frame_ctl) ? - "BEACON" : "PROBE RESPONSE"); + LIBIPW_DEBUG_SCAN("Updating '%*pE' (%pM) via %s.\n", + target->ssid_len, target->ssid, + target->bssid, + is_beacon(beacon->header.frame_ctl) ? + "BEACON" : "PROBE RESPONSE"); update_network(target, &network); network.ibss_dfs = NULL; } diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c index 54aba474443..dd29f46d086 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, char *ev = extra; char *stop = ev + wrqu->data.length; int i = 0; - DECLARE_SSID_BUF(ssid); LIBIPW_DEBUG_WX("Getting scan\n"); @@ -290,12 +289,10 @@ int libipw_wx_get_scan(struct libipw_device *ieee, ev = libipw_translate_scan(ieee, ev, stop, network, info); else { - LIBIPW_DEBUG_SCAN("Not showing network '%s (" - "%pM)' due to age (%ums).\n", - print_ssid(ssid, network->ssid, - network->ssid_len), - network->bssid, - elapsed_jiffies_msecs( + LIBIPW_DEBUG_SCAN("Not showing network '%*pE (%pM)' due to age (%ums).\n", + network->ssid_len, network->ssid, + network->bssid, + elapsed_jiffies_msecs( network->last_scanned)); } } @@ -322,7 +319,6 @@ int libipw_wx_set_encode(struct libipw_device *ieee, int i, key, key_provided, len; struct lib80211_crypt_data **crypt; int host_crypto = ieee->host_encrypt || ieee->host_decrypt; - DECLARE_SSID_BUF(ssid); LIBIPW_DEBUG_WX("SET_ENCODE\n"); @@ -417,8 +413,8 @@ int libipw_wx_set_encode(struct libipw_device *ieee, if (len > erq->length) memset(sec.keys[key] + erq->length, 0, len - erq->length); - LIBIPW_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n", - key, print_ssid(ssid, sec.keys[key], len), + LIBIPW_DEBUG_WX("Setting key %d to '%*pE' (%d:%d bytes)\n", + key, len, sec.keys[key], erq->length, len); sec.key_sizes[key] = len; if (*crypt) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 818b1edaaa9..34f09ef90bb 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, int chan_no = -1; const u8 *ssid = NULL; u8 ssid_len = 0; - DECLARE_SSID_BUF(ssid_buf); int len = get_unaligned_le16(pos); pos += 2; @@ -644,10 +643,8 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, struct ieee80211_channel *channel = ieee80211_get_channel(wiphy, freq); - lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %s, " - "%d dBm\n", - bssid, capa, chan_no, - print_ssid(ssid_buf, ssid, ssid_len), + lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %*pE, %d dBm\n", + bssid, capa, chan_no, ssid_len, ssid, LBS_SCAN_RSSI_TO_MBM(rssi)/100); if (channel && @@ -1984,7 +1981,6 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct lbs_private *priv = wiphy_priv(wiphy); int ret = 0; struct cfg80211_bss *bss; - DECLARE_SSID_BUF(ssid_buf); if (dev == priv->mesh_dev) return -EOPNOTSUPP; diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 01a67f62696..d0c881dd584 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, { struct cmd_ds_mesh_config cmd; struct mrvl_meshie *ie; - DECLARE_SSID_BUF(ssid); memset(&cmd, 0, sizeof(cmd)); cmd.channel = cpu_to_le16(chan); @@ -122,9 +121,9 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, default: return -1; } - lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n", - action, priv->mesh_tlv, chan, - print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len)); + lbs_deb_cmd("mesh config action %d type %x channel %d SSID %*pE\n", + action, priv->mesh_tlv, chan, priv->mesh_ssid_len, + priv->mesh_ssid); return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv); } diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index f959978c7aa..cf0f89364d4 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( } s = dmi_get_system_info(DMI_PRODUCT_VERSION); - if (s && !(strnicmp(s, "ThinkPad", 8) && strnicmp(s, "Lenovo", 6))) { + if (s && !(strncasecmp(s, "ThinkPad", 8) && strncasecmp(s, "Lenovo", 6))) { tp->model_str = kstrdup(s, GFP_KERNEL); if (!tp->model_str) return -ENOMEM; } else { s = dmi_get_system_info(DMI_BIOS_VENDOR); - if (s && !(strnicmp(s, "Lenovo", 6))) { + if (s && !(strncasecmp(s, "Lenovo", 6))) { tp->model_str = kstrdup(s, GFP_KERNEL); if (!tp->model_str) return -ENOMEM; diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index e6c403be09a..4b6808ff0e5 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -346,41 +346,41 @@ static ssize_t resources_store(struct device *dmdev, } buf = skip_spaces(buf); - if (!strnicmp(buf, "disable", 7)) { + if (!strncasecmp(buf, "disable", 7)) { retval = pnp_disable_dev(dev); goto done; } - if (!strnicmp(buf, "activate", 8)) { + if (!strncasecmp(buf, "activate", 8)) { retval = pnp_activate_dev(dev); goto done; } - if (!strnicmp(buf, "fill", 4)) { + if (!strncasecmp(buf, "fill", 4)) { if (dev->active) goto done; retval = pnp_auto_config_dev(dev); goto done; } - if (!strnicmp(buf, "auto", 4)) { + if (!strncasecmp(buf, "auto", 4)) { if (dev->active) goto done; pnp_init_resources(dev); retval = pnp_auto_config_dev(dev); goto done; } - if (!strnicmp(buf, "clear", 5)) { + if (!strncasecmp(buf, "clear", 5)) { if (dev->active) goto done; pnp_init_resources(dev); goto done; } - if (!strnicmp(buf, "get", 3)) { + if (!strncasecmp(buf, "get", 3)) { mutex_lock(&pnp_res_mutex); if (pnp_can_read(dev)) dev->protocol->get(dev); mutex_unlock(&pnp_res_mutex); goto done; } - if (!strnicmp(buf, "set", 3)) { + if (!strncasecmp(buf, "set", 3)) { resource_size_t start; resource_size_t end; unsigned long flags; @@ -392,31 +392,31 @@ static ssize_t resources_store(struct device *dmdev, mutex_lock(&pnp_res_mutex); while (1) { buf = skip_spaces(buf); - if (!strnicmp(buf, "io", 2)) { + if (!strncasecmp(buf, "io", 2)) { buf = pnp_get_resource_value(buf + 2, IORESOURCE_IO, &start, &end, &flags); pnp_add_io_resource(dev, start, end, flags); - } else if (!strnicmp(buf, "mem", 3)) { + } else if (!strncasecmp(buf, "mem", 3)) { buf = pnp_get_resource_value(buf + 3, IORESOURCE_MEM, &start, &end, &flags); pnp_add_mem_resource(dev, start, end, flags); - } else if (!strnicmp(buf, "irq", 3)) { + } else if (!strncasecmp(buf, "irq", 3)) { buf = pnp_get_resource_value(buf + 3, IORESOURCE_IRQ, &start, NULL, &flags); pnp_add_irq_resource(dev, start, flags); - } else if (!strnicmp(buf, "dma", 3)) { + } else if (!strncasecmp(buf, "dma", 3)) { buf = pnp_get_resource_value(buf + 3, IORESOURCE_DMA, &start, NULL, &flags); pnp_add_dma_resource(dev, start, flags); - } else if (!strnicmp(buf, "bus", 3)) { + } else if (!strncasecmp(buf, "bus", 3)) { buf = pnp_get_resource_value(buf + 3, IORESOURCE_BUS, &start, &end, diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 1bea0fc4346..8cd0beebdc3 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -288,6 +288,26 @@ config RTC_DRV_MAX77686 This driver can also be built as a module. If so, the module will be called rtc-max77686. +config RTC_DRV_RK808 + tristate "Rockchip RK808 RTC" + depends on MFD_RK808 + help + If you say yes here you will get support for the + RTC of RK808 PMIC. + + This driver can also be built as a module. If so, the module + will be called rk808-rtc. + +config RTC_DRV_MAX77802 + tristate "Maxim 77802 RTC" + depends on MFD_MAX77686 + help + If you say yes here you will get support for the + RTC of Maxim MAX77802 PMIC. + + This driver can also be built as a module. If so, the module + will be called rtc-max77802. + config RTC_DRV_RS5C372 tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" help @@ -732,6 +752,7 @@ config RTC_DRV_DS1216 config RTC_DRV_DS1286 tristate "Dallas DS1286" + depends on HAS_IOMEM help If you say yes here you get support for the Dallas DS1286 RTC chips. @@ -743,6 +764,7 @@ config RTC_DRV_DS1302 config RTC_DRV_DS1511 tristate "Dallas DS1511" + depends on HAS_IOMEM help If you say yes here you get support for the Dallas DS1511 timekeeping/watchdog chip. @@ -752,6 +774,7 @@ config RTC_DRV_DS1511 config RTC_DRV_DS1553 tristate "Maxim/Dallas DS1553" + depends on HAS_IOMEM help If you say yes here you get support for the Maxim/Dallas DS1553 timekeeping chip. @@ -761,6 +784,7 @@ config RTC_DRV_DS1553 config RTC_DRV_DS1742 tristate "Maxim/Dallas DS1742/1743" + depends on HAS_IOMEM help If you say yes here you get support for the Maxim/Dallas DS1742/1743 timekeeping chip. @@ -816,6 +840,7 @@ config RTC_DRV_EFI config RTC_DRV_STK17TA8 tristate "Simtek STK17TA8" + depends on HAS_IOMEM help If you say yes here you get support for the Simtek STK17TA8 timekeeping chip. @@ -834,6 +859,7 @@ config RTC_DRV_M48T86 config RTC_DRV_M48T35 tristate "ST M48T35" + depends on HAS_IOMEM help If you say Y here you will get support for the ST M48T35 RTC chip. @@ -843,6 +869,7 @@ config RTC_DRV_M48T35 config RTC_DRV_M48T59 tristate "ST M48T59/M48T08/M48T02" + depends on HAS_IOMEM help If you say Y here you will get support for the ST M48T59 RTC chip and compatible ST M48T08 and M48T02. @@ -855,6 +882,7 @@ config RTC_DRV_M48T59 config RTC_DRV_MSM6242 tristate "Oki MSM6242" + depends on HAS_IOMEM help If you say yes here you get support for the Oki MSM6242 timekeeping chip. It is used in some Amiga models (e.g. A2000). @@ -864,6 +892,7 @@ config RTC_DRV_MSM6242 config RTC_DRV_BQ4802 tristate "TI BQ4802" + depends on HAS_IOMEM help If you say Y here you will get support for the TI BQ4802 RTC chip. @@ -873,6 +902,7 @@ config RTC_DRV_BQ4802 config RTC_DRV_RP5C01 tristate "Ricoh RP5C01" + depends on HAS_IOMEM help If you say yes here you get support for the Ricoh RP5C01 timekeeping chip. It is used in some Amiga models (e.g. A3000 @@ -1374,6 +1404,7 @@ config RTC_DRV_MOXART config RTC_DRV_XGENE tristate "APM X-Gene RTC" + depends on HAS_IOMEM help If you say yes here you get support for the APM X-Gene SoC real time clock. diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 9055b7dd3dc..b188323c096 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o +obj-$(CONFIG_RTC_DRV_MAX77802) += rtc-max77802.o obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o @@ -109,6 +110,7 @@ obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o +obj-$(CONFIG_RTC_DRV_RK808) += rtc-rk808.o obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index c74bf0dc52c..314129e66d6 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -2,10 +2,14 @@ * Driver for TI BQ32000 RTC. * * Copyright (C) 2009 Semihalf. + * Copyright (C) 2014 Pavel Machek <pavel@denx.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * You can get hardware description at + * http://www.ti.com/lit/ds/symlink/bq32000.pdf */ #include <linux/module.h> @@ -27,6 +31,10 @@ #define BQ32K_CENT 0x40 /* Century flag */ #define BQ32K_CENT_EN 0x80 /* Century flag enable bit */ +#define BQ32K_CALIBRATION 0x07 /* CAL_CFG1, calibration and control */ +#define BQ32K_TCH2 0x08 /* Trickle charge enable */ +#define BQ32K_CFG2 0x09 /* Trickle charger control */ + struct bq32k_regs { uint8_t seconds; uint8_t minutes; @@ -122,6 +130,57 @@ static const struct rtc_class_ops bq32k_rtc_ops = { .set_time = bq32k_rtc_set_time, }; +static int trickle_charger_of_init(struct device *dev, struct device_node *node) +{ + unsigned char reg; + int error; + u32 ohms = 0; + + if (of_property_read_u32(node, "trickle-resistor-ohms" , &ohms)) + return 0; + + switch (ohms) { + case 180+940: + /* + * TCHE[3:0] == 0x05, TCH2 == 1, TCFE == 0 (charging + * over diode and 940ohm resistor) + */ + + if (of_property_read_bool(node, "trickle-diode-disable")) { + dev_err(dev, "diode and resistor mismatch\n"); + return -EINVAL; + } + reg = 0x05; + break; + + case 180+20000: + /* diode disabled */ + + if (!of_property_read_bool(node, "trickle-diode-disable")) { + dev_err(dev, "bq32k: diode and resistor mismatch\n"); + return -EINVAL; + } + reg = 0x25; + break; + + default: + dev_err(dev, "invalid resistor value (%d)\n", ohms); + return -EINVAL; + } + + error = bq32k_write(dev, ®, BQ32K_CFG2, 1); + if (error) + return error; + + reg = 0x20; + error = bq32k_write(dev, ®, BQ32K_TCH2, 1); + if (error) + return error; + + dev_info(dev, "Enabled trickle RTC battery charge.\n"); + return 0; +} + static int bq32k_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -153,6 +212,9 @@ static int bq32k_probe(struct i2c_client *client, if (error) return error; + if (client && client->dev.of_node) + trickle_charger_of_init(dev, client->dev.of_node); + rtc = devm_rtc_device_register(&client->dev, bq32k_driver.driver.name, &bq32k_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index b0e4a3eb33c..5b2e76159b4 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) cmos->dev = NULL; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int cmos_suspend(struct device *dev) { @@ -907,6 +907,8 @@ static inline int cmos_poweroff(struct device *dev) return cmos_suspend(dev); } +#ifdef CONFIG_PM_SLEEP + static int cmos_resume(struct device *dev) { struct cmos_rtc *cmos = dev_get_drvdata(dev); @@ -954,6 +956,7 @@ static int cmos_resume(struct device *dev) return 0; } +#endif #else static inline int cmos_poweroff(struct device *dev) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index f03d5ba96db..bb43cf703ef 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -126,9 +126,14 @@ struct chip_desc { u16 nvram_offset; u16 nvram_size; u16 trickle_charger_reg; + u8 trickle_charger_setup; + u8 (*do_trickle_setup)(struct i2c_client *, uint32_t, bool); }; -static const struct chip_desc chips[last_ds_type] = { +static u8 do_trickle_setup_ds1339(struct i2c_client *, + uint32_t ohms, bool diode); + +static struct chip_desc chips[last_ds_type] = { [ds_1307] = { .nvram_offset = 8, .nvram_size = 56, @@ -143,6 +148,7 @@ static const struct chip_desc chips[last_ds_type] = { [ds_1339] = { .alarm = 1, .trickle_charger_reg = 0x10, + .do_trickle_setup = &do_trickle_setup_ds1339, }, [ds_1340] = { .trickle_charger_reg = 0x08, @@ -833,15 +839,58 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, return count; } + /*----------------------------------------------------------------------*/ +static u8 do_trickle_setup_ds1339(struct i2c_client *client, + uint32_t ohms, bool diode) +{ + u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE : + DS1307_TRICKLE_CHARGER_NO_DIODE; + + switch (ohms) { + case 250: + setup |= DS1307_TRICKLE_CHARGER_250_OHM; + break; + case 2000: + setup |= DS1307_TRICKLE_CHARGER_2K_OHM; + break; + case 4000: + setup |= DS1307_TRICKLE_CHARGER_4K_OHM; + break; + default: + dev_warn(&client->dev, + "Unsupported ohm value %u in dt\n", ohms); + return 0; + } + return setup; +} + +static void ds1307_trickle_of_init(struct i2c_client *client, + struct chip_desc *chip) +{ + uint32_t ohms = 0; + bool diode = true; + + if (!chip->do_trickle_setup) + goto out; + if (of_property_read_u32(client->dev.of_node, "trickle-resistor-ohms" , &ohms)) + goto out; + if (of_property_read_bool(client->dev.of_node, "trickle-diode-disable")) + diode = false; + chip->trickle_charger_setup = chip->do_trickle_setup(client, + ohms, diode); +out: + return; +} + static int ds1307_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ds1307 *ds1307; int err = -ENODEV; int tmp; - const struct chip_desc *chip = &chips[id->driver_data]; + struct chip_desc *chip = &chips[id->driver_data]; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); bool want_irq = false; unsigned char *buf; @@ -866,9 +915,19 @@ static int ds1307_probe(struct i2c_client *client, ds1307->client = client; ds1307->type = id->driver_data; - if (pdata && pdata->trickle_charger_setup && chip->trickle_charger_reg) + if (!pdata && client->dev.of_node) + ds1307_trickle_of_init(client, chip); + else if (pdata && pdata->trickle_charger_setup) + chip->trickle_charger_setup = pdata->trickle_charger_setup; + + if (chip->trickle_charger_setup && chip->trickle_charger_reg) { + dev_dbg(&client->dev, "writing trickle charger info 0x%x to 0x%x\n", + DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup, + chip->trickle_charger_reg); i2c_smbus_write_byte_data(client, chip->trickle_charger_reg, - DS13XX_TRICKLE_CHARGER_MAGIC | pdata->trickle_charger_setup); + DS13XX_TRICKLE_CHARGER_MAGIC | + chip->trickle_charger_setup); + } buf = ds1307->regs; 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 aa55f081c50..ee3ba7e6b45 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, } #ifdef CONFIG_OF -static struct of_device_id isl12022_dt_match[] = { +static const struct of_device_id isl12022_dt_match[] = { { .compatible = "isl,isl12022" }, { }, }; diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index d20a7f0786e..cf73e969c8c 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -32,15 +32,6 @@ #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) #define RTC_RBUDR_SHIFT 4 #define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) -/* WTSR and SMPL Register */ -#define WTSRT_SHIFT 0 -#define SMPLT_SHIFT 2 -#define WTSR_EN_SHIFT 6 -#define SMPL_EN_SHIFT 7 -#define WTSRT_MASK (3 << WTSRT_SHIFT) -#define SMPLT_MASK (3 << SMPLT_SHIFT) -#define WTSR_EN_MASK (1 << WTSR_EN_SHIFT) -#define SMPL_EN_MASK (1 << SMPL_EN_SHIFT) /* RTC Hour register */ #define HOUR_PM_SHIFT 6 #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) @@ -49,7 +40,6 @@ #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) #define MAX77686_RTC_UPDATE_DELAY 16 -#undef MAX77686_RTC_WTSR_SMPL enum { RTC_SEC = 0, @@ -80,16 +70,6 @@ enum MAX77686_RTC_OP { MAX77686_RTC_READ, }; -static inline int max77686_rtc_calculate_wday(u8 shifted) -{ - int counter = -1; - while (shifted) { - shifted >>= 1; - counter++; - } - return counter; -} - static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, int rtc_24hr_mode) { @@ -103,7 +83,8 @@ static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, tm->tm_hour += 12; } - tm->tm_wday = max77686_rtc_calculate_wday(data[RTC_WEEKDAY] & 0x7f); + /* Only a single bit is set in data[], so fls() would be equivalent */ + tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f) - 1; tm->tm_mday = data[RTC_DATE] & 0x1f; tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; @@ -412,64 +393,6 @@ static const struct rtc_class_ops max77686_rtc_ops = { .alarm_irq_enable = max77686_rtc_alarm_irq_enable, }; -#ifdef MAX77686_RTC_WTSR_SMPL -static void max77686_rtc_enable_wtsr(struct max77686_rtc_info *info, bool enable) -{ - int ret; - unsigned int val, mask; - - if (enable) - val = (1 << WTSR_EN_SHIFT) | (3 << WTSRT_SHIFT); - else - val = 0; - - mask = WTSR_EN_MASK | WTSRT_MASK; - - dev_info(info->dev, "%s: %s WTSR\n", __func__, - enable ? "enable" : "disable"); - - ret = regmap_update_bits(info->max77686->rtc_regmap, - MAX77686_WTSR_SMPL_CNTL, mask, val); - if (ret < 0) { - dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n", - __func__, ret); - return; - } - - max77686_rtc_update(info, MAX77686_RTC_WRITE); -} - -static void max77686_rtc_enable_smpl(struct max77686_rtc_info *info, bool enable) -{ - int ret; - unsigned int val, mask; - - if (enable) - val = (1 << SMPL_EN_SHIFT) | (0 << SMPLT_SHIFT); - else - val = 0; - - mask = SMPL_EN_MASK | SMPLT_MASK; - - dev_info(info->dev, "%s: %s SMPL\n", __func__, - enable ? "enable" : "disable"); - - ret = regmap_update_bits(info->max77686->rtc_regmap, - MAX77686_WTSR_SMPL_CNTL, mask, val); - if (ret < 0) { - dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n", - __func__, ret); - return; - } - - max77686_rtc_update(info, MAX77686_RTC_WRITE); - - val = 0; - regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val); - dev_info(info->dev, "%s: WTSR_SMPL(0x%02x)\n", __func__, val); -} -#endif /* MAX77686_RTC_WTSR_SMPL */ - static int max77686_rtc_init_reg(struct max77686_rtc_info *info) { u8 data[2]; @@ -519,19 +442,12 @@ static int max77686_rtc_probe(struct platform_device *pdev) goto err_rtc; } -#ifdef MAX77686_RTC_WTSR_SMPL - max77686_rtc_enable_wtsr(info, true); - max77686_rtc_enable_smpl(info, true); -#endif - device_init_wakeup(&pdev->dev, 1); info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc", &max77686_rtc_ops, THIS_MODULE); if (IS_ERR(info->rtc_dev)) { - dev_info(&pdev->dev, "%s: fail\n", __func__); - ret = PTR_ERR(info->rtc_dev); dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); if (ret == 0) @@ -539,6 +455,12 @@ static int max77686_rtc_probe(struct platform_device *pdev) goto err_rtc; } + if (!max77686->rtc_irq_data) { + ret = -EINVAL; + dev_err(&pdev->dev, "%s: no RTC regmap IRQ chip\n", __func__); + goto err_rtc; + } + info->virq = regmap_irq_get_virq(max77686->rtc_irq_data, MAX77686_RTCIRQ_RTCA1); if (!info->virq) { @@ -556,33 +478,33 @@ err_rtc: return ret; } -static void max77686_rtc_shutdown(struct platform_device *pdev) +#ifdef CONFIG_PM_SLEEP +static int max77686_rtc_suspend(struct device *dev) { -#ifdef MAX77686_RTC_WTSR_SMPL - struct max77686_rtc_info *info = platform_get_drvdata(pdev); - int i; - u8 val = 0; - - for (i = 0; i < 3; i++) { - max77686_rtc_enable_wtsr(info, false); - regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val); - dev_info(info->dev, "%s: WTSR_SMPL reg(0x%02x)\n", __func__, - val); - if (val & WTSR_EN_MASK) { - dev_emerg(info->dev, "%s: fail to disable WTSR\n", - __func__); - } else { - dev_info(info->dev, "%s: success to disable WTSR\n", - __func__); - break; - } + if (device_may_wakeup(dev)) { + struct max77686_rtc_info *info = dev_get_drvdata(dev); + + return enable_irq_wake(info->virq); } - /* Disable SMPL when power off */ - max77686_rtc_enable_smpl(info, false); -#endif /* MAX77686_RTC_WTSR_SMPL */ + return 0; } +static int max77686_rtc_resume(struct device *dev) +{ + if (device_may_wakeup(dev)) { + struct max77686_rtc_info *info = dev_get_drvdata(dev); + + return disable_irq_wake(info->virq); + } + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(max77686_rtc_pm_ops, + max77686_rtc_suspend, max77686_rtc_resume); + static const struct platform_device_id rtc_id[] = { { "max77686-rtc", 0 }, {}, @@ -592,9 +514,9 @@ static struct platform_driver max77686_rtc_driver = { .driver = { .name = "max77686-rtc", .owner = THIS_MODULE, + .pm = &max77686_rtc_pm_ops, }, .probe = max77686_rtc_probe, - .shutdown = max77686_rtc_shutdown, .id_table = rtc_id, }; diff --git a/drivers/rtc/rtc-max77802.c b/drivers/rtc/rtc-max77802.c new file mode 100644 index 00000000000..566471335b3 --- /dev/null +++ b/drivers/rtc/rtc-max77802.c @@ -0,0 +1,502 @@ +/* + * RTC driver for Maxim MAX77802 + * + * Copyright (C) 2013 Google, Inc + * + * Copyright (C) 2012 Samsung Electronics Co.Ltd + * + * based on rtc-max8997.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include <linux/slab.h> +#include <linux/rtc.h> +#include <linux/delay.h> +#include <linux/mutex.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/mfd/max77686-private.h> +#include <linux/irqdomain.h> +#include <linux/regmap.h> + +/* RTC Control Register */ +#define BCD_EN_SHIFT 0 +#define BCD_EN_MASK (1 << BCD_EN_SHIFT) +#define MODEL24_SHIFT 1 +#define MODEL24_MASK (1 << MODEL24_SHIFT) +/* RTC Update Register1 */ +#define RTC_UDR_SHIFT 0 +#define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) +#define RTC_RBUDR_SHIFT 4 +#define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) +/* RTC Hour register */ +#define HOUR_PM_SHIFT 6 +#define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) +/* RTC Alarm Enable */ +#define ALARM_ENABLE_SHIFT 7 +#define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) + +/* For the RTCAE1 register, we write this value to enable the alarm */ +#define ALARM_ENABLE_VALUE 0x77 + +#define MAX77802_RTC_UPDATE_DELAY_US 200 + +enum { + RTC_SEC = 0, + RTC_MIN, + RTC_HOUR, + RTC_WEEKDAY, + RTC_MONTH, + RTC_YEAR, + RTC_DATE, + RTC_NR_TIME +}; + +struct max77802_rtc_info { + struct device *dev; + struct max77686_dev *max77802; + struct i2c_client *rtc; + struct rtc_device *rtc_dev; + struct mutex lock; + + struct regmap *regmap; + + int virq; + int rtc_24hr_mode; +}; + +enum MAX77802_RTC_OP { + MAX77802_RTC_WRITE, + MAX77802_RTC_READ, +}; + +static void max77802_rtc_data_to_tm(u8 *data, struct rtc_time *tm, + int rtc_24hr_mode) +{ + tm->tm_sec = data[RTC_SEC] & 0xff; + tm->tm_min = data[RTC_MIN] & 0xff; + if (rtc_24hr_mode) + tm->tm_hour = data[RTC_HOUR] & 0x1f; + else { + tm->tm_hour = data[RTC_HOUR] & 0x0f; + if (data[RTC_HOUR] & HOUR_PM_MASK) + tm->tm_hour += 12; + } + + /* Only a single bit is set in data[], so fls() would be equivalent */ + tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0xff) - 1; + tm->tm_mday = data[RTC_DATE] & 0x1f; + tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; + + tm->tm_year = data[RTC_YEAR] & 0xff; + tm->tm_yday = 0; + tm->tm_isdst = 0; +} + +static int max77802_rtc_tm_to_data(struct rtc_time *tm, u8 *data) +{ + data[RTC_SEC] = tm->tm_sec; + data[RTC_MIN] = tm->tm_min; + data[RTC_HOUR] = tm->tm_hour; + data[RTC_WEEKDAY] = 1 << tm->tm_wday; + data[RTC_DATE] = tm->tm_mday; + data[RTC_MONTH] = tm->tm_mon + 1; + data[RTC_YEAR] = tm->tm_year; + + return 0; +} + +static int max77802_rtc_update(struct max77802_rtc_info *info, + enum MAX77802_RTC_OP op) +{ + int ret; + unsigned int data; + + if (op == MAX77802_RTC_WRITE) + data = 1 << RTC_UDR_SHIFT; + else + data = 1 << RTC_RBUDR_SHIFT; + + ret = regmap_update_bits(info->max77802->regmap, + MAX77802_RTC_UPDATE0, data, data); + if (ret < 0) + dev_err(info->dev, "%s: fail to write update reg(ret=%d, data=0x%x)\n", + __func__, ret, data); + else { + /* Minimum delay required before RTC update. */ + usleep_range(MAX77802_RTC_UPDATE_DELAY_US, + MAX77802_RTC_UPDATE_DELAY_US * 2); + } + + return ret; +} + +static int max77802_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct max77802_rtc_info *info = dev_get_drvdata(dev); + u8 data[RTC_NR_TIME]; + int ret; + + mutex_lock(&info->lock); + + ret = max77802_rtc_update(info, MAX77802_RTC_READ); + if (ret < 0) + goto out; + + ret = regmap_bulk_read(info->max77802->regmap, + MAX77802_RTC_SEC, data, RTC_NR_TIME); + if (ret < 0) { + dev_err(info->dev, "%s: fail to read time reg(%d)\n", __func__, + ret); + goto out; + } + + max77802_rtc_data_to_tm(data, tm, info->rtc_24hr_mode); + + ret = rtc_valid_tm(tm); + +out: + mutex_unlock(&info->lock); + return ret; +} + +static int max77802_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct max77802_rtc_info *info = dev_get_drvdata(dev); + u8 data[RTC_NR_TIME]; + int ret; + + ret = max77802_rtc_tm_to_data(tm, data); + if (ret < 0) + return ret; + + mutex_lock(&info->lock); + + ret = regmap_bulk_write(info->max77802->regmap, + MAX77802_RTC_SEC, data, RTC_NR_TIME); + if (ret < 0) { + dev_err(info->dev, "%s: fail to write time reg(%d)\n", __func__, + ret); + goto out; + } + + ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); + +out: + mutex_unlock(&info->lock); + return ret; +} + +static int max77802_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct max77802_rtc_info *info = dev_get_drvdata(dev); + u8 data[RTC_NR_TIME]; + unsigned int val; + int ret; + + mutex_lock(&info->lock); + + ret = max77802_rtc_update(info, MAX77802_RTC_READ); + if (ret < 0) + goto out; + + ret = regmap_bulk_read(info->max77802->regmap, + MAX77802_ALARM1_SEC, data, RTC_NR_TIME); + if (ret < 0) { + dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n", + __func__, __LINE__, ret); + goto out; + } + + max77802_rtc_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); + + alrm->enabled = 0; + ret = regmap_read(info->max77802->regmap, + MAX77802_RTC_AE1, &val); + if (ret < 0) { + dev_err(info->dev, "%s:%d fail to read alarm enable(%d)\n", + __func__, __LINE__, ret); + goto out; + } + if (val) + alrm->enabled = 1; + + alrm->pending = 0; + ret = regmap_read(info->max77802->regmap, MAX77802_REG_STATUS2, &val); + if (ret < 0) { + dev_err(info->dev, "%s:%d fail to read status2 reg(%d)\n", + __func__, __LINE__, ret); + goto out; + } + + if (val & (1 << 2)) /* RTCA1 */ + alrm->pending = 1; + +out: + mutex_unlock(&info->lock); + return 0; +} + +static int max77802_rtc_stop_alarm(struct max77802_rtc_info *info) +{ + int ret; + + if (!mutex_is_locked(&info->lock)) + dev_warn(info->dev, "%s: should have mutex locked\n", __func__); + + ret = max77802_rtc_update(info, MAX77802_RTC_READ); + if (ret < 0) + goto out; + + ret = regmap_write(info->max77802->regmap, + MAX77802_RTC_AE1, 0); + if (ret < 0) { + dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", + __func__, ret); + goto out; + } + + ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); +out: + return ret; +} + +static int max77802_rtc_start_alarm(struct max77802_rtc_info *info) +{ + int ret; + + if (!mutex_is_locked(&info->lock)) + dev_warn(info->dev, "%s: should have mutex locked\n", + __func__); + + ret = max77802_rtc_update(info, MAX77802_RTC_READ); + if (ret < 0) + goto out; + + ret = regmap_write(info->max77802->regmap, + MAX77802_RTC_AE1, + ALARM_ENABLE_VALUE); + + if (ret < 0) { + dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", + __func__, ret); + goto out; + } + + ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); +out: + return ret; +} + +static int max77802_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct max77802_rtc_info *info = dev_get_drvdata(dev); + u8 data[RTC_NR_TIME]; + int ret; + + ret = max77802_rtc_tm_to_data(&alrm->time, data); + if (ret < 0) + return ret; + + mutex_lock(&info->lock); + + ret = max77802_rtc_stop_alarm(info); + if (ret < 0) + goto out; + + ret = regmap_bulk_write(info->max77802->regmap, + MAX77802_ALARM1_SEC, data, RTC_NR_TIME); + + if (ret < 0) { + dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", + __func__, ret); + goto out; + } + + ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); + if (ret < 0) + goto out; + + if (alrm->enabled) + ret = max77802_rtc_start_alarm(info); +out: + mutex_unlock(&info->lock); + return ret; +} + +static int max77802_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + struct max77802_rtc_info *info = dev_get_drvdata(dev); + int ret; + + mutex_lock(&info->lock); + if (enabled) + ret = max77802_rtc_start_alarm(info); + else + ret = max77802_rtc_stop_alarm(info); + mutex_unlock(&info->lock); + + return ret; +} + +static irqreturn_t max77802_rtc_alarm_irq(int irq, void *data) +{ + struct max77802_rtc_info *info = data; + + dev_dbg(info->dev, "%s:irq(%d)\n", __func__, irq); + + rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); + + return IRQ_HANDLED; +} + +static const struct rtc_class_ops max77802_rtc_ops = { + .read_time = max77802_rtc_read_time, + .set_time = max77802_rtc_set_time, + .read_alarm = max77802_rtc_read_alarm, + .set_alarm = max77802_rtc_set_alarm, + .alarm_irq_enable = max77802_rtc_alarm_irq_enable, +}; + +static int max77802_rtc_init_reg(struct max77802_rtc_info *info) +{ + u8 data[2]; + int ret; + + max77802_rtc_update(info, MAX77802_RTC_READ); + + /* Set RTC control register : Binary mode, 24hour mdoe */ + data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); + data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); + + info->rtc_24hr_mode = 1; + + ret = regmap_bulk_write(info->max77802->regmap, + MAX77802_RTC_CONTROLM, data, ARRAY_SIZE(data)); + if (ret < 0) { + dev_err(info->dev, "%s: fail to write controlm reg(%d)\n", + __func__, ret); + return ret; + } + + ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); + return ret; +} + +static int max77802_rtc_probe(struct platform_device *pdev) +{ + struct max77686_dev *max77802 = dev_get_drvdata(pdev->dev.parent); + struct max77802_rtc_info *info; + int ret; + + dev_dbg(&pdev->dev, "%s\n", __func__); + + info = devm_kzalloc(&pdev->dev, sizeof(struct max77802_rtc_info), + GFP_KERNEL); + if (!info) + return -ENOMEM; + + mutex_init(&info->lock); + info->dev = &pdev->dev; + info->max77802 = max77802; + info->rtc = max77802->i2c; + + platform_set_drvdata(pdev, info); + + ret = max77802_rtc_init_reg(info); + + if (ret < 0) { + dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret); + return ret; + } + + device_init_wakeup(&pdev->dev, 1); + + info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77802-rtc", + &max77802_rtc_ops, THIS_MODULE); + + if (IS_ERR(info->rtc_dev)) { + ret = PTR_ERR(info->rtc_dev); + dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); + if (ret == 0) + ret = -EINVAL; + return ret; + } + + if (!max77802->rtc_irq_data) { + dev_err(&pdev->dev, "No RTC regmap IRQ chip\n"); + return -EINVAL; + } + + info->virq = regmap_irq_get_virq(max77802->rtc_irq_data, + MAX77686_RTCIRQ_RTCA1); + + if (info->virq <= 0) { + dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n", + MAX77686_RTCIRQ_RTCA1); + return -EINVAL; + } + + ret = devm_request_threaded_irq(&pdev->dev, info->virq, NULL, + max77802_rtc_alarm_irq, 0, "rtc-alarm1", + info); + if (ret < 0) + dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", + info->virq, ret); + + return ret; +} + +#ifdef CONFIG_PM_SLEEP +static int max77802_rtc_suspend(struct device *dev) +{ + if (device_may_wakeup(dev)) { + struct max77802_rtc_info *info = dev_get_drvdata(dev); + + return enable_irq_wake(info->virq); + } + + return 0; +} + +static int max77802_rtc_resume(struct device *dev) +{ + if (device_may_wakeup(dev)) { + struct max77802_rtc_info *info = dev_get_drvdata(dev); + + return disable_irq_wake(info->virq); + } + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(max77802_rtc_pm_ops, + max77802_rtc_suspend, max77802_rtc_resume); + +static const struct platform_device_id rtc_id[] = { + { "max77802-rtc", 0 }, + {}, +}; + +static struct platform_driver max77802_rtc_driver = { + .driver = { + .name = "max77802-rtc", + .owner = THIS_MODULE, + .pm = &max77802_rtc_pm_ops, + }, + .probe = max77802_rtc_probe, + .id_table = rtc_id, +}; + +module_platform_driver(max77802_rtc_driver); + +MODULE_DESCRIPTION("Maxim MAX77802 RTC driver"); +MODULE_AUTHOR("Simon Glass <sjg@chromium.org>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index dc4f14255cc..3b965ad6f4d 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) } #ifdef CONFIG_OF -static struct of_device_id mpc5121_rtc_match[] = { +static const struct of_device_id mpc5121_rtc_match[] = { { .compatible = "fsl,mpc5121-rtc", }, { .compatible = "fsl,mpc5200-rtc", }, {}, diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 5a197d9dc7e..c2ef0a22ee9 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) char pending; err = pcf8563_get_alarm_mode(pcf8563->client, NULL, &pending); - if (err < 0) - return err; + if (err) + return IRQ_NONE; if (pending) { 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 c2639845186..5911a6dca29 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) { struct i2c_client *client = to_i2c_client(dev); unsigned char ctrl, year[2]; - struct rtc_mem mem = { CMOS_YEAR, sizeof(year), year }; + struct rtc_mem mem = { + .loc = CMOS_YEAR, + .nr = sizeof(year), + .data = year + }; int real_year, year_offset, err; /* @@ -222,8 +226,16 @@ static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct i2c_client *client = to_i2c_client(dev); unsigned char year[2], chk; - struct rtc_mem cmos_year = { CMOS_YEAR, sizeof(year), year }; - struct rtc_mem cmos_check = { CMOS_CHECKSUM, 1, &chk }; + struct rtc_mem cmos_year = { + .loc = CMOS_YEAR, + .nr = sizeof(year), + .data = year + }; + struct rtc_mem cmos_check = { + .loc = CMOS_CHECKSUM, + .nr = 1, + .data = &chk + }; unsigned int proper_year = tm->tm_year + 1900; int ret; diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c new file mode 100644 index 00000000000..df42257668a --- /dev/null +++ b/drivers/rtc/rtc-rk808.c @@ -0,0 +1,414 @@ +/* + * RTC driver for Rockchip RK808 + * + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd + * + * Author: Chris Zhong <zyw@rock-chips.com> + * Author: Zhang Qing <zhangqing@rock-chips.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/rtc.h> +#include <linux/bcd.h> +#include <linux/mfd/rk808.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> + +/* RTC_CTRL_REG bitfields */ +#define BIT_RTC_CTRL_REG_STOP_RTC_M BIT(0) + +/* RK808 has a shadowed register for saving a "frozen" RTC time. + * When user setting "GET_TIME" to 1, the time will save in this shadowed + * register. If set "READSEL" to 1, user read rtc time register, actually + * get the time of that moment. If we need the real time, clr this bit. + */ +#define BIT_RTC_CTRL_REG_RTC_GET_TIME BIT(6) +#define BIT_RTC_CTRL_REG_RTC_READSEL_M BIT(7) +#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M BIT(3) +#define RTC_STATUS_MASK 0xFE + +#define SECONDS_REG_MSK 0x7F +#define MINUTES_REG_MAK 0x7F +#define HOURS_REG_MSK 0x3F +#define DAYS_REG_MSK 0x3F +#define MONTHS_REG_MSK 0x1F +#define YEARS_REG_MSK 0xFF +#define WEEKS_REG_MSK 0x7 + +/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */ + +#define NUM_TIME_REGS (RK808_WEEKS_REG - RK808_SECONDS_REG + 1) +#define NUM_ALARM_REGS (RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1) + +struct rk808_rtc { + struct rk808 *rk808; + struct rtc_device *rtc; + int irq; +}; + +/* Read current time and date in RTC */ +static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) +{ + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); + struct rk808 *rk808 = rk808_rtc->rk808; + u8 rtc_data[NUM_TIME_REGS]; + int ret; + + /* Force an update of the shadowed registers right now */ + ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, + BIT_RTC_CTRL_REG_RTC_GET_TIME, + 0); + if (ret) { + dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret); + return ret; + } + + ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, + BIT_RTC_CTRL_REG_RTC_GET_TIME, + BIT_RTC_CTRL_REG_RTC_GET_TIME); + if (ret) { + dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret); + return ret; + } + + ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG, + rtc_data, NUM_TIME_REGS); + if (ret) { + dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret); + return ret; + } + + tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK); + tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK); + tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK); + tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK); + tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1; + tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100; + tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK); + dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", + 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, + tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec); + + return ret; +} + +/* Set current time and date in RTC */ +static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); + struct rk808 *rk808 = rk808_rtc->rk808; + u8 rtc_data[NUM_TIME_REGS]; + int ret; + + rtc_data[0] = bin2bcd(tm->tm_sec); + rtc_data[1] = bin2bcd(tm->tm_min); + rtc_data[2] = bin2bcd(tm->tm_hour); + rtc_data[3] = bin2bcd(tm->tm_mday); + rtc_data[4] = bin2bcd(tm->tm_mon + 1); + rtc_data[5] = bin2bcd(tm->tm_year - 100); + rtc_data[6] = bin2bcd(tm->tm_wday); + dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", + 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, + tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec); + + /* Stop RTC while updating the RTC registers */ + ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, + BIT_RTC_CTRL_REG_STOP_RTC_M, + BIT_RTC_CTRL_REG_STOP_RTC_M); + if (ret) { + dev_err(dev, "Failed to update RTC control: %d\n", ret); + return ret; + } + + ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG, + rtc_data, NUM_TIME_REGS); + if (ret) { + dev_err(dev, "Failed to bull write rtc_data: %d\n", ret); + return ret; + } + /* Start RTC again */ + ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, + BIT_RTC_CTRL_REG_STOP_RTC_M, 0); + if (ret) { + dev_err(dev, "Failed to update RTC control: %d\n", ret); + return ret; + } + return 0; +} + +/* Read alarm time and date in RTC */ +static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); + struct rk808 *rk808 = rk808_rtc->rk808; + u8 alrm_data[NUM_ALARM_REGS]; + uint32_t int_reg; + int ret; + + ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG, + alrm_data, NUM_ALARM_REGS); + + alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK); + alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK); + alrm->time.tm_hour = bcd2bin(alrm_data[2] & HOURS_REG_MSK); + alrm->time.tm_mday = bcd2bin(alrm_data[3] & DAYS_REG_MSK); + alrm->time.tm_mon = (bcd2bin(alrm_data[4] & MONTHS_REG_MSK)) - 1; + alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100; + + ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg); + if (ret) { + dev_err(dev, "Failed to read RTC INT REG: %d\n", ret); + return ret; + } + + dev_dbg(dev, "alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", + 1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, + alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, + alrm->time.tm_min, alrm->time.tm_sec); + + alrm->enabled = (int_reg & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M) ? 1 : 0; + + return 0; +} + +static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc) +{ + struct rk808 *rk808 = rk808_rtc->rk808; + int ret; + + ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG, + BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0); + + return ret; +} + +static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc) +{ + struct rk808 *rk808 = rk808_rtc->rk808; + int ret; + + ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG, + BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, + BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); + + return ret; +} + +static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); + struct rk808 *rk808 = rk808_rtc->rk808; + u8 alrm_data[NUM_ALARM_REGS]; + int ret; + + ret = rk808_rtc_stop_alarm(rk808_rtc); + if (ret) { + dev_err(dev, "Failed to stop alarm: %d\n", ret); + return ret; + } + dev_dbg(dev, "alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", + 1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, + alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, + alrm->time.tm_min, alrm->time.tm_sec); + + alrm_data[0] = bin2bcd(alrm->time.tm_sec); + alrm_data[1] = bin2bcd(alrm->time.tm_min); + alrm_data[2] = bin2bcd(alrm->time.tm_hour); + alrm_data[3] = bin2bcd(alrm->time.tm_mday); + alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1); + alrm_data[5] = bin2bcd(alrm->time.tm_year - 100); + + ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG, + alrm_data, NUM_ALARM_REGS); + if (ret) { + dev_err(dev, "Failed to bulk write: %d\n", ret); + return ret; + } + if (alrm->enabled) { + ret = rk808_rtc_start_alarm(rk808_rtc); + if (ret) { + dev_err(dev, "Failed to start alarm: %d\n", ret); + return ret; + } + } + return 0; +} + +static int rk808_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); + + if (enabled) + return rk808_rtc_start_alarm(rk808_rtc); + + return rk808_rtc_stop_alarm(rk808_rtc); +} + +/* + * We will just handle setting the frequency and make use the framework for + * reading the periodic interupts. + * + * @freq: Current periodic IRQ freq: + * bit 0: every second + * bit 1: every minute + * bit 2: every hour + * bit 3: every day + */ +static irqreturn_t rk808_alarm_irq(int irq, void *data) +{ + struct rk808_rtc *rk808_rtc = data; + struct rk808 *rk808 = rk808_rtc->rk808; + struct i2c_client *client = rk808->i2c; + int ret; + + ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG, + RTC_STATUS_MASK); + if (ret) { + dev_err(&client->dev, + "%s:Failed to update RTC status: %d\n", __func__, ret); + return ret; + } + + rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF); + dev_dbg(&client->dev, + "%s:irq=%d\n", __func__, irq); + return IRQ_HANDLED; +} + +static const struct rtc_class_ops rk808_rtc_ops = { + .read_time = rk808_rtc_readtime, + .set_time = rk808_rtc_set_time, + .read_alarm = rk808_rtc_readalarm, + .set_alarm = rk808_rtc_setalarm, + .alarm_irq_enable = rk808_rtc_alarm_irq_enable, +}; + +#ifdef CONFIG_PM_SLEEP +/* Turn off the alarm if it should not be a wake source. */ +static int rk808_rtc_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(rk808_rtc->irq); + + return 0; +} + +/* Enable the alarm if it should be enabled (in case it was disabled to + * prevent use as a wake source). + */ +static int rk808_rtc_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(rk808_rtc->irq); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops, + rk808_rtc_suspend, rk808_rtc_resume); + +static int rk808_rtc_probe(struct platform_device *pdev) +{ + struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); + struct rk808_rtc *rk808_rtc; + struct rtc_time tm; + int ret; + + rk808_rtc = devm_kzalloc(&pdev->dev, sizeof(*rk808_rtc), GFP_KERNEL); + if (rk808_rtc == NULL) + return -ENOMEM; + + platform_set_drvdata(pdev, rk808_rtc); + rk808_rtc->rk808 = rk808; + + /* start rtc running by default, and use shadowed timer. */ + ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, + BIT_RTC_CTRL_REG_STOP_RTC_M | + BIT_RTC_CTRL_REG_RTC_READSEL_M, + BIT_RTC_CTRL_REG_RTC_READSEL_M); + if (ret) { + dev_err(&pdev->dev, + "Failed to update RTC control: %d\n", ret); + return ret; + } + + ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG, + RTC_STATUS_MASK); + if (ret) { + dev_err(&pdev->dev, + "Failed to write RTC status: %d\n", ret); + return ret; + } + + /* set init time */ + ret = rk808_rtc_readtime(&pdev->dev, &tm); + if (ret) { + dev_err(&pdev->dev, "Failed to read RTC time\n"); + return ret; + } + ret = rtc_valid_tm(&tm); + if (ret) + dev_warn(&pdev->dev, "invalid date/time\n"); + + device_init_wakeup(&pdev->dev, 1); + + rk808_rtc->rtc = devm_rtc_device_register(&pdev->dev, "rk808-rtc", + &rk808_rtc_ops, THIS_MODULE); + if (IS_ERR(rk808_rtc->rtc)) { + ret = PTR_ERR(rk808_rtc->rtc); + return ret; + } + + rk808_rtc->irq = platform_get_irq(pdev, 0); + if (rk808_rtc->irq < 0) { + if (rk808_rtc->irq != -EPROBE_DEFER) + dev_err(&pdev->dev, "Wake up is not possible as irq = %d\n", + rk808_rtc->irq); + return rk808_rtc->irq; + } + + /* request alarm irq of rk808 */ + ret = devm_request_threaded_irq(&pdev->dev, rk808_rtc->irq, NULL, + rk808_alarm_irq, 0, + "RTC alarm", rk808_rtc); + if (ret) { + dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", + rk808_rtc->irq, ret); + } + + return ret; +} + +static struct platform_driver rk808_rtc_driver = { + .probe = rk808_rtc_probe, + .driver = { + .name = "rk808-rtc", + .pm = &rk808_rtc_pm_ops, + }, +}; + +module_platform_driver(rk808_rtc_driver); + +MODULE_DESCRIPTION("RTC driver for the rk808 series PMICs"); +MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); +MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:rk808-rtc"); diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index ccf54f06396..28871cd7e3b 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) } dev_dbg(&client->dev, - "%02x %02x %02x (%02x) %02x %02x %02x (%02x), " - "%02x %02x %02x, %02x %02x %02x; %02x %02x\n", - rs5c->regs[0], rs5c->regs[1], rs5c->regs[2], rs5c->regs[3], - rs5c->regs[4], rs5c->regs[5], rs5c->regs[6], rs5c->regs[7], - rs5c->regs[8], rs5c->regs[9], rs5c->regs[10], rs5c->regs[11], - rs5c->regs[12], rs5c->regs[13], rs5c->regs[14], rs5c->regs[15]); + "%3ph (%02x) %3ph (%02x), %3ph, %3ph; %02x %02x\n", + rs5c->regs + 0, rs5c->regs[3], + rs5c->regs + 4, rs5c->regs[7], + rs5c->regs + 8, rs5c->regs + 11, + rs5c->regs[14], rs5c->regs[15]); return 0; } diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 4958a363b2c..a6b1252c994 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -32,155 +32,150 @@ #include <asm/irq.h> #include "rtc-s3c.h" -enum s3c_cpu_type { - TYPE_S3C2410, - TYPE_S3C2416, - TYPE_S3C2443, - TYPE_S3C64XX, -}; +struct s3c_rtc { + struct device *dev; + struct rtc_device *rtc; -struct s3c_rtc_drv_data { - int cpu_type; -}; + void __iomem *base; + struct clk *rtc_clk; + struct clk *rtc_src_clk; + bool enabled; + + struct s3c_rtc_data *data; -/* I have yet to find an S3C implementation with more than one - * of these rtc blocks in */ + int irq_alarm; + int irq_tick; -static struct clk *rtc_clk; -static void __iomem *s3c_rtc_base; -static int s3c_rtc_alarmno; -static int s3c_rtc_tickno; -static enum s3c_cpu_type s3c_rtc_cpu_type; + spinlock_t pie_lock; + spinlock_t alarm_clk_lock; -static DEFINE_SPINLOCK(s3c_rtc_pie_lock); + int ticnt_save, ticnt_en_save; + bool wake_en; +}; + +struct s3c_rtc_data { + int max_user_freq; + bool needs_src_clk; + + void (*irq_handler) (struct s3c_rtc *info, int mask); + void (*set_freq) (struct s3c_rtc *info, int freq); + void (*enable_tick) (struct s3c_rtc *info, struct seq_file *seq); + void (*select_tick_clk) (struct s3c_rtc *info); + void (*save_tick_cnt) (struct s3c_rtc *info); + void (*restore_tick_cnt) (struct s3c_rtc *info); + void (*enable) (struct s3c_rtc *info); + void (*disable) (struct s3c_rtc *info); +}; -static void s3c_rtc_alarm_clk_enable(bool enable) +static void s3c_rtc_alarm_clk_enable(struct s3c_rtc *info, bool enable) { - static DEFINE_SPINLOCK(s3c_rtc_alarm_clk_lock); - static bool alarm_clk_enabled; unsigned long irq_flags; - spin_lock_irqsave(&s3c_rtc_alarm_clk_lock, irq_flags); + spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); if (enable) { - if (!alarm_clk_enabled) { - clk_enable(rtc_clk); - alarm_clk_enabled = true; + if (!info->enabled) { + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + info->enabled = true; } } else { - if (alarm_clk_enabled) { - clk_disable(rtc_clk); - alarm_clk_enabled = false; + if (info->enabled) { + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); + info->enabled = false; } } - spin_unlock_irqrestore(&s3c_rtc_alarm_clk_lock, irq_flags); + spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); } /* IRQ Handlers */ - -static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) +static irqreturn_t s3c_rtc_tickirq(int irq, void *id) { - struct rtc_device *rdev = id; - - clk_enable(rtc_clk); - rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); - - if (s3c_rtc_cpu_type == TYPE_S3C64XX) - writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP); - - clk_disable(rtc_clk); + struct s3c_rtc *info = (struct s3c_rtc *)id; - s3c_rtc_alarm_clk_enable(false); + if (info->data->irq_handler) + info->data->irq_handler(info, S3C2410_INTP_TIC); return IRQ_HANDLED; } -static irqreturn_t s3c_rtc_tickirq(int irq, void *id) +static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) { - struct rtc_device *rdev = id; + struct s3c_rtc *info = (struct s3c_rtc *)id; - clk_enable(rtc_clk); - rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); + if (info->data->irq_handler) + info->data->irq_handler(info, S3C2410_INTP_ALM); - if (s3c_rtc_cpu_type == TYPE_S3C64XX) - writeb(S3C2410_INTP_TIC, s3c_rtc_base + S3C2410_INTP); - - clk_disable(rtc_clk); return IRQ_HANDLED; } /* Update control registers */ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) { + struct s3c_rtc *info = dev_get_drvdata(dev); unsigned int tmp; - dev_dbg(dev, "%s: aie=%d\n", __func__, enabled); + dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled); - clk_enable(rtc_clk); - tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; if (enabled) tmp |= S3C2410_RTCALM_ALMEN; - writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); - clk_disable(rtc_clk); + writeb(tmp, info->base + S3C2410_RTCALM); + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); - s3c_rtc_alarm_clk_enable(enabled); + s3c_rtc_alarm_clk_enable(info, enabled); return 0; } -static int s3c_rtc_setfreq(struct device *dev, int freq) +/* Set RTC frequency */ +static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq) { - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc_dev = platform_get_drvdata(pdev); - unsigned int tmp = 0; - int val; - if (!is_power_of_2(freq)) return -EINVAL; - clk_enable(rtc_clk); - spin_lock_irq(&s3c_rtc_pie_lock); + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + spin_lock_irq(&info->pie_lock); - if (s3c_rtc_cpu_type != TYPE_S3C64XX) { - tmp = readb(s3c_rtc_base + S3C2410_TICNT); - tmp &= S3C2410_TICNT_ENABLE; - } + if (info->data->set_freq) + info->data->set_freq(info, freq); - val = (rtc_dev->max_user_freq / freq) - 1; - - if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { - tmp |= S3C2443_TICNT_PART(val); - writel(S3C2443_TICNT1_PART(val), s3c_rtc_base + S3C2443_TICNT1); - - if (s3c_rtc_cpu_type == TYPE_S3C2416) - writel(S3C2416_TICNT2_PART(val), s3c_rtc_base + S3C2416_TICNT2); - } else { - tmp |= val; - } - - writel(tmp, s3c_rtc_base + S3C2410_TICNT); - spin_unlock_irq(&s3c_rtc_pie_lock); - clk_disable(rtc_clk); + spin_unlock_irq(&info->pie_lock); + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); return 0; } /* Time read/write */ - static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) { + struct s3c_rtc *info = dev_get_drvdata(dev); unsigned int have_retried = 0; - void __iomem *base = s3c_rtc_base; - clk_enable(rtc_clk); + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + retry_get_time: - rtc_tm->tm_min = readb(base + S3C2410_RTCMIN); - rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR); - rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE); - rtc_tm->tm_mon = readb(base + S3C2410_RTCMON); - rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR); - rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC); + rtc_tm->tm_min = readb(info->base + S3C2410_RTCMIN); + rtc_tm->tm_hour = readb(info->base + S3C2410_RTCHOUR); + rtc_tm->tm_mday = readb(info->base + S3C2410_RTCDATE); + rtc_tm->tm_mon = readb(info->base + S3C2410_RTCMON); + rtc_tm->tm_year = readb(info->base + S3C2410_RTCYEAR); + rtc_tm->tm_sec = readb(info->base + S3C2410_RTCSEC); /* the only way to work out whether the system was mid-update * 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) rtc_tm->tm_mon -= 1; - clk_disable(rtc_clk); + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); + return rtc_valid_tm(rtc_tm); } static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) { - void __iomem *base = s3c_rtc_base; + struct s3c_rtc *info = dev_get_drvdata(dev); int year = tm->tm_year - 100; 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) return -EINVAL; } - clk_enable(rtc_clk); - writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); - writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); - writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); - writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE); - writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON); - writeb(bin2bcd(year), base + S3C2410_RTCYEAR); - clk_disable(rtc_clk); + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + + writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_RTCSEC); + writeb(bin2bcd(tm->tm_min), info->base + S3C2410_RTCMIN); + writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_RTCHOUR); + writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_RTCDATE); + writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_RTCMON); + writeb(bin2bcd(year), info->base + S3C2410_RTCYEAR); + + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); return 0; } static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) { + struct s3c_rtc *info = dev_get_drvdata(dev); struct rtc_time *alm_tm = &alrm->time; - void __iomem *base = s3c_rtc_base; unsigned int alm_en; - clk_enable(rtc_clk); - alm_tm->tm_sec = readb(base + S3C2410_ALMSEC); - alm_tm->tm_min = readb(base + S3C2410_ALMMIN); - alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR); - alm_tm->tm_mon = readb(base + S3C2410_ALMMON); - alm_tm->tm_mday = readb(base + S3C2410_ALMDATE); - alm_tm->tm_year = readb(base + S3C2410_ALMYEAR); + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); - alm_en = readb(base + S3C2410_RTCALM); + alm_tm->tm_sec = readb(info->base + S3C2410_ALMSEC); + alm_tm->tm_min = readb(info->base + S3C2410_ALMMIN); + alm_tm->tm_hour = readb(info->base + S3C2410_ALMHOUR); + alm_tm->tm_mon = readb(info->base + S3C2410_ALMMON); + alm_tm->tm_mday = readb(info->base + S3C2410_ALMDATE); + alm_tm->tm_year = readb(info->base + S3C2410_ALMYEAR); + + alm_en = readb(info->base + S3C2410_RTCALM); alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; @@ -297,65 +304,74 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) else alm_tm->tm_year = -1; - clk_disable(rtc_clk); + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); + return 0; } static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) { + struct s3c_rtc *info = dev_get_drvdata(dev); struct rtc_time *tm = &alrm->time; - void __iomem *base = s3c_rtc_base; unsigned int alrm_en; - clk_enable(rtc_clk); + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", alrm->enabled, 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; - writeb(0x00, base + S3C2410_RTCALM); + alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; + writeb(0x00, info->base + S3C2410_RTCALM); if (tm->tm_sec < 60 && tm->tm_sec >= 0) { alrm_en |= S3C2410_RTCALM_SECEN; - writeb(bin2bcd(tm->tm_sec), base + S3C2410_ALMSEC); + writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_ALMSEC); } if (tm->tm_min < 60 && tm->tm_min >= 0) { alrm_en |= S3C2410_RTCALM_MINEN; - writeb(bin2bcd(tm->tm_min), base + S3C2410_ALMMIN); + writeb(bin2bcd(tm->tm_min), info->base + S3C2410_ALMMIN); } if (tm->tm_hour < 24 && tm->tm_hour >= 0) { alrm_en |= S3C2410_RTCALM_HOUREN; - writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR); + writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_ALMHOUR); } dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en); - writeb(alrm_en, base + S3C2410_RTCALM); + writeb(alrm_en, info->base + S3C2410_RTCALM); s3c_rtc_setaie(dev, alrm->enabled); - clk_disable(rtc_clk); + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); + return 0; } static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) { - unsigned int ticnt; + struct s3c_rtc *info = dev_get_drvdata(dev); - clk_enable(rtc_clk); - if (s3c_rtc_cpu_type == TYPE_S3C64XX) { - ticnt = readw(s3c_rtc_base + S3C2410_RTCCON); - ticnt &= S3C64XX_RTCCON_TICEN; - } else { - ticnt = readb(s3c_rtc_base + S3C2410_TICNT); - ticnt &= S3C2410_TICNT_ENABLE; - } + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + + if (info->data->enable_tick) + info->data->enable_tick(info, seq); + + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); - seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); - clk_disable(rtc_clk); return 0; } @@ -368,152 +384,199 @@ static const struct rtc_class_ops s3c_rtcops = { .alarm_irq_enable = s3c_rtc_setaie, }; -static void s3c_rtc_enable(struct platform_device *pdev, int en) +static void s3c24xx_rtc_enable(struct s3c_rtc *info) { - void __iomem *base = s3c_rtc_base; - unsigned int tmp; + unsigned int con, tmp; - if (s3c_rtc_base == NULL) - return; - - clk_enable(rtc_clk); - if (!en) { - tmp = readw(base + S3C2410_RTCCON); - if (s3c_rtc_cpu_type == TYPE_S3C64XX) - tmp &= ~S3C64XX_RTCCON_TICEN; - tmp &= ~S3C2410_RTCCON_RTCEN; - writew(tmp, base + S3C2410_RTCCON); - - if (s3c_rtc_cpu_type != TYPE_S3C64XX) { - tmp = readb(base + S3C2410_TICNT); - tmp &= ~S3C2410_TICNT_ENABLE; - writeb(tmp, base + S3C2410_TICNT); - } - } else { - /* re-enable the device, and check it is ok */ + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); - if ((readw(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0) { - dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); + con = readw(info->base + S3C2410_RTCCON); + /* re-enable the device, and check it is ok */ + if ((con & S3C2410_RTCCON_RTCEN) == 0) { + dev_info(info->dev, "rtc disabled, re-enabling\n"); - tmp = readw(base + S3C2410_RTCCON); - writew(tmp | S3C2410_RTCCON_RTCEN, - base + S3C2410_RTCCON); - } + tmp = readw(info->base + S3C2410_RTCCON); + writew(tmp | S3C2410_RTCCON_RTCEN, + info->base + S3C2410_RTCCON); + } - if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)) { - dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); + if (con & S3C2410_RTCCON_CNTSEL) { + dev_info(info->dev, "removing RTCCON_CNTSEL\n"); - tmp = readw(base + S3C2410_RTCCON); - writew(tmp & ~S3C2410_RTCCON_CNTSEL, - base + S3C2410_RTCCON); - } + tmp = readw(info->base + S3C2410_RTCCON); + writew(tmp & ~S3C2410_RTCCON_CNTSEL, + info->base + S3C2410_RTCCON); + } - if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)) { - dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); + if (con & S3C2410_RTCCON_CLKRST) { + dev_info(info->dev, "removing RTCCON_CLKRST\n"); - tmp = readw(base + S3C2410_RTCCON); - writew(tmp & ~S3C2410_RTCCON_CLKRST, - base + S3C2410_RTCCON); - } + tmp = readw(info->base + S3C2410_RTCCON); + writew(tmp & ~S3C2410_RTCCON_CLKRST, + info->base + S3C2410_RTCCON); } - clk_disable(rtc_clk); + + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); } -static int s3c_rtc_remove(struct platform_device *dev) +static void s3c24xx_rtc_disable(struct s3c_rtc *info) { - s3c_rtc_setaie(&dev->dev, 0); + unsigned int con; + + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + + con = readw(info->base + S3C2410_RTCCON); + con &= ~S3C2410_RTCCON_RTCEN; + writew(con, info->base + S3C2410_RTCCON); - clk_unprepare(rtc_clk); - rtc_clk = NULL; + con = readb(info->base + S3C2410_TICNT); + con &= ~S3C2410_TICNT_ENABLE; + writeb(con, info->base + S3C2410_TICNT); + + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); +} + +static void s3c6410_rtc_disable(struct s3c_rtc *info) +{ + unsigned int con; + + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + + con = readw(info->base + S3C2410_RTCCON); + con &= ~S3C64XX_RTCCON_TICEN; + con &= ~S3C2410_RTCCON_RTCEN; + writew(con, info->base + S3C2410_RTCCON); + + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); +} + +static int s3c_rtc_remove(struct platform_device *pdev) +{ + struct s3c_rtc *info = platform_get_drvdata(pdev); + + s3c_rtc_setaie(info->dev, 0); + + clk_unprepare(info->rtc_clk); + info->rtc_clk = NULL; return 0; } static const struct of_device_id s3c_rtc_dt_match[]; -static inline int s3c_rtc_get_driver_data(struct platform_device *pdev) +static struct s3c_rtc_data *s3c_rtc_get_data(struct platform_device *pdev) { -#ifdef CONFIG_OF - struct s3c_rtc_drv_data *data; - if (pdev->dev.of_node) { - const struct of_device_id *match; - match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); - data = (struct s3c_rtc_drv_data *) match->data; - return data->cpu_type; - } -#endif - return platform_get_device_id(pdev)->driver_data; + const struct of_device_id *match; + + match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); + return (struct s3c_rtc_data *)match->data; } static int s3c_rtc_probe(struct platform_device *pdev) { - struct rtc_device *rtc; + struct s3c_rtc *info = NULL; struct rtc_time rtc_tm; struct resource *res; int ret; - int tmp; - dev_dbg(&pdev->dev, "%s: probe=%p\n", __func__, pdev); + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; /* find the IRQs */ - - s3c_rtc_tickno = platform_get_irq(pdev, 1); - if (s3c_rtc_tickno < 0) { + info->irq_tick = platform_get_irq(pdev, 1); + if (info->irq_tick < 0) { dev_err(&pdev->dev, "no irq for rtc tick\n"); - return s3c_rtc_tickno; + return info->irq_tick; + } + + info->dev = &pdev->dev; + info->data = s3c_rtc_get_data(pdev); + if (!info->data) { + dev_err(&pdev->dev, "failed getting s3c_rtc_data\n"); + return -EINVAL; } + spin_lock_init(&info->pie_lock); + spin_lock_init(&info->alarm_clk_lock); + + platform_set_drvdata(pdev, info); - s3c_rtc_alarmno = platform_get_irq(pdev, 0); - if (s3c_rtc_alarmno < 0) { + info->irq_alarm = platform_get_irq(pdev, 0); + if (info->irq_alarm < 0) { dev_err(&pdev->dev, "no irq for alarm\n"); - return s3c_rtc_alarmno; + return info->irq_alarm; } dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n", - s3c_rtc_tickno, s3c_rtc_alarmno); + info->irq_tick, info->irq_alarm); /* get the memory region */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - s3c_rtc_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(s3c_rtc_base)) - return PTR_ERR(s3c_rtc_base); - - rtc_clk = devm_clk_get(&pdev->dev, "rtc"); - if (IS_ERR(rtc_clk)) { - dev_err(&pdev->dev, "failed to find rtc clock source\n"); - ret = PTR_ERR(rtc_clk); - rtc_clk = NULL; - return ret; + info->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(info->base)) + return PTR_ERR(info->base); + + info->rtc_clk = devm_clk_get(&pdev->dev, "rtc"); + if (IS_ERR(info->rtc_clk)) { + dev_err(&pdev->dev, "failed to find rtc clock\n"); + return PTR_ERR(info->rtc_clk); } + clk_prepare_enable(info->rtc_clk); - clk_prepare_enable(rtc_clk); + info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src"); + if (IS_ERR(info->rtc_src_clk)) { + dev_err(&pdev->dev, "failed to find rtc source clock\n"); + return PTR_ERR(info->rtc_src_clk); + } + clk_prepare_enable(info->rtc_src_clk); - /* check to see if everything is setup correctly */ - s3c_rtc_enable(pdev, 1); + /* check to see if everything is setup correctly */ + if (info->data->enable) + info->data->enable(info); dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", - readw(s3c_rtc_base + S3C2410_RTCCON)); + readw(info->base + S3C2410_RTCCON)); device_init_wakeup(&pdev->dev, 1); /* register RTC and exit */ - - rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, + info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, THIS_MODULE); - - if (IS_ERR(rtc)) { + if (IS_ERR(info->rtc)) { dev_err(&pdev->dev, "cannot attach rtc\n"); - ret = PTR_ERR(rtc); + ret = PTR_ERR(info->rtc); goto err_nortc; } - s3c_rtc_cpu_type = s3c_rtc_get_driver_data(pdev); + ret = devm_request_irq(&pdev->dev, info->irq_alarm, s3c_rtc_alarmirq, + 0, "s3c2410-rtc alarm", info); + if (ret) { + dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_alarm, ret); + goto err_nortc; + } - /* Check RTC Time */ + ret = devm_request_irq(&pdev->dev, info->irq_tick, s3c_rtc_tickirq, + 0, "s3c2410-rtc tick", info); + if (ret) { + dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_tick, ret); + goto err_nortc; + } - s3c_rtc_gettime(NULL, &rtc_tm); + /* Check RTC Time */ + s3c_rtc_gettime(&pdev->dev, &rtc_tm); if (rtc_valid_tm(&rtc_tm)) { rtc_tm.tm_year = 100; @@ -523,163 +586,312 @@ static int s3c_rtc_probe(struct platform_device *pdev) rtc_tm.tm_min = 0; rtc_tm.tm_sec = 0; - s3c_rtc_settime(NULL, &rtc_tm); + s3c_rtc_settime(&pdev->dev, &rtc_tm); dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); } - if (s3c_rtc_cpu_type != TYPE_S3C2410) - rtc->max_user_freq = 32768; - else - rtc->max_user_freq = 128; - - if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { - tmp = readw(s3c_rtc_base + S3C2410_RTCCON); - tmp |= S3C2443_RTCCON_TICSEL; - writew(tmp, s3c_rtc_base + S3C2410_RTCCON); - } + if (info->data->select_tick_clk) + info->data->select_tick_clk(info); - platform_set_drvdata(pdev, rtc); + s3c_rtc_setfreq(info, 1); - s3c_rtc_setfreq(&pdev->dev, 1); - - ret = devm_request_irq(&pdev->dev, s3c_rtc_alarmno, s3c_rtc_alarmirq, - 0, "s3c2410-rtc alarm", rtc); - if (ret) { - dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); - goto err_nortc; - } - - ret = devm_request_irq(&pdev->dev, s3c_rtc_tickno, s3c_rtc_tickirq, - 0, "s3c2410-rtc tick", rtc); - if (ret) { - dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); - goto err_nortc; - } - - clk_disable(rtc_clk); + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); return 0; err_nortc: - s3c_rtc_enable(pdev, 0); - clk_disable_unprepare(rtc_clk); + if (info->data->disable) + info->data->disable(info); + clk_disable_unprepare(info->rtc_clk); return ret; } #ifdef CONFIG_PM_SLEEP -/* RTC Power management control */ - -static int ticnt_save, ticnt_en_save; -static bool wake_en; static int s3c_rtc_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); + struct s3c_rtc *info = dev_get_drvdata(dev); + + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); - clk_enable(rtc_clk); /* save TICNT for anyone using periodic interrupts */ - if (s3c_rtc_cpu_type == TYPE_S3C64XX) { - ticnt_en_save = readw(s3c_rtc_base + S3C2410_RTCCON); - ticnt_en_save &= S3C64XX_RTCCON_TICEN; - ticnt_save = readl(s3c_rtc_base + S3C2410_TICNT); - } else { - ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); - } - s3c_rtc_enable(pdev, 0); + if (info->data->save_tick_cnt) + info->data->save_tick_cnt(info); + + if (info->data->disable) + info->data->disable(info); - if (device_may_wakeup(dev) && !wake_en) { - if (enable_irq_wake(s3c_rtc_alarmno) == 0) - wake_en = true; + if (device_may_wakeup(dev) && !info->wake_en) { + if (enable_irq_wake(info->irq_alarm) == 0) + info->wake_en = true; else dev_err(dev, "enable_irq_wake failed\n"); } - clk_disable(rtc_clk); + + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); return 0; } static int s3c_rtc_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - unsigned int tmp; + struct s3c_rtc *info = dev_get_drvdata(dev); - clk_enable(rtc_clk); - s3c_rtc_enable(pdev, 1); - if (s3c_rtc_cpu_type == TYPE_S3C64XX) { - writel(ticnt_save, s3c_rtc_base + S3C2410_TICNT); - if (ticnt_en_save) { - tmp = readw(s3c_rtc_base + S3C2410_RTCCON); - writew(tmp | ticnt_en_save, - s3c_rtc_base + S3C2410_RTCCON); - } - } else { - writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); - } + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); - if (device_may_wakeup(dev) && wake_en) { - disable_irq_wake(s3c_rtc_alarmno); - wake_en = false; + if (info->data->enable) + info->data->enable(info); + + if (info->data->restore_tick_cnt) + info->data->restore_tick_cnt(info); + + if (device_may_wakeup(dev) && info->wake_en) { + disable_irq_wake(info->irq_alarm); + info->wake_en = false; } - clk_disable(rtc_clk); + + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); return 0; } #endif - static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); -#ifdef CONFIG_OF -static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = { - [TYPE_S3C2410] = { TYPE_S3C2410 }, - [TYPE_S3C2416] = { TYPE_S3C2416 }, - [TYPE_S3C2443] = { TYPE_S3C2443 }, - [TYPE_S3C64XX] = { TYPE_S3C64XX }, +static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask) +{ + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); + + s3c_rtc_alarm_clk_enable(info, false); +} + +static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask) +{ + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); + writeb(mask, info->base + S3C2410_INTP); + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); + + s3c_rtc_alarm_clk_enable(info, false); +} + +static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq) +{ + unsigned int tmp = 0; + int val; + + tmp = readb(info->base + S3C2410_TICNT); + tmp &= S3C2410_TICNT_ENABLE; + + val = (info->rtc->max_user_freq / freq) - 1; + tmp |= val; + + writel(tmp, info->base + S3C2410_TICNT); +} + +static void s3c2416_rtc_setfreq(struct s3c_rtc *info, int freq) +{ + unsigned int tmp = 0; + int val; + + tmp = readb(info->base + S3C2410_TICNT); + tmp &= S3C2410_TICNT_ENABLE; + + val = (info->rtc->max_user_freq / freq) - 1; + + tmp |= S3C2443_TICNT_PART(val); + writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1); + + writel(S3C2416_TICNT2_PART(val), info->base + S3C2416_TICNT2); + + writel(tmp, info->base + S3C2410_TICNT); +} + +static void s3c2443_rtc_setfreq(struct s3c_rtc *info, int freq) +{ + unsigned int tmp = 0; + int val; + + tmp = readb(info->base + S3C2410_TICNT); + tmp &= S3C2410_TICNT_ENABLE; + + val = (info->rtc->max_user_freq / freq) - 1; + + tmp |= S3C2443_TICNT_PART(val); + writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1); + + writel(tmp, info->base + S3C2410_TICNT); +} + +static void s3c6410_rtc_setfreq(struct s3c_rtc *info, int freq) +{ + int val; + + val = (info->rtc->max_user_freq / freq) - 1; + writel(val, info->base + S3C2410_TICNT); +} + +static void s3c24xx_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq) +{ + unsigned int ticnt; + + ticnt = readb(info->base + S3C2410_TICNT); + ticnt &= S3C2410_TICNT_ENABLE; + + seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); +} + +static void s3c2416_rtc_select_tick_clk(struct s3c_rtc *info) +{ + unsigned int con; + + con = readw(info->base + S3C2410_RTCCON); + con |= S3C2443_RTCCON_TICSEL; + writew(con, info->base + S3C2410_RTCCON); +} + +static void s3c6410_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq) +{ + unsigned int ticnt; + + ticnt = readw(info->base + S3C2410_RTCCON); + ticnt &= S3C64XX_RTCCON_TICEN; + + seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); +} + +static void s3c24xx_rtc_save_tick_cnt(struct s3c_rtc *info) +{ + info->ticnt_save = readb(info->base + S3C2410_TICNT); +} + +static void s3c24xx_rtc_restore_tick_cnt(struct s3c_rtc *info) +{ + writeb(info->ticnt_save, info->base + S3C2410_TICNT); +} + +static void s3c6410_rtc_save_tick_cnt(struct s3c_rtc *info) +{ + info->ticnt_en_save = readw(info->base + S3C2410_RTCCON); + info->ticnt_en_save &= S3C64XX_RTCCON_TICEN; + info->ticnt_save = readl(info->base + S3C2410_TICNT); +} + +static void s3c6410_rtc_restore_tick_cnt(struct s3c_rtc *info) +{ + unsigned int con; + + writel(info->ticnt_save, info->base + S3C2410_TICNT); + if (info->ticnt_en_save) { + con = readw(info->base + S3C2410_RTCCON); + writew(con | info->ticnt_en_save, + info->base + S3C2410_RTCCON); + } +} + +static struct s3c_rtc_data const s3c2410_rtc_data = { + .max_user_freq = 128, + .irq_handler = s3c24xx_rtc_irq, + .set_freq = s3c2410_rtc_setfreq, + .enable_tick = s3c24xx_rtc_enable_tick, + .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, + .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, + .enable = s3c24xx_rtc_enable, + .disable = s3c24xx_rtc_disable, +}; + +static struct s3c_rtc_data const s3c2416_rtc_data = { + .max_user_freq = 32768, + .irq_handler = s3c24xx_rtc_irq, + .set_freq = s3c2416_rtc_setfreq, + .enable_tick = s3c24xx_rtc_enable_tick, + .select_tick_clk = s3c2416_rtc_select_tick_clk, + .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, + .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, + .enable = s3c24xx_rtc_enable, + .disable = s3c24xx_rtc_disable, +}; + +static struct s3c_rtc_data const s3c2443_rtc_data = { + .max_user_freq = 32768, + .irq_handler = s3c24xx_rtc_irq, + .set_freq = s3c2443_rtc_setfreq, + .enable_tick = s3c24xx_rtc_enable_tick, + .select_tick_clk = s3c2416_rtc_select_tick_clk, + .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, + .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, + .enable = s3c24xx_rtc_enable, + .disable = s3c24xx_rtc_disable, +}; + +static struct s3c_rtc_data const s3c6410_rtc_data = { + .max_user_freq = 32768, + .irq_handler = s3c6410_rtc_irq, + .set_freq = s3c6410_rtc_setfreq, + .enable_tick = s3c6410_rtc_enable_tick, + .save_tick_cnt = s3c6410_rtc_save_tick_cnt, + .restore_tick_cnt = s3c6410_rtc_restore_tick_cnt, + .enable = s3c24xx_rtc_enable, + .disable = s3c6410_rtc_disable, +}; + +static struct s3c_rtc_data const exynos3250_rtc_data = { + .max_user_freq = 32768, + .needs_src_clk = true, + .irq_handler = s3c6410_rtc_irq, + .set_freq = s3c6410_rtc_setfreq, + .enable_tick = s3c6410_rtc_enable_tick, + .save_tick_cnt = s3c6410_rtc_save_tick_cnt, + .restore_tick_cnt = s3c6410_rtc_restore_tick_cnt, + .enable = s3c24xx_rtc_enable, + .disable = s3c6410_rtc_disable, }; static const struct of_device_id s3c_rtc_dt_match[] = { { .compatible = "samsung,s3c2410-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C2410], + .data = (void *)&s3c2410_rtc_data, }, { .compatible = "samsung,s3c2416-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C2416], + .data = (void *)&s3c2416_rtc_data, }, { .compatible = "samsung,s3c2443-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C2443], + .data = (void *)&s3c2443_rtc_data, }, { .compatible = "samsung,s3c6410-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C64XX], - }, - {}, -}; -MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); -#endif - -static struct platform_device_id s3c_rtc_driver_ids[] = { - { - .name = "s3c2410-rtc", - .driver_data = TYPE_S3C2410, - }, { - .name = "s3c2416-rtc", - .driver_data = TYPE_S3C2416, - }, { - .name = "s3c2443-rtc", - .driver_data = TYPE_S3C2443, + .data = (void *)&s3c6410_rtc_data, }, { - .name = "s3c64xx-rtc", - .driver_data = TYPE_S3C64XX, + .compatible = "samsung,exynos3250-rtc", + .data = (void *)&exynos3250_rtc_data, }, - { } + { /* sentinel */ }, }; - -MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); +MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); static struct platform_driver s3c_rtc_driver = { .probe = s3c_rtc_probe, .remove = s3c_rtc_remove, - .id_table = s3c_rtc_driver_ids, .driver = { .name = "s3c-rtc", .owner = THIS_MODULE, @@ -687,7 +899,6 @@ static struct platform_driver s3c_rtc_driver = { .of_match_table = of_match_ptr(s3c_rtc_dt_match), }, }; - module_platform_driver(s3c_rtc_driver); MODULE_DESCRIPTION("Samsung S3C RTC Driver"); diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index d497aa05a72..c692dfebd0b 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, if (!num_args) return count; - if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) { + if (!strncasecmp(cmd, "on", 2) || !strcmp(cmd, "1")) { mutex_lock(&cp->lock); error = s390_vary_chpid(cp->chpid, 1); mutex_unlock(&cp->lock); - } else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) { + } else if (!strncasecmp(cmd, "off", 3) || !strcmp(cmd, "0")) { mutex_lock(&cp->lock); error = s390_vary_chpid(cp->chpid, 0); mutex_unlock(&cp->lock); diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 52a216f21ae..e5afc3884d7 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -528,7 +528,7 @@ ips_setup(char *ips_str) * Update the variables */ for (i = 0; i < ARRAY_SIZE(options); i++) { - if (strnicmp + if (strncasecmp (key, options[i].option_name, strlen(options[i].option_name)) == 0) { if (value) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 2b6d447ad6d..238e06f13b8 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, char work[20]; if (1 == sscanf(buf, "%10s", work)) { - if (0 == strnicmp(work,"0x", 2)) { + if (0 == strncasecmp(work,"0x", 2)) { if (1 == sscanf(&work[2], "%x", &opts)) goto opts_done; } else { diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index 1718229f627..d9d55d12fd5 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) { int cmd_num; for (cmd_num = 0; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++) - if (0 == strnicmp(cmdstr , android_wifi_cmd_str[cmd_num], + if (0 == strncasecmp(cmdstr , android_wifi_cmd_str[cmd_num], strlen(android_wifi_cmd_str[cmd_num]))) break; return cmd_num; diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 91d35df286c..2d82f8993ea 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) static inline const char *escape_essid(const char *essid, u8 essid_len) { static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - const char *s = essid; - char *d = escaped; if (rtllib_is_empty_essid(essid, essid_len)) { memcpy(escaped, "<hidden>", sizeof("<hidden>")); return escaped; } - essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); - while (essid_len--) { - if (*s == '\0') { - *d++ = '\\'; - *d++ = '0'; - s++; - } else { - *d++ = *s++; - } - } - *d = '\0'; + snprintf(escaped, sizeof(escaped), "%*pEn", essid_len, essid); return escaped; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 9ecfa4a2421..b44aa17d30a 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) static inline const char *escape_essid(const char *essid, u8 essid_len) { static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - const char *s = essid; - char *d = escaped; if (ieee80211_is_empty_essid(essid, essid_len)) { memcpy(escaped, "<hidden>", sizeof("<hidden>")); return escaped; } - essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); - while (essid_len--) { - if (*s == '\0') { - *d++ = '\\'; - *d++ = '0'; - s++; - } else { - *d++ = *s++; - } - } - *d = '\0'; + snprintf(escaped, sizeof(escaped), "%*pEn", essid_len, essid); return escaped; } diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 799ce8aa70e..df577dfe7ff 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -60,7 +60,6 @@ #include <linux/netdevice.h> #include <linux/workqueue.h> #include <linux/byteorder/generic.h> -#include <linux/ctype.h> #include <linux/io.h> #include <linux/delay.h> @@ -81,27 +80,6 @@ #include "hfa384x.h" #include "prism2mgmt.h" -/* Create a string of printable chars from something that might not be */ -/* It's recommended that the str be 4*len + 1 bytes long */ -#define wlan_mkprintstr(buf, buflen, str, strlen) \ -{ \ - int i = 0; \ - int j = 0; \ - memset(str, 0, (strlen)); \ - for (i = 0; i < (buflen); i++) { \ - if (isprint((buf)[i])) { \ - (str)[j] = (buf)[i]; \ - j++; \ - } else { \ - (str)[j] = '\\'; \ - (str)[j+1] = 'x'; \ - (str)[j+2] = hex_asc_hi((buf)[i]); \ - (str)[j+3] = hex_asc_lo((buf)[i]); \ - j += 4; \ - } \ - } \ -} - static char *dev_info = "prism2_usb"; static wlandevice_t *create_wlan(void); @@ -607,7 +585,6 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev) hfa384x_t *hw = (hfa384x_t *) wlandev->priv; u16 temp; u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN]; - char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1]; /* Collect version and compatibility info */ /* Some are critical, some are not */ @@ -862,9 +839,8 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev) result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, snum, HFA384x_RID_NICSERIALNUMBER_LEN); if (!result) { - wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN, - pstr, sizeof(pstr)); - netdev_info(wlandev->netdev, "Prism2 card SN: %s\n", pstr); + netdev_info(wlandev->netdev, "Prism2 card SN: %*pEhp\n", + HFA384x_RID_NICSERIALNUMBER_LEN, snum); } else { netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n"); goto failed; diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 71b0ec0c370..1e23f4f8d2c 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) return def_governor; list_for_each_entry(pos, &thermal_governor_list, governor_list) - if (!strnicmp(name, pos->name, THERMAL_NAME_LENGTH)) + if (!strncasecmp(name, pos->name, THERMAL_NAME_LENGTH)) return pos; return NULL; @@ -104,7 +104,7 @@ int thermal_register_governor(struct thermal_governor *governor) name = pos->tzp->governor_name; - if (!strnicmp(name, governor->name, THERMAL_NAME_LENGTH)) + if (!strncasecmp(name, governor->name, THERMAL_NAME_LENGTH)) pos->governor = governor; } @@ -129,7 +129,7 @@ void thermal_unregister_governor(struct thermal_governor *governor) mutex_lock(&thermal_list_lock); list_for_each_entry(pos, &thermal_tz_list, node) { - if (!strnicmp(pos->governor->name, governor->name, + if (!strncasecmp(pos->governor->name, governor->name, THERMAL_NAME_LENGTH)) pos->governor = NULL; } @@ -1665,7 +1665,7 @@ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name) mutex_lock(&thermal_list_lock); list_for_each_entry(pos, &thermal_tz_list, node) - if (!strnicmp(name, pos->type, THERMAL_NAME_LENGTH)) { + if (!strncasecmp(name, pos->type, THERMAL_NAME_LENGTH)) { found++; ref = pos; } diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index 167cffff3d4..7c74f58fc10 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, for (i = 0 ; i < size ; i++ ) { if (s != NULL) { - if (!strnicmp(p[i].name, s, strlen(s))) + if (!strncasecmp(p[i].name, s, strlen(s))) return p[i].val; } else { if (p[i].val == val) diff --git a/drivers/video/fbdev/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c index 43c63a4f317..e350eb57f11 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, if (len < 1) return -EINVAL; - if (strnicmp(buf, "on", 2) == 0 || - strnicmp(buf, "1", 1) == 0) { + if (strncasecmp(buf, "on", 2) == 0 || + strncasecmp(buf, "1", 1) == 0) { debug = 1; dev_dbg(dev, "s3c2410fb: Debug On"); - } else if (strnicmp(buf, "off", 3) == 0 || - strnicmp(buf, "0", 1) == 0) { + } else if (strncasecmp(buf, "off", 3) == 0 || + strncasecmp(buf, "0", 1) == 0) { debug = 0; dev_dbg(dev, "s3c2410fb: Debug Off"); } else { diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c index 3f12a2dd959..4f5cf035ac3 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) return; } - if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { + if(!strncasecmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { if(!quiet) printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); @@ -201,7 +201,7 @@ static void sisfb_search_mode(char *name, bool quiet) i = 0; j = 0; while(sisbios_mode[i].mode_no[0] != 0) { - if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) { + if(!strncasecmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) { if(sisfb_fstn) { if(sisbios_mode[i-1].mode_no[1] == 0x50 || sisbios_mode[i-1].mode_no[1] == 0x56 || @@ -262,7 +262,7 @@ sisfb_search_crt2type(const char *name) if(name == NULL) return; while(sis_crt2type[i].type_no != -1) { - if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) { + if(!strncasecmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) { sisfb_crt2type = sis_crt2type[i].type_no; sisfb_tvplug = sis_crt2type[i].tvplug_no; sisfb_crt2flags = sis_crt2type[i].flags; @@ -289,7 +289,7 @@ sisfb_search_tvstd(const char *name) return; while(sis_tvtype[i].type_no != -1) { - if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) { + if(!strncasecmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) { sisfb_tvstd = sis_tvtype[i].type_no; break; } @@ -308,12 +308,12 @@ sisfb_search_specialtiming(const char *name) if(name == NULL) return; - if(!strnicmp(name, "none", 4)) { + if(!strncasecmp(name, "none", 4)) { sisfb_specialtiming = CUT_FORCENONE; printk(KERN_DEBUG "sisfb: Special timing disabled\n"); } else { while(mycustomttable[i].chipID != 0) { - if(!strnicmp(name,mycustomttable[i].optionName, + if(!strncasecmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) { sisfb_specialtiming = mycustomttable[i].SpecialID; found = true; @@ -3952,68 +3952,68 @@ static int __init sisfb_setup(char *options) if(!(*this_opt)) continue; - if(!strnicmp(this_opt, "off", 3)) { + if(!strncasecmp(this_opt, "off", 3)) { sisfb_off = 1; - } else if(!strnicmp(this_opt, "forcecrt2type:", 14)) { + } else if(!strncasecmp(this_opt, "forcecrt2type:", 14)) { /* Need to check crt2 type first for fstn/dstn */ sisfb_search_crt2type(this_opt + 14); - } else if(!strnicmp(this_opt, "tvmode:",7)) { + } else if(!strncasecmp(this_opt, "tvmode:",7)) { sisfb_search_tvstd(this_opt + 7); - } else if(!strnicmp(this_opt, "tvstandard:",11)) { + } else if(!strncasecmp(this_opt, "tvstandard:",11)) { sisfb_search_tvstd(this_opt + 11); - } else if(!strnicmp(this_opt, "mode:", 5)) { + } else if(!strncasecmp(this_opt, "mode:", 5)) { sisfb_search_mode(this_opt + 5, false); - } else if(!strnicmp(this_opt, "vesa:", 5)) { + } else if(!strncasecmp(this_opt, "vesa:", 5)) { sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false); - } else if(!strnicmp(this_opt, "rate:", 5)) { + } else if(!strncasecmp(this_opt, "rate:", 5)) { sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); - } else if(!strnicmp(this_opt, "forcecrt1:", 10)) { + } else if(!strncasecmp(this_opt, "forcecrt1:", 10)) { sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0); - } else if(!strnicmp(this_opt, "mem:",4)) { + } else if(!strncasecmp(this_opt, "mem:",4)) { sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0); - } else if(!strnicmp(this_opt, "pdc:", 4)) { + } else if(!strncasecmp(this_opt, "pdc:", 4)) { sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0); - } else if(!strnicmp(this_opt, "pdc1:", 5)) { + } else if(!strncasecmp(this_opt, "pdc1:", 5)) { sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0); - } else if(!strnicmp(this_opt, "noaccel", 7)) { + } else if(!strncasecmp(this_opt, "noaccel", 7)) { sisfb_accel = 0; - } else if(!strnicmp(this_opt, "accel", 5)) { + } else if(!strncasecmp(this_opt, "accel", 5)) { sisfb_accel = -1; - } else if(!strnicmp(this_opt, "noypan", 6)) { + } else if(!strncasecmp(this_opt, "noypan", 6)) { sisfb_ypan = 0; - } else if(!strnicmp(this_opt, "ypan", 4)) { + } else if(!strncasecmp(this_opt, "ypan", 4)) { sisfb_ypan = -1; - } else if(!strnicmp(this_opt, "nomax", 5)) { + } else if(!strncasecmp(this_opt, "nomax", 5)) { sisfb_max = 0; - } else if(!strnicmp(this_opt, "max", 3)) { + } else if(!strncasecmp(this_opt, "max", 3)) { sisfb_max = -1; - } else if(!strnicmp(this_opt, "userom:", 7)) { + } else if(!strncasecmp(this_opt, "userom:", 7)) { sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0); - } else if(!strnicmp(this_opt, "useoem:", 7)) { + } else if(!strncasecmp(this_opt, "useoem:", 7)) { sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); - } else if(!strnicmp(this_opt, "nocrt2rate", 10)) { + } else if(!strncasecmp(this_opt, "nocrt2rate", 10)) { sisfb_nocrt2rate = 1; - } else if(!strnicmp(this_opt, "scalelcd:", 9)) { + } else if(!strncasecmp(this_opt, "scalelcd:", 9)) { unsigned long temp = 2; temp = simple_strtoul(this_opt + 9, NULL, 0); if((temp == 0) || (temp == 1)) { sisfb_scalelcd = temp ^ 1; } - } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) { + } else if(!strncasecmp(this_opt, "tvxposoffset:", 13)) { int temp = 0; temp = (int)simple_strtol(this_opt + 13, NULL, 0); if((temp >= -32) && (temp <= 32)) { sisfb_tvxposoffset = temp; } - } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) { + } else if(!strncasecmp(this_opt, "tvyposoffset:", 13)) { int temp = 0; temp = (int)simple_strtol(this_opt + 13, NULL, 0); if((temp >= -32) && (temp <= 32)) { sisfb_tvyposoffset = temp; } - } else if(!strnicmp(this_opt, "specialtiming:", 14)) { + } else if(!strncasecmp(this_opt, "specialtiming:", 14)) { sisfb_search_specialtiming(this_opt + 14); - } else if(!strnicmp(this_opt, "lvdshl:", 7)) { + } else if(!strncasecmp(this_opt, "lvdshl:", 7)) { int temp = 4; temp = simple_strtoul(this_opt + 7, NULL, 0); if((temp >= 0) && (temp <= 3)) { @@ -4022,9 +4022,9 @@ static int __init sisfb_setup(char *options) } else if(this_opt[0] >= '0' && this_opt[0] <= '9') { sisfb_search_mode(this_opt, true); #if !defined(__i386__) && !defined(__x86_64__) - } else if(!strnicmp(this_opt, "resetcard", 9)) { + } else if(!strncasecmp(this_opt, "resetcard", 9)) { sisfb_resetcard = 1; - } else if(!strnicmp(this_opt, "videoram:", 9)) { + } else if(!strncasecmp(this_opt, "videoram:", 9)) { sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0); #endif } else { diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c index c2c8eb66878..9e74e8fbe07 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, if (len < 1) return -EINVAL; - if (strnicmp(buf, "crt", 3) == 0) + if (strncasecmp(buf, "crt", 3) == 0) head = HEAD_CRT; - else if (strnicmp(buf, "panel", 5) == 0) + else if (strncasecmp(buf, "panel", 5) == 0) head = HEAD_PANEL; else return -EINVAL; |