Commit 2310673c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'char-misc-5.2-rc1-part1' of...

Merge tag 'char-misc-5.2-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc update part 1 from Greg KH:
 "This contains only a small number of bugfixes that would have gone to
  you for 5.1-rc8 if that had happened, but instead I let them sit in
  linux-next for an extra week just "to be sure".

  The "big" patch here is for hyper-v, fixing a bug in their sysfs files
  that could cause big problems. The others are all small fixes,
  resolving reported issues that showed up in 5.1-rcs, plus some odd
  'static' cleanups for the phy drivers that really should have waited
  for -rc1. Most of these are tagged for the stable trees, so 5.1 will
  pick them up.

  All of these have been in linux-next for a while, with no reported
  issues"

* tag 'char-misc-5.2-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  misc: rtsx: Fixed rts5260 power saving parameter and sd glitch
  binder: take read mode of mmap_sem in binder_alloc_free_page()
  intel_th: pci: Add Comet Lake support
  stm class: Fix channel bitmap on 32-bit systems
  stm class: Fix channel free in stm output free path
  phy: sun4i-usb: Make sure to disable PHY0 passby for peripheral mode
  phy: fix platform_no_drv_owner.cocci warnings
  phy: mapphone-mdm6600: add gpiolib dependency
  phy: ti: usb2: fix OMAP_CONTROL_PHY dependency
  phy: allwinner: allow compile testing
  phy: qcom-ufs: Make ufs_qcom_phy_disable_iface_clk static
  phy: rockchip-typec: Make usb3_pll_cfg and dp_pll_cfg static
  phy: phy-twl4030-usb: Fix cable state handling
  Drivers: hv: vmbus: Remove the undesired put_cpu_ptr() in hv_synic_cleanup()
  Drivers: hv: vmbus: Fix race condition with new ring_buffer_info mutex
  Drivers: hv: vmbus: Set ring_info field to 0 and remove memset
  Drivers: hv: vmbus: Refactor chan->state if statement
  Drivers: hv: vmbus: Expose monitor data only when monitor pages are used
parents e0dccbdf 24f1bc28
...@@ -81,7 +81,9 @@ What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/latency ...@@ -81,7 +81,9 @@ What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/latency
Date: September. 2017 Date: September. 2017
KernelVersion: 4.14 KernelVersion: 4.14
Contact: Stephen Hemminger <sthemmin@microsoft.com> Contact: Stephen Hemminger <sthemmin@microsoft.com>
Description: Channel signaling latency Description: Channel signaling latency. This file is available only for
performance critical channels (storage, network, etc.) that use
the monitor page mechanism.
Users: Debugging tools Users: Debugging tools
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/out_mask What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/out_mask
...@@ -95,7 +97,9 @@ What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/pending ...@@ -95,7 +97,9 @@ What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/pending
Date: September. 2017 Date: September. 2017
KernelVersion: 4.14 KernelVersion: 4.14
Contact: Stephen Hemminger <sthemmin@microsoft.com> Contact: Stephen Hemminger <sthemmin@microsoft.com>
Description: Channel interrupt pending state Description: Channel interrupt pending state. This file is available only for
performance critical channels (storage, network, etc.) that use
the monitor page mechanism.
Users: Debugging tools Users: Debugging tools
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/read_avail What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/read_avail
...@@ -137,7 +141,9 @@ What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/monitor_id ...@@ -137,7 +141,9 @@ What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/monitor_id
Date: January. 2018 Date: January. 2018
KernelVersion: 4.16 KernelVersion: 4.16
Contact: Stephen Hemminger <sthemmin@microsoft.com> Contact: Stephen Hemminger <sthemmin@microsoft.com>
Description: Monitor bit associated with channel Description: Monitor bit associated with channel. This file is available only
for performance critical channels (storage, network, etc.) that
use the monitor page mechanism.
Users: Debugging tools and userspace drivers Users: Debugging tools and userspace drivers
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/ring What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/ring
......
...@@ -931,8 +931,8 @@ enum lru_status binder_alloc_free_page(struct list_head *item, ...@@ -931,8 +931,8 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
mm = alloc->vma_vm_mm; mm = alloc->vma_vm_mm;
if (!mmget_not_zero(mm)) if (!mmget_not_zero(mm))
goto err_mmget; goto err_mmget;
if (!down_write_trylock(&mm->mmap_sem)) if (!down_read_trylock(&mm->mmap_sem))
goto err_down_write_mmap_sem_failed; goto err_down_read_mmap_sem_failed;
vma = binder_alloc_get_vma(alloc); vma = binder_alloc_get_vma(alloc);
list_lru_isolate(lru, item); list_lru_isolate(lru, item);
...@@ -945,7 +945,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, ...@@ -945,7 +945,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
trace_binder_unmap_user_end(alloc, index); trace_binder_unmap_user_end(alloc, index);
} }
up_write(&mm->mmap_sem); up_read(&mm->mmap_sem);
mmput(mm); mmput(mm);
trace_binder_unmap_kernel_start(alloc, index); trace_binder_unmap_kernel_start(alloc, index);
...@@ -959,7 +959,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, ...@@ -959,7 +959,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
mutex_unlock(&alloc->mutex); mutex_unlock(&alloc->mutex);
return LRU_REMOVED_RETRY; return LRU_REMOVED_RETRY;
err_down_write_mmap_sem_failed: err_down_read_mmap_sem_failed:
mmput_async(mm); mmput_async(mm);
err_mmget: err_mmget:
err_page_already_freed: err_page_already_freed:
......
...@@ -336,6 +336,8 @@ static struct vmbus_channel *alloc_channel(void) ...@@ -336,6 +336,8 @@ static struct vmbus_channel *alloc_channel(void)
tasklet_init(&channel->callback_event, tasklet_init(&channel->callback_event,
vmbus_on_event, (unsigned long)channel); vmbus_on_event, (unsigned long)channel);
hv_ringbuffer_pre_init(channel);
return channel; return channel;
} }
...@@ -345,6 +347,7 @@ static struct vmbus_channel *alloc_channel(void) ...@@ -345,6 +347,7 @@ static struct vmbus_channel *alloc_channel(void)
static void free_channel(struct vmbus_channel *channel) static void free_channel(struct vmbus_channel *channel)
{ {
tasklet_kill(&channel->callback_event); tasklet_kill(&channel->callback_event);
vmbus_remove_channel_attr_group(channel);
kobject_put(&channel->kobj); kobject_put(&channel->kobj);
} }
......
...@@ -408,7 +408,6 @@ int hv_synic_cleanup(unsigned int cpu) ...@@ -408,7 +408,6 @@ int hv_synic_cleanup(unsigned int cpu)
clockevents_unbind_device(hv_cpu->clk_evt, cpu); clockevents_unbind_device(hv_cpu->clk_evt, cpu);
hv_ce_shutdown(hv_cpu->clk_evt); hv_ce_shutdown(hv_cpu->clk_evt);
put_cpu_ptr(hv_cpu);
} }
hv_get_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64); hv_get_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
......
...@@ -193,6 +193,7 @@ extern void hv_synic_clockevents_cleanup(void); ...@@ -193,6 +193,7 @@ extern void hv_synic_clockevents_cleanup(void);
/* Interface */ /* Interface */
void hv_ringbuffer_pre_init(struct vmbus_channel *channel);
int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
struct page *pages, u32 pagecnt); struct page *pages, u32 pagecnt);
...@@ -321,6 +322,8 @@ void vmbus_device_unregister(struct hv_device *device_obj); ...@@ -321,6 +322,8 @@ void vmbus_device_unregister(struct hv_device *device_obj);
int vmbus_add_channel_kobj(struct hv_device *device_obj, int vmbus_add_channel_kobj(struct hv_device *device_obj,
struct vmbus_channel *channel); struct vmbus_channel *channel);
void vmbus_remove_channel_attr_group(struct vmbus_channel *channel);
struct vmbus_channel *relid2channel(u32 relid); struct vmbus_channel *relid2channel(u32 relid);
void vmbus_free_channels(void); void vmbus_free_channels(void);
......
...@@ -166,14 +166,18 @@ hv_get_ringbuffer_availbytes(const struct hv_ring_buffer_info *rbi, ...@@ -166,14 +166,18 @@ hv_get_ringbuffer_availbytes(const struct hv_ring_buffer_info *rbi,
} }
/* Get various debug metrics for the specified ring buffer. */ /* Get various debug metrics for the specified ring buffer. */
int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info, int hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
struct hv_ring_buffer_debug_info *debug_info) struct hv_ring_buffer_debug_info *debug_info)
{ {
u32 bytes_avail_towrite; u32 bytes_avail_towrite;
u32 bytes_avail_toread; u32 bytes_avail_toread;
if (!ring_info->ring_buffer) mutex_lock(&ring_info->ring_buffer_mutex);
if (!ring_info->ring_buffer) {
mutex_unlock(&ring_info->ring_buffer_mutex);
return -EINVAL; return -EINVAL;
}
hv_get_ringbuffer_availbytes(ring_info, hv_get_ringbuffer_availbytes(ring_info,
&bytes_avail_toread, &bytes_avail_toread,
...@@ -184,10 +188,19 @@ int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info, ...@@ -184,10 +188,19 @@ int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
debug_info->current_write_index = ring_info->ring_buffer->write_index; debug_info->current_write_index = ring_info->ring_buffer->write_index;
debug_info->current_interrupt_mask debug_info->current_interrupt_mask
= ring_info->ring_buffer->interrupt_mask; = ring_info->ring_buffer->interrupt_mask;
mutex_unlock(&ring_info->ring_buffer_mutex);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(hv_ringbuffer_get_debuginfo); EXPORT_SYMBOL_GPL(hv_ringbuffer_get_debuginfo);
/* Initialize a channel's ring buffer info mutex locks */
void hv_ringbuffer_pre_init(struct vmbus_channel *channel)
{
mutex_init(&channel->inbound.ring_buffer_mutex);
mutex_init(&channel->outbound.ring_buffer_mutex);
}
/* Initialize the ring buffer. */ /* Initialize the ring buffer. */
int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
struct page *pages, u32 page_cnt) struct page *pages, u32 page_cnt)
...@@ -197,8 +210,6 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, ...@@ -197,8 +210,6 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
BUILD_BUG_ON((sizeof(struct hv_ring_buffer) != PAGE_SIZE)); BUILD_BUG_ON((sizeof(struct hv_ring_buffer) != PAGE_SIZE));
memset(ring_info, 0, sizeof(struct hv_ring_buffer_info));
/* /*
* First page holds struct hv_ring_buffer, do wraparound mapping for * First page holds struct hv_ring_buffer, do wraparound mapping for
* the rest. * the rest.
...@@ -232,6 +243,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, ...@@ -232,6 +243,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
reciprocal_value(ring_info->ring_size / 10); reciprocal_value(ring_info->ring_size / 10);
ring_info->ring_datasize = ring_info->ring_size - ring_info->ring_datasize = ring_info->ring_size -
sizeof(struct hv_ring_buffer); sizeof(struct hv_ring_buffer);
ring_info->priv_read_index = 0;
spin_lock_init(&ring_info->ring_lock); spin_lock_init(&ring_info->ring_lock);
...@@ -241,8 +253,10 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, ...@@ -241,8 +253,10 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
/* Cleanup the ring buffer. */ /* Cleanup the ring buffer. */
void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info) void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
{ {
mutex_lock(&ring_info->ring_buffer_mutex);
vunmap(ring_info->ring_buffer); vunmap(ring_info->ring_buffer);
ring_info->ring_buffer = NULL; ring_info->ring_buffer = NULL;
mutex_unlock(&ring_info->ring_buffer_mutex);
} }
/* Write to the ring buffer. */ /* Write to the ring buffer. */
......
...@@ -630,7 +630,36 @@ static struct attribute *vmbus_dev_attrs[] = { ...@@ -630,7 +630,36 @@ static struct attribute *vmbus_dev_attrs[] = {
&dev_attr_driver_override.attr, &dev_attr_driver_override.attr,
NULL, NULL,
}; };
ATTRIBUTE_GROUPS(vmbus_dev);
/*
* Device-level attribute_group callback function. Returns the permission for
* each attribute, and returns 0 if an attribute is not visible.
*/
static umode_t vmbus_dev_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int idx)
{
struct device *dev = kobj_to_dev(kobj);
const struct hv_device *hv_dev = device_to_hv_device(dev);
/* Hide the monitor attributes if the monitor mechanism is not used. */
if (!hv_dev->channel->offermsg.monitor_allocated &&
(attr == &dev_attr_monitor_id.attr ||
attr == &dev_attr_server_monitor_pending.attr ||
attr == &dev_attr_client_monitor_pending.attr ||
attr == &dev_attr_server_monitor_latency.attr ||
attr == &dev_attr_client_monitor_latency.attr ||
attr == &dev_attr_server_monitor_conn_id.attr ||
attr == &dev_attr_client_monitor_conn_id.attr))
return 0;
return attr->mode;
}
static const struct attribute_group vmbus_dev_group = {
.attrs = vmbus_dev_attrs,
.is_visible = vmbus_dev_attr_is_visible
};
__ATTRIBUTE_GROUPS(vmbus_dev);
/* /*
* vmbus_uevent - add uevent for our device * vmbus_uevent - add uevent for our device
...@@ -1381,7 +1410,7 @@ static void vmbus_chan_release(struct kobject *kobj) ...@@ -1381,7 +1410,7 @@ static void vmbus_chan_release(struct kobject *kobj)
struct vmbus_chan_attribute { struct vmbus_chan_attribute {
struct attribute attr; struct attribute attr;
ssize_t (*show)(const struct vmbus_channel *chan, char *buf); ssize_t (*show)(struct vmbus_channel *chan, char *buf);
ssize_t (*store)(struct vmbus_channel *chan, ssize_t (*store)(struct vmbus_channel *chan,
const char *buf, size_t count); const char *buf, size_t count);
}; };
...@@ -1400,15 +1429,12 @@ static ssize_t vmbus_chan_attr_show(struct kobject *kobj, ...@@ -1400,15 +1429,12 @@ static ssize_t vmbus_chan_attr_show(struct kobject *kobj,
{ {
const struct vmbus_chan_attribute *attribute const struct vmbus_chan_attribute *attribute
= container_of(attr, struct vmbus_chan_attribute, attr); = container_of(attr, struct vmbus_chan_attribute, attr);
const struct vmbus_channel *chan struct vmbus_channel *chan
= container_of(kobj, struct vmbus_channel, kobj); = container_of(kobj, struct vmbus_channel, kobj);
if (!attribute->show) if (!attribute->show)
return -EIO; return -EIO;
if (chan->state != CHANNEL_OPENED_STATE)
return -EINVAL;
return attribute->show(chan, buf); return attribute->show(chan, buf);
} }
...@@ -1416,45 +1442,81 @@ static const struct sysfs_ops vmbus_chan_sysfs_ops = { ...@@ -1416,45 +1442,81 @@ static const struct sysfs_ops vmbus_chan_sysfs_ops = {
.show = vmbus_chan_attr_show, .show = vmbus_chan_attr_show,
}; };
static ssize_t out_mask_show(const struct vmbus_channel *channel, char *buf) static ssize_t out_mask_show(struct vmbus_channel *channel, char *buf)
{ {
const struct hv_ring_buffer_info *rbi = &channel->outbound; struct hv_ring_buffer_info *rbi = &channel->outbound;
ssize_t ret;
mutex_lock(&rbi->ring_buffer_mutex);
if (!rbi->ring_buffer) {
mutex_unlock(&rbi->ring_buffer_mutex);
return -EINVAL;
}
return sprintf(buf, "%u\n", rbi->ring_buffer->interrupt_mask); ret = sprintf(buf, "%u\n", rbi->ring_buffer->interrupt_mask);
mutex_unlock(&rbi->ring_buffer_mutex);
return ret;
} }
static VMBUS_CHAN_ATTR_RO(out_mask); static VMBUS_CHAN_ATTR_RO(out_mask);
static ssize_t in_mask_show(const struct vmbus_channel *channel, char *buf) static ssize_t in_mask_show(struct vmbus_channel *channel, char *buf)
{ {
const struct hv_ring_buffer_info *rbi = &channel->inbound; struct hv_ring_buffer_info *rbi = &channel->inbound;
ssize_t ret;
mutex_lock(&rbi->ring_buffer_mutex);
if (!rbi->ring_buffer) {
mutex_unlock(&rbi->ring_buffer_mutex);
return -EINVAL;
}
return sprintf(buf, "%u\n", rbi->ring_buffer->interrupt_mask); ret = sprintf(buf, "%u\n", rbi->ring_buffer->interrupt_mask);
mutex_unlock(&rbi->ring_buffer_mutex);
return ret;
} }
static VMBUS_CHAN_ATTR_RO(in_mask); static VMBUS_CHAN_ATTR_RO(in_mask);
static ssize_t read_avail_show(const struct vmbus_channel *channel, char *buf) static ssize_t read_avail_show(struct vmbus_channel *channel, char *buf)
{ {
const struct hv_ring_buffer_info *rbi = &channel->inbound; struct hv_ring_buffer_info *rbi = &channel->inbound;
ssize_t ret;
mutex_lock(&rbi->ring_buffer_mutex);
if (!rbi->ring_buffer) {
mutex_unlock(&rbi->ring_buffer_mutex);
return -EINVAL;
}
return sprintf(buf, "%u\n", hv_get_bytes_to_read(rbi)); ret = sprintf(buf, "%u\n", hv_get_bytes_to_read(rbi));
mutex_unlock(&rbi->ring_buffer_mutex);
return ret;
} }
static VMBUS_CHAN_ATTR_RO(read_avail); static VMBUS_CHAN_ATTR_RO(read_avail);
static ssize_t write_avail_show(const struct vmbus_channel *channel, char *buf) static ssize_t write_avail_show(struct vmbus_channel *channel, char *buf)
{ {
const struct hv_ring_buffer_info *rbi = &channel->outbound; struct hv_ring_buffer_info *rbi = &channel->outbound;
ssize_t ret;
mutex_lock(&rbi->ring_buffer_mutex);
if (!rbi->ring_buffer) {
mutex_unlock(&rbi->ring_buffer_mutex);
return -EINVAL;
}
return sprintf(buf, "%u\n", hv_get_bytes_to_write(rbi)); ret = sprintf(buf, "%u\n", hv_get_bytes_to_write(rbi));
mutex_unlock(&rbi->ring_buffer_mutex);
return ret;
} }
static VMBUS_CHAN_ATTR_RO(write_avail); static VMBUS_CHAN_ATTR_RO(write_avail);
static ssize_t show_target_cpu(const struct vmbus_channel *channel, char *buf) static ssize_t show_target_cpu(struct vmbus_channel *channel, char *buf)
{ {
return sprintf(buf, "%u\n", channel->target_cpu); return sprintf(buf, "%u\n", channel->target_cpu);
} }
static VMBUS_CHAN_ATTR(cpu, S_IRUGO, show_target_cpu, NULL); static VMBUS_CHAN_ATTR(cpu, S_IRUGO, show_target_cpu, NULL);
static ssize_t channel_pending_show(const struct vmbus_channel *channel, static ssize_t channel_pending_show(struct vmbus_channel *channel,
char *buf) char *buf)
{ {
return sprintf(buf, "%d\n", return sprintf(buf, "%d\n",
...@@ -1463,7 +1525,7 @@ static ssize_t channel_pending_show(const struct vmbus_channel *channel, ...@@ -1463,7 +1525,7 @@ static ssize_t channel_pending_show(const struct vmbus_channel *channel,
} }
static VMBUS_CHAN_ATTR(pending, S_IRUGO, channel_pending_show, NULL); static VMBUS_CHAN_ATTR(pending, S_IRUGO, channel_pending_show, NULL);
static ssize_t channel_latency_show(const struct vmbus_channel *channel, static ssize_t channel_latency_show(struct vmbus_channel *channel,
char *buf) char *buf)
{ {
return sprintf(buf, "%d\n", return sprintf(buf, "%d\n",
...@@ -1472,19 +1534,19 @@ static ssize_t channel_latency_show(const struct vmbus_channel *channel, ...@@ -1472,19 +1534,19 @@ static ssize_t channel_latency_show(const struct vmbus_channel *channel,
} }
static VMBUS_CHAN_ATTR(latency, S_IRUGO, channel_latency_show, NULL); static VMBUS_CHAN_ATTR(latency, S_IRUGO, channel_latency_show, NULL);
static ssize_t channel_interrupts_show(const struct vmbus_channel *channel, char *buf) static ssize_t channel_interrupts_show(struct vmbus_channel *channel, char *buf)
{ {
return sprintf(buf, "%llu\n", channel->interrupts); return sprintf(buf, "%llu\n", channel->interrupts);
} }
static VMBUS_CHAN_ATTR(interrupts, S_IRUGO, channel_interrupts_show, NULL); static VMBUS_CHAN_ATTR(interrupts, S_IRUGO, channel_interrupts_show, NULL);
static ssize_t channel_events_show(const struct vmbus_channel *channel, char *buf) static ssize_t channel_events_show(struct vmbus_channel *channel, char *buf)
{ {
return sprintf(buf, "%llu\n", channel->sig_events); return sprintf(buf, "%llu\n", channel->sig_events);
} }
static VMBUS_CHAN_ATTR(events, S_IRUGO, channel_events_show, NULL); static VMBUS_CHAN_ATTR(events, S_IRUGO, channel_events_show, NULL);
static ssize_t channel_intr_in_full_show(const struct vmbus_channel *channel, static ssize_t channel_intr_in_full_show(struct vmbus_channel *channel,
char *buf) char *buf)
{ {
return sprintf(buf, "%llu\n", return sprintf(buf, "%llu\n",
...@@ -1492,7 +1554,7 @@ static ssize_t channel_intr_in_full_show(const struct vmbus_channel *channel, ...@@ -1492,7 +1554,7 @@ static ssize_t channel_intr_in_full_show(const struct vmbus_channel *channel,
} }
static VMBUS_CHAN_ATTR(intr_in_full, 0444, channel_intr_in_full_show, NULL); static VMBUS_CHAN_ATTR(intr_in_full, 0444, channel_intr_in_full_show, NULL);
static ssize_t channel_intr_out_empty_show(const struct vmbus_channel *channel, static ssize_t channel_intr_out_empty_show(struct vmbus_channel *channel,
char *buf) char *buf)
{ {
return sprintf(buf, "%llu\n", return sprintf(buf, "%llu\n",
...@@ -1500,7 +1562,7 @@ static ssize_t channel_intr_out_empty_show(const struct vmbus_channel *channel, ...@@ -1500,7 +1562,7 @@ static ssize_t channel_intr_out_empty_show(const struct vmbus_channel *channel,
} }
static VMBUS_CHAN_ATTR(intr_out_empty, 0444, channel_intr_out_empty_show, NULL); static VMBUS_CHAN_ATTR(intr_out_empty, 0444, channel_intr_out_empty_show, NULL);
static ssize_t channel_out_full_first_show(const struct vmbus_channel *channel, static ssize_t channel_out_full_first_show(struct vmbus_channel *channel,
char *buf) char *buf)
{ {
return sprintf(buf, "%llu\n", return sprintf(buf, "%llu\n",
...@@ -1508,7 +1570,7 @@ static ssize_t channel_out_full_first_show(const struct vmbus_channel *channel, ...@@ -1508,7 +1570,7 @@ static ssize_t channel_out_full_first_show(const struct vmbus_channel *channel,
} }
static VMBUS_CHAN_ATTR(out_full_first, 0444, channel_out_full_first_show, NULL); static VMBUS_CHAN_ATTR(out_full_first, 0444, channel_out_full_first_show, NULL);
static ssize_t channel_out_full_total_show(const struct vmbus_channel *channel, static ssize_t channel_out_full_total_show(struct vmbus_channel *channel,
char *buf) char *buf)
{ {
return sprintf(buf, "%llu\n", return sprintf(buf, "%llu\n",
...@@ -1516,14 +1578,14 @@ static ssize_t channel_out_full_total_show(const struct vmbus_channel *channel, ...@@ -1516,14 +1578,14 @@ static ssize_t channel_out_full_total_show(const struct vmbus_channel *channel,
} }
static VMBUS_CHAN_ATTR(out_full_total, 0444, channel_out_full_total_show, NULL); static VMBUS_CHAN_ATTR(out_full_total, 0444, channel_out_full_total_show, NULL);
static ssize_t subchannel_monitor_id_show(const struct vmbus_channel *channel, static ssize_t subchannel_monitor_id_show(struct vmbus_channel *channel,
char *buf) char *buf)
{ {
return sprintf(buf, "%u\n", channel->offermsg.monitorid); return sprintf(buf, "%u\n", channel->offermsg.monitorid);
} }
static VMBUS_CHAN_ATTR(monitor_id, S_IRUGO, subchannel_monitor_id_show, NULL); static VMBUS_CHAN_ATTR(monitor_id, S_IRUGO, subchannel_monitor_id_show, NULL);
static ssize_t subchannel_id_show(const struct vmbus_channel *channel, static ssize_t subchannel_id_show(struct vmbus_channel *channel,
char *buf) char *buf)
{ {
return sprintf(buf, "%u\n", return sprintf(buf, "%u\n",
...@@ -1550,10 +1612,34 @@ static struct attribute *vmbus_chan_attrs[] = { ...@@ -1550,10 +1612,34 @@ static struct attribute *vmbus_chan_attrs[] = {
NULL NULL
}; };
/*
* Channel-level attribute_group callback function. Returns the permission for
* each attribute, and returns 0 if an attribute is not visible.
*/
static umode_t vmbus_chan_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int idx)
{
const struct vmbus_channel *channel =
container_of(kobj, struct vmbus_channel, kobj);
/* Hide the monitor attributes if the monitor mechanism is not used. */
if (!channel->offermsg.monitor_allocated &&
(attr == &chan_attr_pending.attr ||
attr == &chan_attr_latency.attr ||
attr == &chan_attr_monitor_id.attr))
return 0;
return attr->mode;
}
static struct attribute_group vmbus_chan_group = {
.attrs = vmbus_chan_attrs,
.is_visible = vmbus_chan_attr_is_visible
};
static struct kobj_type vmbus_chan_ktype = { static struct kobj_type vmbus_chan_ktype = {
.sysfs_ops = &vmbus_chan_sysfs_ops, .sysfs_ops = &vmbus_chan_sysfs_ops,
.release = vmbus_chan_release, .release = vmbus_chan_release,
.default_attrs = vmbus_chan_attrs,
}; };
/* /*
...@@ -1561,6 +1647,7 @@ static struct kobj_type vmbus_chan_ktype = { ...@@ -1561,6 +1647,7 @@ static struct kobj_type vmbus_chan_ktype = {
*/ */
int vmbus_add_channel_kobj(struct hv_device *dev, struct vmbus_channel *channel) int vmbus_add_channel_kobj(struct hv_device *dev, struct vmbus_channel *channel)
{ {
const struct device *device = &dev->device;
struct kobject *kobj = &channel->kobj; struct kobject *kobj = &channel->kobj;
u32 relid = channel->offermsg.child_relid; u32 relid = channel->offermsg.child_relid;
int ret; int ret;
...@@ -1571,11 +1658,30 @@ int vmbus_add_channel_kobj(struct hv_device *dev, struct vmbus_channel *channel) ...@@ -1571,11 +1658,30 @@ int vmbus_add_channel_kobj(struct hv_device *dev, struct vmbus_channel *channel)
if (ret) if (ret)
return ret; return ret;
ret = sysfs_create_group(kobj, &vmbus_chan_group);
if (ret) {
/*
* The calling functions' error handling paths will cleanup the
* empty channel directory.
*/
dev_err(device, "Unable to set up channel sysfs files\n");
return ret;
}
kobject_uevent(kobj, KOBJ_ADD); kobject_uevent(kobj, KOBJ_ADD);
return 0; return 0;
} }
/*
* vmbus_remove_channel_attr_group - remove the channel's attribute group
*/
void vmbus_remove_channel_attr_group(struct vmbus_channel *channel)
{
sysfs_remove_group(&channel->kobj, &vmbus_chan_group);
}
/* /*
* vmbus_device_create - Creates and registers a new child device * vmbus_device_create - Creates and registers a new child device
* on the vmbus. * on the vmbus.
......
...@@ -165,6 +165,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { ...@@ -165,6 +165,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6), PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6),
.driver_data = (kernel_ulong_t)&intel_th_2x, .driver_data = (kernel_ulong_t)&intel_th_2x,
}, },
{
/* Comet Lake */
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6),
.driver_data = (kernel_ulong_t)&intel_th_2x,
},
{ 0 }, { 0 },
}; };
......
...@@ -166,11 +166,10 @@ stm_master(struct stm_device *stm, unsigned int idx) ...@@ -166,11 +166,10 @@ stm_master(struct stm_device *stm, unsigned int idx)
static int stp_master_alloc(struct stm_device *stm, unsigned int idx) static int stp_master_alloc(struct stm_device *stm, unsigned int idx)
{ {
struct stp_master *master; struct stp_master *master;
size_t size;
size = ALIGN(stm->data->sw_nchannels, 8) / 8; master = kzalloc(struct_size(master, chan_map,
size += sizeof(struct stp_master); BITS_TO_LONGS(stm->data->sw_nchannels)),
master = kzalloc(size, GFP_ATOMIC); GFP_ATOMIC);
if (!master) if (!master)
return -ENOMEM; return -ENOMEM;
...@@ -218,8 +217,8 @@ stm_output_disclaim(struct stm_device *stm, struct stm_output *output) ...@@ -218,8 +217,8 @@ stm_output_disclaim(struct stm_device *stm, struct stm_output *output)
bitmap_release_region(&master->chan_map[0], output->channel, bitmap_release_region(&master->chan_map[0], output->channel,
ilog2(output->nr_chans)); ilog2(output->nr_chans));
output->nr_chans = 0;
master->nr_free += output->nr_chans; master->nr_free += output->nr_chans;
output->nr_chans = 0;
} }
/* /*
......
...@@ -451,6 +451,7 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr) ...@@ -451,6 +451,7 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr)
lss_l1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN) lss_l1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN)
| rtsx_check_dev_flag(pcr, PM_L1_2_EN); | rtsx_check_dev_flag(pcr, PM_L1_2_EN);
rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0);
if (lss_l1_2) { if (lss_l1_2) {
pcr_dbg(pcr, "Set parameters for L1.2."); pcr_dbg(pcr, "Set parameters for L1.2.");
rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL, rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
...@@ -573,10 +574,10 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) ...@@ -573,10 +574,10 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr)
* to drive low, and we forcibly request clock. * to drive low, and we forcibly request clock.
*/ */
if (option->force_clkreq_0) if (option->force_clkreq_0)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, rtsx_pci_write_register(pcr, PETXCFG,
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
else else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, rtsx_pci_write_register(pcr, PETXCFG,
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);
return 0; return 0;
...@@ -704,7 +705,7 @@ void rts5260_init_params(struct rtsx_pcr *pcr) ...@@ -704,7 +705,7 @@ void rts5260_init_params(struct rtsx_pcr *pcr)
option->ocp_en = 1; option->ocp_en = 1;
if (option->ocp_en) if (option->ocp_en)
hw_param->interrupt_en |= SD_OC_INT_EN; hw_param->interrupt_en |= SD_OC_INT_EN;
hw_param->ocp_glitch = SDVIO_OCP_GLITCH_800U | SDVIO_OCP_GLITCH_800U; hw_param->ocp_glitch = SD_OCP_GLITCH_100U | SDVIO_OCP_GLITCH_800U;
option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550; option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550;
option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970; option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970;
} }
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
# #
config PHY_SUN4I_USB config PHY_SUN4I_USB
tristate "Allwinner sunxi SoC USB PHY driver" tristate "Allwinner sunxi SoC USB PHY driver"
depends on ARCH_SUNXI && HAS_IOMEM && OF depends on ARCH_SUNXI || COMPILE_TEST
depends on HAS_IOMEM
depends on RESET_CONTROLLER depends on RESET_CONTROLLER
depends on EXTCON depends on EXTCON
depends on POWER_SUPPLY depends on POWER_SUPPLY
...@@ -19,7 +20,8 @@ config PHY_SUN4I_USB ...@@ -19,7 +20,8 @@ config PHY_SUN4I_USB
config PHY_SUN6I_MIPI_DPHY config PHY_SUN6I_MIPI_DPHY
tristate "Allwinner A31 MIPI D-PHY Support" tristate "Allwinner A31 MIPI D-PHY Support"
depends on ARCH_SUNXI && HAS_IOMEM && OF depends on ARCH_SUNXI || COMPILE_TEST
depends on HAS_IOMEM
depends on RESET_CONTROLLER depends on RESET_CONTROLLER
select GENERIC_PHY select GENERIC_PHY
select GENERIC_PHY_MIPI_DPHY select GENERIC_PHY_MIPI_DPHY
...@@ -31,7 +33,8 @@ config PHY_SUN6I_MIPI_DPHY ...@@ -31,7 +33,8 @@ config PHY_SUN6I_MIPI_DPHY
config PHY_SUN9I_USB config PHY_SUN9I_USB
tristate "Allwinner sun9i SoC USB PHY driver" tristate "Allwinner sun9i SoC USB PHY driver"
depends on ARCH_SUNXI && HAS_IOMEM && OF depends on ARCH_SUNXI || COMPILE_TEST
depends on HAS_IOMEM
depends on RESET_CONTROLLER depends on RESET_CONTROLLER
depends on USB_SUPPORT depends on USB_SUPPORT
select USB_COMMON select USB_COMMON
......
...@@ -554,6 +554,7 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) ...@@ -554,6 +554,7 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
struct sun4i_usb_phy_data *data = struct sun4i_usb_phy_data *data =
container_of(work, struct sun4i_usb_phy_data, detect.work); container_of(work, struct sun4i_usb_phy_data, detect.work);
struct phy *phy0 = data->phys[0].phy; struct phy *phy0 = data->phys[0].phy;
struct sun4i_usb_phy *phy = phy_get_drvdata(phy0);
bool force_session_end, id_notify = false, vbus_notify = false; bool force_session_end, id_notify = false, vbus_notify = false;
int id_det, vbus_det; int id_det, vbus_det;
...@@ -610,6 +611,9 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) ...@@ -610,6 +611,9 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
mutex_unlock(&phy0->mutex); mutex_unlock(&phy0->mutex);
} }
/* Enable PHY0 passby for host mode only. */
sun4i_usb_phy_passby(phy, !id_det);
/* Re-route PHY0 if necessary */ /* Re-route PHY0 if necessary */
if (data->cfg->phy0_dual_route) if (data->cfg->phy0_dual_route)
sun4i_usb_phy0_reroute(data, id_det); sun4i_usb_phy0_reroute(data, id_det);
......
...@@ -266,7 +266,6 @@ static struct platform_driver mvebu_a3700_utmi_driver = { ...@@ -266,7 +266,6 @@ static struct platform_driver mvebu_a3700_utmi_driver = {
.probe = mvebu_a3700_utmi_phy_probe, .probe = mvebu_a3700_utmi_phy_probe,
.driver = { .driver = {
.name = "mvebu-a3700-utmi-phy", .name = "mvebu-a3700-utmi-phy",
.owner = THIS_MODULE,
.of_match_table = mvebu_a3700_utmi_of_match, .of_match_table = mvebu_a3700_utmi_of_match,
}, },
}; };
......
...@@ -13,7 +13,7 @@ config PHY_CPCAP_USB ...@@ -13,7 +13,7 @@ config PHY_CPCAP_USB
config PHY_MAPPHONE_MDM6600 config PHY_MAPPHONE_MDM6600
tristate "Motorola Mapphone MDM6600 modem USB PHY driver" tristate "Motorola Mapphone MDM6600 modem USB PHY driver"
depends on OF && USB_SUPPORT depends on OF && USB_SUPPORT && GPIOLIB
select GENERIC_PHY select GENERIC_PHY
help help
Enable this for MDM6600 USB modem to work on Motorola phones Enable this for MDM6600 USB modem to work on Motorola phones
......
...@@ -459,7 +459,7 @@ static int ufs_qcom_phy_enable_iface_clk(struct ufs_qcom_phy *phy) ...@@ -459,7 +459,7 @@ static int ufs_qcom_phy_enable_iface_clk(struct ufs_qcom_phy *phy)
} }
/* Turn OFF M-PHY RMMI interface clocks */ /* Turn OFF M-PHY RMMI interface clocks */
void ufs_qcom_phy_disable_iface_clk(struct ufs_qcom_phy *phy) static void ufs_qcom_phy_disable_iface_clk(struct ufs_qcom_phy *phy)
{ {
if (phy->is_iface_clk_enabled) { if (phy->is_iface_clk_enabled) {
clk_disable_unprepare(phy->tx_iface_clk); clk_disable_unprepare(phy->tx_iface_clk);
......
...@@ -400,7 +400,7 @@ struct phy_reg { ...@@ -400,7 +400,7 @@ struct phy_reg {
u32 addr; u32 addr;
}; };
struct phy_reg usb3_pll_cfg[] = { static struct phy_reg usb3_pll_cfg[] = {
{ 0xf0, CMN_PLL0_VCOCAL_INIT }, { 0xf0, CMN_PLL0_VCOCAL_INIT },
{ 0x18, CMN_PLL0_VCOCAL_ITER }, { 0x18, CMN_PLL0_VCOCAL_ITER },
{ 0xd0, CMN_PLL0_INTDIV }, { 0xd0, CMN_PLL0_INTDIV },
...@@ -417,7 +417,7 @@ struct phy_reg usb3_pll_cfg[] = { ...@@ -417,7 +417,7 @@ struct phy_reg usb3_pll_cfg[] = {
{ 0x8, CMN_DIAG_PLL0_LF_PROG }, { 0x8, CMN_DIAG_PLL0_LF_PROG },
}; };
struct phy_reg dp_pll_cfg[] = { static struct phy_reg dp_pll_cfg[] = {
{ 0xf0, CMN_PLL1_VCOCAL_INIT }, { 0xf0, CMN_PLL1_VCOCAL_INIT },
{ 0x18, CMN_PLL1_VCOCAL_ITER }, { 0x18, CMN_PLL1_VCOCAL_ITER },
{ 0x30b9, CMN_PLL1_VCOCAL_START }, { 0x30b9, CMN_PLL1_VCOCAL_START },
......
...@@ -37,7 +37,7 @@ config OMAP_USB2 ...@@ -37,7 +37,7 @@ config OMAP_USB2
depends on USB_SUPPORT depends on USB_SUPPORT
select GENERIC_PHY select GENERIC_PHY
select USB_PHY select USB_PHY
select OMAP_CONTROL_PHY if ARCH_OMAP2PLUS select OMAP_CONTROL_PHY if ARCH_OMAP2PLUS || COMPILE_TEST
help help
Enable this to support the transceiver that is part of SOC. This Enable this to support the transceiver that is part of SOC. This
driver takes care of all the PHY functionality apart from comparator. driver takes care of all the PHY functionality apart from comparator.
......
...@@ -172,6 +172,7 @@ struct twl4030_usb { ...@@ -172,6 +172,7 @@ struct twl4030_usb {
int irq; int irq;
enum musb_vbus_id_status linkstat; enum musb_vbus_id_status linkstat;
atomic_t connected;
bool vbus_supplied; bool vbus_supplied;
bool musb_mailbox_pending; bool musb_mailbox_pending;
...@@ -575,39 +576,29 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) ...@@ -575,39 +576,29 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
{ {
struct twl4030_usb *twl = _twl; struct twl4030_usb *twl = _twl;
enum musb_vbus_id_status status; enum musb_vbus_id_status status;
bool status_changed = false;
int err; int err;
status = twl4030_usb_linkstat(twl); status = twl4030_usb_linkstat(twl);
mutex_lock(&twl->lock); mutex_lock(&twl->lock);
if (status >= 0 && status != twl->linkstat) { twl->linkstat = status;
status_changed =
cable_present(twl->linkstat) !=
cable_present(status);
twl->linkstat = status;
}
mutex_unlock(&twl->lock); mutex_unlock(&twl->lock);
if (status_changed) { if (cable_present(status)) {
/* FIXME add a set_power() method so that B-devices can if (atomic_add_unless(&twl->connected, 1, 1)) {
* configure the charger appropriately. It's not always dev_dbg(twl->dev, "%s: cable connected %i\n",
* correct to consume VBUS power, and how much current to __func__, status);
* consume is a function of the USB configuration chosen
* by the host.
*
* REVISIT usb_gadget_vbus_connect(...) as needed, ditto
* its disconnect() sibling, when changing to/from the
* USB_LINK_VBUS state. musb_hdrc won't care until it
* starts to handle softconnect right.
*/
if (cable_present(status)) {
pm_runtime_get_sync(twl->dev); pm_runtime_get_sync(twl->dev);
} else { twl->musb_mailbox_pending = true;
}
} else {
if (atomic_add_unless(&twl->connected, -1, 0)) {
dev_dbg(twl->dev, "%s: cable disconnected %i\n",
__func__, status);
pm_runtime_mark_last_busy(twl->dev); pm_runtime_mark_last_busy(twl->dev);
pm_runtime_put_autosuspend(twl->dev); pm_runtime_put_autosuspend(twl->dev);
twl->musb_mailbox_pending = true;
} }
twl->musb_mailbox_pending = true;
} }
if (twl->musb_mailbox_pending) { if (twl->musb_mailbox_pending) {
err = musb_mailbox(status); err = musb_mailbox(status);
......
...@@ -141,6 +141,11 @@ struct hv_ring_buffer_info { ...@@ -141,6 +141,11 @@ struct hv_ring_buffer_info {
u32 ring_datasize; /* < ring_size */ u32 ring_datasize; /* < ring_size */
u32 priv_read_index; u32 priv_read_index;
/*
* The ring buffer mutex lock. This lock prevents the ring buffer from
* being freed while the ring buffer is being accessed.
*/
struct mutex ring_buffer_mutex;
}; };
...@@ -1206,7 +1211,7 @@ struct hv_ring_buffer_debug_info { ...@@ -1206,7 +1211,7 @@ struct hv_ring_buffer_debug_info {
}; };
int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info, int hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
struct hv_ring_buffer_debug_info *debug_info); struct hv_ring_buffer_debug_info *debug_info);
/* Vmbus interface */ /* Vmbus interface */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment