diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2017-05-30 13:29:26 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2017-05-30 13:29:26 +1000 |
commit | 145b391b59abf3a03186b91471d575f29d4b7de9 (patch) | |
tree | 96f6bf17eb5b5ee75a9d7e08b2e674f0cd5bee99 | |
parent | 6512b25fafb0fed1a8c6ecb45797d1a026405b58 (diff) | |
parent | 46505c802a55189955d97195c8567ee263168747 (diff) |
Merge remote-tracking branch 'char-misc/char-misc-next'
55 files changed, 486 insertions, 473 deletions
diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index c9cea2e39c21..6b71852dadc2 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -369,8 +369,10 @@ 237 = /dev/loop-control Loopback control device 238 = /dev/vhost-net Host kernel accelerator for virtio net 239 = /dev/uhid User-space I/O driver support for HID subsystem + 240 = /dev/userio Serio driver testing device + 241 = /dev/vhost-vsock Host kernel driver for virtio vsock - 240-254 Reserved for local use + 242-254 Reserved for local use 255 Reserved for MISC_DYNAMIC_MINOR 11 char Raw keyboard device (Linux/SPARC only) diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index fba100713924..18325dcdb7f1 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -137,7 +137,6 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type) } } -#define hv_get_current_tick(tick) rdmsrl(HV_X64_MSR_TIME_REF_COUNT, tick) #define hv_init_timer(timer, tick) wrmsrl(timer, tick) #define hv_init_timer_config(config, val) wrmsrl(config, val) diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c index e0c014c2356f..7a8b8fb2f572 100644 --- a/drivers/auxdisplay/panel.c +++ b/drivers/auxdisplay/panel.c @@ -1345,14 +1345,11 @@ static inline void input_state_falling(struct logical_input *input) static void panel_process_inputs(void) { - struct list_head *item; struct logical_input *input; keypressed = 0; inputs_stable = 1; - list_for_each(item, &logical_inputs) { - input = list_entry(item, struct logical_input, list); - + list_for_each_entry(input, &logical_inputs, list) { switch (input->state) { case INPUT_ST_LOW: if ((phys_curr & input->mask) != input->value) diff --git a/drivers/firmware/google/memconsole-coreboot.c b/drivers/firmware/google/memconsole-coreboot.c index 02711114dece..52738887735c 100644 --- a/drivers/firmware/google/memconsole-coreboot.c +++ b/drivers/firmware/google/memconsole-coreboot.c @@ -26,12 +26,52 @@ /* CBMEM firmware console log descriptor. */ struct cbmem_cons { - u32 buffer_size; - u32 buffer_cursor; - u8 buffer_body[0]; + u32 size_dont_access_after_boot; + u32 cursor; + u8 body[0]; } __packed; +#define CURSOR_MASK ((1 << 28) - 1) +#define OVERFLOW (1 << 31) + static struct cbmem_cons __iomem *cbmem_console; +static u32 cbmem_console_size; + +/* + * The cbmem_console structure is read again on every access because it may + * change at any time if runtime firmware logs new messages. This may rarely + * lead to race conditions where the firmware overwrites the beginning of the + * ring buffer with more lines after we have already read |cursor|. It should be + * rare and harmless enough that we don't spend extra effort working around it. + */ +static ssize_t memconsole_coreboot_read(char *buf, loff_t pos, size_t count) +{ + u32 cursor = cbmem_console->cursor & CURSOR_MASK; + u32 flags = cbmem_console->cursor & ~CURSOR_MASK; + u32 size = cbmem_console_size; + struct seg { /* describes ring buffer segments in logical order */ + u32 phys; /* physical offset from start of mem buffer */ + u32 len; /* length of segment */ + } seg[2] = { {0}, {0} }; + size_t done = 0; + int i; + + if (flags & OVERFLOW) { + if (cursor > size) /* Shouldn't really happen, but... */ + cursor = 0; + seg[0] = (struct seg){.phys = cursor, .len = size - cursor}; + seg[1] = (struct seg){.phys = 0, .len = cursor}; + } else { + seg[0] = (struct seg){.phys = 0, .len = min(cursor, size)}; + } + + for (i = 0; i < ARRAY_SIZE(seg) && count > done; i++) { + done += memory_read_from_buffer(buf + done, count - done, &pos, + cbmem_console->body + seg[i].phys, seg[i].len); + pos -= seg[i].len; + } + return done; +} static int memconsole_coreboot_init(phys_addr_t physaddr) { @@ -42,17 +82,17 @@ static int memconsole_coreboot_init(phys_addr_t physaddr) if (!tmp_cbmc) return -ENOMEM; + /* Read size only once to prevent overrun attack through /dev/mem. */ + cbmem_console_size = tmp_cbmc->size_dont_access_after_boot; cbmem_console = memremap(physaddr, - tmp_cbmc->buffer_size + sizeof(*cbmem_console), + cbmem_console_size + sizeof(*cbmem_console), MEMREMAP_WB); memunmap(tmp_cbmc); if (!cbmem_console) return -ENOMEM; - memconsole_setup(cbmem_console->buffer_body, - min(cbmem_console->buffer_cursor, cbmem_console->buffer_size)); - + memconsole_setup(memconsole_coreboot_read); return 0; } diff --git a/drivers/firmware/google/memconsole-x86-legacy.c b/drivers/firmware/google/memconsole-x86-legacy.c index 1f279ee883b9..8c1bf6dbdaa6 100644 --- a/drivers/firmware/google/memconsole-x86-legacy.c +++ b/drivers/firmware/google/memconsole-x86-legacy.c @@ -48,6 +48,15 @@ struct biosmemcon_ebda { }; } __packed; +static char *memconsole_baseaddr; +static size_t memconsole_length; + +static ssize_t memconsole_read(char *buf, loff_t pos, size_t count) +{ + return memory_read_from_buffer(buf, count, &pos, memconsole_baseaddr, + memconsole_length); +} + static void found_v1_header(struct biosmemcon_ebda *hdr) { pr_info("memconsole: BIOS console v1 EBDA structure found at %p\n", @@ -56,7 +65,9 @@ static void found_v1_header(struct biosmemcon_ebda *hdr) hdr->v1.buffer_addr, hdr->v1.start, hdr->v1.end, hdr->v1.num_chars); - memconsole_setup(phys_to_virt(hdr->v1.buffer_addr), hdr->v1.num_chars); + memconsole_baseaddr = phys_to_virt(hdr->v1.buffer_addr); + memconsole_length = hdr->v1.num_chars; + memconsole_setup(memconsole_read); } static void found_v2_header(struct biosmemcon_ebda *hdr) @@ -67,8 +78,9 @@ static void found_v2_header(struct biosmemcon_ebda *hdr) hdr->v2.buffer_addr, hdr->v2.start, hdr->v2.end, hdr->v2.num_bytes); - memconsole_setup(phys_to_virt(hdr->v2.buffer_addr + hdr->v2.start), - hdr->v2.end - hdr->v2.start); + memconsole_baseaddr = phys_to_virt(hdr->v2.buffer_addr + hdr->v2.start); + memconsole_length = hdr->v2.end - hdr->v2.start; + memconsole_setup(memconsole_read); } /* diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c index 94e200ddb4fa..166f07c68c02 100644 --- a/drivers/firmware/google/memconsole.c +++ b/drivers/firmware/google/memconsole.c @@ -22,15 +22,15 @@ #include "memconsole.h" -static char *memconsole_baseaddr; -static size_t memconsole_length; +static ssize_t (*memconsole_read_func)(char *, loff_t, size_t); static ssize_t memconsole_read(struct file *filp, struct kobject *kobp, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { - return memory_read_from_buffer(buf, count, &pos, memconsole_baseaddr, - memconsole_length); + if (WARN_ON_ONCE(!memconsole_read_func)) + return -EIO; + return memconsole_read_func(buf, pos, count); } static struct bin_attribute memconsole_bin_attr = { @@ -38,16 +38,14 @@ static struct bin_attribute memconsole_bin_attr = { .read = memconsole_read, }; -void memconsole_setup(void *baseaddr, size_t length) +void memconsole_setup(ssize_t (*read_func)(char *, loff_t, size_t)) { - memconsole_baseaddr = baseaddr; - memconsole_length = length; + memconsole_read_func = read_func; } EXPORT_SYMBOL(memconsole_setup); int memconsole_sysfs_init(void) { - memconsole_bin_attr.size = memconsole_length; return sysfs_create_bin_file(firmware_kobj, &memconsole_bin_attr); } EXPORT_SYMBOL(memconsole_sysfs_init); diff --git a/drivers/firmware/google/memconsole.h b/drivers/firmware/google/memconsole.h index 190fc03a51ae..ff1592dc7d1a 100644 --- a/drivers/firmware/google/memconsole.h +++ b/drivers/firmware/google/memconsole.h @@ -18,13 +18,14 @@ #ifndef __FIRMWARE_GOOGLE_MEMCONSOLE_H #define __FIRMWARE_GOOGLE_MEMCONSOLE_H +#include <linux/types.h> + /* * memconsole_setup * - * Initialize the memory console from raw (virtual) base - * address and length. + * Initialize the memory console, passing the function to handle read accesses. */ -void memconsole_setup(void *baseaddr, size_t length); +void memconsole_setup(ssize_t (*read_func)(char *, loff_t, size_t)); /* * memconsole_sysfs_init diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c index 31058d400bda..78945729388e 100644 --- a/drivers/firmware/google/vpd.c +++ b/drivers/firmware/google/vpd.c @@ -118,14 +118,13 @@ static int vpd_section_attrib_add(const u8 *key, s32 key_len, info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - info->key = kzalloc(key_len + 1, GFP_KERNEL); + + info->key = kstrndup(key, key_len, GFP_KERNEL); if (!info->key) { ret = -ENOMEM; goto free_info; } - memcpy(info->key, key, key_len); - sysfs_bin_attr_init(&info->bin_attr); info->bin_attr.attr.name = info->key; info->bin_attr.attr.mode = 0444; @@ -191,8 +190,7 @@ static int vpd_section_create_attribs(struct vpd_section *sec) static int vpd_section_init(const char *name, struct vpd_section *sec, phys_addr_t physaddr, size_t size) { - int ret; - int raw_len; + int err; sec->baseaddr = memremap(physaddr, size, MEMREMAP_WB); if (!sec->baseaddr) @@ -201,10 +199,11 @@ static int vpd_section_init(const char *name, struct vpd_section *sec, sec->name = name; /* We want to export the raw partion with name ${name}_raw */ - raw_len = strlen(name) + 5; - sec->raw_name = kzalloc(raw_len, GFP_KERNEL); - strncpy(sec->raw_name, name, raw_len); - strncat(sec->raw_name, "_raw", raw_len); + sec->raw_name = kasprintf(GFP_KERNEL, "%s_raw", name); + if (!sec->raw_name) { + err = -ENOMEM; + goto err_iounmap; + } sysfs_bin_attr_init(&sec->bin_attr); sec->bin_attr.attr.name = sec->raw_name; @@ -213,14 +212,14 @@ static int vpd_section_init(const char *name, struct vpd_section *sec, sec->bin_attr.read = vpd_section_read; sec->bin_attr.private = sec; - ret = sysfs_create_bin_file(vpd_kobj, &sec->bin_attr); - if (ret) - goto free_sec; + err = sysfs_create_bin_file(vpd_kobj, &sec->bin_attr); + if (err) + goto err_free_raw_name; sec->kobj = kobject_create_and_add(name, vpd_kobj); if (!sec->kobj) { - ret = -EINVAL; - goto sysfs_remove; + err = -EINVAL; + goto err_sysfs_remove; } INIT_LIST_HEAD(&sec->attribs); @@ -230,14 +229,13 @@ static int vpd_section_init(const char *name, struct vpd_section *sec, return 0; -sysfs_remove: +err_sysfs_remove: sysfs_remove_bin_file(vpd_kobj, &sec->bin_attr); - -free_sec: +err_free_raw_name: kfree(sec->raw_name); +err_iounmap: iounmap(sec->baseaddr); - - return ret; + return err; } static int vpd_section_destroy(struct vpd_section *sec) @@ -319,9 +317,6 @@ static int __init vpd_platform_init(void) if (!vpd_kobj) return -ENOMEM; - memset(&ro_vpd, 0, sizeof(ro_vpd)); - memset(&rw_vpd, 0, sizeof(rw_vpd)); - platform_driver_register(&vpd_driver); return 0; diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 736ac76d2a6a..e9bf0bb87ac4 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -630,9 +630,13 @@ void vmbus_close(struct vmbus_channel *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); + if (cur_channel->rescind) { + mutex_lock(&vmbus_connection.channel_mutex); + hv_process_channel_removal(cur_channel, + cur_channel->offermsg.child_relid); + mutex_unlock(&vmbus_connection.channel_mutex); + } } /* * Now close the primary. diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 735f9363f2e4..0fabd410efd9 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -428,7 +428,6 @@ void vmbus_free_channels(void) { struct vmbus_channel *channel, *tmp; - mutex_lock(&vmbus_connection.channel_mutex); list_for_each_entry_safe(channel, tmp, &vmbus_connection.chn_list, listentry) { /* hv_process_channel_removal() needs this */ @@ -436,7 +435,6 @@ void vmbus_free_channels(void) vmbus_device_unregister(channel->device_obj); } - mutex_unlock(&vmbus_connection.channel_mutex); } /* @@ -483,8 +481,10 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) list_add_tail(&newchannel->sc_list, &channel->sc_list); channel->num_sc++; spin_unlock_irqrestore(&channel->lock, flags); - } else + } else { + atomic_dec(&vmbus_connection.offer_in_progress); goto err_free_chan; + } } dev_type = hv_get_dev_type(newchannel); @@ -511,6 +511,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) if (!fnew) { if (channel->sc_creation_callback != NULL) channel->sc_creation_callback(newchannel); + atomic_dec(&vmbus_connection.offer_in_progress); return; } @@ -532,9 +533,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) * binding which eventually invokes the device driver's AddDevice() * method. */ - mutex_lock(&vmbus_connection.channel_mutex); ret = vmbus_device_register(newchannel->device_obj); - mutex_unlock(&vmbus_connection.channel_mutex); if (ret != 0) { pr_err("unable to add child device object (relid %d)\n", @@ -542,6 +541,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) kfree(newchannel->device_obj); goto err_deq_chan; } + + atomic_dec(&vmbus_connection.offer_in_progress); return; err_deq_chan: @@ -797,6 +798,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) newchannel = alloc_channel(); if (!newchannel) { vmbus_release_relid(offer->child_relid); + atomic_dec(&vmbus_connection.offer_in_progress); pr_err("Unable to allocate channel object\n"); return; } @@ -843,16 +845,38 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) rescind = (struct vmbus_channel_rescind_offer *)hdr; + /* + * The offer msg and the corresponding rescind msg + * from the host are guranteed to be ordered - + * offer comes in first and then the rescind. + * Since we process these events in work elements, + * and with preemption, we may end up processing + * the events out of order. Given that we handle these + * work elements on the same CPU, this is possible only + * in the case of preemption. In any case wait here + * until the offer processing has moved beyond the + * point where the channel is discoverable. + */ + + while (atomic_read(&vmbus_connection.offer_in_progress) != 0) { + /* + * We wait here until any channel offer is currently + * being processed. + */ + msleep(1); + } + mutex_lock(&vmbus_connection.channel_mutex); channel = relid2channel(rescind->child_relid); + mutex_unlock(&vmbus_connection.channel_mutex); if (channel == NULL) { /* - * This is very impossible, because in - * vmbus_process_offer(), we have already invoked - * vmbus_release_relid() on error. + * We failed in processing the offer message; + * we would have cleaned up the relid in that + * failure path. */ - goto out; + return; } spin_lock_irqsave(&channel->lock, flags); @@ -864,7 +888,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) if (channel->device_obj) { if (channel->chn_rescind_callback) { channel->chn_rescind_callback(channel); - goto out; + return; } /* * We will have to unregister this device from the @@ -875,13 +899,26 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) vmbus_device_unregister(channel->device_obj); put_device(dev); } - } else { - hv_process_channel_removal(channel, - channel->offermsg.child_relid); } - -out: - mutex_unlock(&vmbus_connection.channel_mutex); + if (channel->primary_channel != NULL) { + /* + * Sub-channel is being rescinded. Following is the channel + * close sequence when initiated from the driveri (refer to + * vmbus_close() for details): + * 1. Close all sub-channels first + * 2. Then close the primary channel. + */ + if (channel->state == CHANNEL_OPEN_STATE) { + /* + * The channel is currently not open; + * it is safe for us to cleanup the channel. + */ + mutex_lock(&vmbus_connection.channel_mutex); + hv_process_channel_removal(channel, + channel->offermsg.child_relid); + mutex_unlock(&vmbus_connection.channel_mutex); + } + } } void vmbus_hvsock_device_unregister(struct vmbus_channel *channel) diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index fce27fb141cc..59c11ff90d12 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -93,10 +93,13 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, * all the CPUs. This is needed for kexec to work correctly where * the CPU attempting to connect may not be CPU 0. */ - if (version >= VERSION_WIN8_1) + if (version >= VERSION_WIN8_1) { msg->target_vcpu = hv_context.vp_index[smp_processor_id()]; - else + vmbus_connection.connect_cpu = smp_processor_id(); + } else { msg->target_vcpu = 0; + vmbus_connection.connect_cpu = 0; + } /* * Add to list before we send the request since we may @@ -370,7 +373,7 @@ int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep) break; case HV_STATUS_INSUFFICIENT_MEMORY: case HV_STATUS_INSUFFICIENT_BUFFERS: - ret = -ENOMEM; + ret = -ENOBUFS; break; case HV_STATUS_SUCCESS: return ret; @@ -387,7 +390,7 @@ int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep) else mdelay(usec / 1000); - if (usec < 256000) + if (retries < 22) usec *= 2; } return ret; diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 12e7baecb84e..2ea12207caa0 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -82,10 +82,15 @@ int hv_post_message(union hv_connection_id connection_id, aligned_msg->message_type = message_type; aligned_msg->payload_size = payload_size; memcpy((void *)aligned_msg->payload, payload, payload_size); - put_cpu_ptr(hv_cpu); status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL); + /* Preemption must remain disabled until after the hypercall + * so some other thread can't get scheduled onto this cpu and + * corrupt the per-cpu post_msg_page + */ + put_cpu_ptr(hv_cpu); + return status & 0xFFFF; } @@ -96,7 +101,7 @@ static int hv_ce_set_next_event(unsigned long delta, WARN_ON(!clockevent_state_oneshot(evt)); - hv_get_current_tick(current_tick); + current_tick = hyperv_cs->read(NULL); current_tick += delta; hv_init_timer(HV_X64_MSR_STIMER0_COUNT, current_tick); return 0; diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index e99ff2ddad40..9a90b915b5be 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -112,7 +112,7 @@ static void kvp_poll_wrapper(void *channel) { /* Transaction is finished, reset the state here to avoid races. */ kvp_transaction.state = HVUTIL_READY; - hv_kvp_onchannelcallback(channel); + tasklet_schedule(&((struct vmbus_channel *)channel)->callback_event); } static void kvp_register_done(void) @@ -159,7 +159,7 @@ static void kvp_timeout_func(struct work_struct *dummy) static void kvp_host_handshake_func(struct work_struct *dummy) { - hv_poll_channel(kvp_transaction.recv_channel, hv_kvp_onchannelcallback); + tasklet_schedule(&kvp_transaction.recv_channel->callback_event); } static int kvp_handle_handshake(struct hv_kvp_msg *msg) @@ -625,16 +625,17 @@ void hv_kvp_onchannelcallback(void *context) NEGO_IN_PROGRESS, NEGO_FINISHED} host_negotiatied = NEGO_NOT_STARTED; - if (host_negotiatied == NEGO_NOT_STARTED && - kvp_transaction.state < HVUTIL_READY) { + if (kvp_transaction.state < HVUTIL_READY) { /* * If userspace daemon is not connected and host is asking * us to negotiate we need to delay to not lose messages. * This is important for Failover IP setting. */ - host_negotiatied = NEGO_IN_PROGRESS; - schedule_delayed_work(&kvp_host_handshake_work, + if (host_negotiatied == NEGO_NOT_STARTED) { + host_negotiatied = NEGO_IN_PROGRESS; + schedule_delayed_work(&kvp_host_handshake_work, HV_UTIL_NEGO_TIMEOUT * HZ); + } return; } if (kvp_transaction.state > HVUTIL_READY) @@ -702,6 +703,7 @@ void hv_kvp_onchannelcallback(void *context) VM_PKT_DATA_INBAND, 0); host_negotiatied = NEGO_FINISHED; + hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper); } } diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index 186b10083c55..14dce25c104f 100644 --- a/drivers/hv/hv_util.c +++ b/drivers/hv/hv_util.c @@ -202,27 +202,39 @@ static void shutdown_onchannelcallback(void *context) /* * Set the host time in a process context. */ +static struct work_struct adj_time_work; -struct adj_time_work { - struct work_struct work; - u64 host_time; - u64 ref_time; - u8 flags; -}; +/* + * The last time sample, received from the host. PTP device responds to + * requests by using this data and the current partition-wide time reference + * count. + */ +static struct { + u64 host_time; + u64 ref_time; + spinlock_t lock; +} host_ts; -static void hv_set_host_time(struct work_struct *work) +static struct timespec64 hv_get_adj_host_time(void) { - struct adj_time_work *wrk; - struct timespec64 host_ts; - u64 reftime, newtime; - - wrk = container_of(work, struct adj_time_work, work); + struct timespec64 ts; + u64 newtime, reftime; + unsigned long flags; + spin_lock_irqsave(&host_ts.lock, flags); reftime = hyperv_cs->read(hyperv_cs); - newtime = wrk->host_time + (reftime - wrk->ref_time); - host_ts = ns_to_timespec64((newtime - WLTIMEDELTA) * 100); + newtime = host_ts.host_time + (reftime - host_ts.ref_time); + ts = ns_to_timespec64((newtime - WLTIMEDELTA) * 100); + spin_unlock_irqrestore(&host_ts.lock, flags); - do_settimeofday64(&host_ts); + return ts; +} + +static void hv_set_host_time(struct work_struct *work) +{ + struct timespec64 ts = hv_get_adj_host_time(); + + do_settimeofday64(&ts); } /* @@ -238,62 +250,35 @@ static void hv_set_host_time(struct work_struct *work) * typically used as a hint to the guest. The guest is under no obligation * to discipline the clock. */ -static struct adj_time_work wrk; - -/* - * The last time sample, received from the host. PTP device responds to - * requests by using this data and the current partition-wide time reference - * count. - */ -static struct { - u64 host_time; - u64 ref_time; - struct system_time_snapshot snap; - spinlock_t lock; -} host_ts; - static inline void adj_guesttime(u64 hosttime, u64 reftime, u8 adj_flags) { unsigned long flags; u64 cur_reftime; /* - * This check is safe since we are executing in the - * interrupt context and time synch messages are always - * delivered on the same CPU. + * Save the adjusted time sample from the host and the snapshot + * of the current system time. */ - if (adj_flags & ICTIMESYNCFLAG_SYNC) { - /* Queue a job to do do_settimeofday64() */ - if (work_pending(&wrk.work)) - return; - - wrk.host_time = hosttime; - wrk.ref_time = reftime; - wrk.flags = adj_flags; - schedule_work(&wrk.work); - } else { - /* - * Save the adjusted time sample from the host and the snapshot - * of the current system time for PTP device. - */ - spin_lock_irqsave(&host_ts.lock, flags); - - cur_reftime = hyperv_cs->read(hyperv_cs); - host_ts.host_time = hosttime; - host_ts.ref_time = cur_reftime; - ktime_get_snapshot(&host_ts.snap); - - /* - * TimeSync v4 messages contain reference time (guest's Hyper-V - * clocksource read when the time sample was generated), we can - * improve the precision by adding the delta between now and the - * time of generation. - */ - if (ts_srv_version > TS_VERSION_3) - host_ts.host_time += (cur_reftime - reftime); - - spin_unlock_irqrestore(&host_ts.lock, flags); - } + spin_lock_irqsave(&host_ts.lock, flags); + + cur_reftime = hyperv_cs->read(hyperv_cs); + host_ts.host_time = hosttime; + host_ts.ref_time = cur_reftime; + + /* + * TimeSync v4 messages contain reference time (guest's Hyper-V + * clocksource read when the time sample was generated), we can + * improve the precision by adding the delta between now and the + * time of generation. For older protocols we set + * reftime == cur_reftime on call. + */ + host_ts.host_time += (cur_reftime - reftime); + + spin_unlock_irqrestore(&host_ts.lock, flags); + + /* Schedule work to do do_settimeofday64() */ + if (adj_flags & ICTIMESYNCFLAG_SYNC) + schedule_work(&adj_time_work); } /* @@ -341,8 +326,8 @@ static void timesync_onchannelcallback(void *context) sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; adj_guesttime(timedatap->parenttime, - 0, - timedatap->flags); + hyperv_cs->read(hyperv_cs), + timedatap->flags); } } @@ -526,58 +511,17 @@ static int hv_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) static int hv_ptp_gettime(struct ptp_clock_info *info, struct timespec64 *ts) { - unsigned long flags; - u64 newtime, reftime; - - spin_lock_irqsave(&host_ts.lock, flags); - reftime = hyperv_cs->read(hyperv_cs); - newtime = host_ts.host_time + (reftime - host_ts.ref_time); - *ts = ns_to_timespec64((newtime - WLTIMEDELTA) * 100); - spin_unlock_irqrestore(&host_ts.lock, flags); + *ts = hv_get_adj_host_time(); return 0; } -static int hv_ptp_get_syncdevicetime(ktime_t *device, - struct system_counterval_t *system, - void *ctx) -{ - system->cs = hyperv_cs; - system->cycles = host_ts.ref_time; - *device = ns_to_ktime((host_ts.host_time - WLTIMEDELTA) * 100); - - return 0; -} - -static int hv_ptp_getcrosststamp(struct ptp_clock_info *ptp, - struct system_device_crosststamp *xtstamp) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(&host_ts.lock, flags); - - /* - * host_ts contains the last time sample from the host and the snapshot - * of system time. We don't need to calculate the time delta between - * the reception and now as get_device_system_crosststamp() does the - * required interpolation. - */ - ret = get_device_system_crosststamp(hv_ptp_get_syncdevicetime, - NULL, &host_ts.snap, xtstamp); - - spin_unlock_irqrestore(&host_ts.lock, flags); - - return ret; -} - static struct ptp_clock_info ptp_hyperv_info = { .name = "hyperv", .enable = hv_ptp_enable, .adjtime = hv_ptp_adjtime, .adjfreq = hv_ptp_adjfreq, .gettime64 = hv_ptp_gettime, - .getcrosststamp = hv_ptp_getcrosststamp, .settime64 = hv_ptp_settime, .owner = THIS_MODULE, }; @@ -592,7 +536,7 @@ static int hv_timesync_init(struct hv_util_service *srv) spin_lock_init(&host_ts.lock); - INIT_WORK(&wrk.work, hv_set_host_time); + INIT_WORK(&adj_time_work, hv_set_host_time); /* * ptp_clock_register() returns NULL when CONFIG_PTP_1588_CLOCK is @@ -613,7 +557,7 @@ static void hv_timesync_deinit(void) { if (hv_ptp_clock) ptp_clock_unregister(hv_ptp_clock); - cancel_work_sync(&wrk.work); + cancel_work_sync(&adj_time_work); } static int __init init_hyperv_utils(void) diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 6113e915c50e..1b6a5e0dfa75 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -303,6 +303,13 @@ enum vmbus_connect_state { #define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT struct vmbus_connection { + /* + * CPU on which the initial host contact was made. + */ + int connect_cpu; + + atomic_t offer_in_progress; + enum vmbus_connect_state conn_state; atomic_t next_gpadl_handle; @@ -411,6 +418,10 @@ static inline void hv_poll_channel(struct vmbus_channel *channel, if (!channel) return; + if (in_interrupt() && (channel->target_cpu == smp_processor_id())) { + cb(channel); + return; + } smp_call_function_single(channel->target_cpu, cb, channel, true); } diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 0087b49095eb..ed84e96715a0 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -608,40 +608,6 @@ static void vmbus_free_dynids(struct hv_driver *drv) spin_unlock(&drv->dynids.lock); } -/* Parse string of form: 1b4e28ba-2fa1-11d2-883f-b9a761bde3f */ -static int get_uuid_le(const char *str, uuid_le *uu) -{ - unsigned int b[16]; - int i; - - if (strlen(str) < 37) - return -1; - - for (i = 0; i < 36; i++) { - switch (i) { - case 8: case 13: case 18: case 23: - if (str[i] != '-') - return -1; - break; - default: - if (!isxdigit(str[i])) - return -1; - } - } - - /* unparse little endian output byte order */ - if (sscanf(str, - "%2x%2x%2x%2x-%2x%2x-%2x%2x-%2x%2x-%2x%2x%2x%2x%2x%2x", - &b[3], &b[2], &b[1], &b[0], - &b[5], &b[4], &b[7], &b[6], &b[8], &b[9], - &b[10], &b[11], &b[12], &b[13], &b[14], &b[15]) != 16) - return -1; - - for (i = 0; i < 16; i++) - uu->b[i] = b[i]; - return 0; -} - /* * store_new_id - sysfs frontend to vmbus_add_dynid() * @@ -651,11 +617,12 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf, size_t count) { struct hv_driver *drv = drv_to_hv_drv(driver); - uuid_le guid = NULL_UUID_LE; + uuid_le guid; ssize_t retval; - if (get_uuid_le(buf, &guid) != 0) - return -EINVAL; + retval = uuid_le_to_bin(buf, &guid); + if (retval) + return retval; if (hv_vmbus_get_id(drv, &guid)) return -EEXIST; @@ -677,12 +644,14 @@ static ssize_t remove_id_store(struct device_driver *driver, const char *buf, { struct hv_driver *drv = drv_to_hv_drv(driver); struct vmbus_dynid *dynid, *n; - uuid_le guid = NULL_UUID_LE; - size_t retval = -ENODEV; + uuid_le guid; + ssize_t retval; - if (get_uuid_le(buf, &guid)) - return -EINVAL; + retval = uuid_le_to_bin(buf, &guid); + if (retval) + return retval; + retval = -ENODEV; spin_lock(&drv->dynids.lock); list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { struct hv_vmbus_device_id *id = &dynid->id; @@ -798,8 +767,10 @@ static void vmbus_device_release(struct device *device) struct hv_device *hv_dev = device_to_hv_device(device); struct vmbus_channel *channel = hv_dev->channel; + mutex_lock(&vmbus_connection.channel_mutex); hv_process_channel_removal(channel, channel->offermsg.child_relid); + mutex_unlock(&vmbus_connection.channel_mutex); kfree(hv_dev); } @@ -877,7 +848,32 @@ void vmbus_on_msg_dpc(unsigned long data) INIT_WORK(&ctx->work, vmbus_onmessage_work); memcpy(&ctx->msg, msg, sizeof(*msg)); - queue_work(vmbus_connection.work_queue, &ctx->work); + /* + * The host can generate a rescind message while we + * may still be handling the original offer. We deal with + * this condition by ensuring the processing is done on the + * same CPU. + */ + switch (hdr->msgtype) { + case CHANNELMSG_RESCIND_CHANNELOFFER: + /* + * If we are handling the rescind message; + * schedule the work on the global work queue. + */ + schedule_work_on(vmbus_connection.connect_cpu, + &ctx->work); + break; + + case CHANNELMSG_OFFERCHANNEL: + atomic_inc(&vmbus_connection.offer_in_progress); + queue_work_on(vmbus_connection.connect_cpu, + vmbus_connection.work_queue, + &ctx->work); + break; + + default: + queue_work(vmbus_connection.work_queue, &ctx->work); + } } else entry->message_handler(hdr); diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c index 12102448fddd..a1e07a77d4e6 100644 --- a/drivers/ipack/ipack.c +++ b/drivers/ipack/ipack.c @@ -212,7 +212,7 @@ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, int bus_nr; struct ipack_bus_device *bus; - bus = kzalloc(sizeof(struct ipack_bus_device), GFP_KERNEL); + bus = kzalloc(sizeof(*bus), GFP_KERNEL); if (!bus) return NULL; @@ -402,7 +402,6 @@ static int ipack_device_read_id(struct ipack_device *dev) * ID ROM contents */ dev->id = kmalloc(dev->id_avail, GFP_KERNEL); if (!dev->id) { - dev_err(&dev->dev, "dev->id alloc failed.\n"); ret = -ENOMEM; goto out; } diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index dfb72ecfa604..c341164edaad 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -32,7 +32,7 @@ #include <linux/delay.h> #include <linux/wait.h> #include <linux/slab.h> -#include <linux/i2c/apds990x.h> +#include <linux/platform_data/apds990x.h> /* Register map */ #define APDS990X_ENABLE 0x00 /* Enable of states and interrupts */ diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c index 845466e45b95..38fcfe219d1c 100644 --- a/drivers/misc/bh1770glc.c +++ b/drivers/misc/bh1770glc.c @@ -27,7 +27,7 @@ #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/mutex.h> -#include <linux/i2c/bh1770glc.h> +#include <linux/platform_data/bh1770glc.h> #include <linux/regulator/consumer.h> #include <linux/pm_runtime.h> #include <linux/workqueue.h> diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index d1928fdd0f43..42078e6be47f 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -1038,7 +1038,7 @@ static void mei_cl_bus_dev_init(struct mei_device *bus, * * @bus: mei device */ -void mei_cl_bus_rescan(struct mei_device *bus) +static void mei_cl_bus_rescan(struct mei_device *bus) { struct mei_cl_device *cldev, *n; struct mei_me_client *me_cl; diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h index e1e4d47d4d7d..5c8286b40b62 100644 --- a/drivers/misc/mei/hw.h +++ b/drivers/misc/mei/hw.h @@ -65,7 +65,7 @@ #define HBM_MAJOR_VERSION_DOT 2 /* - * MEI version with notifcation support + * MEI version with notification support */ #define HBM_MINOR_VERSION_EV 0 #define HBM_MAJOR_VERSION_EV 2 diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 63a67c99fc78..ebcd5132e447 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -306,7 +306,6 @@ struct mei_hw_ops { }; /* MEI bus API*/ -void mei_cl_bus_rescan(struct mei_device *bus); void mei_cl_bus_rescan_work(struct work_struct *work); void mei_cl_bus_dev_fixup(struct mei_cl_device *dev); ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, diff --git a/drivers/misc/sram-exec.c b/drivers/misc/sram-exec.c index 3d528a13b8fc..426ad912b441 100644 --- a/drivers/misc/sram-exec.c +++ b/drivers/misc/sram-exec.c @@ -19,6 +19,7 @@ #include <linux/mm.h> #include <linux/sram.h> +#include <asm/fncpy.h> #include <asm/set_memory.h> #include "sram.h" @@ -58,20 +59,32 @@ int sram_add_protect_exec(struct sram_partition *part) * @src: Source address for the data to copy * @size: Size of copy to perform, which starting from dst, must reside in pool * + * Return: Address for copied data that can safely be called through function + * pointer, or NULL if problem. + * * This helper function allows sram driver to act as central control location * of 'protect-exec' pools which are normal sram pools but are always set * read-only and executable except when copying data to them, at which point * they are set to read-write non-executable, to make sure no memory is * writeable and executable at the same time. This region must be page-aligned * and is checked during probe, otherwise page attribute manipulation would - * not be possible. + * not be possible. Care must be taken to only call the returned address as + * dst address is not guaranteed to be safely callable. + * + * NOTE: This function uses the fncpy macro to move code to the executable + * region. Some architectures have strict requirements for relocating + * executable code, so fncpy is a macro that must be defined by any arch + * making use of this functionality that guarantees a safe copy of exec + * data and returns a safe address that can be called as a C function + * pointer. */ -int sram_exec_copy(struct gen_pool *pool, void *dst, void *src, - size_t size) +void *sram_exec_copy(struct gen_pool *pool, void *dst, void *src, + size_t size) { struct sram_partition *part = NULL, *p; unsigned long base; int pages; + void *dst_cpy; mutex_lock(&exec_pool_list_mutex); list_for_each_entry(p, &exec_pool_list, list) { @@ -81,10 +94,10 @@ int sram_exec_copy(struct gen_pool *pool, void *dst, void *src, mutex_unlock(&exec_pool_list_mutex); if (!part) - return -EINVAL; + return NULL; if (!addr_in_gen_pool(pool, (unsigned long)dst, size)) - return -EINVAL; + return NULL; base = (unsigned long)part->base; pages = PAGE_ALIGN(size) / PAGE_SIZE; @@ -94,13 +107,13 @@ int sram_exec_copy(struct gen_pool *pool, void *dst, void *src, set_memory_nx((unsigned long)base, pages); set_memory_rw((unsigned long)base, pages); - memcpy(dst, src, size); + dst_cpy = fncpy(dst, src, size); set_memory_ro((unsigned long)base, pages); set_memory_x((unsigned long)base, pages); mutex_unlock(&part->lock); - return 0; + return dst_cpy; } EXPORT_SYMBOL_GPL(sram_exec_copy); diff --git a/drivers/platform/goldfish/goldfish_pipe.c b/drivers/platform/goldfish/goldfish_pipe.c index 5f3672153b12..0578d34eec3f 100644 --- a/drivers/platform/goldfish/goldfish_pipe.c +++ b/drivers/platform/goldfish/goldfish_pipe.c @@ -266,7 +266,7 @@ struct goldfish_pipe_dev { unsigned char __iomem *base; }; -struct goldfish_pipe_dev pipe_dev[1] = {}; +static struct goldfish_pipe_dev pipe_dev[1] = {}; static int goldfish_cmd_locked(struct goldfish_pipe *pipe, enum PipeCmdCode cmd) { diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig index 564a51abeece..4b29a7182d7b 100644 --- a/drivers/pps/Kconfig +++ b/drivers/pps/Kconfig @@ -2,9 +2,7 @@ # PPS support configuration # -menu "PPS support" - -config PPS +menuconfig PPS tristate "PPS support" ---help--- PPS (Pulse Per Second) is a special pulse provided by some GPS @@ -20,10 +18,10 @@ config PPS To compile this driver as a module, choose M here: the module will be called pps_core.ko. -if PPS config PPS_DEBUG bool "PPS debugging messages" + depends on PPS help Say Y here if you want the PPS support to produce a bunch of debug messages to the system log. Select this if you are having a @@ -31,17 +29,13 @@ config PPS_DEBUG config NTP_PPS bool "PPS kernel consumer support" - depends on !NO_HZ_COMMON + depends on PPS && !NO_HZ_COMMON help This option adds support for direct in-kernel time synchronization using an external PPS signal. It doesn't work on tickless systems at the moment. -endif - source drivers/pps/clients/Kconfig source drivers/pps/generators/Kconfig - -endmenu diff --git a/drivers/pps/clients/Kconfig b/drivers/pps/clients/Kconfig index 0c9f2805d076..efec021ce662 100644 --- a/drivers/pps/clients/Kconfig +++ b/drivers/pps/clients/Kconfig @@ -2,12 +2,12 @@ # PPS clients configuration # -if PPS - comment "PPS clients support" + depends on PPS config PPS_CLIENT_KTIMER tristate "Kernel timer client (Testing client, use for debug)" + depends on PPS help If you say yes here you get support for a PPS debugging client which uses a kernel timer to generate the PPS signal. @@ -37,5 +37,3 @@ config PPS_CLIENT_GPIO GPIO. To be useful you must also register a platform device specifying the GPIO pin and other options, usually in your board setup. - -endif diff --git a/drivers/pps/generators/Kconfig b/drivers/pps/generators/Kconfig index e4c4f3dc0728..86b59378e71f 100644 --- a/drivers/pps/generators/Kconfig +++ b/drivers/pps/generators/Kconfig @@ -3,10 +3,11 @@ # comment "PPS generators support" + depends on PPS config PPS_GENERATOR_PARPORT tristate "Parallel port PPS signal generator" - depends on PARPORT && BROKEN + depends on PPS && PARPORT && BROKEN help If you say yes here you get support for a PPS signal generator which utilizes STROBE pin of a parallel port to send PPS signals. It uses diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c index d0b508b68f3c..a56fdf972dbe 100644 --- a/drivers/uio/uio_pci_generic.c +++ b/drivers/uio/uio_pci_generic.c @@ -66,14 +66,7 @@ static int probe(struct pci_dev *pdev, return err; } - if (!pdev->irq) { - dev_warn(&pdev->dev, "No IRQ assigned to device: " - "no support for interrupts?\n"); - pci_disable_device(pdev); - return -ENODEV; - } - - if (!pci_intx_mask_supported(pdev)) { + if (pdev->irq && !pci_intx_mask_supported(pdev)) { err = -ENODEV; goto err_verify; } @@ -86,10 +79,15 @@ static int probe(struct pci_dev *pdev, gdev->info.name = "uio_pci_generic"; gdev->info.version = DRIVER_VERSION; - gdev->info.irq = pdev->irq; - gdev->info.irq_flags = IRQF_SHARED; - gdev->info.handler = irqhandler; gdev->pdev = pdev; + if (pdev->irq) { + gdev->info.irq = pdev->irq; + gdev->info.irq_flags = IRQF_SHARED; + gdev->info.handler = irqhandler; + } else { + dev_warn(&pdev->dev, "No IRQ assigned to device: " + "no support for interrupts?\n"); + } err = uio_register_device(&pdev->dev, &gdev->info); if (err) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 3acef3c5d8ed..3f63e03de8e8 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -706,7 +706,7 @@ static const struct file_operations vhost_vsock_fops = { }; static struct miscdevice vhost_vsock_misc = { - .minor = MISC_DYNAMIC_MINOR, + .minor = VHOST_VSOCK_MINOR, .name = "vhost-vsock", .fops = &vhost_vsock_fops, }; @@ -778,3 +778,5 @@ module_exit(vhost_vsock_exit); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Asias He"); MODULE_DESCRIPTION("vhost transport for vsock "); +MODULE_ALIAS_MISCDEV(VHOST_VSOCK_MINOR); +MODULE_ALIAS("devname:vhost-vsock"); diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index 2e30db1b1a43..e8730ea3e3aa 100644 --- a/drivers/w1/masters/ds2482.c +++ b/drivers/w1/masters/ds2482.c @@ -35,6 +35,8 @@ */ static int ds2482_active_pullup = 1; module_param_named(active_pullup, ds2482_active_pullup, int, 0644); +MODULE_PARM_DESC(active_pullup, "Active pullup (apply to all buses): " \ + "0-disable, 1-enable (default)"); /** * The DS2482 registers - there are 3 registers that are addressed by a read @@ -93,30 +95,6 @@ static const u8 ds2482_chan_rd[8] = #define DS2482_REG_STS_PPD 0x02 #define DS2482_REG_STS_1WB 0x01 - -static int ds2482_probe(struct i2c_client *client, - const struct i2c_device_id *id); -static int ds2482_remove(struct i2c_client *client); - - -/** - * Driver data (common to all clients) - */ -static const struct i2c_device_id ds2482_id[] = { - { "ds2482", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ds2482_id); - -static struct i2c_driver ds2482_driver = { - .driver = { - .name = "ds2482", - }, - .probe = ds2482_probe, - .remove = ds2482_remove, - .id_table = ds2482_id, -}; - /* * Client data (each client gets its own) */ @@ -560,10 +538,25 @@ static int ds2482_remove(struct i2c_client *client) return 0; } +/** + * Driver data (common to all clients) + */ +static const struct i2c_device_id ds2482_id[] = { + { "ds2482", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ds2482_id); + +static struct i2c_driver ds2482_driver = { + .driver = { + .name = "ds2482", + }, + .probe = ds2482_probe, + .remove = ds2482_remove, + .id_table = ds2482_id, +}; module_i2c_driver(ds2482_driver); -MODULE_PARM_DESC(active_pullup, "Active pullup (apply to all buses): " \ - "0-disable, 1-enable (default)"); MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>"); MODULE_DESCRIPTION("DS2482 driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c index be77b7914fad..d748e34d4ce5 100644 --- a/drivers/w1/masters/ds2490.c +++ b/drivers/w1/masters/ds2490.c @@ -179,28 +179,9 @@ struct ds_status u8 reserved2; }; -static struct usb_device_id ds_id_table [] = { - { USB_DEVICE(0x04fa, 0x2490) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, ds_id_table); - -static int ds_probe(struct usb_interface *, const struct usb_device_id *); -static void ds_disconnect(struct usb_interface *); - -static int ds_send_control(struct ds_device *, u16, u16); -static int ds_send_control_cmd(struct ds_device *, u16, u16); - static LIST_HEAD(ds_devices); static DEFINE_MUTEX(ds_mutex); -static struct usb_driver ds_driver = { - .name = "DS9490R", - .probe = ds_probe, - .disconnect = ds_disconnect, - .id_table = ds_id_table, -}; - static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) { int err; @@ -1108,8 +1089,20 @@ static void ds_disconnect(struct usb_interface *intf) kfree(dev); } +static struct usb_device_id ds_id_table [] = { + { USB_DEVICE(0x04fa, 0x2490) }, + { }, +}; +MODULE_DEVICE_TABLE(usb, ds_id_table); + +static struct usb_driver ds_driver = { + .name = "DS9490R", + .probe = ds_probe, + .disconnect = ds_disconnect, + .id_table = ds_id_table, +}; module_usb_driver(ds_driver); -MODULE_LICENSE("GPL"); MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); MODULE_DESCRIPTION("DS2490 USB <-> W1 bus master driver (DS9490*)"); +MODULE_LICENSE("GPL"); diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c index 97a676bf5989..f20d03ecfd1d 100644 --- a/drivers/w1/masters/matrox_w1.c +++ b/drivers/w1/masters/matrox_w1.c @@ -37,26 +37,6 @@ #include "../w1.h" #include "../w1_int.h" -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); -MODULE_DESCRIPTION("Driver for transport(Dallas 1-wire protocol) over VGA DDC(matrox gpio)."); - -static struct pci_device_id matrox_w1_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400) }, - { }, -}; -MODULE_DEVICE_TABLE(pci, matrox_w1_tbl); - -static int matrox_w1_probe(struct pci_dev *, const struct pci_device_id *); -static void matrox_w1_remove(struct pci_dev *); - -static struct pci_driver matrox_w1_pci_driver = { - .name = "matrox_w1", - .id_table = matrox_w1_tbl, - .probe = matrox_w1_probe, - .remove = matrox_w1_remove, -}; - /* * Matrox G400 DDC registers. */ @@ -88,9 +68,6 @@ struct matrox_device struct w1_bus_master *bus_master; }; -static u8 matrox_w1_read_ddc_bit(void *); -static void matrox_w1_write_ddc_bit(void *, u8); - /* * These functions read and write DDC Data bit. * @@ -226,4 +203,21 @@ static void matrox_w1_remove(struct pci_dev *pdev) } kfree(dev); } + +static struct pci_device_id matrox_w1_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400) }, + { }, +}; +MODULE_DEVICE_TABLE(pci, matrox_w1_tbl); + +static struct pci_driver matrox_w1_pci_driver = { + .name = "matrox_w1", + .id_table = matrox_w1_tbl, + .probe = matrox_w1_probe, + .remove = matrox_w1_remove, +}; module_pci_driver(matrox_w1_pci_driver); + +MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); +MODULE_DESCRIPTION("Driver for transport(Dallas 1-wire protocol) over VGA DDC(matrox gpio)."); +MODULE_LICENSE("GPL"); diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index fb190c259607..3302cbd2344a 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -53,7 +53,10 @@ #define OMAP_HDQ_MAX_USER 4 static DECLARE_WAIT_QUEUE_HEAD(hdq_wait_queue); + static int w1_id; +module_param(w1_id, int, S_IRUSR); +MODULE_PARM_DESC(w1_id, "1-wire id for the slave detection in HDQ mode"); struct hdq_data { struct device *dev; @@ -76,36 +79,6 @@ struct hdq_data { }; -static int omap_hdq_probe(struct platform_device *pdev); -static int omap_hdq_remove(struct platform_device *pdev); - -static const struct of_device_id omap_hdq_dt_ids[] = { - { .compatible = "ti,omap3-1w" }, - { .compatible = "ti,am4372-hdq" }, - {} -}; -MODULE_DEVICE_TABLE(of, omap_hdq_dt_ids); - -static struct platform_driver omap_hdq_driver = { - .probe = omap_hdq_probe, - .remove = omap_hdq_remove, - .driver = { - .name = "omap_hdq", - .of_match_table = omap_hdq_dt_ids, - }, -}; - -static u8 omap_w1_read_byte(void *_hdq); -static void omap_w1_write_byte(void *_hdq, u8 byte); -static u8 omap_w1_reset_bus(void *_hdq); - - -static struct w1_bus_master omap_w1_master = { - .read_byte = omap_w1_read_byte, - .write_byte = omap_w1_write_byte, - .reset_bus = omap_w1_reset_bus, -}; - /* HDQ register I/O routines */ static inline u8 hdq_reg_in(struct hdq_data *hdq_data, u32 offset) { @@ -678,6 +651,12 @@ static void omap_w1_write_byte(void *_hdq, u8 byte) } } +static struct w1_bus_master omap_w1_master = { + .read_byte = omap_w1_read_byte, + .write_byte = omap_w1_write_byte, + .reset_bus = omap_w1_reset_bus, +}; + static int omap_hdq_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -787,10 +766,22 @@ static int omap_hdq_remove(struct platform_device *pdev) return 0; } -module_platform_driver(omap_hdq_driver); +static const struct of_device_id omap_hdq_dt_ids[] = { + { .compatible = "ti,omap3-1w" }, + { .compatible = "ti,am4372-hdq" }, + {} +}; +MODULE_DEVICE_TABLE(of, omap_hdq_dt_ids); -module_param(w1_id, int, S_IRUSR); -MODULE_PARM_DESC(w1_id, "1-wire id for the slave detection in HDQ mode"); +static struct platform_driver omap_hdq_driver = { + .probe = omap_hdq_probe, + .remove = omap_hdq_remove, + .driver = { + .name = "omap_hdq", + .of_match_table = omap_hdq_dt_ids, + }, +}; +module_platform_driver(omap_hdq_driver); MODULE_AUTHOR("Texas Instruments"); MODULE_DESCRIPTION("HDQ-1W driver Library"); diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c index 9f4a86b754ba..d480900a28ab 100644 --- a/drivers/w1/slaves/w1_bq27000.c +++ b/drivers/w1/slaves/w1_bq27000.c @@ -25,6 +25,8 @@ #define HDQ_CMD_WRITE (1<<7) static int F_ID; +module_param(F_ID, int, S_IRUSR); +MODULE_PARM_DESC(F_ID, "1-wire slave FID for BQ device"); static int w1_bq27000_read(struct device *dev, unsigned int reg) { @@ -106,13 +108,10 @@ static void __exit w1_bq27000_exit(void) w1_unregister_family(&w1_bq27000_family); } - module_init(w1_bq27000_init); module_exit(w1_bq27000_exit); -module_param(F_ID, int, S_IRUSR); -MODULE_PARM_DESC(F_ID, "1-wire slave FID for BQ device"); -MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_BQ27000)); -MODULE_LICENSE("GPL"); MODULE_AUTHOR("Texas Instruments Ltd"); MODULE_DESCRIPTION("HDQ/1-wire slave driver bq27000 battery monitor chip"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_BQ27000)); diff --git a/drivers/w1/slaves/w1_ds2406.c b/drivers/w1/slaves/w1_ds2406.c index 51f2f66d6555..709bd5e02eed 100644 --- a/drivers/w1/slaves/w1_ds2406.c +++ b/drivers/w1/slaves/w1_ds2406.c @@ -21,10 +21,6 @@ #include "../w1_int.h" #include "../w1_family.h" -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Scott Alfter <scott@alfter.us>"); -MODULE_DESCRIPTION("w1 family 12 driver for DS2406 2 Pin IO"); - #define W1_F12_FUNC_READ_STATUS 0xAA #define W1_F12_FUNC_WRITE_STATUS 0x55 @@ -154,3 +150,7 @@ static struct w1_family w1_family_12 = { .fops = &w1_f12_fops, }; module_w1_family(w1_family_12); + +MODULE_AUTHOR("Scott Alfter <scott@alfter.us>"); +MODULE_DESCRIPTION("w1 family 12 driver for DS2406 2 Pin IO"); +MODULE_LICENSE("GPL"); diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index aec5958e66e9..e01d2b3997bc 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c @@ -19,12 +19,6 @@ #include "../w1_int.h" #include "../w1_family.h" -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 #define W1_F29_REG_LOGIG_STATE 0x88 /* R */ @@ -352,3 +346,8 @@ static struct w1_family w1_family_29 = { .fops = &w1_f29_fops, }; module_w1_family(w1_family_29); + +MODULE_AUTHOR("Jean-Francois Dagenais <dagenaisj@sonatest.com>"); +MODULE_DESCRIPTION("w1 family 29 driver for DS2408 8 Pin IO"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2408)); diff --git a/drivers/w1/slaves/w1_ds2413.c b/drivers/w1/slaves/w1_ds2413.c index f2e1c51533b9..9cc6f0bc2e95 100644 --- a/drivers/w1/slaves/w1_ds2413.c +++ b/drivers/w1/slaves/w1_ds2413.c @@ -20,11 +20,6 @@ #include "../w1_int.h" #include "../w1_family.h" -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 #define W1_F3A_FUNC_PIO_ACCESS_WRITE 0x5A @@ -136,3 +131,8 @@ static struct w1_family w1_family_3a = { .fops = &w1_f3a_fops, }; module_w1_family(w1_family_3a); + +MODULE_AUTHOR("Mariusz Bialonczyk <manio@skyboo.net>"); +MODULE_DESCRIPTION("w1 family 3a driver for DS2413 2 Pin IO"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2413)); diff --git a/drivers/w1/slaves/w1_ds2423.c b/drivers/w1/slaves/w1_ds2423.c index 4ab54fd9dde2..306240fe496c 100644 --- a/drivers/w1/slaves/w1_ds2423.c +++ b/drivers/w1/slaves/w1_ds2423.c @@ -140,7 +140,7 @@ static struct w1_family w1_family_1d = { }; module_w1_family(w1_family_1d); -MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mika Laitio <lamikr@pilppa.org>"); MODULE_DESCRIPTION("w1 family 1d driver for DS2423, 4 counters and 4kb ram"); +MODULE_LICENSE("GPL"); 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 80572cb63ba8..20182d4a4b19 100644 --- a/drivers/w1/slaves/w1_ds2431.c +++ b/drivers/w1/slaves/w1_ds2431.c @@ -290,7 +290,7 @@ static struct w1_family w1_family_2d = { }; module_w1_family(w1_family_2d); -MODULE_LICENSE("GPL"); MODULE_AUTHOR("Bernhard Weirich <bernhard.weirich@riedel.net>"); MODULE_DESCRIPTION("w1 family 2d driver for DS2431, 1kb EEPROM"); +MODULE_LICENSE("GPL"); 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 6cf378c89ecb..86c30aceea3e 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c @@ -26,11 +26,6 @@ #include "../w1_int.h" #include "../w1_family.h" -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 #define W1_PAGE_SIZE 32 @@ -306,3 +301,8 @@ static struct w1_family w1_family_23 = { .fops = &w1_f23_fops, }; module_w1_family(w1_family_23); + +MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>"); +MODULE_DESCRIPTION("w1 family 23 driver for DS2433, 4kb EEPROM"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("w1-family-" __stringify(W1_EEPROM_DS2433)); diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index ffa37f773b3b..f35d1e2ef9bb 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c @@ -63,11 +63,13 @@ int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count) { return w1_ds2760_io(dev, buf, addr, count, 0); } +EXPORT_SYMBOL(w1_ds2760_read); int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count) { return w1_ds2760_io(dev, buf, addr, count, 1); } +EXPORT_SYMBOL(w1_ds2760_write); static int w1_ds2760_eeprom_cmd(struct device *dev, int addr, int cmd) { @@ -91,11 +93,13 @@ int w1_ds2760_store_eeprom(struct device *dev, int addr) { return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_COPY_DATA); } +EXPORT_SYMBOL(w1_ds2760_store_eeprom); int w1_ds2760_recall_eeprom(struct device *dev, int addr) { return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA); } +EXPORT_SYMBOL(w1_ds2760_recall_eeprom); static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, @@ -164,12 +168,7 @@ static struct w1_family w1_ds2760_family = { }; module_w1_family(w1_ds2760_family); -EXPORT_SYMBOL(w1_ds2760_read); -EXPORT_SYMBOL(w1_ds2760_write); -EXPORT_SYMBOL(w1_ds2760_store_eeprom); -EXPORT_SYMBOL(w1_ds2760_recall_eeprom); - -MODULE_LICENSE("GPL"); MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>"); MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip"); +MODULE_LICENSE("GPL"); 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 f5c2aa429a92..292972212107 100644 --- a/drivers/w1/slaves/w1_ds2780.c +++ b/drivers/w1/slaves/w1_ds2780.c @@ -156,7 +156,7 @@ static struct w1_family w1_ds2780_family = { }; module_w1_family(w1_ds2780_family); -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_LICENSE("GPL"); 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 9c03e014cf9e..a5d75067b230 100644 --- a/drivers/w1/slaves/w1_ds2781.c +++ b/drivers/w1/slaves/w1_ds2781.c @@ -153,7 +153,7 @@ static struct w1_family w1_ds2781_family = { }; module_w1_family(w1_ds2781_family); -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_LICENSE("GPL"); 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 5e348d38ec5c..c62858c05e8f 100644 --- a/drivers/w1/slaves/w1_ds28e04.c +++ b/drivers/w1/slaves/w1_ds28e04.c @@ -24,11 +24,6 @@ #include "../w1_int.h" #include "../w1_family.h" -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 * current to copy the data from the scratchpad to EEPROM. If it is enabled @@ -428,3 +423,8 @@ static struct w1_family w1_family_1C = { .fops = &w1_f1C_fops, }; module_w1_family(w1_family_1C); + +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_LICENSE("GPL"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS28E04)); diff --git a/drivers/w1/slaves/w1_smem.c b/drivers/w1/slaves/w1_smem.c index ed4c87506def..99b03bfb9941 100644 --- a/drivers/w1/slaves/w1_smem.c +++ b/drivers/w1/slaves/w1_smem.c @@ -31,12 +31,6 @@ #include "../w1_int.h" #include "../w1_family.h" -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, }; @@ -70,3 +64,9 @@ static void __exit w1_smem_fini(void) module_init(w1_smem_init); module_exit(w1_smem_fini); + +MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); +MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family."); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_SMEM_01)); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_SMEM_81)); diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 82611f197b0a..ccaf29994a42 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -34,15 +34,6 @@ #include "../w1_int.h" #include "../w1_family.h" -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 * current to do a temperature conversion. If it is enabled parasite powered @@ -646,3 +637,12 @@ static void __exit w1_therm_fini(void) module_init(w1_therm_init); module_exit(w1_therm_fini); + +MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); +MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family."); +MODULE_LICENSE("GPL"); +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)); diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 8511d1685db9..8172dee5e23c 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -33,20 +33,15 @@ #include "w1_family.h" #include "w1_netlink.h" -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); -MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); - static int w1_timeout = 10; -static int w1_timeout_us = 0; -int w1_max_slave_count = 64; -int w1_max_slave_ttl = 10; - module_param_named(timeout, w1_timeout, int, 0); MODULE_PARM_DESC(timeout, "time in seconds between automatic slave searches"); + +static int w1_timeout_us = 0; module_param_named(timeout_us, w1_timeout_us, int, 0); MODULE_PARM_DESC(timeout_us, "time in microseconds between automatic slave searches"); + /* A search stops when w1_max_slave_count devices have been found in that * search. The next search will start over and detect the same set of devices * on a static 1-wire bus. Memory is not allocated based on this number, just @@ -55,9 +50,12 @@ MODULE_PARM_DESC(timeout_us, * device on the network and w1_max_slave_count is set to 1, the device id can * be read directly skipping the normal slower search process. */ +int w1_max_slave_count = 64; module_param_named(max_slave_count, w1_max_slave_count, int, 0); MODULE_PARM_DESC(max_slave_count, "maximum number of slaves detected in a search"); + +int w1_max_slave_ttl = 10; module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); MODULE_PARM_DESC(slave_ttl, "Number of searches not seeing a slave before it will be removed"); @@ -1228,3 +1226,7 @@ static void __exit w1_fini(void) module_init(w1_init); module_exit(w1_fini); + +MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); +MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); +MODULE_LICENSE("GPL"); diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c index 2096f460498f..9759cdaf22f4 100644 --- a/drivers/w1/w1_family.c +++ b/drivers/w1/w1_family.c @@ -55,6 +55,7 @@ int w1_register_family(struct w1_family *newf) return ret; } +EXPORT_SYMBOL(w1_register_family); /** * w1_unregister_family() - unregister a device family driver @@ -87,6 +88,7 @@ void w1_unregister_family(struct w1_family *fent) flush_signals(current); } } +EXPORT_SYMBOL(w1_unregister_family); /* * Should be called under w1_flock held. @@ -136,6 +138,3 @@ void __w1_family_get(struct w1_family *f) atomic_inc(&f->refcnt); smp_mb__after_atomic(); } - -EXPORT_SYMBOL(w1_unregister_family); -EXPORT_SYMBOL(w1_register_family); diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 1072a2e620bb..4439d10709bb 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c @@ -179,6 +179,7 @@ err_out_free_dev: return retval; } +EXPORT_SYMBOL(w1_add_master_device); void __w1_remove_master_device(struct w1_master *dev) { @@ -251,6 +252,4 @@ void w1_remove_master_device(struct w1_bus_master *bm) __w1_remove_master_device(found); } - -EXPORT_SYMBOL(w1_add_master_device); EXPORT_SYMBOL(w1_remove_master_device); diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index 762b5fec3383..58751eae5f77 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -54,6 +54,7 @@ #define VHOST_NET_MINOR 238 #define UHID_MINOR 239 #define USERIO_MINOR 240 +#define VHOST_VSOCK_MINOR 241 #define MISC_DYNAMIC_MINOR 255 struct device; diff --git a/include/linux/i2c/apds990x.h b/include/linux/platform_data/apds990x.h index d186fcc5d257..d186fcc5d257 100644 --- a/include/linux/i2c/apds990x.h +++ b/include/linux/platform_data/apds990x.h diff --git a/include/linux/i2c/bh1770glc.h b/include/linux/platform_data/bh1770glc.h index 8b5e2df36c72..8b5e2df36c72 100644 --- a/include/linux/i2c/bh1770glc.h +++ b/include/linux/platform_data/bh1770glc.h diff --git a/include/linux/sram.h b/include/linux/sram.h index c97dcbe8ce25..4fb405fb0480 100644 --- a/include/linux/sram.h +++ b/include/linux/sram.h @@ -16,12 +16,12 @@ struct gen_pool; #ifdef CONFIG_SRAM_EXEC -int sram_exec_copy(struct gen_pool *pool, void *dst, void *src, size_t size); +void *sram_exec_copy(struct gen_pool *pool, void *dst, void *src, size_t size); #else -static inline int sram_exec_copy(struct gen_pool *pool, void *dst, void *src, - size_t size) +static inline void *sram_exec_copy(struct gen_pool *pool, void *dst, void *src, + size_t size) { - return -ENODEV; + return NULL; } #endif /* CONFIG_SRAM_EXEC */ #endif /* __LINUX_SRAM_H__ */ diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index f1758fcbc37d..88b20e007c05 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -39,6 +39,7 @@ #include <fcntl.h> #include <dirent.h> #include <net/if.h> +#include <limits.h> #include <getopt.h> /* @@ -97,6 +98,8 @@ static struct utsname uts_buf; #define KVP_SCRIPTS_PATH "/usr/libexec/hypervkvpd/" #endif +#define KVP_NET_DIR "/sys/class/net/" + #define MAX_FILE_NAME 100 #define ENTRIES_PER_BLOCK 50 @@ -596,26 +599,21 @@ static char *kvp_get_if_name(char *guid) DIR *dir; struct dirent *entry; FILE *file; - char *p, *q, *x; + char *p, *x; char *if_name = NULL; char buf[256]; - char *kvp_net_dir = "/sys/class/net/"; - char dev_id[256]; + char dev_id[PATH_MAX]; - dir = opendir(kvp_net_dir); + dir = opendir(KVP_NET_DIR); if (dir == NULL) return NULL; - snprintf(dev_id, sizeof(dev_id), "%s", kvp_net_dir); - q = dev_id + strlen(kvp_net_dir); - while ((entry = readdir(dir)) != NULL) { /* * Set the state for the next pass. */ - *q = '\0'; - strcat(dev_id, entry->d_name); - strcat(dev_id, "/device/device_id"); + snprintf(dev_id, sizeof(dev_id), "%s%s/device/device_id", + KVP_NET_DIR, entry->d_name); file = fopen(dev_id, "r"); if (file == NULL) @@ -653,12 +651,12 @@ static char *kvp_if_name_to_mac(char *if_name) FILE *file; char *p, *x; char buf[256]; - char addr_file[256]; + char addr_file[PATH_MAX]; unsigned int i; char *mac_addr = NULL; - snprintf(addr_file, sizeof(addr_file), "%s%s%s", "/sys/class/net/", - if_name, "/address"); + snprintf(addr_file, sizeof(addr_file), "%s%s%s", KVP_NET_DIR, + if_name, "/address"); file = fopen(addr_file, "r"); if (file == NULL) @@ -688,28 +686,22 @@ static char *kvp_mac_to_if_name(char *mac) DIR *dir; struct dirent *entry; FILE *file; - char *p, *q, *x; + char *p, *x; char *if_name = NULL; char buf[256]; - char *kvp_net_dir = "/sys/class/net/"; - char dev_id[256]; + char dev_id[PATH_MAX]; unsigned int i; - dir = opendir(kvp_net_dir); + dir = opendir(KVP_NET_DIR); if (dir == NULL) return NULL; - snprintf(dev_id, sizeof(dev_id), "%s", kvp_net_dir); - q = dev_id + strlen(kvp_net_dir); - while ((entry = readdir(dir)) != NULL) { /* * Set the state for the next pass. */ - *q = '\0'; - - strcat(dev_id, entry->d_name); - strcat(dev_id, "/address"); + snprintf(dev_id, sizeof(dev_id), "%s%s/address", KVP_NET_DIR, + entry->d_name); file = fopen(dev_id, "r"); if (file == NULL) @@ -1218,9 +1210,9 @@ static int process_ip_string(FILE *f, char *ip_string, int type) static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val) { int error = 0; - char if_file[128]; + char if_file[PATH_MAX]; FILE *file; - char cmd[512]; + char cmd[PATH_MAX]; char *mac_addr; /* diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index e0829809c897..7ba54195934c 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -261,7 +261,9 @@ int main(int argc, char *argv[]) if (len != sizeof(struct hv_vss_msg)) { syslog(LOG_ERR, "write failed; error: %d %s", errno, strerror(errno)); - exit(EXIT_FAILURE); + + if (op == VSS_OP_FREEZE) + vss_operate(VSS_OP_THAW); } } |