Revision ab170c27361d1578b4769276ce2bbdb14394743d authored by Ondrej Jirman on 21 April 2018, 04:51:55 UTC, committed by Sean Paul on 25 April 2018, 19:03:12 UTC
The reverted commit broke LVDS output on TBS A711 Tablet. That tablet
has simple-panel node that has fixed pixel clock-frequency that A83T
SoC used in the tablet can't generate exactly.

Requested rate is 52000000 and rounded_rate is calculated as 51857142.
It's close enough for it to work in practice, but with strict check
in the reverted commit, the mode is rejected needlessly in this case.

DT allows to specify a range of values for simple-panel/clock-frequency,
but driver doesn't respect that ATM. Given that TBS A711 is the single
user of sun4i-lvds driver, let's revert that commit for now, until
a better solution for the problem is found.

Also see: https://patchwork.kernel.org/patch/9446385/ for relevant
discussion (or search for "[RFC] drm/sun4i: rgb: Add 5% tolerance
to dot clock frequency check").

Fixes: e4e4b7ad50cf ("drm/sun4i: add lvds mode_valid function")
Reported-by: Ondrej Jirman <megous@megous.com>
Signed-off-by: Ondrej Jirman <megous@megous.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180421045155.15332-1-megous@megous.com
Signed-off-by: Sean Paul <seanpaul@chromium.org>
1 parent 6d08b06
Raw File
vsock_addr.c
/*
 * VMware vSockets Driver
 *
 * Copyright (C) 2007-2012 VMware, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation version 2 and no later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#include <linux/types.h>
#include <linux/socket.h>
#include <linux/stddef.h>
#include <net/sock.h>
#include <net/vsock_addr.h>

void vsock_addr_init(struct sockaddr_vm *addr, u32 cid, u32 port)
{
	memset(addr, 0, sizeof(*addr));
	addr->svm_family = AF_VSOCK;
	addr->svm_cid = cid;
	addr->svm_port = port;
}
EXPORT_SYMBOL_GPL(vsock_addr_init);

int vsock_addr_validate(const struct sockaddr_vm *addr)
{
	if (!addr)
		return -EFAULT;

	if (addr->svm_family != AF_VSOCK)
		return -EAFNOSUPPORT;

	if (addr->svm_zero[0] != 0)
		return -EINVAL;

	return 0;
}
EXPORT_SYMBOL_GPL(vsock_addr_validate);

bool vsock_addr_bound(const struct sockaddr_vm *addr)
{
	return addr->svm_port != VMADDR_PORT_ANY;
}
EXPORT_SYMBOL_GPL(vsock_addr_bound);

void vsock_addr_unbind(struct sockaddr_vm *addr)
{
	vsock_addr_init(addr, VMADDR_CID_ANY, VMADDR_PORT_ANY);
}
EXPORT_SYMBOL_GPL(vsock_addr_unbind);

bool vsock_addr_equals_addr(const struct sockaddr_vm *addr,
			    const struct sockaddr_vm *other)
{
	return addr->svm_cid == other->svm_cid &&
		addr->svm_port == other->svm_port;
}
EXPORT_SYMBOL_GPL(vsock_addr_equals_addr);

int vsock_addr_cast(const struct sockaddr *addr,
		    size_t len, struct sockaddr_vm **out_addr)
{
	if (len < sizeof(**out_addr))
		return -EFAULT;

	*out_addr = (struct sockaddr_vm *)addr;
	return vsock_addr_validate(*out_addr);
}
EXPORT_SYMBOL_GPL(vsock_addr_cast);
back to top