Changes queued in gpio/next for the start of the 3.3 merge window

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJPBSJSAAoJEEFnBt12D9kBDmIP/R6PWxg+NrJaGDmxRWBBkOch
 iI4Et7GT3Sk5hYqPz0kehiSz1F4bqpYK3JmdfqotJIhQCM2znXM+BaDLzgFnMsRf
 g4t70PIZQMpk3pj4gtIkMpZCkRdA9VFriIf1cEdHcLiRdNVsXlTE6CcQT4fbE1P/
 JTAGBrVDwbchuoPsf7Mbu8SYT+cQdWLKpgzC4fAzI++QoYyYBtfvuCHTE4VvasNS
 jMDOfT+u0Gwp6LW34v0gKk7MXEQzeq07r1VZxMyuaWbRQoiLr5d1fy97+Fh5+4dU
 Rb9C6zGIoBzRdiJLlfNYrls/FueDHwPyIwXuapMp5QbaGN5fkhVpIVIhYICOLdHW
 IXH2V3saK1s6QbD7nErNT2lCWZQSCUKq/PR9W40dj3PYAI0oxbRBSoPdfGuW1Bl7
 fYqClUza1Bln8bEmmsvAOnIDdfs6zpkWmfouwx4AGaHTfzIAg4VRdoxdUpS8h+/d
 sNEYi99IuYfl3KWCwQbWJMgCOvoBdOGZSCsTrXnjLf1HJCsQOt/Md69Ff6DLn1VR
 gDp0EeqgDH5oXJmQTW1WjXaJJair2j8pY8mlmGxl1AqA4aY8C3dxIfHxlBPzdxii
 I6KTPaIUSXZaOo6e7XDjjjTzabL4q0aQGT5ahpKj928Rnx00QZNXoTy4FmYkL+0k
 j7QZfM/p6+vfxekKUR17
 =9ugo
 -----END PGP SIGNATURE-----

Merge tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6

Changes queued in gpio/next for the start of the 3.3 merge window

* tag 'gpio-for-linus-20120104' of git://git.secretlab.ca/git/linux-2.6:
  gpio: Add decode of WM8994 GPIO configuration
  gpio: Convert GPIO drivers to module_platform_driver
  gpio: Fix typo in comment in Samsung driver
  gpio: Explicitly index samsung_gpio_cfgs
  gpio: Add Linus Walleij as gpio co-maintainer
  of: Add device tree selftests
  of: create of_phandle_args to simplify return of phandle parsing data
  gpio/powerpc: Eliminate duplication of of_get_named_gpio_flags()
  gpio/microblaze: Eliminate duplication of of_get_named_gpio_flags()
  gpiolib: output basic details and consolidate gpio device drivers
  pch_gpio: Change company name OKI SEMICONDUCTOR to LAPIS Semiconductor
  pch_gpio: Support new device LAPIS Semiconductor ML7831 IOH
  spi/pl022: make the chip deselect handling thread safe
  spi/pl022: add support for pm_runtime autosuspend
  spi/pl022: disable the PL022 block when unused
  spi/pl022: move device disable to workqueue thread
  spi/pl022: skip default configuration before suspending
  spi/pl022: fix build warnings
  spi/pl022: only enable RX interrupts when TX is complete
This commit is contained in:
Linus Torvalds 2012-01-07 12:15:36 -08:00
commit fbce1c234f
37 changed files with 530 additions and 402 deletions

View file

@ -15,6 +15,15 @@ config PROC_DEVICETREE
an image of the device tree that the kernel copies from Open
Firmware or other boot firmware. If unsure, say Y here.
config OF_SELFTEST
bool "Device Tree Runtime self tests"
help
This option builds in test cases for the device tree infrastructure
that are executed one at boot time, and the results dumped to the
console.
If unsure, say N here, but this option is safe to enable.
config OF_FLATTREE
bool
select DTC

View file

@ -8,6 +8,7 @@ obj-$(CONFIG_OF_GPIO) += gpio.o
obj-$(CONFIG_OF_I2C) += of_i2c.o
obj-$(CONFIG_OF_NET) += of_net.o
obj-$(CONFIG_OF_SPI) += of_spi.o
obj-$(CONFIG_OF_SELFTEST) += selftest.o
obj-$(CONFIG_OF_MDIO) += of_mdio.o
obj-$(CONFIG_OF_PCI) += of_pci.o
obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o

View file

@ -824,17 +824,19 @@ of_parse_phandle(struct device_node *np, const char *phandle_name, int index)
EXPORT_SYMBOL(of_parse_phandle);
/**
* of_parse_phandles_with_args - Find a node pointed by phandle in a list
* of_parse_phandle_with_args() - Find a node pointed by phandle in a list
* @np: pointer to a device tree node containing a list
* @list_name: property name that contains a list
* @cells_name: property name that specifies phandles' arguments count
* @index: index of a phandle to parse out
* @out_node: optional pointer to device_node struct pointer (will be filled)
* @out_args: optional pointer to arguments pointer (will be filled)
* @out_args: optional pointer to output arguments structure (will be filled)
*
* This function is useful to parse lists of phandles and their arguments.
* Returns 0 on success and fills out_node and out_args, on error returns
* appropriate errno value.
* Returns 0 on success and fills out_args, on error returns appropriate
* errno value.
*
* Caller is responsible to call of_node_put() on the returned out_args->node
* pointer.
*
* Example:
*
@ -851,94 +853,96 @@ EXPORT_SYMBOL(of_parse_phandle);
* }
*
* To get a device_node of the `node2' node you may call this:
* of_parse_phandles_with_args(node3, "list", "#list-cells", 2, &node2, &args);
* of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
*/
int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
int of_parse_phandle_with_args(struct device_node *np, const char *list_name,
const char *cells_name, int index,
struct device_node **out_node,
const void **out_args)
struct of_phandle_args *out_args)
{
int ret = -EINVAL;
const __be32 *list;
const __be32 *list_end;
int size;
int cur_index = 0;
const __be32 *list, *list_end;
int size, cur_index = 0;
uint32_t count = 0;
struct device_node *node = NULL;
const void *args = NULL;
phandle phandle;
/* Retrieve the phandle list property */
list = of_get_property(np, list_name, &size);
if (!list) {
ret = -ENOENT;
goto err0;
}
if (!list)
return -EINVAL;
list_end = list + size / sizeof(*list);
/* Loop over the phandles until all the requested entry is found */
while (list < list_end) {
const __be32 *cells;
phandle phandle;
count = 0;
/*
* If phandle is 0, then it is an empty entry with no
* arguments. Skip forward to the next entry.
*/
phandle = be32_to_cpup(list++);
args = list;
if (phandle) {
/*
* Find the provider node and parse the #*-cells
* property to determine the argument length
*/
node = of_find_node_by_phandle(phandle);
if (!node) {
pr_err("%s: could not find phandle\n",
np->full_name);
break;
}
if (of_property_read_u32(node, cells_name, &count)) {
pr_err("%s: could not get %s for %s\n",
np->full_name, cells_name,
node->full_name);
break;
}
/* one cell hole in the list = <>; */
if (!phandle)
goto next;
node = of_find_node_by_phandle(phandle);
if (!node) {
pr_debug("%s: could not find phandle\n",
np->full_name);
goto err0;
/*
* Make sure that the arguments actually fit in the
* remaining property data length
*/
if (list + count > list_end) {
pr_err("%s: arguments longer than property\n",
np->full_name);
break;
}
}
cells = of_get_property(node, cells_name, &size);
if (!cells || size != sizeof(*cells)) {
pr_debug("%s: could not get %s for %s\n",
np->full_name, cells_name, node->full_name);
goto err1;
}
/*
* All of the error cases above bail out of the loop, so at
* this point, the parsing is successful. If the requested
* index matches, then fill the out_args structure and return,
* or return -ENOENT for an empty entry.
*/
if (cur_index == index) {
if (!phandle)
return -ENOENT;
list += be32_to_cpup(cells);
if (list > list_end) {
pr_debug("%s: insufficient arguments length\n",
np->full_name);
goto err1;
if (out_args) {
int i;
if (WARN_ON(count > MAX_PHANDLE_ARGS))
count = MAX_PHANDLE_ARGS;
out_args->np = node;
out_args->args_count = count;
for (i = 0; i < count; i++)
out_args->args[i] = be32_to_cpup(list++);
}
return 0;
}
next:
if (cur_index == index)
break;
of_node_put(node);
node = NULL;
args = NULL;
list += count;
cur_index++;
}
if (!node) {
/*
* args w/o node indicates that the loop above has stopped at
* the 'hole' cell. Report this differently.
*/
if (args)
ret = -EEXIST;
else
ret = -ENOENT;
goto err0;
}
if (out_node)
*out_node = node;
if (out_args)
*out_args = args;
return 0;
err1:
of_node_put(node);
err0:
pr_debug("%s failed with status %d\n", __func__, ret);
return ret;
/* Loop exited without finding a valid entry; return an error */
if (node)
of_node_put(node);
return -EINVAL;
}
EXPORT_SYMBOL(of_parse_phandles_with_args);
EXPORT_SYMBOL(of_parse_phandle_with_args);
/**
* prom_add_property - Add a property to a node

View file

@ -35,32 +35,27 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname,
int index, enum of_gpio_flags *flags)
{
int ret;
struct device_node *gpio_np;
struct gpio_chip *gc;
int size;
const void *gpio_spec;
const __be32 *gpio_cells;
struct of_phandle_args gpiospec;
ret = of_parse_phandles_with_args(np, propname, "#gpio-cells", index,
&gpio_np, &gpio_spec);
ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index,
&gpiospec);
if (ret) {
pr_debug("%s: can't parse gpios property\n", __func__);
goto err0;
}
gc = of_node_to_gpiochip(gpio_np);
gc = of_node_to_gpiochip(gpiospec.np);
if (!gc) {
pr_debug("%s: gpio controller %s isn't registered\n",
np->full_name, gpio_np->full_name);
np->full_name, gpiospec.np->full_name);
ret = -ENODEV;
goto err1;
}
gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size);
if (!gpio_cells || size != sizeof(*gpio_cells) ||
be32_to_cpup(gpio_cells) != gc->of_gpio_n_cells) {
if (gpiospec.args_count != gc->of_gpio_n_cells) {
pr_debug("%s: wrong #gpio-cells for %s\n",
np->full_name, gpio_np->full_name);
np->full_name, gpiospec.np->full_name);
ret = -EINVAL;
goto err1;
}
@ -69,13 +64,13 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname,
if (flags)
*flags = 0;
ret = gc->of_xlate(gc, np, gpio_spec, flags);
ret = gc->of_xlate(gc, &gpiospec, flags);
if (ret < 0)
goto err1;
ret += gc->base;
err1:
of_node_put(gpio_np);
of_node_put(gpiospec.np);
err0:
pr_debug("%s exited with status %d\n", __func__, ret);
return ret;
@ -105,8 +100,8 @@ unsigned int of_gpio_count(struct device_node *np)
do {
int ret;
ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells",
cnt, NULL, NULL);
ret = of_parse_phandle_with_args(np, "gpios", "#gpio-cells",
cnt, NULL);
/* A hole in the gpios = <> counts anyway. */
if (ret < 0 && ret != -EEXIST)
break;
@ -127,12 +122,9 @@ EXPORT_SYMBOL(of_gpio_count);
* gpio chips. This function performs only one sanity check: whether gpio
* is less than ngpios (that is specified in the gpio_chip).
*/
int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np,
const void *gpio_spec, u32 *flags)
int of_gpio_simple_xlate(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags)
{
const __be32 *gpio = gpio_spec;
const u32 n = be32_to_cpup(gpio);
/*
* We're discouraging gpio_cells < 2, since that way you'll have to
* write your own xlate function (that will have to retrive the GPIO
@ -144,13 +136,16 @@ int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np,
return -EINVAL;
}
if (n > gc->ngpio)
if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
return -EINVAL;
if (gpiospec->args[0] > gc->ngpio)
return -EINVAL;
if (flags)
*flags = be32_to_cpu(gpio[1]);
*flags = gpiospec->args[1];
return n;
return gpiospec->args[0];
}
EXPORT_SYMBOL(of_gpio_simple_xlate);
@ -198,8 +193,6 @@ int of_mm_gpiochip_add(struct device_node *np,
if (ret)
goto err2;
pr_debug("%s: registered as generic GPIO chip, base is %d\n",
np->full_name, gc->base);
return 0;
err2:
iounmap(mm_gc->regs);

139
drivers/of/selftest.c Normal file
View file

@ -0,0 +1,139 @@
/*
* Self tests for device tree subsystem
*/
#define pr_fmt(fmt) "### %s(): " fmt, __func__
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/device.h>
static bool selftest_passed = true;
#define selftest(result, fmt, ...) { \
selftest_passed &= (result); \
if (!(result)) \
pr_err("FAIL %s:%i " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
}
static void __init of_selftest_parse_phandle_with_args(void)
{
struct device_node *np;
struct of_phandle_args args;
int rc, i;
bool passed_all = true;
pr_info("start\n");
np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
if (!np) {
pr_err("missing testcase data\n");
return;
}
for (i = 0; i < 7; i++) {
bool passed = true;
rc = of_parse_phandle_with_args(np, "phandle-list",
"#phandle-cells", i, &args);
/* Test the values from tests-phandle.dtsi */
switch (i) {
case 0:
passed &= !rc;
passed &= (args.args_count == 1);
passed &= (args.args[0] == (i + 1));
break;
case 1:
passed &= !rc;
passed &= (args.args_count == 2);
passed &= (args.args[0] == (i + 1));
passed &= (args.args[1] == 0);
break;
case 2:
passed &= (rc == -ENOENT);
break;
case 3:
passed &= !rc;
passed &= (args.args_count == 3);
passed &= (args.args[0] == (i + 1));
passed &= (args.args[1] == 4);
passed &= (args.args[2] == 3);
break;
case 4:
passed &= !rc;
passed &= (args.args_count == 2);
passed &= (args.args[0] == (i + 1));
passed &= (args.args[1] == 100);
break;
case 5:
passed &= !rc;
passed &= (args.args_count == 0);
break;
case 6:
passed &= !rc;
passed &= (args.args_count == 1);
passed &= (args.args[0] == (i + 1));
break;
case 7:
passed &= (rc == -EINVAL);
break;
default:
passed = false;
}
if (!passed) {
int j;
pr_err("index %i - data error on node %s rc=%i regs=[",
i, args.np->full_name, rc);
for (j = 0; j < args.args_count; j++)
printk(" %i", args.args[j]);
printk(" ]\n");
passed_all = false;
}
}
/* Check for missing list property */
rc = of_parse_phandle_with_args(np, "phandle-list-missing",
"#phandle-cells", 0, &args);
passed_all &= (rc == -EINVAL);
/* Check for missing cells property */
rc = of_parse_phandle_with_args(np, "phandle-list",
"#phandle-cells-missing", 0, &args);
passed_all &= (rc == -EINVAL);
/* Check for bad phandle in list */
rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle",
"#phandle-cells", 0, &args);
passed_all &= (rc == -EINVAL);
/* Check for incorrectly formed argument list */
rc = of_parse_phandle_with_args(np, "phandle-list-bad-args",
"#phandle-cells", 1, &args);
passed_all &= (rc == -EINVAL);
pr_info("end - %s\n", passed_all ? "PASS" : "FAIL");
}
static int __init of_selftest(void)
{
struct device_node *np;
np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
if (!np) {
pr_info("No testcase data in device tree; not running tests\n");
return 0;
}
of_node_put(np);
pr_info("start of selftest - you will see error messages\n");
of_selftest_parse_phandle_with_args();
pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL");
return 0;
}
late_initcall(of_selftest);