(DSA_MAX_SWITCHES).
Each of these switch child nodes should have the following required properties:
-- reg : Describes the switch address on the MII bus
+- reg : Contains two fields. The first one describes the
+ address on the MII bus. The second is the switch
+ number that must be unique in cascaded configurations
- #address-cells : Must be 1
- #size-cells : Must be 0
byte 4: 0 y6 y5 y4 y3 y2 y1 y0
byte 5: 0 z6 z5 z4 z3 z2 z1 z0
+Protocol Version 2 DualPoint devices send standard PS/2 mouse packets for
+the DualPoint Stick.
+
Dualpoint device -- interleaved packet format
---------------------------------------------
byte 7: 0 y6 y5 y4 y3 y2 y1 y0
byte 8: 0 z6 z5 z4 z3 z2 z1 z0
+Devices which use the interleaving format normally send standard PS/2 mouse
+packets for the DualPoint Stick + ALPS Absolute Mode packets for the
+touchpad, switching to the interleaved packet format when both the stick and
+the touchpad are used at the same time.
+
ALPS Absolute Mode - Protocol Version 3
---------------------------------------
The kernel does not provide button emulation for such devices but treats
them as any other INPUT_PROP_BUTTONPAD device.
+INPUT_PROP_ACCELEROMETER
+-------------------------
+Directional axes on this device (absolute and/or relative x, y, z) represent
+accelerometer data. All other axes retain their meaning. A device must not mix
+regular directional axes and accelerometer axes on the same event node.
+
Guidelines:
==========
The guidelines below ensure proper single-touch and multi-finger functionality.
The type of approaching tool. A lot of kernel drivers cannot distinguish
between different tool types, such as a finger or a pen. In such cases, the
-event should be omitted. The protocol currently supports MT_TOOL_FINGER and
-MT_TOOL_PEN [2]. For type B devices, this event is handled by input core;
-drivers should instead use input_mt_report_slot_state().
+event should be omitted. The protocol currently supports MT_TOOL_FINGER,
+MT_TOOL_PEN, and MT_TOOL_PALM [2]. For type B devices, this event is handled
+by input core; drivers should instead use input_mt_report_slot_state().
+A contact's ABS_MT_TOOL_TYPE may change over time while still touching the
+device, because the firmware may not be able to determine which tool is being
+used when it first appears.
ABS_MT_BLOB_ID
F: include/uapi/linux/kfd_ioctl.h
AMD MICROCODE UPDATE SUPPORT
-M: Andreas Herrmann <herrmann.der.user@googlemail.com>
-L: amd64-microcode@amd64.org
+M: Borislav Petkov <bp@alien8.de>
S: Maintained
F: arch/x86/kernel/cpu/microcode/amd*
F: drivers/platform/x86/intel_menlow.c
INTEL IA32 MICROCODE UPDATE SUPPORT
-M: Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
+M: Borislav Petkov <bp@alien8.de>
S: Maintained
F: arch/x86/kernel/cpu/microcode/core*
F: arch/x86/kernel/cpu/microcode/intel*
VERSION = 4
PATCHLEVEL = 0
SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc7
NAME = Hurr durr I'ma sheep
# *DOCUMENTATION*
static inline int cpu_nr_cores(void)
{
- return NR_CPUS >> threads_shift;
+ return nr_cpu_ids >> threads_shift;
}
static inline cpumask_t cpu_online_cores_map(void)
INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
/* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
- INTEL_EVENT_CONSTRAINT(0x08a3, 0x4),
+ INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4),
/* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
- INTEL_EVENT_CONSTRAINT(0x0ca3, 0x4),
+ INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4),
/* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
- INTEL_EVENT_CONSTRAINT(0x04a3, 0xf),
+ INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf),
EVENT_CONSTRAINT_END
};
if (c)
return c;
- c = intel_pebs_constraints(event);
+ c = intel_shared_regs_constraints(cpuc, event);
if (c)
return c;
- c = intel_shared_regs_constraints(cpuc, event);
+ c = intel_pebs_constraints(event);
if (c)
return c;
cmpq %r11,(EFLAGS-ARGOFFSET)(%rsp) /* R11 == RFLAGS */
jne opportunistic_sysret_failed
- testq $X86_EFLAGS_RF,%r11 /* sysret can't restore RF */
+ /*
+ * SYSRET can't restore RF. SYSRET can restore TF, but unlike IRET,
+ * restoring TF results in a trap from userspace immediately after
+ * SYSRET. This would cause an infinite loop whenever #DB happens
+ * with register state that satisfies the opportunistic SYSRET
+ * conditions. For example, single-stepping this user code:
+ *
+ * movq $stuck_here,%rcx
+ * pushfq
+ * popq %r11
+ * stuck_here:
+ *
+ * would never get past 'stuck_here'.
+ */
+ testq $(X86_EFLAGS_RF|X86_EFLAGS_TF), %r11
jnz opportunistic_sysret_failed
/* nothing to check for RSP */
{ "bx", 8, offsetof(struct pt_regs, bx) },
{ "cx", 8, offsetof(struct pt_regs, cx) },
{ "dx", 8, offsetof(struct pt_regs, dx) },
- { "si", 8, offsetof(struct pt_regs, dx) },
+ { "si", 8, offsetof(struct pt_regs, si) },
{ "di", 8, offsetof(struct pt_regs, di) },
{ "bp", 8, offsetof(struct pt_regs, bp) },
{ "sp", 8, offsetof(struct pt_regs, sp) },
},
},
+ /* ASRock */
+ { /* Handle problems with rebooting on ASRock Q1900DC-ITX */
+ .callback = set_pci_reboot,
+ .ident = "ASRock Q1900DC-ITX",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASRock"),
+ DMI_MATCH(DMI_BOARD_NAME, "Q1900DC-ITX"),
+ },
+ },
+
/* ASUS */
{ /* Handle problems with rebooting on ASUS P4S800 */
.callback = set_bios_reboot,
unsigned long xen_max_p2m_pfn __read_mostly;
EXPORT_SYMBOL_GPL(xen_max_p2m_pfn);
+#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT
+#define P2M_LIMIT CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT
+#else
+#define P2M_LIMIT 0
+#endif
+
static DEFINE_SPINLOCK(p2m_update_lock);
static unsigned long *p2m_mid_missing_mfn;
void __init xen_vmalloc_p2m_tree(void)
{
static struct vm_struct vm;
+ unsigned long p2m_limit;
+ p2m_limit = (phys_addr_t)P2M_LIMIT * 1024 * 1024 * 1024 / PAGE_SIZE;
vm.flags = VM_ALLOC;
- vm.size = ALIGN(sizeof(unsigned long) * xen_max_p2m_pfn,
+ vm.size = ALIGN(sizeof(unsigned long) * max(xen_max_p2m_pfn, p2m_limit),
PMD_SIZE * PMDS_PER_MID_PAGE);
vm_area_register_early(&vm, PMD_SIZE * PMDS_PER_MID_PAGE);
pr_notice("p2m virtual area at %p, size is %lx\n", vm.addr, vm.size);
b->physical_block_size);
t->io_min = max(t->io_min, b->io_min);
- t->io_opt = lcm(t->io_opt, b->io_opt);
+ t->io_opt = lcm_not_zero(t->io_opt, b->io_opt);
t->cluster &= b->cluster;
t->discard_zeroes_data &= b->discard_zeroes_data;
b->raid_partial_stripes_expensive);
/* Find lowest common alignment_offset */
- t->alignment_offset = lcm(t->alignment_offset, alignment)
+ t->alignment_offset = lcm_not_zero(t->alignment_offset, alignment)
% max(t->physical_block_size, t->io_min);
/* Verify that new alignment_offset is on a logical block boundary */
b->max_discard_sectors);
t->discard_granularity = max(t->discard_granularity,
b->discard_granularity);
- t->discard_alignment = lcm(t->discard_alignment, alignment) %
+ t->discard_alignment = lcm_not_zero(t->discard_alignment, alignment) %
t->discard_granularity;
}
int i = 0;
/*
- * Stop when we see all the items the table claimed to have
- * OR we run off the end of the table (also happens)
+ * Stop when we have seen all the items the table claimed to have
+ * (SMBIOS < 3.0 only) OR we reach an end-of-table marker OR we run
+ * off the end of the table (should never happen but sometimes does
+ * on bogus implementations.)
*/
- while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
+ while ((!num || i < num) &&
+ (data - buf + sizeof(struct dmi_header)) <= len) {
const struct dmi_header *dm = (const struct dmi_header *)data;
/*
if (memcmp(buf, "_SM3_", 5) == 0 &&
buf[6] < 32 && dmi_checksum(buf, buf[6])) {
dmi_ver = get_unaligned_be16(buf + 7);
+ dmi_num = 0; /* No longer specified */
dmi_len = get_unaligned_le32(buf + 12);
dmi_base = get_unaligned_le64(buf + 16);
- /*
- * The 64-bit SMBIOS 3.0 entry point no longer has a field
- * containing the number of structures present in the table.
- * Instead, it defines the table size as a maximum size, and
- * relies on the end-of-table structure type (#127) to be used
- * to signal the end of the table.
- * So let's define dmi_num as an upper bound as well: each
- * structure has a 4 byte header, so dmi_len / 4 is an upper
- * bound for the number of structures in the table.
- */
- dmi_num = dmi_len / 4;
-
if (dmi_walk_early(dmi_decode) == 0) {
pr_info("SMBIOS %d.%d present.\n",
dmi_ver >> 8, dmi_ver & 0xFF);
drm_mode_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
+ drm_edid_to_eld(connector, edid);
kfree(edid);
return ret;
struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
count = drm_add_edid_modes(connector, edid);
+ drm_edid_to_eld(connector, edid);
} else
count = (*connector_funcs->get_modes)(connector);
}
unsigned int ovl_height;
unsigned int fb_width;
unsigned int fb_height;
+ unsigned int fb_pitch;
unsigned int bpp;
unsigned int pixel_format;
dma_addr_t dma_addr;
win_data->offset_y = plane->crtc_y;
win_data->ovl_width = plane->crtc_width;
win_data->ovl_height = plane->crtc_height;
+ win_data->fb_pitch = plane->pitch;
win_data->fb_width = plane->fb_width;
win_data->fb_height = plane->fb_height;
win_data->dma_addr = plane->dma_addr[0] + offset;
win_data->bpp = plane->bpp;
win_data->pixel_format = plane->pixel_format;
- win_data->buf_offsize = (plane->fb_width - plane->crtc_width) *
- (plane->bpp >> 3);
+ win_data->buf_offsize =
+ plane->pitch - (plane->crtc_width * (plane->bpp >> 3));
win_data->line_size = plane->crtc_width * (plane->bpp >> 3);
DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n",
writel(val, ctx->regs + VIDWx_BUF_START(win, 0));
/* buffer end address */
- size = win_data->fb_width * win_data->ovl_height * (win_data->bpp >> 3);
+ size = win_data->fb_pitch * win_data->ovl_height * (win_data->bpp >> 3);
val = (unsigned long)(win_data->dma_addr + size);
writel(val, ctx->regs + VIDWx_BUF_END(win, 0));
unsigned int fb_x;
unsigned int fb_y;
unsigned int fb_width;
+ unsigned int fb_pitch;
unsigned int fb_height;
unsigned int src_width;
unsigned int src_height;
} else {
luma_addr[0] = win_data->dma_addr;
chroma_addr[0] = win_data->dma_addr
- + (win_data->fb_width * win_data->fb_height);
+ + (win_data->fb_pitch * win_data->fb_height);
}
if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) {
luma_addr[1] = luma_addr[0] + 0x40;
chroma_addr[1] = chroma_addr[0] + 0x40;
} else {
- luma_addr[1] = luma_addr[0] + win_data->fb_width;
- chroma_addr[1] = chroma_addr[0] + win_data->fb_width;
+ luma_addr[1] = luma_addr[0] + win_data->fb_pitch;
+ chroma_addr[1] = chroma_addr[0] + win_data->fb_pitch;
}
} else {
ctx->interlace = false;
vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
/* setting size of input image */
- vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) |
+ vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_pitch) |
VP_IMG_VSIZE(win_data->fb_height));
/* chroma height has to reduced by 2 to avoid chroma distorions */
- vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) |
+ vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_pitch) |
VP_IMG_VSIZE(win_data->fb_height / 2));
vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width);
/* converting dma address base and source offset */
dma_addr = win_data->dma_addr
+ (win_data->fb_x * win_data->bpp >> 3)
- + (win_data->fb_y * win_data->fb_width * win_data->bpp >> 3);
+ + (win_data->fb_y * win_data->fb_pitch);
src_x_offset = 0;
src_y_offset = 0;
MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
/* setup geometry */
- mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width);
+ mixer_reg_write(res, MXR_GRAPHIC_SPAN(win),
+ win_data->fb_pitch / (win_data->bpp >> 3));
/* setup display size */
if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
win_data->fb_y = plane->fb_y;
win_data->fb_width = plane->fb_width;
win_data->fb_height = plane->fb_height;
+ win_data->fb_pitch = plane->pitch;
win_data->src_width = plane->src_width;
win_data->src_height = plane->src_height;
goto err;
}
- if (i915_needs_cmd_parser(ring)) {
+ if (i915_needs_cmd_parser(ring) && args->batch_len) {
batch_obj = i915_gem_execbuffer_parse(ring,
&shadow_exec_entry,
eb,
drm_modeset_lock_all(dev);
plane = drm_plane_find(dev, set->plane_id);
- if (!plane) {
+ if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) {
ret = -ENOENT;
goto out_unlock;
}
drm_modeset_lock_all(dev);
plane = drm_plane_find(dev, get->plane_id);
- if (!plane) {
+ if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) {
ret = -ENOENT;
goto out_unlock;
}
#define VCE_UENC_REG_CLOCK_GATING 0x207c0
#define VCE_SYS_INT_EN 0x21300
# define VCE_SYS_INT_TRAP_INTERRUPT_EN (1 << 3)
+#define VCE_LMI_VCPU_CACHE_40BIT_BAR 0x2145c
#define VCE_LMI_CTRL2 0x21474
#define VCE_LMI_CTRL 0x21498
#define VCE_LMI_VM_CTRL 0x214a0
int new_active_crtc_count;
u32 current_active_crtcs;
int current_active_crtc_count;
+ bool single_display;
struct radeon_dpm_dynamic_state dyn_state;
struct radeon_dpm_fan fan;
u32 tdp_limit;
static bool radeon_read_bios(struct radeon_device *rdev)
{
- uint8_t __iomem *bios;
+ uint8_t __iomem *bios, val1, val2;
size_t size;
rdev->bios = NULL;
return false;
}
- if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
+ val1 = readb(&bios[0]);
+ val2 = readb(&bios[1]);
+
+ if (size == 0 || val1 != 0x55 || val2 != 0xaa) {
pci_unmap_rom(rdev->pdev, bios);
return false;
}
- rdev->bios = kmemdup(bios, size, GFP_KERNEL);
+ rdev->bios = kzalloc(size, GFP_KERNEL);
if (rdev->bios == NULL) {
pci_unmap_rom(rdev->pdev, bios);
return false;
}
+ memcpy_fromio(rdev->bios, bios, size);
pci_unmap_rom(rdev->pdev, bios);
return true;
}
it = interval_tree_iter_first(&rmn->objects, start, end);
while (it) {
struct radeon_bo *bo;
- struct fence *fence;
int r;
bo = container_of(it, struct radeon_bo, mn_it);
continue;
}
- fence = reservation_object_get_excl(bo->tbo.resv);
- if (fence) {
- r = radeon_fence_wait((struct radeon_fence *)fence, false);
- if (r)
- DRM_ERROR("(%d) failed to wait for user bo\n", r);
- }
+ r = reservation_object_wait_timeout_rcu(bo->tbo.resv, true,
+ false, MAX_SCHEDULE_TIMEOUT);
+ if (r)
+ DRM_ERROR("(%d) failed to wait for user bo\n", r);
radeon_ttm_placement_from_domain(bo, RADEON_GEM_DOMAIN_CPU);
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
radeon_pm_compute_clocks(rdev);
}
-static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev,
- enum radeon_pm_state_type dpm_state)
+static bool radeon_dpm_single_display(struct radeon_device *rdev)
{
- int i;
- struct radeon_ps *ps;
- u32 ui_class;
bool single_display = (rdev->pm.dpm.new_active_crtc_count < 2) ?
true : false;
if (single_display && (r600_dpm_get_vrefresh(rdev) >= 120))
single_display = false;
+ return single_display;
+}
+
+static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev,
+ enum radeon_pm_state_type dpm_state)
+{
+ int i;
+ struct radeon_ps *ps;
+ u32 ui_class;
+ bool single_display = radeon_dpm_single_display(rdev);
+
/* certain older asics have a separare 3D performance state,
* so try that first if the user selected performance
*/
struct radeon_ps *ps;
enum radeon_pm_state_type dpm_state;
int ret;
+ bool single_display = radeon_dpm_single_display(rdev);
/* if dpm init failed */
if (!rdev->pm.dpm_enabled)
/* vce just modifies an existing state so force a change */
if (ps->vce_active != rdev->pm.dpm.vce_active)
goto force;
+ /* user has made a display change (such as timing) */
+ if (rdev->pm.dpm.single_display != single_display)
+ goto force;
if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) {
/* for pre-BTC and APUs if the num crtcs changed but state is the same,
* all we need to do is update the display configuration.
rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
+ rdev->pm.dpm.single_display = single_display;
/* wait for the rings to drain */
for (i = 0; i < RADEON_NUM_RINGS; i++) {
seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
seq_printf(m, "%u dwords in ring\n", count);
- if (!ring->ready)
+ if (!ring->ring)
return 0;
/* print 8 dw before current rptr as often it's the last executed
enum dma_data_direction direction = write ?
DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
+ /* double check that we don't free the table twice */
+ if (!ttm->sg->sgl)
+ return;
+
/* free the sg table and pages again */
dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
WREG32(VCE_LMI_SWAP_CNTL1, 0);
WREG32(VCE_LMI_VM_CTRL, 0);
+ WREG32(VCE_LMI_VCPU_CACHE_40BIT_BAR, addr >> 8);
+
+ addr &= 0xff;
size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size);
WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);
WREG32(VCE_VCPU_CACHE_SIZE0, size);
mutex_lock(&data->mutex);
- for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+ for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
ret = bma180_get_data_reg(data, bit);
if (ret < 0) {
int val;
int val2;
u8 bw_bits;
-} bmc150_accel_samp_freq_table[] = { {7, 810000, 0x08},
- {15, 630000, 0x09},
- {31, 250000, 0x0A},
- {62, 500000, 0x0B},
- {125, 0, 0x0C},
- {250, 0, 0x0D},
- {500, 0, 0x0E},
- {1000, 0, 0x0F} };
+} bmc150_accel_samp_freq_table[] = { {15, 620000, 0x08},
+ {31, 260000, 0x09},
+ {62, 500000, 0x0A},
+ {125, 0, 0x0B},
+ {250, 0, 0x0C},
+ {500, 0, 0x0D},
+ {1000, 0, 0x0E},
+ {2000, 0, 0x0F} };
static const struct {
int bw_bits;
}
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
- "7.810000 15.630000 31.250000 62.500000 125 250 500 1000");
+ "15.620000 31.260000 62.50000 125 250 500 1000 2000");
static struct attribute *bmc150_accel_attributes[] = {
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
int bit, ret, i = 0;
mutex_lock(&data->mutex);
- for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+ for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
ret = i2c_smbus_read_word_data(data->client,
BMC150_ACCEL_AXIS_TO_REG(bit));
mutex_lock(&data->mutex);
- for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+ for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
ret = kxcjk1013_get_acc_reg(data, bit);
if (ret < 0) {
config CC10001_ADC
tristate "Cosmic Circuits 10001 ADC driver"
- depends on HAS_IOMEM || HAVE_CLK || REGULATOR
+ depends on HAVE_CLK || REGULATOR
+ depends on HAS_IOMEM
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
{
struct iio_dev *idev = iio_trigger_get_drvdata(trig);
struct at91_adc_state *st = iio_priv(idev);
- struct iio_buffer *buffer = idev->buffer;
struct at91_adc_reg_desc *reg = st->registers;
u32 status = at91_adc_readl(st, reg->trigger_register);
int value;
at91_adc_writel(st, reg->trigger_register,
status | value);
- for_each_set_bit(bit, buffer->scan_mask,
+ for_each_set_bit(bit, idev->active_scan_mask,
st->num_channels) {
struct iio_chan_spec const *chan = idev->channels + bit;
at91_adc_writel(st, AT91_ADC_CHER,
at91_adc_writel(st, reg->trigger_register,
status & ~value);
- for_each_set_bit(bit, buffer->scan_mask,
+ for_each_set_bit(bit, idev->active_scan_mask,
st->num_channels) {
struct iio_chan_spec const *chan = idev->channels + bit;
at91_adc_writel(st, AT91_ADC_CHDR,
static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
{
struct tiadc_device *adc_dev = iio_priv(indio_dev);
- struct iio_buffer *buffer = indio_dev->buffer;
unsigned int enb = 0;
u8 bit;
tiadc_step_config(indio_dev);
- for_each_set_bit(bit, buffer->scan_mask, adc_dev->channels)
+ for_each_set_bit(bit, indio_dev->active_scan_mask, adc_dev->channels)
enb |= (get_adc_step_bit(adc_dev, bit) << 1);
adc_dev->buffer_en_ch_steps = enb;
struct regulator *vref;
struct vf610_adc_feature adc_feature;
+ u32 sample_freq_avail[5];
+
struct completion completion;
};
+static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
+
#define VF610_ADC_CHAN(_idx, _chan_type) { \
.type = (_chan_type), \
.indexed = 1, \
/* sentinel */
};
-/*
- * ADC sample frequency, unit is ADCK cycles.
- * ADC clk source is ipg clock, which is the same as bus clock.
- *
- * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder)
- * SFCAdder: fixed to 6 ADCK cycles
- * AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
- * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
- * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles
- *
- * By default, enable 12 bit resolution mode, clock source
- * set to ipg clock, So get below frequency group:
- */
-static const u32 vf610_sample_freq_avail[5] =
-{1941176, 559332, 286957, 145374, 73171};
+static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
+{
+ unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk);
+ int i;
+
+ /*
+ * Calculate ADC sample frequencies
+ * Sample time unit is ADCK cycles. ADCK clk source is ipg clock,
+ * which is the same as bus clock.
+ *
+ * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder)
+ * SFCAdder: fixed to 6 ADCK cycles
+ * AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
+ * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
+ * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles
+ */
+ adck_rate = ipg_rate / info->adc_feature.clk_div;
+ for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++)
+ info->sample_freq_avail[i] =
+ adck_rate / (6 + vf610_hw_avgs[i] * (25 + 3));
+}
static inline void vf610_adc_cfg_init(struct vf610_adc *info)
{
+ struct vf610_adc_feature *adc_feature = &info->adc_feature;
+
/* set default Configuration for ADC controller */
- info->adc_feature.clk_sel = VF610_ADCIOC_BUSCLK_SET;
- info->adc_feature.vol_ref = VF610_ADCIOC_VR_VREF_SET;
+ adc_feature->clk_sel = VF610_ADCIOC_BUSCLK_SET;
+ adc_feature->vol_ref = VF610_ADCIOC_VR_VREF_SET;
+
+ adc_feature->calibration = true;
+ adc_feature->ovwren = true;
+
+ adc_feature->res_mode = 12;
+ adc_feature->sample_rate = 1;
+ adc_feature->lpm = true;
- info->adc_feature.calibration = true;
- info->adc_feature.ovwren = true;
+ /* Use a save ADCK which is below 20MHz on all devices */
+ adc_feature->clk_div = 8;
- info->adc_feature.clk_div = 1;
- info->adc_feature.res_mode = 12;
- info->adc_feature.sample_rate = 1;
- info->adc_feature.lpm = true;
+ vf610_adc_calculate_rates(info);
}
static void vf610_adc_cfg_post_set(struct vf610_adc *info)
cfg_data = readl(info->regs + VF610_REG_ADC_CFG);
- /* low power configuration */
cfg_data &= ~VF610_ADC_ADLPC_EN;
if (adc_feature->lpm)
cfg_data |= VF610_ADC_ADLPC_EN;
- /* disable high speed */
cfg_data &= ~VF610_ADC_ADHSC_EN;
writel(cfg_data, info->regs + VF610_REG_ADC_CFG);
return IRQ_HANDLED;
}
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1941176, 559332, 286957, 145374, 73171");
+static ssize_t vf610_show_samp_freq_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vf610_adc *info = iio_priv(dev_to_iio_dev(dev));
+ size_t len = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(info->sample_freq_avail); i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "%u ", info->sample_freq_avail[i]);
+
+ /* replace trailing space by newline */
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(vf610_show_samp_freq_avail);
static struct attribute *vf610_attributes[] = {
- &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
NULL
};
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_SAMP_FREQ:
- *val = vf610_sample_freq_avail[info->adc_feature.sample_rate];
+ *val = info->sample_freq_avail[info->adc_feature.sample_rate];
*val2 = 0;
return IIO_VAL_INT;
switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ:
for (i = 0;
- i < ARRAY_SIZE(vf610_sample_freq_avail);
+ i < ARRAY_SIZE(info->sample_freq_avail);
i++)
- if (val == vf610_sample_freq_avail[i]) {
+ if (val == info->sample_freq_avail[i]) {
info->adc_feature.sample_rate = i;
vf610_adc_sample_set(info);
return 0;
int bit, ret, i = 0;
mutex_lock(&data->mutex);
- for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+ for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
ret = i2c_smbus_read_word_data(data->client,
BMG160_AXIS_TO_REG(bit));
iio_trigger_set_drvdata(adis->trig, adis);
ret = iio_trigger_register(adis->trig);
- indio_dev->trig = adis->trig;
+ indio_dev->trig = iio_trigger_get(adis->trig);
if (ret)
goto error_free_irq;
}
}
-static int inv_mpu6050_write_fsr(struct inv_mpu6050_state *st, int fsr)
+static int inv_mpu6050_write_gyro_scale(struct inv_mpu6050_state *st, int val)
{
- int result;
+ int result, i;
u8 d;
- if (fsr < 0 || fsr > INV_MPU6050_MAX_GYRO_FS_PARAM)
- return -EINVAL;
- if (fsr == st->chip_config.fsr)
- return 0;
+ for (i = 0; i < ARRAY_SIZE(gyro_scale_6050); ++i) {
+ if (gyro_scale_6050[i] == val) {
+ d = (i << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
+ result = inv_mpu6050_write_reg(st,
+ st->reg->gyro_config, d);
+ if (result)
+ return result;
- d = (fsr << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
- result = inv_mpu6050_write_reg(st, st->reg->gyro_config, d);
- if (result)
- return result;
- st->chip_config.fsr = fsr;
+ st->chip_config.fsr = i;
+ return 0;
+ }
+ }
- return 0;
+ return -EINVAL;
}
-static int inv_mpu6050_write_accel_fs(struct inv_mpu6050_state *st, int fs)
+static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val)
{
- int result;
+ int result, i;
u8 d;
- if (fs < 0 || fs > INV_MPU6050_MAX_ACCL_FS_PARAM)
- return -EINVAL;
- if (fs == st->chip_config.accl_fs)
- return 0;
+ for (i = 0; i < ARRAY_SIZE(accel_scale); ++i) {
+ if (accel_scale[i] == val) {
+ d = (i << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
+ result = inv_mpu6050_write_reg(st,
+ st->reg->accl_config, d);
+ if (result)
+ return result;
- d = (fs << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
- result = inv_mpu6050_write_reg(st, st->reg->accl_config, d);
- if (result)
- return result;
- st->chip_config.accl_fs = fs;
+ st->chip_config.accl_fs = i;
+ return 0;
+ }
+ }
- return 0;
+ return -EINVAL;
}
static int inv_mpu6050_write_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_ANGL_VEL:
- result = inv_mpu6050_write_fsr(st, val);
+ result = inv_mpu6050_write_gyro_scale(st, val2);
break;
case IIO_ACCEL:
- result = inv_mpu6050_write_accel_fs(st, val);
+ result = inv_mpu6050_write_accel_scale(st, val2);
break;
default:
result = -EINVAL;
#include <linux/poll.h>
#include "inv_mpu_iio.h"
+static void inv_clear_kfifo(struct inv_mpu6050_state *st)
+{
+ unsigned long flags;
+
+ /* take the spin lock sem to avoid interrupt kick in */
+ spin_lock_irqsave(&st->time_stamp_lock, flags);
+ kfifo_reset(&st->timestamps);
+ spin_unlock_irqrestore(&st->time_stamp_lock, flags);
+}
+
int inv_reset_fifo(struct iio_dev *indio_dev)
{
int result;
INV_MPU6050_BIT_FIFO_RST);
if (result)
goto reset_fifo_fail;
+
+ /* clear timestamps fifo */
+ inv_clear_kfifo(st);
+
/* enable interrupt */
if (st->chip_config.accl_fifo_enable ||
st->chip_config.gyro_fifo_enable) {
return result;
}
-static void inv_clear_kfifo(struct inv_mpu6050_state *st)
-{
- unsigned long flags;
-
- /* take the spin lock sem to avoid interrupt kick in */
- spin_lock_irqsave(&st->time_stamp_lock, flags);
- kfifo_reset(&st->timestamps);
- spin_unlock_irqrestore(&st->time_stamp_lock, flags);
-}
-
/**
* inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt.
*/
flush_fifo:
/* Flush HW and SW FIFOs. */
inv_reset_fifo(indio_dev);
- inv_clear_kfifo(st);
mutex_unlock(&indio_dev->mlock);
iio_trigger_notify_done(indio_dev->trig);
base = KMX61_MAG_XOUT_L;
mutex_lock(&data->lock);
- for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+ for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
ret = kmx61_read_measurement(data, base, bit);
if (ret < 0) {
* @attr_list: List of IIO device attributes
*
* This function frees the memory allocated for each of the IIO device
- * attributes in the list. Note: if you want to reuse the list after calling
- * this function you have to reinitialize it using INIT_LIST_HEAD().
+ * attributes in the list.
*/
void iio_free_chan_devattr_list(struct list_head *attr_list)
{
list_for_each_entry_safe(p, n, attr_list, l) {
kfree(p->dev_attr.attr.name);
+ list_del(&p->l);
kfree(p);
}
}
iio_free_chan_devattr_list(&indio_dev->channel_attr_list);
kfree(indio_dev->chan_attr_group.attrs);
+ indio_dev->chan_attr_group.attrs = NULL;
}
static void iio_dev_release(struct device *device)
error_free_setup_event_lines:
iio_free_chan_devattr_list(&indio_dev->event_interface->dev_attr_list);
kfree(indio_dev->event_interface);
+ indio_dev->event_interface = NULL;
return ret;
}
mutex_lock(&data->mutex);
- for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+ for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
ret = sx9500_read_proximity(data, &indio_dev->channels[bit],
&val);
if (dmasync)
dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs);
+ /*
+ * If the combination of the addr and size requested for this memory
+ * region causes an integer overflow, return error.
+ */
+ if ((PAGE_ALIGN(addr + size) <= size) ||
+ (PAGE_ALIGN(addr + size) <= addr))
+ return ERR_PTR(-EINVAL);
+
if (!can_do_mlock())
return ERR_PTR(-EPERM);
mutex_unlock(&alps_mutex);
}
-static void alps_report_bare_ps2_packet(struct input_dev *dev,
+static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
unsigned char packet[],
bool report_buttons)
{
+ struct alps_data *priv = psmouse->private;
+ struct input_dev *dev;
+
+ /* Figure out which device to use to report the bare packet */
+ if (priv->proto_version == ALPS_PROTO_V2 &&
+ (priv->flags & ALPS_DUALPOINT)) {
+ /* On V2 devices the DualPoint Stick reports bare packets */
+ dev = priv->dev2;
+ } else if (unlikely(IS_ERR_OR_NULL(priv->dev3))) {
+ /* Register dev3 mouse if we received PS/2 packet first time */
+ if (!IS_ERR(priv->dev3))
+ psmouse_queue_work(psmouse, &priv->dev3_register_work,
+ 0);
+ return;
+ } else {
+ dev = priv->dev3;
+ }
+
if (report_buttons)
alps_report_buttons(dev, NULL,
packet[0] & 1, packet[0] & 2, packet[0] & 4);
* de-synchronization.
*/
- alps_report_bare_ps2_packet(priv->dev2,
- &psmouse->packet[3], false);
+ alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3],
+ false);
/*
* Continue with the standard ALPS protocol handling,
* properly we only do this if the device is fully synchronized.
*/
if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) {
-
- /* Register dev3 mouse if we received PS/2 packet first time */
- if (unlikely(!priv->dev3))
- psmouse_queue_work(psmouse,
- &priv->dev3_register_work, 0);
-
if (psmouse->pktcnt == 3) {
- /* Once dev3 mouse device is registered report data */
- if (likely(!IS_ERR_OR_NULL(priv->dev3)))
- alps_report_bare_ps2_packet(priv->dev3,
- psmouse->packet,
- true);
+ alps_report_bare_ps2_packet(psmouse, psmouse->packet,
+ true);
return PSMOUSE_FULL_PACKET;
}
return PSMOUSE_GOOD_DATA;
priv->set_abs_params = alps_set_abs_params_mt;
priv->nibble_commands = alps_v3_nibble_commands;
priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
- priv->x_max = 1360;
- priv->y_max = 660;
priv->x_bits = 23;
priv->y_bits = 12;
+
+ if (alps_dolphin_get_device_area(psmouse, priv))
+ return -EIO;
+
break;
case ALPS_PROTO_V6:
priv->set_abs_params = alps_set_abs_params_mt;
priv->nibble_commands = alps_v3_nibble_commands;
priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
-
- if (alps_dolphin_get_device_area(psmouse, priv))
- return -EIO;
+ priv->x_max = 0xfff;
+ priv->y_max = 0x7ff;
if (priv->fw_ver[1] != 0xba)
priv->flags |= ALPS_BUTTONPAD;
{ANY_BOARD_ID, ANY_BOARD_ID},
1024, 5022, 2508, 4832
},
+ {
+ (const char * const []){"LEN2006", NULL},
+ {2691, 2691},
+ 1024, 5045, 2457, 4832
+ },
{
(const char * const []){"LEN2006", NULL},
{ANY_BOARD_ID, ANY_BOARD_ID},
"LEN2003",
"LEN2004", /* L440 */
"LEN2005",
- "LEN2006",
+ "LEN2006", /* Edge E440/E540 */
"LEN2007",
"LEN2008",
"LEN2009",
static void its_encode_devid(struct its_cmd_block *cmd, u32 devid)
{
- cmd->raw_cmd[0] &= ~(0xffffUL << 32);
+ cmd->raw_cmd[0] &= BIT_ULL(32) - 1;
cmd->raw_cmd[0] |= ((u64)devid) << 32;
}
int i;
int psz = SZ_64K;
u64 shr = GITS_BASER_InnerShareable;
+ u64 cache = GITS_BASER_WaWb;
for (i = 0; i < GITS_BASER_NR_REGS; i++) {
u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
val = (virt_to_phys(base) |
(type << GITS_BASER_TYPE_SHIFT) |
((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
- GITS_BASER_WaWb |
+ cache |
shr |
GITS_BASER_VALID);
* Shareability didn't stick. Just use
* whatever the read reported, which is likely
* to be the only thing this redistributor
- * supports.
+ * supports. If that's zero, make it
+ * non-cacheable as well.
*/
shr = tmp & GITS_BASER_SHAREABILITY_MASK;
+ if (!shr)
+ cache = GITS_BASER_nC;
goto retry_baser;
}
tmp = readq_relaxed(rbase + GICR_PROPBASER);
if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
+ if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
+ /*
+ * The HW reports non-shareable, we must
+ * remove the cacheability attributes as
+ * well.
+ */
+ val &= ~(GICR_PROPBASER_SHAREABILITY_MASK |
+ GICR_PROPBASER_CACHEABILITY_MASK);
+ val |= GICR_PROPBASER_nC;
+ writeq_relaxed(val, rbase + GICR_PROPBASER);
+ }
pr_info_once("GIC: using cache flushing for LPI property table\n");
gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING;
}
/* set PENDBASE */
val = (page_to_phys(pend_page) |
- GICR_PROPBASER_InnerShareable |
- GICR_PROPBASER_WaWb);
+ GICR_PENDBASER_InnerShareable |
+ GICR_PENDBASER_WaWb);
writeq_relaxed(val, rbase + GICR_PENDBASER);
+ tmp = readq_relaxed(rbase + GICR_PENDBASER);
+
+ if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
+ /*
+ * The HW reports non-shareable, we must remove the
+ * cacheability attributes as well.
+ */
+ val &= ~(GICR_PENDBASER_SHAREABILITY_MASK |
+ GICR_PENDBASER_CACHEABILITY_MASK);
+ val |= GICR_PENDBASER_nC;
+ writeq_relaxed(val, rbase + GICR_PENDBASER);
+ }
/* Enable LPIs */
val = readl_relaxed(rbase + GICR_CTLR);
* This ITS wants a linear CPU number.
*/
target = readq_relaxed(gic_data_rdist_rd_base() + GICR_TYPER);
- target = GICR_TYPER_CPU_NUMBER(target);
+ target = GICR_TYPER_CPU_NUMBER(target) << 16;
}
/* Perform collection mapping */
writeq_relaxed(baser, its->base + GITS_CBASER);
tmp = readq_relaxed(its->base + GITS_CBASER);
- writeq_relaxed(0, its->base + GITS_CWRITER);
- writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
- if ((tmp ^ baser) & GITS_BASER_SHAREABILITY_MASK) {
+ if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
+ if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
+ /*
+ * The HW reports non-shareable, we must
+ * remove the cacheability attributes as
+ * well.
+ */
+ baser &= ~(GITS_CBASER_SHAREABILITY_MASK |
+ GITS_CBASER_CACHEABILITY_MASK);
+ baser |= GITS_CBASER_nC;
+ writeq_relaxed(baser, its->base + GITS_CBASER);
+ }
pr_info("ITS: using cache flushing for cmd queue\n");
its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING;
}
+ writeq_relaxed(0, its->base + GITS_CWRITER);
+ writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
+
if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) {
its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its);
if (!its->domain) {
static int mvneta_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct mvneta_port *pp = netdev_priv(dev);
- int ret;
if (!pp->phy_dev)
return -ENOTSUPP;
- ret = phy_mii_ioctl(pp->phy_dev, ifr, cmd);
- if (!ret)
- mvneta_adjust_link(dev);
-
- return ret;
+ return phy_mii_ioctl(pp->phy_dev, ifr, cmd);
}
/* Ethtool methods */
* on the host, we deprecate the error message for this
* specific command/input_mod/opcode_mod/fw-status to be debug.
*/
- if (op == MLX4_CMD_SET_PORT && in_modifier == 1 &&
+ if (op == MLX4_CMD_SET_PORT &&
+ (in_modifier == 1 || in_modifier == 2) &&
op_modifier == MLX4_SET_PORT_IB_OPCODE &&
context->fw_status == CMD_STAT_BAD_SIZE)
mlx4_dbg(dev, "command 0x%x failed: fw status = 0x%x\n",
static int xennet_change_mtu(struct net_device *dev, int mtu)
{
- int max = xennet_can_sg(dev) ?
- XEN_NETIF_MAX_TX_SIZE - MAX_TCP_HEADER : ETH_DATA_LEN;
+ int max = xennet_can_sg(dev) ? XEN_NETIF_MAX_TX_SIZE : ETH_DATA_LEN;
if (mtu > max)
return -EINVAL;
netdev->ethtool_ops = &xennet_ethtool_ops;
SET_NETDEV_DEV(netdev, &dev->dev);
- netif_set_gso_max_size(netdev, XEN_NETIF_MAX_TX_SIZE - MAX_TCP_HEADER);
-
np->netdev = netdev;
netif_carrier_off(netdev);
return NULL;
}
-static int of_empty_ranges_quirk(void)
+static int of_empty_ranges_quirk(struct device_node *np)
{
if (IS_ENABLED(CONFIG_PPC)) {
- /* To save cycles, we cache the result */
+ /* To save cycles, we cache the result for global "Mac" setting */
static int quirk_state = -1;
+ /* PA-SEMI sdc DT bug */
+ if (of_device_is_compatible(np, "1682m-sdc"))
+ return true;
+
+ /* Make quirk cached */
if (quirk_state < 0)
quirk_state =
of_machine_is_compatible("Power Macintosh") ||
* This code is only enabled on powerpc. --gcl
*/
ranges = of_get_property(parent, rprop, &rlen);
- if (ranges == NULL && !of_empty_ranges_quirk()) {
+ if (ranges == NULL && !of_empty_ranges_quirk(parent)) {
pr_debug("OF: no ranges; cannot translate\n");
return 1;
}
config IIO_SIMPLE_DUMMY_BUFFER
bool "Buffered capture support"
select IIO_BUFFER
+ select IIO_TRIGGER
select IIO_KFIFO_BUF
help
Add buffered data capture to the simple dummy driver.
mutex_init(&data->lock);
indio_dev->dev.parent = dev;
+ indio_dev->name = dev->driver->name;
indio_dev->info = &hmc5843_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = data->variant->channels;
writeb(val | UARTPFIFO_TXFE | UARTPFIFO_RXFE,
sport->port.membase + UARTPFIFO);
+ /* explicitly clear RDRF */
+ readb(sport->port.membase + UARTSR1);
+
/* flush Tx and Rx FIFO */
writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH,
sport->port.membase + UARTCFIFO);
sport->txfifo_size = 0x1 << (((temp >> UARTPFIFO_TXSIZE_OFF) &
UARTPFIFO_FIFOSIZE_MASK) + 1);
+ sport->port.fifosize = sport->txfifo_size;
+
sport->rxfifo_size = 0x1 << (((temp >> UARTPFIFO_RXSIZE_OFF) &
UARTPFIFO_FIFOSIZE_MASK) + 1);
free_irq(ourport->tx_irq, ourport);
tx_enabled(port) = 0;
ourport->tx_claimed = 0;
+ ourport->tx_mode = 0;
}
if (ourport->rx_claimed) {
status = PORT_PLC;
port_change_bit = "link state";
break;
+ case USB_PORT_FEAT_C_PORT_CONFIG_ERROR:
+ status = PORT_CEC;
+ port_change_bit = "config error";
+ break;
default:
/* Should never happen */
return;
status |= USB_PORT_STAT_C_LINK_STATE << 16;
if ((raw_port_status & PORT_WRC))
status |= USB_PORT_STAT_C_BH_RESET << 16;
+ if ((raw_port_status & PORT_CEC))
+ status |= USB_PORT_STAT_C_CONFIG_ERROR << 16;
}
if (hcd->speed != HCD_USB3) {
case USB_PORT_FEAT_C_OVER_CURRENT:
case USB_PORT_FEAT_C_ENABLE:
case USB_PORT_FEAT_C_PORT_LINK_STATE:
+ case USB_PORT_FEAT_C_PORT_CONFIG_ERROR:
xhci_clear_port_change_bit(xhci, wValue, wIndex,
port_array[wIndex], temp);
break;
*/
status = bus_state->resuming_ports;
- mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC;
+ mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC;
spin_lock_irqsave(&xhci->lock, flags);
/* For each port, did anything change? If so, set that bit in buf. */
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
xhci->quirks |= XHCI_LPM_SUPPORT;
xhci->quirks |= XHCI_INTEL_HOST;
+ xhci->quirks |= XHCI_AVOID_BEI;
}
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) {
* PPT chipsets.
*/
xhci->quirks |= XHCI_SPURIOUS_REBOOT;
- xhci->quirks |= XHCI_AVOID_BEI;
}
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
if (udc->driver) {
dev_err(udc->isp->dev, "UDC already has a gadget driver\n");
- spin_unlock(&udc->lock);
+ spin_unlock_irqrestore(&udc->lock, flags);
return -EBUSY;
}
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLXM_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_SYNAPSE_SS200_PID) },
/*
* ELV devices:
*/
{
struct usb_device *udev = serial->dev;
- if ((udev->manufacturer && !strcmp(udev->manufacturer, "CALAO Systems")) ||
- (udev->product && !strcmp(udev->product, "BeagleBone/XDS100V2")))
+ if (udev->manufacturer && !strcmp(udev->manufacturer, "CALAO Systems"))
+ return ftdi_jtag_probe(serial);
+
+ if (udev->product &&
+ (!strcmp(udev->product, "BeagleBone/XDS100V2") ||
+ !strcmp(udev->product, "SNAP Connect E10")))
return ftdi_jtag_probe(serial);
return 0;
*/
#define FTDI_NT_ORIONLXM_PID 0x7c90 /* OrionLXm Substation Automation Platform */
+/*
+ * Synapse Wireless product ids (FTDI_VID)
+ * http://www.synapse-wireless.com
+ */
+#define FTDI_SYNAPSE_SS200_PID 0x9090 /* SS200 - SNAP Stick 200 */
+
/********************************/
/** third-party VID/PID combos **/
/* For Xircom PGSDB9 and older Entrega version of the same device */
#define XIRCOM_VENDOR_ID 0x085a
#define XIRCOM_FAKE_ID 0x8027
+#define XIRCOM_FAKE_ID_2 0x8025 /* "PGMFHUB" serial */
#define ENTREGA_VENDOR_ID 0x1645
#define ENTREGA_FAKE_ID 0x8093
#endif
#ifdef XIRCOM
{ USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
+ { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID_2) },
{ USB_DEVICE(ENTREGA_VENDOR_ID, ENTREGA_FAKE_ID) },
#endif
{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
#ifdef XIRCOM
static const struct usb_device_id id_table_fake_xircom[] = {
{ USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
+ { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID_2) },
{ USB_DEVICE(ENTREGA_VENDOR_ID, ENTREGA_FAKE_ID) },
{ }
};
In that case step 3 should be omitted.
+config XEN_BALLOON_MEMORY_HOTPLUG_LIMIT
+ int "Hotplugged memory limit (in GiB) for a PV guest"
+ default 512 if X86_64
+ default 4 if X86_32
+ range 0 64 if X86_32
+ depends on XEN_HAVE_PVMMU
+ depends on XEN_BALLOON_MEMORY_HOTPLUG
+ help
+ Maxmium amount of memory (in GiB) that a PV guest can be
+ expanded to when using memory hotplug.
+
+ A PV guest can have more memory than this limit if is
+ started with a larger maximum.
+
+ This value is used to allocate enough space in internal
+ tables needed for physical memory administration.
+
config XEN_SCRUB_PAGES
bool "Scrub pages before returning them to system"
depends on XEN_BALLOON
balloon_hotplug = round_up(balloon_hotplug, PAGES_PER_SECTION);
nid = memory_add_physaddr_to_nid(hotplug_start_paddr);
+#ifdef CONFIG_XEN_HAVE_PVMMU
+ /*
+ * add_memory() will build page tables for the new memory so
+ * the p2m must contain invalid entries so the correct
+ * non-present PTEs will be written.
+ *
+ * If a failure occurs, the original (identity) p2m entries
+ * are not restored since this region is now known not to
+ * conflict with any devices.
+ */
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ unsigned long pfn, i;
+
+ pfn = PFN_DOWN(hotplug_start_paddr);
+ for (i = 0; i < balloon_hotplug; i++) {
+ if (!set_phys_to_machine(pfn + i, INVALID_P2M_ENTRY)) {
+ pr_warn("set_phys_to_machine() failed, no memory added\n");
+ return BP_ECANCELED;
+ }
+ }
+ }
+#endif
+
rc = add_memory(nid, hotplug_start_paddr, balloon_hotplug << PAGE_SHIFT);
if (rc) {
/*
* fs/cifs/cifsencrypt.c
*
+ * Encryption and hashing operations relating to NTLM, NTLMv2. See MS-NLMP
+ * for more detailed information
+ *
* Copyright (C) International Business Machines Corp., 2005,2013
* Author(s): Steve French (sfrench@us.ibm.com)
*
__func__);
return rc;
}
- } else if (ses->serverName) {
+ } else {
+ /* We use ses->serverName if no domain name available */
len = strlen(ses->serverName);
server = kmalloc(2 + (len * 2), GFP_KERNEL);
pr_warn("CIFS: username too long\n");
goto cifs_parse_mount_err;
}
+
+ kfree(vol->username);
vol->username = kstrdup(string, GFP_KERNEL);
if (!vol->username)
goto cifs_parse_mount_err;
goto cifs_parse_mount_err;
}
+ kfree(vol->domainname);
vol->domainname = kstrdup(string, GFP_KERNEL);
if (!vol->domainname) {
pr_warn("CIFS: no memory for domainname\n");
}
if (strncasecmp(string, "default", 7) != 0) {
+ kfree(vol->iocharset);
vol->iocharset = kstrdup(string,
GFP_KERNEL);
if (!vol->iocharset) {
* calling name ends in null (byte 16) from old smb
* convention.
*/
- if (server->workstation_RFC1001_name &&
- server->workstation_RFC1001_name[0] != 0)
+ if (server->workstation_RFC1001_name[0] != 0)
rfc1002mangle(ses_init_buf->trailer.
session_req.calling_name,
server->workstation_RFC1001_name,
#endif /* CIFS_WEAK_PW_HASH */
rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
bcc_ptr, nls_codepage);
+ if (rc) {
+ cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
+ __func__, rc);
+ cifs_buf_release(smb_buffer);
+ return rc;
+ }
bcc_ptr += CIFS_AUTH_RESP_SIZE;
if (ses->capabilities & CAP_UNICODE) {
cifsFileInfo_put(inv_file);
spin_lock(&cifs_file_list_lock);
++refind;
+ inv_file = NULL;
goto refind_writable;
}
}
cifs_buf_release(srchinf->ntwrk_buf_start);
}
kfree(srchinf);
+ if (rc)
+ goto cgii_exit;
} else
goto cgii_exit;
/* return pointer to beginning of data area, ie offset from SMB start */
if ((*off != 0) && (*len != 0))
- return hdr->ProtocolId + *off;
+ return (char *)(&hdr->ProtocolId[0]) + *off;
else
return NULL;
}
/* No need to change MaxChunks since already set to 1 */
chunk_sizes_updated = true;
- }
+ } else
+ goto cchunk_out;
}
cchunk_out:
struct smb2_ioctl_req *req;
struct smb2_ioctl_rsp *rsp;
struct TCP_Server_Info *server;
- struct cifs_ses *ses = tcon->ses;
+ struct cifs_ses *ses;
struct kvec iov[2];
int resp_buftype;
int num_iovecs;
if (plen)
*plen = 0;
+ if (tcon)
+ ses = tcon->ses;
+ else
+ return -EIO;
+
if (ses && (ses->server))
server = ses->server;
else
rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
if ((rc != 0) && (rc != -EINVAL)) {
- if (tcon)
- cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
+ cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
goto ioctl_exit;
} else if (rc == -EINVAL) {
if ((opcode != FSCTL_SRV_COPYCHUNK_WRITE) &&
(opcode != FSCTL_SRV_COPYCHUNK)) {
- if (tcon)
- cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
+ cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
goto ioctl_exit;
}
}
rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0);
- if ((rc != 0) && tcon)
+ if (rc != 0)
cifs_stats_fail_inc(tcon, SMB2_FLUSH_HE);
free_rsp_buf(resp_buftype, iov[0].iov_base);
struct kvec iov[2];
int rc = 0;
int len;
- int resp_buftype;
+ int resp_buftype = CIFS_NO_BUFFER;
unsigned char *bufptr;
struct TCP_Server_Info *server;
struct cifs_ses *ses = tcon->ses;
#define GICR_PROPBASER_WaWb (5U << 7)
#define GICR_PROPBASER_RaWaWt (6U << 7)
#define GICR_PROPBASER_RaWaWb (7U << 7)
+#define GICR_PROPBASER_CACHEABILITY_MASK (7U << 7)
#define GICR_PROPBASER_IDBITS_MASK (0x1f)
+#define GICR_PENDBASER_NonShareable (0U << 10)
+#define GICR_PENDBASER_InnerShareable (1U << 10)
+#define GICR_PENDBASER_OuterShareable (2U << 10)
+#define GICR_PENDBASER_SHAREABILITY_MASK (3UL << 10)
+#define GICR_PENDBASER_nCnB (0U << 7)
+#define GICR_PENDBASER_nC (1U << 7)
+#define GICR_PENDBASER_RaWt (2U << 7)
+#define GICR_PENDBASER_RaWb (3U << 7)
+#define GICR_PENDBASER_WaWt (4U << 7)
+#define GICR_PENDBASER_WaWb (5U << 7)
+#define GICR_PENDBASER_RaWaWt (6U << 7)
+#define GICR_PENDBASER_RaWaWb (7U << 7)
+#define GICR_PENDBASER_CACHEABILITY_MASK (7U << 7)
+
/*
* Re-Distributor registers, offsets from SGI_base
*/
#define GITS_CBASER_WaWb (5UL << 59)
#define GITS_CBASER_RaWaWt (6UL << 59)
#define GITS_CBASER_RaWaWb (7UL << 59)
+#define GITS_CBASER_CACHEABILITY_MASK (7UL << 59)
#define GITS_CBASER_NonShareable (0UL << 10)
#define GITS_CBASER_InnerShareable (1UL << 10)
#define GITS_CBASER_OuterShareable (2UL << 10)
#define GITS_BASER_WaWb (5UL << 59)
#define GITS_BASER_RaWaWt (6UL << 59)
#define GITS_BASER_RaWaWb (7UL << 59)
+#define GITS_BASER_CACHEABILITY_MASK (7UL << 59)
#define GITS_BASER_TYPE_SHIFT (56)
#define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7)
#define GITS_BASER_ENTRY_SIZE_SHIFT (48)
#include <linux/compiler.h>
unsigned long lcm(unsigned long a, unsigned long b) __attribute_const__;
+unsigned long lcm_not_zero(unsigned long a, unsigned long b) __attribute_const__;
#endif /* _LCM_H */
void synchronize_net(void);
int init_dummy_netdev(struct net_device *dev);
+DECLARE_PER_CPU(int, xmit_recursion);
+static inline int dev_recursion_level(void)
+{
+ return this_cpu_read(xmit_recursion);
+}
+
struct net_device *dev_get_by_index(struct net *net, int ifindex);
struct net_device *__dev_get_by_index(struct net *net, int ifindex);
struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
#endif
-static inline int sk_mc_loop(struct sock *sk)
-{
- if (!sk)
- return 1;
- switch (sk->sk_family) {
- case AF_INET:
- return inet_sk(sk)->mc_loop;
-#if IS_ENABLED(CONFIG_IPV6)
- case AF_INET6:
- return inet6_sk(sk)->mc_loop;
-#endif
- }
- WARN_ON(1);
- return 1;
-}
-
bool ip_call_ra_chain(struct sk_buff *skb);
/*
static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
{
- struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
+ struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
+ inet6_sk(skb->sk) : NULL;
return (np && np->pmtudisc >= IPV6_PMTUDISC_PROBE) ?
skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie);
+bool sk_mc_loop(struct sock *sk);
+
static inline bool sk_can_gso(const struct sock *sk)
{
return net_gso_ok(sk->sk_route_caps, sk->sk_gso_type);
*/
#define MT_TOOL_FINGER 0
#define MT_TOOL_PEN 1
-#define MT_TOOL_MAX 1
+#define MT_TOOL_PALM 2
+#define MT_TOOL_MAX 2
/*
* Values describing the status of a force-feedback effect
return 0;
}
EXPORT_SYMBOL_GPL(lcm);
+
+unsigned long lcm_not_zero(unsigned long a, unsigned long b)
+{
+ unsigned long l = lcm(a, b);
+
+ if (l)
+ return l;
+
+ return (b ? : a);
+}
+EXPORT_SYMBOL_GPL(lcm_not_zero);
#define skb_update_prio(skb)
#endif
-static DEFINE_PER_CPU(int, xmit_recursion);
+DEFINE_PER_CPU(int, xmit_recursion);
+EXPORT_SYMBOL(xmit_recursion);
+
#define RECURSION_LIMIT 10
/**
spin_lock(&net->rules_mod_lock);
list_del_rcu(&ops->list);
- fib_rules_cleanup_ops(ops);
spin_unlock(&net->rules_mod_lock);
+ fib_rules_cleanup_ops(ops);
kfree_rcu(ops, rcu);
}
EXPORT_SYMBOL_GPL(fib_rules_unregister);
*/
int peernet2id(struct net *net, struct net *peer)
{
- int id = __peernet2id(net, peer, true);
+ bool alloc = atomic_read(&peer->count) == 0 ? false : true;
+ int id;
+ id = __peernet2id(net, peer, alloc);
return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED;
}
EXPORT_SYMBOL(peernet2id);
static void cleanup_net(struct work_struct *work)
{
const struct pernet_operations *ops;
- struct net *net, *tmp, *peer;
+ struct net *net, *tmp;
struct list_head net_kill_list;
LIST_HEAD(net_exit_list);
list_for_each_entry(net, &net_kill_list, cleanup_list) {
list_del_rcu(&net->list);
list_add_tail(&net->exit_list, &net_exit_list);
+ for_each_net(tmp) {
+ int id = __peernet2id(tmp, net, false);
+
+ if (id >= 0)
+ idr_remove(&tmp->netns_ids, id);
+ }
+ idr_destroy(&net->netns_ids);
+
}
rtnl_unlock();
*/
rcu_barrier();
- rtnl_lock();
/* Finally it is safe to free my network namespace structure */
list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
- /* Unreference net from all peers (no need to loop over
- * net_exit_list because idr_destroy() will be called for each
- * element of this list.
- */
- for_each_net(peer) {
- int id = __peernet2id(peer, net, false);
-
- if (id >= 0)
- idr_remove(&peer->netns_ids, id);
- }
- idr_destroy(&net->netns_ids);
-
list_del_init(&net->exit_list);
put_user_ns(net->user_ns);
net_drop_ns(net);
}
- rtnl_unlock();
}
static DECLARE_WORK(net_cleanup_work, cleanup_net);
sock_reset_flag(sk, bit);
}
+bool sk_mc_loop(struct sock *sk)
+{
+ if (dev_recursion_level())
+ return false;
+ if (!sk)
+ return true;
+ switch (sk->sk_family) {
+ case AF_INET:
+ return inet_sk(sk)->mc_loop;
+#if IS_ENABLED(CONFIG_IPV6)
+ case AF_INET6:
+ return inet6_sk(sk)->mc_loop;
+#endif
+ }
+ WARN_ON(1);
+ return true;
+}
+EXPORT_SYMBOL(sk_mc_loop);
+
/*
* This is meant for all protocols to use and covers goings on
* at the socket level. Everything here is generic.
void __exit dn_fib_rules_cleanup(void)
{
+ rtnl_lock();
fib_rules_unregister(dn_fib_rules_ops);
+ rtnl_unlock();
rcu_barrier();
}
#ifdef CONFIG_OF
static int dsa_of_setup_routing_table(struct dsa_platform_data *pd,
struct dsa_chip_data *cd,
- int chip_index,
+ int chip_index, int port_index,
struct device_node *link)
{
- int ret;
const __be32 *reg;
- int link_port_addr;
int link_sw_addr;
struct device_node *parent_sw;
int len;
if (!reg || (len != sizeof(*reg) * 2))
return -EINVAL;
+ /*
+ * Get the destination switch number from the second field of its 'reg'
+ * property, i.e. for "reg = <0x19 1>" sw_addr is '1'.
+ */
link_sw_addr = be32_to_cpup(reg + 1);
if (link_sw_addr >= pd->nr_chips)
memset(cd->rtable, -1, pd->nr_chips * sizeof(s8));
}
- reg = of_get_property(link, "reg", NULL);
- if (!reg) {
- ret = -EINVAL;
- goto out;
- }
-
- link_port_addr = be32_to_cpup(reg);
-
- cd->rtable[link_sw_addr] = link_port_addr;
+ cd->rtable[link_sw_addr] = port_index;
return 0;
-out:
- kfree(cd->rtable);
- return ret;
}
static void dsa_of_free_platform_data(struct dsa_platform_data *pd)
if (!strcmp(port_name, "dsa") && link &&
pd->nr_chips > 1) {
ret = dsa_of_setup_routing_table(pd, cd,
- chip_index, link);
+ chip_index, port_index, link);
if (ret)
goto out_free_chip;
}
unsigned int i;
rtnl_lock();
-
#ifdef CONFIG_IP_MULTIPLE_TABLES
RCU_INIT_POINTER(net->ipv4.fib_local, NULL);
RCU_INIT_POINTER(net->ipv4.fib_main, NULL);
RCU_INIT_POINTER(net->ipv4.fib_default, NULL);
#endif
-
for (i = 0; i < FIB_TABLE_HASHSZ; i++) {
struct hlist_head *head = &net->ipv4.fib_table_hash[i];
struct hlist_node *tmp;
{
struct mr_table *mrt, *next;
+ rtnl_lock();
list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) {
list_del(&mrt->list);
ipmr_free_table(mrt);
}
fib_rules_unregister(net->ipv4.mr_rules_ops);
+ rtnl_unlock();
}
#else
#define ipmr_for_each_table(mrt, net) \
static void __net_exit ipmr_rules_exit(struct net *net)
{
+ rtnl_lock();
ipmr_free_table(net->ipv4.mrt);
+ net->ipv4.mrt = NULL;
+ rtnl_unlock();
}
#endif
if (!first_ackt.v64)
first_ackt = last_ackt;
- if (!(sacked & TCPCB_SACKED_ACKED))
+ if (!(sacked & TCPCB_SACKED_ACKED)) {
reord = min(pkts_acked, reord);
- if (!after(scb->end_seq, tp->high_seq))
- flag |= FLAG_ORIG_SACK_ACKED;
+ if (!after(scb->end_seq, tp->high_seq))
+ flag |= FLAG_ORIG_SACK_ACKED;
+ }
}
if (sacked & TCPCB_SACKED_ACKED)
static void __net_exit fib6_rules_net_exit(struct net *net)
{
+ rtnl_lock();
fib_rules_unregister(net->ipv6.fib6_rules_ops);
+ rtnl_unlock();
}
static struct pernet_operations fib6_rules_net_ops = {
{
struct sk_buff *frag;
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
- struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
+ struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
+ inet6_sk(skb->sk) : NULL;
struct ipv6hdr *tmp_hdr;
struct frag_hdr *fh;
unsigned int mtu, hlen, left, len;
list_del(&mrt->list);
ip6mr_free_table(mrt);
}
- rtnl_unlock();
fib_rules_unregister(net->ipv6.mr6_rules_ops);
+ rtnl_unlock();
}
#else
#define ip6mr_for_each_table(mrt, net) \
static void ip6mr_free_table(struct mr6_table *mrt)
{
- del_timer(&mrt->ipmr_expire_timer);
+ del_timer_sync(&mrt->ipmr_expire_timer);
mroute_clean_tables(mrt);
kfree(mrt);
}
l2tp_wq = alloc_workqueue("l2tp", WQ_UNBOUND, 0);
if (!l2tp_wq) {
pr_err("alloc_workqueue failed\n");
+ unregister_pernet_device(&l2tp_net_ops);
rc = -ENOMEM;
goto out;
}