diff options
Diffstat (limited to 'drivers')
64 files changed, 1033 insertions, 662 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 1ccbe9482faa..2ca6d7844ad9 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -745,7 +745,7 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig) offset += file->f_pos; case SEEK_SET: /* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */ - if ((unsigned long long)offset >= ~0xFFFULL) { + if (IS_ERR_VALUE((unsigned long long)offset)) { ret = -EOVERFLOW; break; } diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index e1f60f968fdd..f1d7fa45c275 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c @@ -267,7 +267,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma, if ((vma->vm_flags & VM_WRITE) == 0) return -EPERM; - pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + pages = vma_pages(vma); vdata_size = sizeof(struct vma_data) + pages * sizeof(long); if (vdata_size <= PAGE_SIZE) vdata = kzalloc(vdata_size, GFP_KERNEL); diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h index d31ee23c9f13..38b145eaf24d 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.h +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h @@ -37,7 +37,7 @@ #include <linux/cdev.h> #include <linux/platform_device.h> -#include <asm/io.h> +#include <linux/io.h> struct hwicap_drvdata { u32 write_buffer_in_use; /* Always in [0,3] */ @@ -85,7 +85,13 @@ struct hwicap_driver_config { void (*reset)(struct hwicap_drvdata *drvdata); }; -/* Number of times to poll the done regsiter */ +/* Number of times to poll the done register. This has to be large + * enough to allow an entire configuration to complete. If an entire + * page (4kb) is configured at once, that could take up to 4k cycles + * with a byte-wide icap interface. In most cases, this driver is + * used with a much smaller fifo, but this should be sufficient in the + * worst case. + */ #define XHI_MAX_RETRIES 5000 /************ Constant Definitions *************/ diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 0b122f8c7005..6de6c98ce6eb 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -116,6 +116,15 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, unsigned long flags; int ret, t, err = 0; + spin_lock_irqsave(&newchannel->sc_lock, flags); + if (newchannel->state == CHANNEL_OPEN_STATE) { + newchannel->state = CHANNEL_OPENING_STATE; + } else { + spin_unlock_irqrestore(&newchannel->sc_lock, flags); + return -EINVAL; + } + spin_unlock_irqrestore(&newchannel->sc_lock, flags); + newchannel->onchannel_callback = onchannelcallback; newchannel->channel_callback_context = context; @@ -216,6 +225,9 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, list_del(&open_info->msglistentry); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); + if (err == 0) + newchannel->state = CHANNEL_OPENED_STATE; + kfree(open_info); return err; @@ -500,15 +512,14 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) } EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl); -/* - * vmbus_close - Close the specified channel - */ -void vmbus_close(struct vmbus_channel *channel) +static void vmbus_close_internal(struct vmbus_channel *channel) { struct vmbus_channel_close_channel *msg; int ret; unsigned long flags; + channel->state = CHANNEL_OPEN_STATE; + channel->sc_creation_callback = NULL; /* Stop callback and cancel the timer asap */ spin_lock_irqsave(&channel->inbound_lock, flags); channel->onchannel_callback = NULL; @@ -538,6 +549,37 @@ void vmbus_close(struct vmbus_channel *channel) } + +/* + * vmbus_close - Close the specified channel + */ +void vmbus_close(struct vmbus_channel *channel) +{ + struct list_head *cur, *tmp; + struct vmbus_channel *cur_channel; + + if (channel->primary_channel != NULL) { + /* + * We will only close sub-channels when + * the primary is closed. + */ + return; + } + /* + * Close all the sub-channels first and then close the + * primary channel. + */ + list_for_each_safe(cur, tmp, &channel->sc_list) { + cur_channel = list_entry(cur, struct vmbus_channel, sc_list); + if (cur_channel->state != CHANNEL_OPENED_STATE) + continue; + vmbus_close_internal(cur_channel); + } + /* + * Now close the primary. + */ + vmbus_close_internal(channel); +} EXPORT_SYMBOL_GPL(vmbus_close); /** diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 21ef68934a20..0df75908200e 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -115,6 +115,9 @@ static struct vmbus_channel *alloc_channel(void) return NULL; spin_lock_init(&channel->inbound_lock); + spin_lock_init(&channel->sc_lock); + + INIT_LIST_HEAD(&channel->sc_list); channel->controlwq = create_workqueue("hv_vmbus_ctl"); if (!channel->controlwq) { @@ -166,6 +169,7 @@ static void vmbus_process_rescind_offer(struct work_struct *work) struct vmbus_channel, work); unsigned long flags; + struct vmbus_channel *primary_channel; struct vmbus_channel_relid_released msg; vmbus_device_unregister(channel->device_obj); @@ -174,9 +178,16 @@ static void vmbus_process_rescind_offer(struct work_struct *work) msg.header.msgtype = CHANNELMSG_RELID_RELEASED; vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released)); - spin_lock_irqsave(&vmbus_connection.channel_lock, flags); - list_del(&channel->listentry); - spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); + if (channel->primary_channel == NULL) { + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); + list_del(&channel->listentry); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); + } else { + primary_channel = channel->primary_channel; + spin_lock_irqsave(&primary_channel->sc_lock, flags); + list_del(&channel->listentry); + spin_unlock_irqrestore(&primary_channel->sc_lock, flags); + } free_channel(channel); } @@ -228,6 +239,24 @@ static void vmbus_process_offer(struct work_struct *work) spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); if (!fnew) { + /* + * Check to see if this is a sub-channel. + */ + if (newchannel->offermsg.offer.sub_channel_index != 0) { + /* + * Process the sub-channel. + */ + newchannel->primary_channel = channel; + spin_lock_irqsave(&channel->sc_lock, flags); + list_add_tail(&newchannel->sc_list, &channel->sc_list); + spin_unlock_irqrestore(&channel->sc_lock, flags); + newchannel->state = CHANNEL_OPEN_STATE; + if (channel->sc_creation_callback != NULL) + channel->sc_creation_callback(newchannel); + + return; + } + free_channel(newchannel); return; } @@ -685,4 +714,86 @@ cleanup: return ret; } -/* eof */ +/* + * Retrieve the (sub) channel on which to send an outgoing request. + * When a primary channel has multiple sub-channels, we choose a + * channel whose VCPU binding is closest to the VCPU on which + * this call is being made. + */ +struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary) +{ + struct list_head *cur, *tmp; + int cur_cpu = hv_context.vp_index[smp_processor_id()]; + struct vmbus_channel *cur_channel; + struct vmbus_channel *outgoing_channel = primary; + int cpu_distance, new_cpu_distance; + + if (list_empty(&primary->sc_list)) + return outgoing_channel; + + list_for_each_safe(cur, tmp, &primary->sc_list) { + cur_channel = list_entry(cur, struct vmbus_channel, sc_list); + if (cur_channel->state != CHANNEL_OPENED_STATE) + continue; + + if (cur_channel->target_vp == cur_cpu) + return cur_channel; + + cpu_distance = ((outgoing_channel->target_vp > cur_cpu) ? + (outgoing_channel->target_vp - cur_cpu) : + (cur_cpu - outgoing_channel->target_vp)); + + new_cpu_distance = ((cur_channel->target_vp > cur_cpu) ? + (cur_channel->target_vp - cur_cpu) : + (cur_cpu - cur_channel->target_vp)); + + if (cpu_distance < new_cpu_distance) + continue; + + outgoing_channel = cur_channel; + } + + return outgoing_channel; +} +EXPORT_SYMBOL_GPL(vmbus_get_outgoing_channel); + +static void invoke_sc_cb(struct vmbus_channel *primary_channel) +{ + struct list_head *cur, *tmp; + struct vmbus_channel *cur_channel; + + if (primary_channel->sc_creation_callback == NULL) + return; + + list_for_each_safe(cur, tmp, &primary_channel->sc_list) { + cur_channel = list_entry(cur, struct vmbus_channel, sc_list); + + primary_channel->sc_creation_callback(cur_channel); + } +} + +void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel, + void (*sc_cr_cb)(struct vmbus_channel *new_sc)) +{ + primary_channel->sc_creation_callback = sc_cr_cb; +} +EXPORT_SYMBOL_GPL(vmbus_set_sc_create_callback); + +bool vmbus_are_subchannels_present(struct vmbus_channel *primary) +{ + bool ret; + + ret = !list_empty(&primary->sc_list); + + if (ret) { + /* + * Invoke the callback on sub-channel creation. + * This will present a uniform interface to the + * clients. + */ + invoke_sc_cb(primary); + } + + return ret; +} +EXPORT_SYMBOL_GPL(vmbus_are_subchannels_present); diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index 253a74ba245c..ec3b8cdf1e04 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -246,12 +246,26 @@ struct vmbus_channel *relid2channel(u32 relid) struct vmbus_channel *channel; struct vmbus_channel *found_channel = NULL; unsigned long flags; + struct list_head *cur, *tmp; + struct vmbus_channel *cur_sc; spin_lock_irqsave(&vmbus_connection.channel_lock, flags); list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { if (channel->offermsg.child_relid == relid) { found_channel = channel; break; + } else if (!list_empty(&channel->sc_list)) { + /* + * Deal with sub-channels. + */ + list_for_each_safe(cur, tmp, &channel->sc_list) { + cur_sc = list_entry(cur, struct vmbus_channel, + sc_list); + if (cur_sc->offermsg.child_relid == relid) { + found_channel = cur_sc; + break; + } + } } } spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index 067f31174a0e..29a11db365bc 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -20,6 +20,16 @@ config TI_EMIF parameters and other settings during frequency, voltage and temperature changes +config MVEBU_DEVBUS + bool "Marvell EBU Device Bus Controller" + default y + depends on PLAT_ORION && OF + help + This driver is for the Device Bus controller available in some + Marvell EBU SoCs such as Discovery (mv78xx0), Orion (88f5xxx) and + Armada 370 and Armada XP. This controller allows to handle flash + devices such as NOR, NAND, SRAM, and FPGA. + config TEGRA20_MC bool "Tegra20 Memory Controller(MC) driver" default y diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index 9cce5d70ed52..969d923dad93 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -6,5 +6,6 @@ ifeq ($(CONFIG_DDR),y) obj-$(CONFIG_OF) += of_memory.o endif obj-$(CONFIG_TI_EMIF) += emif.o +obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o obj-$(CONFIG_TEGRA30_MC) += tegra30-mc.o diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c new file mode 100644 index 000000000000..978e8e3abc5c --- /dev/null +++ b/drivers/memory/mvebu-devbus.c @@ -0,0 +1,340 @@ +/* + * Marvell EBU SoC Device Bus Controller + * (memory controller for NOR/NAND/SRAM/FPGA devices) + * + * Copyright (C) 2013 Marvell + * + * 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 version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/mbus.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> + +/* Register definitions */ +#define DEV_WIDTH_BIT 30 +#define BADR_SKEW_BIT 28 +#define RD_HOLD_BIT 23 +#define ACC_NEXT_BIT 17 +#define RD_SETUP_BIT 12 +#define ACC_FIRST_BIT 6 + +#define SYNC_ENABLE_BIT 24 +#define WR_HIGH_BIT 16 +#define WR_LOW_BIT 8 + +#define READ_PARAM_OFFSET 0x0 +#define WRITE_PARAM_OFFSET 0x4 + +static const char * const devbus_wins[] = { + "devbus-boot", + "devbus-cs0", + "devbus-cs1", + "devbus-cs2", + "devbus-cs3", +}; + +struct devbus_read_params { + u32 bus_width; + u32 badr_skew; + u32 turn_off; + u32 acc_first; + u32 acc_next; + u32 rd_setup; + u32 rd_hold; +}; + +struct devbus_write_params { + u32 sync_enable; + u32 wr_high; + u32 wr_low; + u32 ale_wr; +}; + +struct devbus { + struct device *dev; + void __iomem *base; + unsigned long tick_ps; +}; + +static int get_timing_param_ps(struct devbus *devbus, + struct device_node *node, + const char *name, + u32 *ticks) +{ + u32 time_ps; + int err; + + err = of_property_read_u32(node, name, &time_ps); + if (err < 0) { + dev_err(devbus->dev, "%s has no '%s' property\n", + name, node->full_name); + return err; + } + + *ticks = (time_ps + devbus->tick_ps - 1) / devbus->tick_ps; + + dev_dbg(devbus->dev, "%s: %u ps -> 0x%x\n", + name, time_ps, *ticks); + return 0; +} + +static int devbus_set_timing_params(struct devbus *devbus, + struct device_node *node) +{ + struct devbus_read_params r; + struct devbus_write_params w; + u32 value; + int err; + + dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n", + devbus->tick_ps); + + /* Get read timings */ + err = of_property_read_u32(node, "devbus,bus-width", &r.bus_width); + if (err < 0) { + dev_err(devbus->dev, + "%s has no 'devbus,bus-width' property\n", + node->full_name); + return err; + } + /* Convert bit width to byte width */ + r.bus_width /= 8; + + err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps", + &r.badr_skew); + if (err < 0) + return err; + + err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps", + &r.turn_off); + if (err < 0) + return err; + + err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps", + &r.acc_first); + if (err < 0) + return err; + + err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps", + &r.acc_next); + if (err < 0) + return err; + + err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps", + &r.rd_setup); + if (err < 0) + return err; + + err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps", + &r.rd_hold); + if (err < 0) + return err; + + /* Get write timings */ + err = of_property_read_u32(node, "devbus,sync-enable", + &w.sync_enable); + if (err < 0) { + dev_err(devbus->dev, + "%s has no 'devbus,sync-enable' property\n", + node->full_name); + return err; + } + + err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps", + &w.ale_wr); + if (err < 0) + return err; + + err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps", + &w.wr_low); + if (err < 0) + return err; + + err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps", + &w.wr_high); + if (err < 0) + return err; + + /* Set read timings */ + value = r.bus_width << DEV_WIDTH_BIT | + r.badr_skew << BADR_SKEW_BIT | + r.rd_hold << RD_HOLD_BIT | + r.acc_next << ACC_NEXT_BIT | + r.rd_setup << RD_SETUP_BIT | + r.acc_first << ACC_FIRST_BIT | + r.turn_off; + + dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n", + devbus->base + READ_PARAM_OFFSET, + value); + + writel(value, devbus->base + READ_PARAM_OFFSET); + + /* Set write timings */ + value = w.sync_enable << SYNC_ENABLE_BIT | + w.wr_low << WR_LOW_BIT | + w.wr_high << WR_HIGH_BIT | + w.ale_wr; + + dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n", + devbus->base + WRITE_PARAM_OFFSET, + value); + + writel(value, devbus->base + WRITE_PARAM_OFFSET); + + return 0; +} + +static int mvebu_devbus_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = pdev->dev.of_node; + struct device_node *parent; + struct devbus *devbus; + struct resource *res; + struct clk *clk; + unsigned long rate; + const __be32 *ranges; + int err, cs; + int addr_cells, p_addr_cells, size_cells; + int ranges_len, tuple_len; + u32 base, size; + + devbus = devm_kzalloc(&pdev->dev, sizeof(struct devbus), GFP_KERNEL); + if (!devbus) + return -ENOMEM; + + devbus->dev = dev; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + devbus->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(devbus->base)) + return PTR_ERR(devbus->base); + + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + clk_prepare_enable(clk); + + /* + * Obtain clock period in picoseconds, + * we need this in order to convert timing + * parameters from cycles to picoseconds. + */ + rate = clk_get_rate(clk) / 1000; + devbus->tick_ps = 1000000000 / rate; + + /* Read the device tree node and set the new timing parameters */ + err = devbus_set_timing_params(devbus, node); + if (err < 0) + return err; + + /* + * Allocate an address window for this device. + * If the device probing fails, then we won't be able to + * remove the allocated address decoding window. + * + * FIXME: This is only a temporary hack! We need to do this here + * because we still don't have device tree bindings for mbus. + * Once that support is added, we will declare these address windows + * statically in the device tree, and remove the window configuration + * from here. + */ + + /* + * Get the CS to choose the window string. + * This is a bit hacky, but it will be removed once the + * address windows are declared in the device tree. + */ + cs = (((unsigned long)devbus->base) % 0x400) / 8; + + /* + * Parse 'ranges' property to obtain a (base,size) window tuple. + * This will be removed once the address windows + * are declared in the device tree. + */ + parent = of_get_parent(node); + if (!parent) + return -EINVAL; + + p_addr_cells = of_n_addr_cells(parent); + of_node_put(parent); + + addr_cells = of_n_addr_cells(node); + size_cells = of_n_size_cells(node); + tuple_len = (p_addr_cells + addr_cells + size_cells) * sizeof(__be32); + + ranges = of_get_property(node, "ranges", &ranges_len); + if (ranges == NULL || ranges_len != tuple_len) + return -EINVAL; + + base = of_translate_address(node, ranges + addr_cells); + if (base == OF_BAD_ADDR) + return -EINVAL; + size = of_read_number(ranges + addr_cells + p_addr_cells, size_cells); + + /* + * Create an mbus address windows. + * FIXME: Remove this, together with the above code, once the + * address windows are declared in the device tree. + */ + err = mvebu_mbus_add_window(devbus_wins[cs], base, size); + if (err < 0) + return err; + + /* + * We need to create a child device explicitly from here to + * guarantee that the child will be probed after the timing + * parameters for the bus are written. + */ + err = of_platform_populate(node, NULL, NULL, dev); + if (err < 0) { + mvebu_mbus_del_window(base, size); + return err; + } + + return 0; +} + +static const struct of_device_id mvebu_devbus_of_match[] = { + { .compatible = "marvell,mvebu-devbus" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match); + +static struct platform_driver mvebu_devbus_driver = { + .probe = mvebu_devbus_probe, + .driver = { + .name = "mvebu-devbus", + .owner = THIS_MODULE, + .of_match_table = mvebu_devbus_of_match, + }, +}; + +static int __init mvebu_devbus_init(void) +{ + return platform_driver_register(&mvebu_devbus_driver); +} +module_init(mvebu_devbus_init); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>"); +MODULE_DESCRIPTION("Marvell EBU SoC Device Bus controller"); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index c002d8660e30..80889d5f95f5 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -480,6 +480,7 @@ config BMP085_SPI config PCH_PHUB tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB" + select GENERIC_NET_UTILS depends on PCI help This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 8f99e8e3f0ac..0daadcf1ed7a 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -470,7 +470,7 @@ static ssize_t sysfs_set_reg(struct device *dev, !test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask)) return -EPERM; - err = strict_strtoul(buf, 10, &value); + err = kstrtoul(buf, 10, &value); if (err) return err; diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index 5b5fd8416b3e..0c6e037153d2 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -126,8 +126,9 @@ static ssize_t als_sensing_range_store(struct device *dev, int ret_val; unsigned long val; - if (strict_strtoul(buf, 10, &val)) - return -EINVAL; + ret_val = kstrtoul(buf, 10, &val); + if (ret_val) + return ret_val; if (val < 4096) val = 1; diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index 98f9bb26492a..868a30a1b417 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -696,9 +696,11 @@ static ssize_t apds990x_lux_calib_store(struct device *dev, { struct apds990x_chip *chip = dev_get_drvdata(dev); unsigned long value; + int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; chip->lux_calib = value; @@ -759,8 +761,9 @@ static ssize_t apds990x_rate_store(struct device *dev, unsigned long value; int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; mutex_lock(&chip->mutex); ret = apds990x_set_arate(chip, value); @@ -813,9 +816,11 @@ static ssize_t apds990x_prox_enable_store(struct device *dev, { struct apds990x_chip *chip = dev_get_drvdata(dev); unsigned long value; + int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; mutex_lock(&chip->mutex); @@ -892,11 +897,12 @@ static ssize_t apds990x_lux_thresh_below_show(struct device *dev, static ssize_t apds990x_set_lux_thresh(struct apds990x_chip *chip, u32 *target, const char *buf) { - int ret = 0; unsigned long thresh; + int ret; - if (strict_strtoul(buf, 0, &thresh)) - return -EINVAL; + ret = kstrtoul(buf, 0, &thresh); + if (ret) + return ret; if (thresh > APDS_RANGE) return -EINVAL; @@ -957,9 +963,11 @@ static ssize_t apds990x_prox_threshold_store(struct device *dev, { struct apds990x_chip *chip = dev_get_drvdata(dev); unsigned long value; + int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; if ((value > APDS_RANGE) || (value == 0) || (value < APDS_PROX_HYSTERESIS)) @@ -990,9 +998,12 @@ static ssize_t apds990x_power_state_store(struct device *dev, { struct apds990x_chip *chip = dev_get_drvdata(dev); unsigned long value; + int ret; + + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; if (value) { pm_runtime_get_sync(dev); mutex_lock(&chip->mutex); diff --git a/drivers/misc/arm-charlcd.c b/drivers/misc/arm-charlcd.c index 48651ef0028c..1256a4bf1c04 100644 --- a/drivers/misc/arm-charlcd.c +++ b/drivers/misc/arm-charlcd.c @@ -291,7 +291,7 @@ static int __init charlcd_probe(struct platform_device *pdev) lcd->virtbase = ioremap(lcd->phybase, lcd->physize); if (!lcd->virtbase) { ret = -ENOMEM; - goto out_no_remap; + goto out_no_memregion; } lcd->irq = platform_get_irq(pdev, 0); @@ -320,8 +320,6 @@ static int __init charlcd_probe(struct platform_device *pdev) out_no_irq: iounmap(lcd->virtbase); -out_no_remap: - platform_set_drvdata(pdev, NULL); out_no_memregion: release_mem_region(lcd->phybase, SZ_4K); out_no_resource: @@ -337,7 +335,6 @@ static int __exit charlcd_remove(struct platform_device *pdev) free_irq(lcd->irq, lcd); iounmap(lcd->virtbase); release_mem_region(lcd->phybase, lcd->physize); - platform_set_drvdata(pdev, NULL); kfree(lcd); } diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c index f4975f7d0d5b..99a04686e45f 100644 --- a/drivers/misc/bh1770glc.c +++ b/drivers/misc/bh1770glc.c @@ -651,8 +651,9 @@ static ssize_t bh1770_power_state_store(struct device *dev, unsigned long value; ssize_t ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; mutex_lock(&chip->mutex); if (value) { @@ -726,9 +727,11 @@ static ssize_t bh1770_prox_enable_store(struct device *dev, { struct bh1770_chip *chip = dev_get_drvdata(dev); unsigned long value; + int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; mutex_lock(&chip->mutex); /* Assume no proximity. Sensor will tell real state soon */ @@ -824,9 +827,11 @@ static ssize_t bh1770_set_prox_rate_above(struct device *dev, { struct bh1770_chip *chip = dev_get_drvdata(dev); unsigned long value; + int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; mutex_lock(&chip->mutex); chip->prox_rate_threshold = bh1770_prox_rate_validate(value); @@ -840,9 +845,11 @@ static ssize_t bh1770_set_prox_rate_below(struct device *dev, { struct bh1770_chip *chip = dev_get_drvdata(dev); unsigned long value; + int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; mutex_lock(&chip->mutex); chip->prox_rate = bh1770_prox_rate_validate(value); @@ -865,8 +872,10 @@ static ssize_t bh1770_set_prox_thres(struct device *dev, unsigned long value; int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; + if (value > BH1770_PROX_RANGE) return -EINVAL; @@ -893,9 +902,11 @@ static ssize_t bh1770_prox_persistence_store(struct device *dev, { struct bh1770_chip *chip = dev_get_drvdata(dev); unsigned long value; + int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; if (value > BH1770_PROX_MAX_PERSISTENCE) return -EINVAL; @@ -918,9 +929,11 @@ static ssize_t bh1770_prox_abs_thres_store(struct device *dev, { struct bh1770_chip *chip = dev_get_drvdata(dev); unsigned long value; + int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; if (value > BH1770_PROX_RANGE) return -EINVAL; @@ -963,9 +976,11 @@ static ssize_t bh1770_lux_calib_store(struct device *dev, unsigned long value; u32 old_calib; u32 new_corr; + int ret; - if (strict_strtoul(buf, 0, &value)) - return -EINVAL; + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; mutex_lock(&chip->mutex); old_calib = chip->lux_calib; @@ -1012,8 +1027,9 @@ static ssize_t bh1770_set_lux_rate(struct device *dev, unsigned long rate_hz; int ret, i; - if (strict_strtoul(buf, 0, &rate_hz)) - return -EINVAL; + ret = kstrtoul(buf, 0, &rate_hz); + if (ret) + return ret; for (i = 0; i < ARRAY_SIZE(lux_rates_hz) - 1; i++) if (rate_hz >= lux_rates_hz[i]) @@ -1047,11 +1063,12 @@ static ssize_t bh1770_get_lux_thresh_below(struct device *dev, static ssize_t bh1770_set_lux_thresh(struct bh1770_chip *chip, u16 *target, const char *buf) { - int ret = 0; unsigned long thresh; + int ret; - if (strict_strtoul(buf, 0, &thresh)) - return -EINVAL; + ret = kstrtoul(buf, 0, &thresh); + if (ret) + return ret; if (thresh > BH1770_LUX_RANGE) return -EINVAL; diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c index 818f3a0e62bf..057580e026c0 100644 --- a/drivers/misc/bh1780gli.c +++ b/drivers/misc/bh1780gli.c @@ -107,7 +107,7 @@ static ssize_t bh1780_store_power_state(struct device *dev, unsigned long val; int error; - error = strict_strtoul(buf, 0, &val); + error = kstrtoul(buf, 0, &val); if (error) return error; diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c index 736c7714f565..c6bd7e84de24 100644 --- a/drivers/misc/carma/carma-fpga-program.c +++ b/drivers/misc/carma/carma-fpga-program.c @@ -830,8 +830,9 @@ static ssize_t penable_store(struct device *dev, struct device_attribute *attr, unsigned long val; int ret; - if (strict_strtoul(buf, 0, &val)) - return -EINVAL; + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; if (val) { ret = fpga_enable_power_supplies(priv); @@ -859,8 +860,9 @@ static ssize_t program_store(struct device *dev, struct device_attribute *attr, unsigned long val; int ret; - if (strict_strtoul(buf, 0, &val)) - return -EINVAL; + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; /* We can't have an image writer and be programming simultaneously */ if (mutex_lock_interruptible(&priv->lock)) @@ -919,7 +921,7 @@ static bool dma_filter(struct dma_chan *chan, void *data) static int fpga_of_remove(struct platform_device *op) { - struct fpga_dev *priv = dev_get_drvdata(&op->dev); + struct fpga_dev *priv = platform_get_drvdata(op); struct device *this_device = priv->miscdev.this_device; sysfs_remove_group(&this_device->kobj, &fpga_attr_group); @@ -969,7 +971,7 @@ static int fpga_of_probe(struct platform_device *op) kref_init(&priv->ref); - dev_set_drvdata(&op->dev, priv); + platform_set_drvdata(op, priv); priv->dev = &op->dev; mutex_init(&priv->lock); init_completion(&priv->completion); diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c index 7508cafff103..7b56563f8b74 100644 --- a/drivers/misc/carma/carma-fpga.c +++ b/drivers/misc/carma/carma-fpga.c @@ -1002,10 +1002,10 @@ static ssize_t data_en_set(struct device *dev, struct device_attribute *attr, unsigned long enable; int ret; - ret = strict_strtoul(buf, 0, &enable); + ret = kstrtoul(buf, 0, &enable); if (ret) { dev_err(priv->dev, "unable to parse enable input\n"); - return -EINVAL; + return ret; } /* protect against concurrent enable/disable */ @@ -1296,7 +1296,7 @@ static int data_of_probe(struct platform_device *op) goto out_return; } - dev_set_drvdata(&op->dev, priv); + platform_set_drvdata(op, priv); priv->dev = &op->dev; kref_init(&priv->ref); mutex_init(&priv->mutex); @@ -1400,7 +1400,7 @@ out_return: static int data_of_remove(struct platform_device *op) { - struct fpga_device *priv = dev_get_drvdata(&op->dev); + struct fpga_device *priv = platform_get_drvdata(op); struct device *this_device = priv->miscdev.this_device; /* remove all sysfs files, now the device cannot be re-enabled */ diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 2baeec56edfe..5d4fd69d04ca 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -492,10 +492,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) if (client->dev.platform_data) { chip = *(struct at24_platform_data *)client->dev.platform_data; } else { - if (!id->driver_data) { - err = -ENODEV; - goto err_out; - } + if (!id->driver_data) + return -ENODEV; + magic = id->driver_data; chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN)); magic >>= AT24_SIZE_BYTELEN; @@ -519,8 +518,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) "byte_len looks suspicious (no power of 2)!\n"); if (!chip.page_size) { dev_err(&client->dev, "page_size must not be 0!\n"); - err = -EINVAL; - goto err_out; + return -EINVAL; } if (!is_power_of_2(chip.page_size)) dev_warn(&client->dev, @@ -528,10 +526,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Use I2C operations unless we're stuck with SMBus extensions. */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - if (chip.flags & AT24_FLAG_ADDR16) { - err = -EPFNOSUPPORT; - goto err_out; - } + if (chip.flags & AT24_FLAG_ADDR16) + return -EPFNOSUPPORT; + if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; @@ -542,8 +539,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) I2C_FUNC_SMBUS_READ_BYTE_DATA)) { use_smbus = I2C_SMBUS_BYTE_DATA; } else { - err = -EPFNOSUPPORT; - goto err_out; + return -EPFNOSUPPORT; } } @@ -553,12 +549,10 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) num_addresses = DIV_ROUND_UP(chip.byte_len, (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256); - at24 = kzalloc(sizeof(struct at24_data) + + at24 = devm_kzalloc(&client->dev, sizeof(struct at24_data) + num_addresses * sizeof(struct i2c_client *), GFP_KERNEL); - if (!at24) { - err = -ENOMEM; - goto err_out; - } + if (!at24) + return -ENOMEM; mutex_init(&at24->lock); at24->use_smbus = use_smbus; @@ -596,11 +590,10 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) at24->write_max = write_max; /* buffer (data + address at the beginning) */ - at24->writebuf = kmalloc(write_max + 2, GFP_KERNEL); - if (!at24->writebuf) { - err = -ENOMEM; - goto err_struct; - } + at24->writebuf = devm_kzalloc(&client->dev, + write_max + 2, GFP_KERNEL); + if (!at24->writebuf) + return -ENOMEM; } else { dev_warn(&client->dev, "cannot write due to controller restrictions."); @@ -648,11 +641,6 @@ err_clients: if (at24->client[i]) i2c_unregister_device(at24->client[i]); - kfree(at24->writebuf); -err_struct: - kfree(at24); -err_out: - dev_dbg(&client->dev, "probe error %d\n", err); return err; } @@ -667,8 +655,6 @@ static int at24_remove(struct i2c_client *client) for (i = 1; i < at24->num_addresses; i++) i2c_unregister_device(at24->client[i]); - kfree(at24->writebuf); - kfree(at24); return 0; } diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index ad8fd8e64937..840b3594a5ae 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -371,11 +371,10 @@ static int at25_probe(struct spi_device *spi) if (np) { err = at25_np_to_chip(&spi->dev, np, &chip); if (err) - goto fail; + return err; } else { dev_err(&spi->dev, "Error: no chip description\n"); - err = -ENODEV; - goto fail; + return -ENODEV; } } else chip = *(struct spi_eeprom *)spi->dev.platform_data; @@ -389,8 +388,7 @@ static int at25_probe(struct spi_device *spi) addrlen = 3; else { dev_dbg(&spi->dev, "unsupported address type\n"); - err = -EINVAL; - goto fail; + return -EINVAL; } /* Ping the chip ... the status register is pretty portable, @@ -400,14 +398,12 @@ static int at25_probe(struct spi_device *spi) sr = spi_w8r8(spi, AT25_RDSR); if (sr < 0 || sr & AT25_SR_nRDY) { dev_dbg(&spi->dev, "rdsr --> %d (%02x)\n", sr, sr); - err = -ENXIO; - goto fail; + return -ENXIO; } - if (!(at25 = kzalloc(sizeof *at25, GFP_KERNEL))) { - err = -ENOMEM; - goto fail; - } + at25 = devm_kzalloc(&spi->dev, sizeof(struct at25_data), GFP_KERNEL); + if (!at25) + return -ENOMEM; mutex_init(&at25->lock); at25->chip = chip; @@ -439,7 +435,7 @@ static int at25_probe(struct spi_device *spi) err = sysfs_create_bin_file(&spi->dev.kobj, &at25->bin); if (err) - goto fail; + return err; if (chip.setup) chip.setup(&at25->mem, chip.context); @@ -453,10 +449,6 @@ static int at25_probe(struct spi_device *spi) (chip.flags & EE_READONLY) ? " (readonly)" : "", at25->chip.page_size); return 0; -fail: - dev_dbg(&spi->dev, "probe err %d\n", err); - kfree(at25); - return err; } static int at25_remove(struct spi_device *spi) @@ -465,7 +457,6 @@ static int at25_remove(struct spi_device *spi) at25 = spi_get_drvdata(spi); sysfs_remove_bin_file(&spi->dev.kobj, &at25->bin); - kfree(at25); return 0; } diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c index 96787ec15cad..cdb67a9c1959 100644 --- a/drivers/misc/ep93xx_pwm.c +++ b/drivers/misc/ep93xx_pwm.c @@ -39,63 +39,6 @@ struct ep93xx_pwm { u32 duty_percent; }; -static inline void ep93xx_pwm_writel(struct ep93xx_pwm *pwm, - unsigned int val, unsigned int off) -{ - __raw_writel(val, pwm->mmio_base + off); -} - -static inline unsigned int ep93xx_pwm_readl(struct ep93xx_pwm *pwm, - unsigned int off) -{ - return __raw_readl(pwm->mmio_base + off); -} - -static inline void ep93xx_pwm_write_tc(struct ep93xx_pwm *pwm, u16 value) -{ - ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_TERM_COUNT); -} - -static inline u16 ep93xx_pwm_read_tc(struct ep93xx_pwm *pwm) -{ - return ep93xx_pwm_readl(pwm, EP93XX_PWMx_TERM_COUNT); -} - -static inline void ep93xx_pwm_write_dc(struct ep93xx_pwm *pwm, u16 value) -{ - ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_DUTY_CYCLE); -} - -static inline void ep93xx_pwm_enable(struct ep93xx_pwm *pwm) -{ - ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_ENABLE); -} - -static inline void ep93xx_pwm_disable(struct ep93xx_pwm *pwm) -{ - ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_ENABLE); -} - -static inline int ep93xx_pwm_is_enabled(struct ep93xx_pwm *pwm) -{ - return ep93xx_pwm_readl(pwm, EP93XX_PWMx_ENABLE) & 0x1; -} - -static inline void ep93xx_pwm_invert(struct ep93xx_pwm *pwm) -{ - ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_INVERT); -} - -static inline void ep93xx_pwm_normal(struct ep93xx_pwm *pwm) -{ - ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_INVERT); -} - -static inline int ep93xx_pwm_is_inverted(struct ep93xx_pwm *pwm) -{ - return ep93xx_pwm_readl(pwm, EP93XX_PWMx_INVERT) & 0x1; -} - /* * /sys/devices/platform/ep93xx-pwm.N * /min_freq read-only minimum pwm output frequency @@ -131,9 +74,9 @@ static ssize_t ep93xx_pwm_get_freq(struct device *dev, struct platform_device *pdev = to_platform_device(dev); struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); - if (ep93xx_pwm_is_enabled(pwm)) { + if (readl(pwm->mmio_base + EP93XX_PWMx_ENABLE) & 0x1) { unsigned long rate = clk_get_rate(pwm->clk); - u16 term = ep93xx_pwm_read_tc(pwm); + u16 term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); return sprintf(buf, "%ld\n", rate / (term + 1)); } else { @@ -149,12 +92,12 @@ static ssize_t ep93xx_pwm_set_freq(struct device *dev, long val; int err; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return -EINVAL; if (val == 0) { - ep93xx_pwm_disable(pwm); + writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE); } else if (val <= (clk_get_rate(pwm->clk) / 2)) { u32 term, duty; @@ -164,20 +107,20 @@ static ssize_t ep93xx_pwm_set_freq(struct device *dev, if (val < 1) val = 1; - term = ep93xx_pwm_read_tc(pwm); + term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); duty = ((val + 1) * pwm->duty_percent / 100) - 1; /* If pwm is running, order is important */ if (val > term) { - ep93xx_pwm_write_tc(pwm, val); - ep93xx_pwm_write_dc(pwm, duty); + writel(val, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); + writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE); } else { - ep93xx_pwm_write_dc(pwm, duty); - ep93xx_pwm_write_tc(pwm, val); + writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE); + writel(val, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); } - if (!ep93xx_pwm_is_enabled(pwm)) - ep93xx_pwm_enable(pwm); + if (!readl(pwm->mmio_base + EP93XX_PWMx_ENABLE) & 0x1) + writel(0x1, pwm->mmio_base + EP93XX_PWMx_ENABLE); } else { return -EINVAL; } @@ -202,13 +145,15 @@ static ssize_t ep93xx_pwm_set_duty_percent(struct device *dev, long val; int err; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return -EINVAL; if (val > 0 && val < 100) { - u32 term = ep93xx_pwm_read_tc(pwm); - ep93xx_pwm_write_dc(pwm, ((term + 1) * val / 100) - 1); + u32 term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); + u32 duty = ((term + 1) * val / 100) - 1; + + writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE); pwm->duty_percent = val; return count; } @@ -221,8 +166,9 @@ static ssize_t ep93xx_pwm_get_invert(struct device *dev, { struct platform_device *pdev = to_platform_device(dev); struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); + int inverted = readl(pwm->mmio_base + EP93XX_PWMx_INVERT) & 0x1; - return sprintf(buf, "%d\n", ep93xx_pwm_is_inverted(pwm)); + return sprintf(buf, "%d\n", inverted); } static ssize_t ep93xx_pwm_set_invert(struct device *dev, @@ -233,14 +179,14 @@ static ssize_t ep93xx_pwm_set_invert(struct device *dev, long val; int err; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return -EINVAL; if (val == 0) - ep93xx_pwm_normal(pwm); + writel(0x0, pwm->mmio_base + EP93XX_PWMx_INVERT); else if (val == 1) - ep93xx_pwm_invert(pwm); + writel(0x1, pwm->mmio_base + EP93XX_PWMx_INVERT); else return -EINVAL; @@ -269,89 +215,55 @@ static const struct attribute_group ep93xx_pwm_sysfs_files = { .attrs = ep93xx_pwm_attrs, }; -static int __init ep93xx_pwm_probe(struct platform_device *pdev) +static int ep93xx_pwm_probe(struct platform_device *pdev) { struct ep93xx_pwm *pwm; struct resource *res; - int err; + int ret; - err = ep93xx_pwm_acquire_gpio(pdev); - if (err) - return err; + pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); + if (!pwm) + return -ENOMEM; - pwm = kzalloc(sizeof(struct ep93xx_pwm), GFP_KERNEL); - if (!pwm) { - err = -ENOMEM; - goto fail_no_mem; - } + pwm->clk = devm_clk_get(&pdev->dev, "pwm_clk"); + if (IS_ERR(pwm->clk)) + return PTR_ERR(pwm->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - err = -ENXIO; - goto fail_no_mem_resource; - } - - res = request_mem_region(res->start, resource_size(res), pdev->name); - if (res == NULL) { - err = -EBUSY; - goto fail_no_mem_resource; - } - - pwm->mmio_base = ioremap(res->start, resource_size(res)); - if (pwm->mmio_base == NULL) { - err = -ENXIO; - goto fail_no_ioremap; - } - - err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); - if (err) - goto fail_no_sysfs; - - pwm->clk = clk_get(&pdev->dev, "pwm_clk"); - if (IS_ERR(pwm->clk)) { - err = PTR_ERR(pwm->clk); - goto fail_no_clk; + pwm->mmio_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pwm->mmio_base)) + return PTR_ERR(pwm->mmio_base); + + ret = ep93xx_pwm_acquire_gpio(pdev); + if (ret) + return ret; + + ret = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); + if (ret) { + ep93xx_pwm_release_gpio(pdev); + return ret; } pwm->duty_percent = 50; - platform_set_drvdata(pdev, pwm); - /* disable pwm at startup. Avoids zero value. */ - ep93xx_pwm_disable(pwm); - ep93xx_pwm_write_tc(pwm, EP93XX_PWM_MAX_COUNT); - ep93xx_pwm_write_dc(pwm, EP93XX_PWM_MAX_COUNT / 2); + writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE); + writel(EP93XX_PWM_MAX_COUNT, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); + writel(EP93XX_PWM_MAX_COUNT/2, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE); clk_enable(pwm->clk); + platform_set_drvdata(pdev, pwm); return 0; - -fail_no_clk: - sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); -fail_no_sysfs: - iounmap(pwm->mmio_base); -fail_no_ioremap: - release_mem_region(res->start, resource_size(res)); -fail_no_mem_resource: - kfree(pwm); -fail_no_mem: - ep93xx_pwm_release_gpio(pdev); - return err; } -static int __exit ep93xx_pwm_remove(struct platform_device *pdev) +static int ep93xx_pwm_remove(struct platform_device *pdev) { struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ep93xx_pwm_disable(pwm); + writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE); clk_disable(pwm->clk); - clk_put(pwm->clk); - platform_set_drvdata(pdev, NULL); sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); - iounmap(pwm->mmio_base); - release_mem_region(res->start, resource_size(res)); - kfree(pwm); ep93xx_pwm_release_gpio(pdev); return 0; @@ -362,10 +274,10 @@ static struct platform_driver ep93xx_pwm_driver = { .name = "ep93xx-pwm", .owner = THIS_MODULE, }, - .remove = __exit_p(ep93xx_pwm_remove), + .probe = ep93xx_pwm_probe, + .remove = ep93xx_pwm_remove, }; - -module_platform_driver_probe(ep93xx_pwm_driver, ep93xx_pwm_probe); +module_platform_driver(ep93xx_pwm_driver); MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, " "H Hartley Sweeten <hsweeten@visionengravers.com>"); diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c index 423cd40f1c0f..170bd3daf336 100644 --- a/drivers/misc/hmc6352.c +++ b/drivers/misc/hmc6352.c @@ -46,8 +46,9 @@ static int compass_store(struct device *dev, const char *buf, size_t count, int ret; unsigned long val; - if (strict_strtoul(buf, 10, &val)) - return -EINVAL; + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; if (val >= strlen(map)) return -EINVAL; mutex_lock(&compass_mutex); diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index c5145b3fcce8..e3183f26216b 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -208,7 +208,11 @@ static ssize_t isl29003_store_range(struct device *dev, unsigned long val; int ret; - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3)) + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + if (val > 3) return -EINVAL; ret = isl29003_set_range(client, val); @@ -239,7 +243,11 @@ static ssize_t isl29003_store_resolution(struct device *dev, unsigned long val; int ret; - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3)) + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + if (val > 3) return -EINVAL; ret = isl29003_set_resolution(client, val); @@ -267,7 +275,11 @@ static ssize_t isl29003_store_mode(struct device *dev, unsigned long val; int ret; - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 2)) + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + if (val > 2) return -EINVAL; ret = isl29003_set_mode(client, val); @@ -298,7 +310,11 @@ static ssize_t isl29003_store_power_state(struct device *dev, unsigned long val; int ret; - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1)) + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + if (val > 1) return -EINVAL; ret = isl29003_set_power_state(client, val); diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index 0aa08c746463..b7f84dacf822 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c @@ -90,8 +90,10 @@ static ssize_t als_sensing_range_store(struct device *dev, int ret_val; unsigned long val; - if (strict_strtoul(buf, 10, &val)) - return -EINVAL; + ret_val = kstrtoul(buf, 10, &val); + if (ret_val) + return ret_val; + if (val < 1 || val > 64000) return -EINVAL; diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index 4cd4a3d2a76a..036effe9a795 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -831,9 +831,11 @@ static ssize_t lis3lv02d_rate_set(struct device *dev, { struct lis3lv02d *lis3 = dev_get_drvdata(dev); unsigned long rate; + int ret; - if (strict_strtoul(buf, 0, &rate)) - return -EINVAL; + ret = kstrtoul(buf, 0, &rate); + if (ret) + return ret; lis3lv02d_sysfs_poweron(lis3); if (lis3lv02d_set_odr(lis3, rate)) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index b3e50984d2c8..749452f8e2f6 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -443,11 +443,11 @@ unsigned int mei_amthif_poll(struct mei_device *dev, * * returns 0, OK; otherwise, error. */ -int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) +int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb, + s32 *slots, struct mei_cl_cb *cmpl_list) { + struct mei_device *dev = cl->dev; struct mei_msg_hdr mei_hdr; - struct mei_cl *cl = cb->cl; size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index; u32 msg_slots = mei_data2slots(len); diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index e310ca6ed1a3..c2534ca5c6f1 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -785,6 +785,32 @@ err: } +/** + * mei_cl_complete - processes completed operation for a client + * + * @cl: private data of the file object. + * @cb: callback block. + */ +void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) +{ + if (cb->fop_type == MEI_FOP_WRITE) { + mei_io_cb_free(cb); + cb = NULL; + cl->writing_state = MEI_WRITE_COMPLETE; + if (waitqueue_active(&cl->tx_wait)) + wake_up_interruptible(&cl->tx_wait); + + } else if (cb->fop_type == MEI_FOP_READ && + MEI_READING == cl->reading_state) { + cl->reading_state = MEI_READ_COMPLETE; + if (waitqueue_active(&cl->rx_wait)) + wake_up_interruptible(&cl->rx_wait); + else + mei_cl_bus_rx_event(cl); + + } +} + /** * mei_cl_all_disconnect - disconnect forcefully all connected clients diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index cfdb144526aa..7dc2af7b6fba 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -89,6 +89,7 @@ int mei_cl_disconnect(struct mei_cl *cl); int mei_cl_connect(struct mei_cl *cl, struct file *file); int mei_cl_read_start(struct mei_cl *cl, size_t length); int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking); +void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb); void mei_host_client_init(struct work_struct *work); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 2ad736989410..7d9509a094e9 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -31,32 +31,6 @@ /** - * mei_cl_complete_handler - processes completed operation for a client - * - * @cl: private data of the file object. - * @cb: callback block. - */ -static void mei_cl_complete_handler(struct mei_cl *cl, struct mei_cl_cb *cb) -{ - if (cb->fop_type == MEI_FOP_WRITE) { - mei_io_cb_free(cb); - cb = NULL; - cl->writing_state = MEI_WRITE_COMPLETE; - if (waitqueue_active(&cl->tx_wait)) - wake_up_interruptible(&cl->tx_wait); - - } else if (cb->fop_type == MEI_FOP_READ && - MEI_READING == cl->reading_state) { - cl->reading_state = MEI_READ_COMPLETE; - if (waitqueue_active(&cl->rx_wait)) - wake_up_interruptible(&cl->rx_wait); - else - mei_cl_bus_rx_event(cl); - - } -} - -/** * mei_irq_compl_handler - dispatch complete handelers * for the completed callbacks * @@ -78,7 +52,7 @@ void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list) if (cl == &dev->iamthif_cl) mei_amthif_complete(dev, cb); else - mei_cl_complete_handler(cl, cb); + mei_cl_complete(cl, cb); } } EXPORT_SYMBOL_GPL(mei_irq_compl_handler); @@ -189,21 +163,21 @@ static int mei_cl_irq_read_msg(struct mei_device *dev, } /** - * _mei_irq_thread_close - processes close related operation. + * mei_cl_irq_close - processes close related operation from + * interrupt thread context - send disconnect request * - * @dev: the device structure. + * @cl: client + * @cb: callback block. * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. * @cmpl_list: complete list. * * returns 0, OK; otherwise, error. */ -static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_cl_cb *cmpl_list) +static int mei_cl_irq_close(struct mei_cl *cl, struct mei_cl_cb *cb, + s32 *slots, struct mei_cl_cb *cmpl_list) { + struct mei_device *dev = cl->dev; + u32 msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request)); @@ -214,15 +188,15 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, if (mei_hbm_cl_disconnect_req(dev, cl)) { cl->status = 0; - cb_pos->buf_idx = 0; - list_move_tail(&cb_pos->list, &cmpl_list->list); + cb->buf_idx = 0; + list_move_tail(&cb->list, &cmpl_list->list); return -EIO; } cl->state = MEI_FILE_DISCONNECTING; cl->status = 0; - cb_pos->buf_idx = 0; - list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list); + cb->buf_idx = 0; + list_move_tail(&cb->list, &dev->ctrl_rd_list.list); cl->timer_count = MEI_CONNECT_TIMEOUT; return 0; @@ -230,26 +204,26 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, /** - * _mei_irq_thread_read - processes read related operation. + * mei_cl_irq_close - processes client read related operation from the + * interrupt thread context - request for flow control credits * - * @dev: the device structure. + * @cl: client + * @cb: callback block. * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. * @cmpl_list: complete list. * * returns 0, OK; otherwise, error. */ -static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_cl_cb *cmpl_list) +static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, + s32 *slots, struct mei_cl_cb *cmpl_list) { + struct mei_device *dev = cl->dev; + u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); if (*slots < msg_slots) { /* return the cancel routine */ - list_del(&cb_pos->list); + list_del(&cb->list); return -EMSGSIZE; } @@ -257,38 +231,38 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, if (mei_hbm_cl_flow_control_req(dev, cl)) { cl->status = -ENODEV; - cb_pos->buf_idx = 0; - list_move_tail(&cb_pos->list, &cmpl_list->list); + cb->buf_idx = 0; + list_move_tail(&cb->list, &cmpl_list->list); return -ENODEV; } - list_move_tail(&cb_pos->list, &dev->read_list.list); + list_move_tail(&cb->list, &dev->read_list.list); return 0; } /** - * _mei_irq_thread_ioctl - processes ioctl related operation. + * mei_cl_irq_ioctl - processes client ioctl related operation from the + * interrupt thread context - send connection request * - * @dev: the device structure. + * @cl: client + * @cb: callback block. * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. * @cmpl_list: complete list. * * returns 0, OK; otherwise, error. */ -static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_cl_cb *cmpl_list) +static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb, + s32 *slots, struct mei_cl_cb *cmpl_list) { + struct mei_device *dev = cl->dev; + u32 msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request)); if (*slots < msg_slots) { /* return the cancel routine */ - list_del(&cb_pos->list); + list_del(&cb->list); return -EMSGSIZE; } @@ -298,31 +272,31 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, if (mei_hbm_cl_connect_req(dev, cl)) { cl->status = -ENODEV; - cb_pos->buf_idx = 0; - list_del(&cb_pos->list); + cb->buf_idx = 0; + list_del(&cb->list); return -ENODEV; - } else { - list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list); - cl->timer_count = MEI_CONNECT_TIMEOUT; } + + list_move_tail(&cb->list, &dev->ctrl_rd_list.list); + cl->timer_count = MEI_CONNECT_TIMEOUT; return 0; } /** - * mei_irq_thread_write_complete - write messages to device. + * mei_cl_irq_write_complete - write messages to device. * - * @dev: the device structure. - * @slots: free slots. + * @cl: client * @cb: callback block. + * @slots: free slots. * @cmpl_list: complete list. * * returns 0, OK; otherwise, error. */ -static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) +static int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb, + s32 *slots, struct mei_cl_cb *cmpl_list) { + struct mei_device *dev = cl->dev; struct mei_msg_hdr mei_hdr; - struct mei_cl *cl = cb->cl; size_t len = cb->request_buffer.size - cb->buf_idx; u32 msg_slots = mei_data2slots(len); @@ -481,7 +455,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) { struct mei_cl *cl; - struct mei_cl_cb *pos = NULL, *next = NULL; + struct mei_cl_cb *cb, *next; struct mei_cl_cb *list; s32 slots; int ret; @@ -498,19 +472,19 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); list = &dev->write_waiting_list; - list_for_each_entry_safe(pos, next, &list->list, list) { - cl = pos->cl; + list_for_each_entry_safe(cb, next, &list->list, list) { + cl = cb->cl; if (cl == NULL) continue; cl->status = 0; - list_del(&pos->list); + list_del(&cb->list); if (MEI_WRITING == cl->writing_state && - pos->fop_type == MEI_FOP_WRITE && + cb->fop_type == MEI_FOP_WRITE && cl != &dev->iamthif_cl) { dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n"); cl->writing_state = MEI_WRITE_COMPLETE; - list_add_tail(&pos->list, &cmpl_list->list); + list_add_tail(&cb->list, &cmpl_list->list); } if (cl == &dev->iamthif_cl) { dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); @@ -552,25 +526,23 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) /* complete control write list CB */ dev_dbg(&dev->pdev->dev, "complete control write list cb.\n"); - list_for_each_entry_safe(pos, next, &dev->ctrl_wr_list.list, list) { - cl = pos->cl; + list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list.list, list) { + cl = cb->cl; if (!cl) { - list_del(&pos->list); + list_del(&cb->list); return -ENODEV; } - switch (pos->fop_type) { + switch (cb->fop_type) { case MEI_FOP_CLOSE: /* send disconnect message */ - ret = _mei_irq_thread_close(dev, &slots, pos, - cl, cmpl_list); + ret = mei_cl_irq_close(cl, cb, &slots, cmpl_list); if (ret) return ret; break; case MEI_FOP_READ: /* send flow control message */ - ret = _mei_irq_thread_read(dev, &slots, pos, - cl, cmpl_list); + ret = mei_cl_irq_read(cl, cb, &slots, cmpl_list); if (ret) return ret; @@ -579,8 +551,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) /* connect message */ if (mei_cl_is_other_connecting(cl)) continue; - ret = _mei_irq_thread_ioctl(dev, &slots, pos, - cl, cmpl_list); + ret = mei_cl_irq_ioctl(cl, cb, &slots, cmpl_list); if (ret) return ret; @@ -593,8 +564,8 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) } /* complete write list CB */ dev_dbg(&dev->pdev->dev, "complete write list cb.\n"); - list_for_each_entry_safe(pos, next, &dev->write_list.list, list) { - cl = pos->cl; + list_for_each_entry_safe(cb, next, &dev->write_list.list, list) { + cl = cb->cl; if (cl == NULL) continue; if (mei_cl_flow_ctrl_creds(cl) <= 0) { @@ -605,14 +576,13 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) } if (cl == &dev->iamthif_cl) - ret = mei_amthif_irq_write_complete(dev, &slots, - pos, cmpl_list); + ret = mei_amthif_irq_write_complete(cl, cb, + &slots, cmpl_list); else - ret = mei_irq_thread_write_complete(dev, &slots, pos, - cmpl_list); + ret = mei_cl_irq_write_complete(cl, cb, + &slots, cmpl_list); if (ret) return ret; - } return 0; } diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 053139f61086..5e11b5b9b65d 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -194,7 +194,6 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, struct mei_cl_cb *cb_pos = NULL; struct mei_cl_cb *cb = NULL; struct mei_device *dev; - int i; int rets; int err; @@ -210,38 +209,26 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, goto out; } - if ((cl->sm_state & MEI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) { - /* Do not allow to read watchdog client */ - i = mei_me_cl_by_uuid(dev, &mei_wd_guid); - if (i >= 0) { - struct mei_me_client *me_client = &dev->me_clients[i]; - if (cl->me_client_id == me_client->client_id) { - rets = -EBADF; - goto out; - } - } - } else { - cl->sm_state &= ~MEI_WD_STATE_INDEPENDENCE_MSG_SENT; - } - if (cl == &dev->iamthif_cl) { rets = mei_amthif_read(dev, file, ubuf, length, offset); goto out; } - if (cl->read_cb && cl->read_cb->buf_idx > *offset) { - cb = cl->read_cb; - goto copy_buffer; - } else if (cl->read_cb && cl->read_cb->buf_idx > 0 && - cl->read_cb->buf_idx <= *offset) { + if (cl->read_cb) { cb = cl->read_cb; - rets = 0; - goto free; - } else if ((!cl->read_cb || !cl->read_cb->buf_idx) && *offset > 0) { - /*Offset needs to be cleaned for contiguous reads*/ + /* read what left */ + if (cb->buf_idx > *offset) + goto copy_buffer; + /* offset is beyond buf_idx we have no more data return 0 */ + if (cb->buf_idx > 0 && cb->buf_idx <= *offset) { + rets = 0; + goto free; + } + /* Offset needs to be cleaned for contiguous reads*/ + if (cb->buf_idx == 0 && *offset > 0) + *offset = 0; + } else if (*offset > 0) { *offset = 0; - rets = 0; - goto out; } err = mei_cl_read_start(cl, length); @@ -420,16 +407,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (rets) goto out; - cl->sm_state = 0; - if (length == 4 && - ((memcmp(mei_wd_state_independence_msg[0], - write_cb->request_buffer.data, 4) == 0) || - (memcmp(mei_wd_state_independence_msg[1], - write_cb->request_buffer.data, 4) == 0) || - (memcmp(mei_wd_state_independence_msg[2], - write_cb->request_buffer.data, 4) == 0))) - cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; - if (cl == &dev->iamthif_cl) { rets = mei_amthif_write(dev, write_cb); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 4de5140e7379..80a90319fc29 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -56,11 +56,6 @@ extern const uuid_le mei_amthif_guid; extern const uuid_le mei_wd_guid; /* - * Watchdog independence state message - */ -extern const u8 mei_wd_state_independence_msg[3][4]; - -/* * Number of Maximum MEI Clients */ #define MEI_CLIENTS_MAX 256 @@ -201,7 +196,6 @@ struct mei_cl { u8 timer_count; enum mei_file_transaction_states reading_state; enum mei_file_transaction_states writing_state; - int sm_state; struct mei_cl_cb *read_cb; /* MEI CL bus data */ @@ -502,8 +496,8 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, void mei_amthif_run_next_cmd(struct mei_device *dev); -int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list); +int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb, + s32 *slots, struct mei_cl_cb *cmpl_list); void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb); int mei_amthif_irq_read_msg(struct mei_device *dev, @@ -522,15 +516,6 @@ void mei_nfc_host_exit(void); */ extern const uuid_le mei_nfc_guid; -int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list); - -void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb); -int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, - struct mei_device *dev, struct mei_msg_hdr *mei_hdr); -int mei_amthif_irq_read(struct mei_device *dev, s32 *slots); - - int mei_wd_send(struct mei_device *dev); int mei_wd_stop(struct mei_device *dev); int mei_wd_host_init(struct mei_device *dev); diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 0f268329bd3a..1b3844e82379 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -43,9 +43,6 @@ #include "hw-me.h" #include "client.h" -/* AMT device is a singleton on the platform */ -static struct pci_dev *mei_pdev; - /* mei_pci_tbl - PCI Device ID Table */ static DEFINE_PCI_DEVICE_TABLE(mei_me_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)}, @@ -88,8 +85,6 @@ static DEFINE_PCI_DEVICE_TABLE(mei_me_pci_tbl) = { MODULE_DEVICE_TABLE(pci, mei_me_pci_tbl); -static DEFINE_MUTEX(mei_mutex); - /** * mei_quirk_probe - probe for devices that doesn't valid ME interface * @@ -126,17 +121,12 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct mei_me_hw *hw; int err; - mutex_lock(&mei_mutex); if (!mei_me_quirk_probe(pdev, ent)) { err = -ENODEV; goto end; } - if (mei_pdev) { - err = -EEXIST; - goto end; - } /* enable pci dev */ err = pci_enable_device(pdev); if (err) { @@ -195,13 +185,10 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto release_irq; - mei_pdev = pdev; pci_set_drvdata(pdev, dev); schedule_delayed_work(&dev->timer_work, HZ); - mutex_unlock(&mei_mutex); - pr_debug("initialization successful.\n"); return 0; @@ -220,7 +207,6 @@ release_regions: disable_device: pci_disable_device(pdev); end: - mutex_unlock(&mei_mutex); dev_err(&pdev->dev, "initialization failed.\n"); return err; } @@ -238,9 +224,6 @@ static void mei_me_remove(struct pci_dev *pdev) struct mei_device *dev; struct mei_me_hw *hw; - if (mei_pdev != pdev) - return; - dev = pci_get_drvdata(pdev); if (!dev) return; @@ -251,8 +234,6 @@ static void mei_me_remove(struct pci_dev *pdev) dev_err(&pdev->dev, "stop\n"); mei_stop(dev); - mei_pdev = NULL; - /* disable interrupts */ mei_disable_interrupts(dev); diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 6251a4ee7067..b8921432e89d 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -31,12 +31,6 @@ static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; -const u8 mei_wd_state_independence_msg[3][4] = { - {0x05, 0x02, 0x51, 0x10}, - {0x05, 0x02, 0x52, 0x10}, - {0x07, 0x02, 0x01, 0x10} -}; - /* * AMT Watchdog Device */ diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 931e635aa491..a5925f7f17f6 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -633,17 +633,13 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr, static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - u8 mac[6]; + u8 mac[ETH_ALEN]; ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(dev); - if (count != 18) + if (!mac_pton(buf, mac)) return -EINVAL; - sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", - (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3], - (u32 *)&mac[4], (u32 *)&mac[5]); - chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); if (!chip->pch_phub_extrom_base_address) return -ENOMEM; @@ -669,8 +665,6 @@ static struct bin_attribute pch_bin_attr = { static int pch_phub_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - int retval; - int ret; struct pch_phub_reg *chip; @@ -713,13 +707,13 @@ static int pch_phub_probe(struct pci_dev *pdev, if (id->driver_data == 1) { /* EG20T PCH */ const char *board_name; - retval = sysfs_create_file(&pdev->dev.kobj, - &dev_attr_pch_mac.attr); - if (retval) + ret = sysfs_create_file(&pdev->dev.kobj, + &dev_attr_pch_mac.attr); + if (ret) goto err_sysfs_create; - retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); - if (retval) + ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); + if (ret) goto exit_bin_attr; pch_phub_read_modify_write_reg(chip, @@ -743,8 +737,8 @@ static int pch_phub_probe(struct pci_dev *pdev, chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T; chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T; } else if (id->driver_data == 2) { /* ML7213 IOH */ - retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); - if (retval) + ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); + if (ret) goto err_sysfs_create; /* set the prefech value * Device2(USB OHCI #1/ USB EHCI #1/ USB Device):a @@ -766,12 +760,12 @@ static int pch_phub_probe(struct pci_dev *pdev, PCH_PHUB_ROM_START_ADDR_ML7223; chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; } else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/ - retval = sysfs_create_file(&pdev->dev.kobj, - &dev_attr_pch_mac.attr); - if (retval) + ret = sysfs_create_file(&pdev->dev.kobj, + &dev_attr_pch_mac.attr); + if (ret) goto err_sysfs_create; - retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); - if (retval) + ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); + if (ret) goto exit_bin_attr; /* set the prefech value * Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a @@ -783,13 +777,13 @@ static int pch_phub_probe(struct pci_dev *pdev, PCH_PHUB_ROM_START_ADDR_ML7223; chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; } else if (id->driver_data == 5) { /* ML7831 */ - retval = sysfs_create_file(&pdev->dev.kobj, - &dev_attr_pch_mac.attr); - if (retval) + ret = sysfs_create_file(&pdev->dev.kobj, + &dev_attr_pch_mac.attr); + if (ret) goto err_sysfs_create; - retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); - if (retval) + ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); + if (ret) goto exit_bin_attr; /* set the prefech value */ diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c index 797d7962cc88..4f7635922394 100644 --- a/drivers/misc/sgi-gru/gruprocfs.c +++ b/drivers/misc/sgi-gru/gruprocfs.c @@ -160,15 +160,11 @@ static int options_show(struct seq_file *s, void *p) static ssize_t options_write(struct file *file, const char __user *userbuf, size_t count, loff_t *data) { - char buf[20]; - - if (count >= sizeof(buf)) - return -EINVAL; - if (copy_from_user(buf, userbuf, count)) - return -EFAULT; - buf[count] = '\0'; - if (strict_strtoul(buf, 0, &gru_options)) - return -EINVAL; + int ret; + + ret = kstrtoul_from_user(userbuf, count, 0, &gru_options); + if (ret) + return ret; return count; } diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c index 7deb25dc86a7..2e13614d41e8 100644 --- a/drivers/misc/spear13xx_pcie_gadget.c +++ b/drivers/misc/spear13xx_pcie_gadget.c @@ -316,8 +316,12 @@ static ssize_t pcie_gadget_store_no_of_msi( struct spear_pcie_gadget_config *config, const char *buf, size_t count) { - if (strict_strtoul(buf, 0, &config->requested_msi)) - return -EINVAL; + int ret; + + ret = kstrtoul(buf, 0, &config->requested_msi); + if (ret) + return ret; + if (config->requested_msi > 32) config->requested_msi = 32; @@ -330,9 +334,11 @@ static ssize_t pcie_gadget_store_inta( { struct pcie_app_reg __iomem *app_reg = config->va_app_base; ulong en; + int ret; - if (strict_strtoul(buf, 0, &en)) - return -EINVAL; + ret = kstrtoul(buf, 0, &en); + if (ret) + return ret; if (en) writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID), @@ -351,9 +357,11 @@ static ssize_t pcie_gadget_store_send_msi( struct pcie_app_reg __iomem *app_reg = config->va_app_base; ulong vector; u32 ven_msi; + int ret; - if (strict_strtoul(buf, 0, &vector)) - return -EINVAL; + ret = kstrtoul(buf, 0, &vector); + if (ret) + return ret; if (!config->configured_msi) return -EINVAL; @@ -395,9 +403,11 @@ static ssize_t pcie_gadget_store_vendor_id( const char *buf, size_t count) { ulong id; + int ret; - if (strict_strtoul(buf, 0, &id)) - return -EINVAL; + ret = kstrtoul(buf, 0, &id); + if (ret) + return ret; spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id); @@ -420,9 +430,11 @@ static ssize_t pcie_gadget_store_device_id( const char *buf, size_t count) { ulong id; + int ret; - if (strict_strtoul(buf, 0, &id)) - return -EINVAL; + ret = kstrtoul(buf, 0, &id); + if (ret) + return ret; spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id); @@ -443,9 +455,12 @@ static ssize_t pcie_gadget_store_bar0_size( ulong size; u32 pos, pos1; u32 no_of_bit = 0; + int ret; + + ret = kstrtoul(buf, 0, &size); + if (ret) + return ret; - if (strict_strtoul(buf, 0, &size)) - return -EINVAL; /* min bar size is 256 */ if (size <= 0x100) size = 0x100; @@ -490,9 +505,11 @@ static ssize_t pcie_gadget_store_bar0_address( { struct pcie_app_reg __iomem *app_reg = config->va_app_base; ulong address; + int ret; - if (strict_strtoul(buf, 0, &address)) - return -EINVAL; + ret = kstrtoul(buf, 0, &address); + if (ret) + return ret; address &= ~(config->bar0_size - 1); if (config->va_bar0_address) @@ -518,9 +535,11 @@ static ssize_t pcie_gadget_store_bar0_rw_offset( const char *buf, size_t count) { ulong offset; + int ret; - if (strict_strtoul(buf, 0, &offset)) - return -EINVAL; + ret = kstrtoul(buf, 0, &offset); + if (ret) + return ret; if (offset % 4) return -EINVAL; @@ -549,9 +568,11 @@ static ssize_t pcie_gadget_store_bar0_data( const char *buf, size_t count) { ulong data; + int ret; - if (strict_strtoul(buf, 0, &data)) - return -EINVAL; + ret = kstrtoul(buf, 0, &data); + if (ret) + return ret; if (!config->va_bar0_address) return -ENOMEM; @@ -776,7 +797,7 @@ static int spear_pcie_gadget_probe(struct platform_device *pdev) goto err_iounmap_app; } - dev_set_drvdata(&pdev->dev, target); + platform_set_drvdata(pdev, target); irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -814,9 +835,11 @@ static int spear_pcie_gadget_probe(struct platform_device *pdev) clk = clk_get_sys("pcie1", NULL); if (IS_ERR(clk)) { pr_err("%s:couldn't get clk for pcie1\n", __func__); + status = PTR_ERR(clk); goto err_irq; } - if (clk_enable(clk)) { + status = clk_enable(clk); + if (status) { pr_err("%s:couldn't enable clk for pcie1\n", __func__); goto err_irq; } @@ -828,9 +851,11 @@ static int spear_pcie_gadget_probe(struct platform_device *pdev) clk = clk_get_sys("pcie2", NULL); if (IS_ERR(clk)) { pr_err("%s:couldn't get clk for pcie2\n", __func__); + status = PTR_ERR(clk); goto err_irq; } - if (clk_enable(clk)) { + status = clk_enable(clk); + if (status) { pr_err("%s:couldn't enable clk for pcie2\n", __func__); goto err_irq; } @@ -863,7 +888,7 @@ static int spear_pcie_gadget_remove(struct platform_device *pdev) res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); irq = platform_get_irq(pdev, 0); - target = dev_get_drvdata(&pdev->dev); + target = platform_get_drvdata(pdev); config = &target->config; free_irq(irq, NULL); diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 437192e43006..4a938860fec0 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -50,9 +50,10 @@ static int sram_probe(struct platform_device *pdev) size = resource_size(res); - virt_base = devm_request_and_ioremap(&pdev->dev, res); - if (!virt_base) - return -EADDRNOTAVAIL; + virt_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(virt_base)) + return PTR_ERR(virt_base); + sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL); if (!sram) diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 83269f1d16e3..83907c720594 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -680,7 +680,7 @@ void st_kim_ref(struct st_data_s **core_data, int id) *core_data = NULL; return; } - kim_gdata = dev_get_drvdata(&pdev->dev); + kim_gdata = platform_get_drvdata(pdev); *core_data = kim_gdata->core_data; } @@ -735,7 +735,7 @@ static int kim_probe(struct platform_device *pdev) pr_err("no mem to allocate"); return -ENOMEM; } - dev_set_drvdata(&pdev->dev, kim_gdata); + platform_set_drvdata(pdev, kim_gdata); err = st_core_init(&kim_gdata->core_data); if (err != 0) { @@ -810,7 +810,7 @@ static int kim_remove(struct platform_device *pdev) struct ti_st_plat_data *pdata = pdev->dev.platform_data; struct kim_data_s *kim_gdata; - kim_gdata = dev_get_drvdata(&pdev->dev); + kim_gdata = platform_get_drvdata(pdev); /* Free the Bluetooth/FM/GPIO * nShutdown gpio from the system diff --git a/drivers/misc/ti_dac7512.c b/drivers/misc/ti_dac7512.c index 1d86407189eb..9b237221bc4e 100644 --- a/drivers/misc/ti_dac7512.c +++ b/drivers/misc/ti_dac7512.c @@ -33,9 +33,11 @@ static ssize_t dac7512_store_val(struct device *dev, struct spi_device *spi = to_spi_device(dev); unsigned char tmp[2]; unsigned long val; + int ret; - if (strict_strtoul(buf, 10, &val) < 0) - return -EINVAL; + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; tmp[0] = val >> 8; tmp[1] = val & 0xff; diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c index 1dfde4d543db..5bc10fa193de 100644 --- a/drivers/misc/tsl2550.c +++ b/drivers/misc/tsl2550.c @@ -204,7 +204,7 @@ static ssize_t tsl2550_store_power_state(struct device *dev, unsigned long val = simple_strtoul(buf, NULL, 10); int ret; - if (val < 0 || val > 1) + if (val > 1) return -EINVAL; mutex_lock(&data->update_lock); @@ -236,7 +236,7 @@ static ssize_t tsl2550_store_operating_mode(struct device *dev, unsigned long val = simple_strtoul(buf, NULL, 10); int ret; - if (val < 0 || val > 1) + if (val > 1) return -EINVAL; if (data->power_state == 0) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 59ac143dec25..4f777ed9b089 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -40,6 +40,7 @@ #include <linux/slab.h> #include <linux/console.h> #include <linux/moduleparam.h> +#include <linux/kernel.h> #include <linux/string.h> #include <linux/netpoll.h> #include <linux/inet.h> diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index b90f85bf5f81..80faa56c684d 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -288,7 +288,7 @@ config BFIN_CFPCMCIA config AT91_CF tristate "AT91 CompactFlash Controller" - depends on PCMCIA && ARCH_AT91RM9200 + depends on PCMCIA && ARCH_AT91 help Say Y here to support the CompactFlash controller on AT91 chips. Or choose M to compile the driver as a module named "at91_cf". diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 01463c781847..b8f5acf02261 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -18,13 +18,14 @@ #include <linux/slab.h> #include <linux/gpio.h> #include <linux/platform_data/atmel.h> +#include <linux/io.h> +#include <linux/sizes.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> #include <pcmcia/ss.h> -#include <mach/hardware.h> -#include <asm/io.h> -#include <asm/sizes.h> - #include <mach/at91rm9200_mc.h> #include <mach/at91_ramc.h> @@ -41,8 +42,6 @@ /*--------------------------------------------------------------------------*/ -static const char driver_name[] = "at91_cf"; - struct at91_cf_socket { struct pcmcia_socket socket; @@ -76,7 +75,7 @@ static irqreturn_t at91_cf_irq(int irq, void *_cf) /* kick pccard as needed */ if (present != cf->present) { cf->present = present; - pr_debug("%s: card %s\n", driver_name, + dev_dbg(&cf->pdev->dev, "card %s\n", present ? "present" : "gone"); pcmcia_parse_events(&cf->socket, SS_DETECT); } @@ -100,9 +99,9 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) int vcc = gpio_is_valid(cf->board->vcc_pin); *sp = SS_DETECT | SS_3VCARD; - if (!rdy || gpio_get_value(rdy)) + if (!rdy || gpio_get_value(cf->board->irq_pin)) *sp |= SS_READY; - if (!vcc || gpio_get_value(vcc)) + if (!vcc || gpio_get_value(cf->board->vcc_pin)) *sp |= SS_POWERON; } else *sp = 0; @@ -120,22 +119,22 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) /* switch Vcc if needed and possible */ if (gpio_is_valid(cf->board->vcc_pin)) { switch (s->Vcc) { - case 0: - gpio_set_value(cf->board->vcc_pin, 0); - break; - case 33: - gpio_set_value(cf->board->vcc_pin, 1); - break; - default: - return -EINVAL; + case 0: + gpio_set_value(cf->board->vcc_pin, 0); + break; + case 33: + gpio_set_value(cf->board->vcc_pin, 1); + break; + default: + return -EINVAL; } } /* toggle reset if needed */ gpio_set_value(cf->board->rst_pin, s->flags & SS_RESET); - pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n", - driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask); + dev_dbg(&cf->pdev->dev, "Vcc %d, io_irq %d, flags %04x csc %04x\n", + s->Vcc, s->io_irq, s->flags, s->csc_mask); return 0; } @@ -171,10 +170,10 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) */ if (!(io->flags & (MAP_16BIT | MAP_AUTOSZ))) { csr |= AT91_SMC_DBW_8; - pr_debug("%s: 8bit i/o bus\n", driver_name); + dev_dbg(&cf->pdev->dev, "8bit i/o bus\n"); } else { csr |= AT91_SMC_DBW_16; - pr_debug("%s: 16bit i/o bus\n", driver_name); + dev_dbg(&cf->pdev->dev, "16bit i/o bus\n"); } at91_ramc_write(0, AT91_SMC_CSR(cf->board->chipselect), csr); @@ -215,6 +214,37 @@ static struct pccard_operations at91_cf_ops = { /*--------------------------------------------------------------------------*/ +#if defined(CONFIG_OF) +static const struct of_device_id at91_cf_dt_ids[] = { + { .compatible = "atmel,at91rm9200-cf" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, at91_cf_dt_ids); + +static int at91_cf_dt_init(struct platform_device *pdev) +{ + struct at91_cf_data *board; + + board = devm_kzalloc(&pdev->dev, sizeof(*board), GFP_KERNEL); + if (!board) + return -ENOMEM; + + board->irq_pin = of_get_gpio(pdev->dev.of_node, 0); + board->det_pin = of_get_gpio(pdev->dev.of_node, 1); + board->vcc_pin = of_get_gpio(pdev->dev.of_node, 2); + board->rst_pin = of_get_gpio(pdev->dev.of_node, 3); + + pdev->dev.platform_data = board; + + return 0; +} +#else +static int at91_cf_dt_init(struct platform_device *pdev) +{ + return -ENODEV; +} +#endif + static int __init at91_cf_probe(struct platform_device *pdev) { struct at91_cf_socket *cf; @@ -222,14 +252,22 @@ static int __init at91_cf_probe(struct platform_device *pdev) struct resource *io; int status; - if (!board || !gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin)) + if (!board) { + status = at91_cf_dt_init(pdev); + if (status) + return status; + + board = pdev->dev.platform_data; + } + + if (!gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin)) return -ENODEV; io = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!io) return -ENODEV; - cf = kzalloc(sizeof *cf, GFP_KERNEL); + cf = devm_kzalloc(&pdev->dev, sizeof(*cf), GFP_KERNEL); if (!cf) return -ENOMEM; @@ -239,22 +277,25 @@ static int __init at91_cf_probe(struct platform_device *pdev) platform_set_drvdata(pdev, cf); /* must be a GPIO; ergo must trigger on both edges */ - status = gpio_request(board->det_pin, "cf_det"); + status = devm_gpio_request(&pdev->dev, board->det_pin, "cf_det"); if (status < 0) - goto fail0; - status = request_irq(gpio_to_irq(board->det_pin), at91_cf_irq, 0, driver_name, cf); + return status; + + status = devm_request_irq(&pdev->dev, gpio_to_irq(board->det_pin), + at91_cf_irq, 0, "at91_cf detect", cf); if (status < 0) - goto fail00; + return status; + device_init_wakeup(&pdev->dev, 1); - status = gpio_request(board->rst_pin, "cf_rst"); + status = devm_gpio_request(&pdev->dev, board->rst_pin, "cf_rst"); if (status < 0) goto fail0a; if (gpio_is_valid(board->vcc_pin)) { - status = gpio_request(board->vcc_pin, "cf_vcc"); + status = devm_gpio_request(&pdev->dev, board->vcc_pin, "cf_vcc"); if (status < 0) - goto fail0b; + goto fail0a; } /* @@ -264,32 +305,33 @@ static int __init at91_cf_probe(struct platform_device *pdev) * (Note: DK board doesn't wire the IRQ pin...) */ if (gpio_is_valid(board->irq_pin)) { - status = gpio_request(board->irq_pin, "cf_irq"); + status = devm_gpio_request(&pdev->dev, board->irq_pin, "cf_irq"); if (status < 0) - goto fail0c; - status = request_irq(gpio_to_irq(board->irq_pin), at91_cf_irq, - IRQF_SHARED, driver_name, cf); + goto fail0a; + + status = devm_request_irq(&pdev->dev, gpio_to_irq(board->irq_pin), + at91_cf_irq, IRQF_SHARED, "at91_cf", cf); if (status < 0) - goto fail0d; + goto fail0a; cf->socket.pci_irq = gpio_to_irq(board->irq_pin); } else cf->socket.pci_irq = nr_irqs + 1; /* pcmcia layer only remaps "real" memory not iospace */ - cf->socket.io_offset = (unsigned long) - ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K); + cf->socket.io_offset = (unsigned long) devm_ioremap(&pdev->dev, + cf->phys_baseaddr + CF_IO_PHYS, SZ_2K); if (!cf->socket.io_offset) { status = -ENXIO; - goto fail1; + goto fail0a; } /* reserve chip-select regions */ - if (!request_mem_region(io->start, resource_size(io), driver_name)) { + if (!devm_request_mem_region(&pdev->dev, io->start, resource_size(io), "at91_cf")) { status = -ENXIO; - goto fail1; + goto fail0a; } - pr_info("%s: irqs det #%d, io #%d\n", driver_name, + dev_info(&pdev->dev, "irqs det #%d, io #%d\n", gpio_to_irq(board->det_pin), gpio_to_irq(board->irq_pin)); cf->socket.owner = THIS_MODULE; @@ -303,55 +345,22 @@ static int __init at91_cf_probe(struct platform_device *pdev) status = pcmcia_register_socket(&cf->socket); if (status < 0) - goto fail2; + goto fail0a; return 0; -fail2: - release_mem_region(io->start, resource_size(io)); -fail1: - if (cf->socket.io_offset) - iounmap((void __iomem *) cf->socket.io_offset); - if (gpio_is_valid(board->irq_pin)) { - free_irq(gpio_to_irq(board->irq_pin), cf); -fail0d: - gpio_free(board->irq_pin); - } -fail0c: - if (gpio_is_valid(board->vcc_pin)) - gpio_free(board->vcc_pin); -fail0b: - gpio_free(board->rst_pin); fail0a: device_init_wakeup(&pdev->dev, 0); - free_irq(gpio_to_irq(board->det_pin), cf); -fail00: - gpio_free(board->det_pin); -fail0: - kfree(cf); return status; } static int __exit at91_cf_remove(struct platform_device *pdev) { struct at91_cf_socket *cf = platform_get_drvdata(pdev); - struct at91_cf_data *board = cf->board; - struct resource *io = cf->socket.io[0].res; pcmcia_unregister_socket(&cf->socket); - release_mem_region(io->start, resource_size(io)); - iounmap((void __iomem *) cf->socket.io_offset); - if (gpio_is_valid(board->irq_pin)) { - free_irq(gpio_to_irq(board->irq_pin), cf); - gpio_free(board->irq_pin); - } - if (gpio_is_valid(board->vcc_pin)) - gpio_free(board->vcc_pin); - gpio_free(board->rst_pin); device_init_wakeup(&pdev->dev, 0); - free_irq(gpio_to_irq(board->det_pin), cf); - gpio_free(board->det_pin); - kfree(cf); + return 0; } @@ -391,8 +400,9 @@ static int at91_cf_resume(struct platform_device *pdev) static struct platform_driver at91_cf_driver = { .driver = { - .name = (char *) driver_name, + .name = "at91_cf", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(at91_cf_dt_ids), }, .remove = __exit_p(at91_cf_remove), .suspend = at91_cf_suspend, @@ -401,17 +411,7 @@ static struct platform_driver at91_cf_driver = { /*--------------------------------------------------------------------------*/ -static int __init at91_cf_init(void) -{ - return platform_driver_probe(&at91_cf_driver, at91_cf_probe); -} -module_init(at91_cf_init); - -static void __exit at91_cf_exit(void) -{ - platform_driver_unregister(&at91_cf_driver); -} -module_exit(at91_cf_exit); +module_platform_driver_probe(at91_cf_driver, at91_cf_probe); MODULE_DESCRIPTION("AT91 Compact Flash Driver"); MODULE_AUTHOR("David Brownell"); diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index b29d97e170ae..a4c16ee5c718 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -644,6 +644,7 @@ static int pd6729_pci_probe(struct pci_dev *dev, if (!pci_resource_start(dev, 0)) { dev_warn(&dev->dev, "refusing to load the driver as the " "io_base is NULL.\n"); + ret = -ENOMEM; goto err_out_disable; } @@ -673,6 +674,7 @@ static int pd6729_pci_probe(struct pci_dev *dev, mask = pd6729_isa_scan(); if (irq_mode == 0 && mask == 0) { dev_warn(&dev->dev, "no ISA interrupt is available.\n"); + ret = -ENODEV; goto err_out_free_res; } diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c index 1548982db58b..f3611c2d83b6 100644 --- a/drivers/uio/uio_aec.c +++ b/drivers/uio/uio_aec.c @@ -160,17 +160,5 @@ static struct pci_driver pci_driver = { .remove = remove, }; -static int __init aectc_init(void) -{ - return pci_register_driver(&pci_driver); -} - -static void __exit aectc_exit(void) -{ - pci_unregister_driver(&pci_driver); -} - +module_pci_driver(pci_driver); MODULE_LICENSE("GPL"); - -module_init(aectc_init); -module_exit(aectc_exit); diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c index 7dd6fc60539d..22cdf385ab33 100644 --- a/drivers/uio/uio_cif.c +++ b/drivers/uio/uio_cif.c @@ -135,19 +135,7 @@ static struct pci_driver hilscher_pci_driver = { .remove = hilscher_pci_remove, }; -static int __init hilscher_init_module(void) -{ - return pci_register_driver(&hilscher_pci_driver); -} - -static void __exit hilscher_exit_module(void) -{ - pci_unregister_driver(&hilscher_pci_driver); -} - -module_init(hilscher_init_module); -module_exit(hilscher_exit_module); - +module_pci_driver(hilscher_pci_driver); MODULE_DEVICE_TABLE(pci, hilscher_pci_ids); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger"); diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c index 6a4ba5e83e37..28a766b9e198 100644 --- a/drivers/uio/uio_netx.c +++ b/drivers/uio/uio_netx.c @@ -174,19 +174,7 @@ static struct pci_driver netx_pci_driver = { .remove = netx_pci_remove, }; -static int __init netx_init_module(void) -{ - return pci_register_driver(&netx_pci_driver); -} - -static void __exit netx_exit_module(void) -{ - pci_unregister_driver(&netx_pci_driver); -} - -module_init(netx_init_module); -module_exit(netx_exit_module); - +module_pci_driver(netx_pci_driver); MODULE_DEVICE_TABLE(pci, netx_pci_ids); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Hans J. Koch, Manuel Traut"); diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c index 14aa10c1f6de..077ae12269ce 100644 --- a/drivers/uio/uio_pci_generic.c +++ b/drivers/uio/uio_pci_generic.c @@ -113,27 +113,14 @@ static void remove(struct pci_dev *pdev) kfree(gdev); } -static struct pci_driver driver = { +static struct pci_driver uio_pci_driver = { .name = "uio_pci_generic", .id_table = NULL, /* only dynamic id's */ .probe = probe, .remove = remove, }; -static int __init init(void) -{ - pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); - return pci_register_driver(&driver); -} - -static void __exit cleanup(void) -{ - pci_unregister_driver(&driver); -} - -module_init(init); -module_exit(cleanup); - +module_pci_driver(uio_pci_driver); MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c index 6e2ab007fe9c..21f7a72301e4 100644 --- a/drivers/uio/uio_pruss.c +++ b/drivers/uio/uio_pruss.c @@ -136,9 +136,9 @@ static int pruss_probe(struct platform_device *dev) gdev->pruss_clk = clk_get(&dev->dev, "pruss"); if (IS_ERR(gdev->pruss_clk)) { dev_err(&dev->dev, "Failed to get clock\n"); + ret = PTR_ERR(gdev->pruss_clk); kfree(gdev->info); kfree(gdev); - ret = PTR_ERR(gdev->pruss_clk); return ret; } else { clk_enable(gdev->pruss_clk); diff --git a/drivers/uio/uio_sercos3.c b/drivers/uio/uio_sercos3.c index 81a10a563120..541983217085 100644 --- a/drivers/uio/uio_sercos3.c +++ b/drivers/uio/uio_sercos3.c @@ -226,19 +226,7 @@ static struct pci_driver sercos3_pci_driver = { .remove = sercos3_pci_remove, }; -static int __init sercos3_init_module(void) -{ - return pci_register_driver(&sercos3_pci_driver); -} - -static void __exit sercos3_exit_module(void) -{ - pci_unregister_driver(&sercos3_pci_driver); -} - -module_init(sercos3_init_module); -module_exit(sercos3_exit_module); - +module_pci_driver(sercos3_pci_driver); MODULE_DESCRIPTION("UIO driver for the Automata Sercos III PCI card"); MODULE_AUTHOR("John Ogness <john.ogness@linutronix.de>"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c index 5e6c7d74e19f..f6856b427496 100644 --- a/drivers/vme/vme.c +++ b/drivers/vme/vme.c @@ -959,6 +959,8 @@ int vme_dma_free(struct vme_resource *resource) mutex_unlock(&ctrlr->mtx); + kfree(resource); + return 0; } EXPORT_SYMBOL(vme_dma_free); diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c index 46d97014342e..f54ece268c98 100644 --- a/drivers/w1/masters/w1-gpio.c +++ b/drivers/w1/masters/w1-gpio.c @@ -16,7 +16,6 @@ #include <linux/gpio.h> #include <linux/of_platform.h> #include <linux/of_gpio.h> -#include <linux/pinctrl/consumer.h> #include <linux/err.h> #include <linux/of.h> @@ -78,13 +77,8 @@ static int w1_gpio_probe(struct platform_device *pdev) { struct w1_bus_master *master; struct w1_gpio_platform_data *pdata; - struct pinctrl *pinctrl; int err; - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) - dev_warn(&pdev->dev, "unable to select pin group\n"); - if (of_have_populated_dt()) { err = w1_gpio_probe_dt(pdev); if (err < 0) { diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index e45eca1044bd..91cc2cdf02c0 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c @@ -22,6 +22,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jean-Francois Dagenais <dagenaisj@sonatest.com>"); MODULE_DESCRIPTION("w1 family 29 driver for DS2408 8 Pin IO"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2408)); #define W1_F29_RETRIES 3 diff --git a/drivers/w1/slaves/w1_ds2413.c b/drivers/w1/slaves/w1_ds2413.c index 829786252c6b..85937773a96a 100644 --- a/drivers/w1/slaves/w1_ds2413.c +++ b/drivers/w1/slaves/w1_ds2413.c @@ -23,6 +23,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mariusz Bialonczyk <manio@skyboo.net>"); MODULE_DESCRIPTION("w1 family 3a driver for DS2413 2 Pin IO"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2413)); #define W1_F3A_RETRIES 3 #define W1_F3A_FUNC_PIO_ACCESS_READ 0xF5 diff --git a/drivers/w1/slaves/w1_ds2423.c b/drivers/w1/slaves/w1_ds2423.c index 40a10b5ed120..7f86aec74088 100644 --- a/drivers/w1/slaves/w1_ds2423.c +++ b/drivers/w1/slaves/w1_ds2423.c @@ -164,3 +164,4 @@ module_exit(w1_f1d_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mika Laitio <lamikr@pilppa.org>"); MODULE_DESCRIPTION("w1 family 1d driver for DS2423, 4 counters and 4kb ram"); +MODULE_ALIAS("w1-family-" __stringify(W1_COUNTER_DS2423)); diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c index 984b30331a45..cef8605e43ec 100644 --- a/drivers/w1/slaves/w1_ds2431.c +++ b/drivers/w1/slaves/w1_ds2431.c @@ -310,3 +310,4 @@ module_exit(w1_f2d_fini); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Bernhard Weirich <bernhard.weirich@riedel.net>"); MODULE_DESCRIPTION("w1 family 2d driver for DS2431, 1kb EEPROM"); +MODULE_ALIAS("w1-family-" __stringify(W1_EEPROM_DS2431)); diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index 85f2cdb27fa2..10cc1b6176e6 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c @@ -29,6 +29,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>"); MODULE_DESCRIPTION("w1 family 23 driver for DS2433, 4kb EEPROM"); +MODULE_ALIAS("w1-family-" __stringify(W1_EEPROM_DS2433)); #define W1_EEPROM_SIZE 512 #define W1_PAGE_COUNT 16 diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index e86a69dc411e..93719d25d849 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c @@ -203,3 +203,4 @@ module_exit(w1_ds2760_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>"); MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2760)); diff --git a/drivers/w1/slaves/w1_ds2780.c b/drivers/w1/slaves/w1_ds2780.c index 98ed9c49cf50..0cd7a27b5d6b 100644 --- a/drivers/w1/slaves/w1_ds2780.c +++ b/drivers/w1/slaves/w1_ds2780.c @@ -188,3 +188,4 @@ module_exit(w1_ds2780_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>"); MODULE_DESCRIPTION("1-wire Driver for Maxim/Dallas DS2780 Stand-Alone Fuel Gauge IC"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2780)); diff --git a/drivers/w1/slaves/w1_ds2781.c b/drivers/w1/slaves/w1_ds2781.c index 5140d7be67ab..1aba8e41ad46 100644 --- a/drivers/w1/slaves/w1_ds2781.c +++ b/drivers/w1/slaves/w1_ds2781.c @@ -186,3 +186,4 @@ module_exit(w1_ds2781_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Renata Sayakhova <renata@oktetlabs.ru>"); MODULE_DESCRIPTION("1-wire Driver for Maxim/Dallas DS2781 Stand-Alone Fuel Gauge IC"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2781)); diff --git a/drivers/w1/slaves/w1_ds28e04.c b/drivers/w1/slaves/w1_ds28e04.c index 98117db595bb..cd30a6d95ea5 100644 --- a/drivers/w1/slaves/w1_ds28e04.c +++ b/drivers/w1/slaves/w1_ds28e04.c @@ -27,6 +27,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Markus Franke <franke.m@sebakmt.com>, <franm@hrz.tu-chemnitz.de>"); MODULE_DESCRIPTION("w1 family 1C driver for DS28E04, 4kb EEPROM and PIO"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS28E04)); /* Allow the strong pullup to be disabled, but default to enabled. * If it was disabled a parasite powered device might not get the required diff --git a/drivers/w1/slaves/w1_smem.c b/drivers/w1/slaves/w1_smem.c index 84655625c870..ed4c87506def 100644 --- a/drivers/w1/slaves/w1_smem.c +++ b/drivers/w1/slaves/w1_smem.c @@ -34,6 +34,8 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family."); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_SMEM_01)); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_SMEM_81)); static struct w1_family w1_smem_family_01 = { .fid = W1_FAMILY_SMEM_01, diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index c1a702f8c803..8978360bd387 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -36,6 +36,11 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family."); +MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS18S20)); +MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS1822)); +MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS18B20)); +MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS1825)); +MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS28EA00)); /* Allow the strong pullup to be disabled, but default to enabled. * If it was disabled a parasite powered device might not get the require diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 7ce277d2bb67..0459df843c58 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -680,6 +680,8 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) atomic_set(&sl->refcnt, 0); init_completion(&sl->released); + request_module("w1-family-0x%0x", rn->family); + spin_lock(&w1_flock); f = w1_family_registered(rn->family); if (!f) { |