Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 204903
b: refs/heads/master
c: 594fa26
h: refs/heads/master
i:
  204901: 1fdd6d4
  204899: 56d7da0
  204895: d0578a5
v: v3
  • Loading branch information
Grant Likely committed Jul 5, 2010
1 parent b2022ea commit ad593b2
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a19e3da5bc5fc6c10ab73f310bea80f3845b4531
refs/heads/master: 594fa265e084073443390c5b93d5410fd28e9bcd
2 changes: 1 addition & 1 deletion trunk/arch/microblaze/kernel/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static int of_reset_gpio_handle(void)
goto err0;
}

gc = gpio->data;
gc = of_node_to_gpiochip(gpio);
if (!gc) {
pr_debug("%s: gpio controller %s isn't registered\n",
root->full_name, gpio->full_name);
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
gpt->gc.base = -1;
gpt->gc.of_gpio_n_cells = 2;
gpt->gc.of_xlate = of_gpio_simple_xlate;
gpt->gc.of_node = node;
of_node_get(node);

/* Setup external pin in GPIO mode */
Expand Down
23 changes: 3 additions & 20 deletions trunk/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

struct mcu {
struct mutex lock;
struct device_node *np;
struct i2c_client *client;
struct gpio_chip gc;
u8 reg_ctrl;
Expand Down Expand Up @@ -79,7 +78,6 @@ static int mcu_gpiochip_add(struct mcu *mcu)
{
struct device_node *np;
struct gpio_chip *gc = &mcu->gc;
int ret;

np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx");
if (!np)
Expand All @@ -94,29 +92,14 @@ static int mcu_gpiochip_add(struct mcu *mcu)
gc->direction_output = mcu_gpio_dir_out;
gc->of_gpio_n_cells = 2;
gc->of_xlate = of_gpio_simple_xlate;
gc->of_node = np;

mcu->np = np;

/*
* We don't want to lose the node, its ->data and ->full_name...
* So, if succeeded, we don't put the node here.
*/
ret = gpiochip_add(gc);
if (ret)
of_node_put(np);
return ret;
return gpiochip_add(gc);
}

static int mcu_gpiochip_remove(struct mcu *mcu)
{
int ret;

ret = gpiochip_remove(&mcu->gc);
if (ret)
return ret;
of_node_put(mcu->np);

return 0;
return gpiochip_remove(&mcu->gc);
}

static int __devinit mcu_probe(struct i2c_client *client,
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/sysdev/qe_lib/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
goto err1;
}

gc = gpio_np->data;
gc = of_node_to_gpiochip(gpio_np);
if (!gc) {
pr_debug("%s: gpio controller %s isn't registered\n",
np->full_name, gpio_np->full_name);
Expand Down
32 changes: 32 additions & 0 deletions trunk/drivers/gpio/gpiolib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,38 @@ int gpiochip_remove(struct gpio_chip *chip)
}
EXPORT_SYMBOL_GPL(gpiochip_remove);

/**
* gpiochip_find() - iterator for locating a specific gpio_chip
* @data: data to pass to match function
* @callback: Callback function to check gpio_chip
*
* Similar to bus_find_device. It returns a reference to a gpio_chip as
* determined by a user supplied @match callback. The callback should return
* 0 if the device doesn't match and non-zero if it does. If the callback is
* non-zero, this function will return to the caller and not iterate over any
* more gpio_chips.
*/
struct gpio_chip *gpiochip_find(void *data,
int (*match)(struct gpio_chip *chip, void *data))
{
struct gpio_chip *chip = NULL;
unsigned long flags;
int i;

spin_lock_irqsave(&gpio_lock, flags);
for (i = 0; i < ARCH_NR_GPIOS; i++) {
if (!gpio_desc[i].chip)
continue;

if (match(gpio_desc[i].chip, data)) {
chip = gpio_desc[i].chip;
break;
}
}
spin_unlock_irqrestore(&gpio_lock, flags);

return chip;
}

/* These "optional" allocation calls help prevent drivers from stomping
* on each other, and help provide better diagnostics in debugfs.
Expand Down
15 changes: 12 additions & 3 deletions trunk/drivers/of/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ int of_get_gpio_flags(struct device_node *np, int index,
goto err0;
}

gc = gpio_np->data;
gc = of_node_to_gpiochip(gpio_np);
if (!gc) {
pr_debug("%s: gpio controller %s isn't registered\n",
np->full_name, gpio_np->full_name);
Expand Down Expand Up @@ -193,7 +193,6 @@ int of_mm_gpiochip_add(struct device_node *np,
if (mm_gc->save_regs)
mm_gc->save_regs(mm_gc);

np->data = &mm_gc->gc;
mm_gc->gc.of_node = np;

ret = gpiochip_add(gc);
Expand All @@ -207,7 +206,6 @@ int of_mm_gpiochip_add(struct device_node *np,
np->full_name, gc->base);
return 0;
err2:
np->data = NULL;
iounmap(mm_gc->regs);
err1:
kfree(gc->label);
Expand All @@ -217,3 +215,14 @@ int of_mm_gpiochip_add(struct device_node *np,
return ret;
}
EXPORT_SYMBOL(of_mm_gpiochip_add);

/* Private function for resolving node pointer to gpio_chip */
static int of_gpiochip_is_match(struct gpio_chip *chip, void *data)
{
return chip->of_node == data;
}

struct gpio_chip *of_node_to_gpiochip(struct device_node *np)
{
return gpiochip_find(np, of_gpiochip_is_match);
}
3 changes: 3 additions & 0 deletions trunk/include/asm-generic/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ extern int __must_check gpiochip_reserve(int start, int ngpio);
/* add/remove chips */
extern int gpiochip_add(struct gpio_chip *chip);
extern int __must_check gpiochip_remove(struct gpio_chip *chip);
extern struct gpio_chip *gpiochip_find(void *data,
int (*match)(struct gpio_chip *chip,
void *data));


/* Always use the library code for GPIO management calls,
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/of_gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ extern int of_mm_gpiochip_add(struct device_node *np,
struct of_mm_gpio_chip *mm_gc);
extern int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np,
const void *gpio_spec, u32 *flags);

extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np);

#else /* CONFIG_OF_GPIO */

/* Drivers may not strictly depend on the GPIO support, so let them link. */
Expand Down

0 comments on commit ad593b2

Please sign in to comment.