Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98965287 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'device-properties'

* device-properties:
  device property: avoid allocations of 0 length
  device property: the secondary fwnode needs to depend on the primary
  device property: add spaces to PROPERTY_ENTRY_STRING macro
  include/linux/property.h: fix build issues with gcc-4.4.4
  i2c: designware: Convert to use unified device property API
  mfd: intel-lpss: Pass HSUART configuration via properties
  mfd: intel-lpss: Pass SDA hold time to I2C host controller driver
  mfd: intel-lpss: Add support for passing device properties
  mfd: core: propagate device properties to sub devices drivers
  driver core: Do not overwrite secondary fwnode with NULL if it is set
  driver core: platform: Add support for built-in device properties
  device property: Take a copy of the property set
  device property: Fallback to secondary fwnode if primary misses the property
  device property: return -EINVAL when property isn't found in ACPI
  device property: improve readability of macros
  device property: helper macros for property entry creation
  device property: keep single value inplace
  device property: refactor built-in properties support
  device property: rename helper functions
  device property: always check for fwnode type
parents afd2ff9b f6740c18
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -346,7 +346,7 @@ void acpi_free_properties(struct acpi_device *adev)
 *
 * Return: %0 if property with @name has been found (success),
 *         %-EINVAL if the arguments are invalid,
 *         %-ENODATA if the property doesn't exist,
 *         %-EINVAL if the property doesn't exist,
 *         %-EPROTO if the property value type doesn't match @type.
 */
static int acpi_data_get_property(struct acpi_device_data *data,
@@ -360,7 +360,7 @@ static int acpi_data_get_property(struct acpi_device_data *data,
		return -EINVAL;

	if (!data->pointer || !data->properties)
		return -ENODATA;
		return -EINVAL;

	properties = data->properties;
	for (i = 0; i < properties->package.count; i++) {
@@ -375,13 +375,13 @@ static int acpi_data_get_property(struct acpi_device_data *data,
		if (!strcmp(name, propname->string.pointer)) {
			if (type != ACPI_TYPE_ANY && propvalue->type != type)
				return -EPROTO;
			else if (obj)
			if (obj)
				*obj = propvalue;

			return 0;
		}
	}
	return -ENODATA;
	return -EINVAL;
}

/**
@@ -439,7 +439,7 @@ int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
 *
 * Return: %0 if array property (package) with @name has been found (success),
 *         %-EINVAL if the arguments are invalid,
 *         %-ENODATA if the property doesn't exist,
 *         %-EINVAL if the property doesn't exist,
 *         %-EPROTO if the property is not a package or the type of its elements
 *           doesn't match @type.
 */
+4 −1
Original line number Diff line number Diff line
@@ -2261,7 +2261,10 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
		if (fwnode_is_primary(fn))
			fn = fn->secondary;

		if (fn) {
			WARN_ON(fwnode->secondary);
			fwnode->secondary = fn;
		}
		dev->fwnode = fwnode;
	} else {
		dev->fwnode = fwnode_is_primary(dev->fwnode) ?
+25 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/acpi.h>
#include <linux/clk/clk-conf.h>
#include <linux/limits.h>
#include <linux/property.h>

#include "base.h"
#include "power/power.h"
@@ -298,6 +299,22 @@ int platform_device_add_data(struct platform_device *pdev, const void *data,
}
EXPORT_SYMBOL_GPL(platform_device_add_data);

/**
 * platform_device_add_properties - add built-in properties to a platform device
 * @pdev: platform device to add properties to
 * @pset: properties to add
 *
 * The function will take deep copy of the properties in @pset and attach
 * the copy to the platform device. The memory associated with properties
 * will be freed when the platform device is released.
 */
int platform_device_add_properties(struct platform_device *pdev,
				   const struct property_set *pset)
{
	return device_add_property_set(&pdev->dev, pset);
}
EXPORT_SYMBOL_GPL(platform_device_add_properties);

/**
 * platform_device_add - add a platform device to device hierarchy
 * @pdev: platform device we're adding
@@ -409,6 +426,8 @@ void platform_device_del(struct platform_device *pdev)
			if (r->parent)
				release_resource(r);
		}

		device_remove_property_set(&pdev->dev);
	}
}
EXPORT_SYMBOL_GPL(platform_device_del);
@@ -487,6 +506,12 @@ struct platform_device *platform_device_register_full(
	if (ret)
		goto err;

	if (pdevinfo->pset) {
		ret = platform_device_add_properties(pdev, pdevinfo->pset);
		if (ret)
			goto err;
	}

	ret = platform_device_add(pdev);
	if (ret) {
err:
+401 −94
Original line number Diff line number Diff line
@@ -19,32 +19,14 @@
#include <linux/etherdevice.h>
#include <linux/phy.h>

/**
 * device_add_property_set - Add a collection of properties to a device object.
 * @dev: Device to add properties to.
 * @pset: Collection of properties to add.
 *
 * Associate a collection of device properties represented by @pset with @dev
 * as its secondary firmware node.
 */
void device_add_property_set(struct device *dev, struct property_set *pset)
{
	if (!pset)
		return;

	pset->fwnode.type = FWNODE_PDATA;
	set_secondary_fwnode(dev, &pset->fwnode);
}
EXPORT_SYMBOL_GPL(device_add_property_set);

static inline bool is_pset(struct fwnode_handle *fwnode)
static inline bool is_pset_node(struct fwnode_handle *fwnode)
{
	return fwnode && fwnode->type == FWNODE_PDATA;
}

static inline struct property_set *to_pset(struct fwnode_handle *fwnode)
static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode)
{
	return is_pset(fwnode) ?
	return is_pset_node(fwnode) ?
		container_of(fwnode, struct property_set, fwnode) : NULL;
}

@@ -63,45 +45,135 @@ static struct property_entry *pset_prop_get(struct property_set *pset,
	return NULL;
}

static int pset_prop_read_array(struct property_set *pset, const char *name,
				enum dev_prop_type type, void *val, size_t nval)
static void *pset_prop_find(struct property_set *pset, const char *propname,
			    size_t length)
{
	struct property_entry *prop;
	unsigned int item_size;
	void *pointer;

	prop = pset_prop_get(pset, name);
	prop = pset_prop_get(pset, propname);
	if (!prop)
		return -ENODATA;
		return ERR_PTR(-EINVAL);
	if (prop->is_array)
		pointer = prop->pointer.raw_data;
	else
		pointer = &prop->value.raw_data;
	if (!pointer)
		return ERR_PTR(-ENODATA);
	if (length > prop->length)
		return ERR_PTR(-EOVERFLOW);
	return pointer;
}

	if (prop->type != type)
		return -EPROTO;
static int pset_prop_read_u8_array(struct property_set *pset,
				   const char *propname,
				   u8 *values, size_t nval)
{
	void *pointer;
	size_t length = nval * sizeof(*values);

	if (!val)
		return prop->nval;
	pointer = pset_prop_find(pset, propname, length);
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);

	if (prop->nval < nval)
		return -EOVERFLOW;
	memcpy(values, pointer, length);
	return 0;
}

	switch (type) {
	case DEV_PROP_U8:
		item_size = sizeof(u8);
		break;
	case DEV_PROP_U16:
		item_size = sizeof(u16);
		break;
	case DEV_PROP_U32:
		item_size = sizeof(u32);
		break;
	case DEV_PROP_U64:
		item_size = sizeof(u64);
		break;
	case DEV_PROP_STRING:
		item_size = sizeof(const char *);
		break;
	default:
static int pset_prop_read_u16_array(struct property_set *pset,
				    const char *propname,
				    u16 *values, size_t nval)
{
	void *pointer;
	size_t length = nval * sizeof(*values);

	pointer = pset_prop_find(pset, propname, length);
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);

	memcpy(values, pointer, length);
	return 0;
}

static int pset_prop_read_u32_array(struct property_set *pset,
				    const char *propname,
				    u32 *values, size_t nval)
{
	void *pointer;
	size_t length = nval * sizeof(*values);

	pointer = pset_prop_find(pset, propname, length);
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);

	memcpy(values, pointer, length);
	return 0;
}

static int pset_prop_read_u64_array(struct property_set *pset,
				    const char *propname,
				    u64 *values, size_t nval)
{
	void *pointer;
	size_t length = nval * sizeof(*values);

	pointer = pset_prop_find(pset, propname, length);
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);

	memcpy(values, pointer, length);
	return 0;
}

static int pset_prop_count_elems_of_size(struct property_set *pset,
					 const char *propname, size_t length)
{
	struct property_entry *prop;

	prop = pset_prop_get(pset, propname);
	if (!prop)
		return -EINVAL;

	return prop->length / length;
}

static int pset_prop_read_string_array(struct property_set *pset,
				       const char *propname,
				       const char **strings, size_t nval)
{
	void *pointer;
	size_t length = nval * sizeof(*strings);

	pointer = pset_prop_find(pset, propname, length);
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);

	memcpy(strings, pointer, length);
	return 0;
}

static int pset_prop_read_string(struct property_set *pset,
				 const char *propname, const char **strings)
{
	struct property_entry *prop;
	const char **pointer;

	prop = pset_prop_get(pset, propname);
	if (!prop)
		return -EINVAL;
	if (!prop->is_string)
		return -EILSEQ;
	if (prop->is_array) {
		pointer = prop->pointer.str;
		if (!pointer)
			return -ENODATA;
	} else {
		pointer = &prop->value.str;
		if (*pointer && strnlen(*pointer, prop->length) >= prop->length)
			return -EILSEQ;
	}
	memcpy(val, prop->value.raw_data, nval * item_size);

	*strings = *pointer;
	return 0;
}

@@ -124,6 +196,18 @@ bool device_property_present(struct device *dev, const char *propname)
}
EXPORT_SYMBOL_GPL(device_property_present);

static bool __fwnode_property_present(struct fwnode_handle *fwnode,
				      const char *propname)
{
	if (is_of_node(fwnode))
		return of_property_read_bool(to_of_node(fwnode), propname);
	else if (is_acpi_node(fwnode))
		return !acpi_node_prop_get(fwnode, propname, NULL);
	else if (is_pset_node(fwnode))
		return !!pset_prop_get(to_pset_node(fwnode), propname);
	return false;
}

/**
 * fwnode_property_present - check if a property of a firmware node is present
 * @fwnode: Firmware node whose property to check
@@ -131,12 +215,12 @@ EXPORT_SYMBOL_GPL(device_property_present);
 */
bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
{
	if (is_of_node(fwnode))
		return of_property_read_bool(to_of_node(fwnode), propname);
	else if (is_acpi_node(fwnode))
		return !acpi_node_prop_get(fwnode, propname, NULL);
	bool ret;

	return !!pset_prop_get(to_pset(fwnode), propname);
	ret = __fwnode_property_present(fwnode, propname);
	if (ret == false && fwnode && fwnode->secondary)
		ret = __fwnode_property_present(fwnode->secondary, propname);
	return ret;
}
EXPORT_SYMBOL_GPL(fwnode_property_present);

@@ -313,7 +397,11 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
	(val) ? of_property_read_##type##_array((node), (propname), (val), (nval))	\
	      : of_property_count_elems_of_size((node), (propname), sizeof(type))

#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
#define PSET_PROP_READ_ARRAY(node, propname, type, val, nval)				\
	(val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval))	\
	      : pset_prop_count_elems_of_size((node), (propname), sizeof(type))

#define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_)	\
({											\
	int _ret_;									\
	if (is_of_node(_fwnode_))							\
@@ -322,14 +410,25 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
	else if (is_acpi_node(_fwnode_))						\
		_ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_,		\
					    _val_, _nval_);				\
	else if (is_pset(_fwnode_)) \
		_ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \
					     _proptype_, _val_, _nval_); \
	else if (is_pset_node(_fwnode_)) 						\
		_ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_,	\
					     _type_, _val_, _nval_);			\
	else										\
		_ret_ = -ENXIO;								\
	_ret_;										\
})

#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_)	\
({											\
	int _ret_;									\
	_ret_ = FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_,		\
				 _val_, _nval_);					\
	if (_ret_ == -EINVAL && _fwnode_ && _fwnode_->secondary)			\
		_ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_,	\
				_proptype_, _val_, _nval_);				\
	_ret_;										\
})

/**
 * fwnode_property_read_u8_array - return a u8 array property of firmware node
 * @fwnode: Firmware node to get the property of
@@ -434,6 +533,41 @@ int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
}
EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);

static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
					       const char *propname,
					       const char **val, size_t nval)
{
	if (is_of_node(fwnode))
		return val ?
			of_property_read_string_array(to_of_node(fwnode),
						      propname, val, nval) :
			of_property_count_strings(to_of_node(fwnode), propname);
	else if (is_acpi_node(fwnode))
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
					   val, nval);
	else if (is_pset_node(fwnode))
		return val ?
			pset_prop_read_string_array(to_pset_node(fwnode),
						    propname, val, nval) :
			pset_prop_count_elems_of_size(to_pset_node(fwnode),
						      propname,
						      sizeof(const char *));
	return -ENXIO;
}

static int __fwnode_property_read_string(struct fwnode_handle *fwnode,
					 const char *propname, const char **val)
{
	if (is_of_node(fwnode))
		return of_property_read_string(to_of_node(fwnode), propname, val);
	else if (is_acpi_node(fwnode))
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
					   val, 1);
	else if (is_pset_node(fwnode))
		return pset_prop_read_string(to_pset_node(fwnode), propname, val);
	return -ENXIO;
}

/**
 * fwnode_property_read_string_array - return string array property of a node
 * @fwnode: Firmware node to get the property of
@@ -456,18 +590,13 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
				      const char *propname, const char **val,
				      size_t nval)
{
	if (is_of_node(fwnode))
		return val ?
			of_property_read_string_array(to_of_node(fwnode),
						      propname, val, nval) :
			of_property_count_strings(to_of_node(fwnode), propname);
	else if (is_acpi_node(fwnode))
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
					   val, nval);
	else if (is_pset(fwnode))
		return pset_prop_read_array(to_pset(fwnode), propname,
					    DEV_PROP_STRING, val, nval);
	return -ENXIO;
	int ret;

	ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
	if (ret == -EINVAL && fwnode && fwnode->secondary)
		ret = __fwnode_property_read_string_array(fwnode->secondary,
							  propname, val, nval);
	return ret;
}
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);

@@ -489,14 +618,13 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
int fwnode_property_read_string(struct fwnode_handle *fwnode,
				const char *propname, const char **val)
{
	if (is_of_node(fwnode))
		return of_property_read_string(to_of_node(fwnode), propname, val);
	else if (is_acpi_node(fwnode))
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
					   val, 1);
	int ret;

	return pset_prop_read_array(to_pset(fwnode), propname,
				    DEV_PROP_STRING, val, 1);
	ret = __fwnode_property_read_string(fwnode, propname, val);
	if (ret == -EINVAL && fwnode && fwnode->secondary)
		ret = __fwnode_property_read_string(fwnode->secondary,
						    propname, val);
	return ret;
}
EXPORT_SYMBOL_GPL(fwnode_property_read_string);

@@ -525,6 +653,9 @@ int fwnode_property_match_string(struct fwnode_handle *fwnode,
	if (nval < 0)
		return nval;

	if (nval == 0)
		return -ENODATA;

	values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
	if (!values)
		return -ENOMEM;
@@ -546,6 +677,182 @@ int fwnode_property_match_string(struct fwnode_handle *fwnode,
}
EXPORT_SYMBOL_GPL(fwnode_property_match_string);

/**
 * pset_free_set - releases memory allocated for copied property set
 * @pset: Property set to release
 *
 * Function takes previously copied property set and releases all the
 * memory allocated to it.
 */
static void pset_free_set(struct property_set *pset)
{
	const struct property_entry *prop;
	size_t i, nval;

	if (!pset)
		return;

	for (prop = pset->properties; prop->name; prop++) {
		if (prop->is_array) {
			if (prop->is_string && prop->pointer.str) {
				nval = prop->length / sizeof(const char *);
				for (i = 0; i < nval; i++)
					kfree(prop->pointer.str[i]);
			}
			kfree(prop->pointer.raw_data);
		} else if (prop->is_string) {
			kfree(prop->value.str);
		}
		kfree(prop->name);
	}

	kfree(pset->properties);
	kfree(pset);
}

static int pset_copy_entry(struct property_entry *dst,
			   const struct property_entry *src)
{
	const char **d, **s;
	size_t i, nval;

	dst->name = kstrdup(src->name, GFP_KERNEL);
	if (!dst->name)
		return -ENOMEM;

	if (src->is_array) {
		if (!src->length)
			return -ENODATA;

		if (src->is_string) {
			nval = src->length / sizeof(const char *);
			dst->pointer.str = kcalloc(nval, sizeof(const char *),
						   GFP_KERNEL);
			if (!dst->pointer.str)
				return -ENOMEM;

			d = dst->pointer.str;
			s = src->pointer.str;
			for (i = 0; i < nval; i++) {
				d[i] = kstrdup(s[i], GFP_KERNEL);
				if (!d[i] && s[i])
					return -ENOMEM;
			}
		} else {
			dst->pointer.raw_data = kmemdup(src->pointer.raw_data,
							src->length, GFP_KERNEL);
			if (!dst->pointer.raw_data)
				return -ENOMEM;
		}
	} else if (src->is_string) {
		dst->value.str = kstrdup(src->value.str, GFP_KERNEL);
		if (!dst->value.str && src->value.str)
			return -ENOMEM;
	} else {
		dst->value.raw_data = src->value.raw_data;
	}

	dst->length = src->length;
	dst->is_array = src->is_array;
	dst->is_string = src->is_string;

	return 0;
}

/**
 * pset_copy_set - copies property set
 * @pset: Property set to copy
 *
 * This function takes a deep copy of the given property set and returns
 * pointer to the copy. Call device_free_property_set() to free resources
 * allocated in this function.
 *
 * Return: Pointer to the new property set or error pointer.
 */
static struct property_set *pset_copy_set(const struct property_set *pset)
{
	const struct property_entry *entry;
	struct property_set *p;
	size_t i, n = 0;

	p = kzalloc(sizeof(*p), GFP_KERNEL);
	if (!p)
		return ERR_PTR(-ENOMEM);

	while (pset->properties[n].name)
		n++;

	p->properties = kcalloc(n + 1, sizeof(*entry), GFP_KERNEL);
	if (!p->properties) {
		kfree(p);
		return ERR_PTR(-ENOMEM);
	}

	for (i = 0; i < n; i++) {
		int ret = pset_copy_entry(&p->properties[i],
					  &pset->properties[i]);
		if (ret) {
			pset_free_set(p);
			return ERR_PTR(ret);
		}
	}

	return p;
}

/**
 * device_remove_property_set - Remove properties from a device object.
 * @dev: Device whose properties to remove.
 *
 * The function removes properties previously associated to the device
 * secondary firmware node with device_add_property_set(). Memory allocated
 * to the properties will also be released.
 */
void device_remove_property_set(struct device *dev)
{
	struct fwnode_handle *fwnode;

	fwnode = dev_fwnode(dev);
	if (!fwnode)
		return;
	/*
	 * Pick either primary or secondary node depending which one holds
	 * the pset. If there is no real firmware node (ACPI/DT) primary
	 * will hold the pset.
	 */
	if (!is_pset_node(fwnode))
		fwnode = fwnode->secondary;
	if (!IS_ERR(fwnode) && is_pset_node(fwnode))
		pset_free_set(to_pset_node(fwnode));
	set_secondary_fwnode(dev, NULL);
}
EXPORT_SYMBOL_GPL(device_remove_property_set);

/**
 * device_add_property_set - Add a collection of properties to a device object.
 * @dev: Device to add properties to.
 * @pset: Collection of properties to add.
 *
 * Associate a collection of device properties represented by @pset with @dev
 * as its secondary firmware node. The function takes a copy of @pset.
 */
int device_add_property_set(struct device *dev, const struct property_set *pset)
{
	struct property_set *p;

	if (!pset)
		return -EINVAL;

	p = pset_copy_set(pset);
	if (IS_ERR(p))
		return PTR_ERR(p);

	p->fwnode.type = FWNODE_PDATA;
	set_secondary_fwnode(dev, &p->fwnode);
	return 0;
}
EXPORT_SYMBOL_GPL(device_add_property_set);

/**
 * device_get_next_child_node - Return the next child node handle for a device
 * @dev: Device to find the next child node for.
+23 −27
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/acpi.h>
@@ -134,10 +135,10 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev)

static int dw_i2c_plat_probe(struct platform_device *pdev)
{
	struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct dw_i2c_dev *dev;
	struct i2c_adapter *adap;
	struct resource *mem;
	struct dw_i2c_platform_data *pdata;
	int irq, r;
	u32 clk_freq, ht = 0;

@@ -161,34 +162,29 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
	/* fast mode by default because of legacy reasons */
	clk_freq = 400000;

	if (has_acpi_companion(&pdev->dev)) {
		dw_i2c_acpi_configure(pdev);
	} else if (pdev->dev.of_node) {
		of_property_read_u32(pdev->dev.of_node,
					"i2c-sda-hold-time-ns", &ht);

		of_property_read_u32(pdev->dev.of_node,
				     "i2c-sda-falling-time-ns",
	if (pdata) {
		clk_freq = pdata->i2c_scl_freq;
	} else {
		device_property_read_u32(&pdev->dev, "i2c-sda-hold-time-ns",
					 &ht);
		device_property_read_u32(&pdev->dev, "i2c-sda-falling-time-ns",
					 &dev->sda_falling_time);
		of_property_read_u32(pdev->dev.of_node,
				     "i2c-scl-falling-time-ns",
		device_property_read_u32(&pdev->dev, "i2c-scl-falling-time-ns",
					 &dev->scl_falling_time);

		of_property_read_u32(pdev->dev.of_node, "clock-frequency",
		device_property_read_u32(&pdev->dev, "clock-frequency",
					 &clk_freq);
	}

		/* Only standard mode at 100kHz and fast mode at 400kHz
		 * are supported.
	if (has_acpi_companion(&pdev->dev))
		dw_i2c_acpi_configure(pdev);

	/*
	 * Only standard mode at 100kHz and fast mode at 400kHz are supported.
	 */
	if (clk_freq != 100000 && clk_freq != 400000) {
		dev_err(&pdev->dev, "Only 100kHz and 400kHz supported");
		return -EINVAL;
	}
	} else {
		pdata = dev_get_platdata(&pdev->dev);
		if (pdata)
			clk_freq = pdata->i2c_scl_freq;
	}

	r = i2c_dw_eval_lock_support(dev);
	if (r)
Loading