Skip to content

Commit 82e39b0

Browse files
Uwe Kleine-Königlinusw
authored andcommitted
gpio: mpc8xxx: handle differences between incarnations at a single place
The gpio controllers that are handled by the mpc8xxx driver differ slightly. Up to now some differences were handled by use of of_device_is_compatible, others by use of struct of_device_id's data. To make this consistent and easily extendable handle the differences at a single place. Signed-off-by: Uwe Kleine-König <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent 4183afe commit 82e39b0

File tree

1 file changed

+38
-11
lines changed

1 file changed

+38
-11
lines changed

drivers/gpio/gpio-mpc8xxx.c

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -312,17 +312,13 @@ static struct irq_chip mpc8xxx_irq_chip = {
312312
.irq_unmask = mpc8xxx_irq_unmask,
313313
.irq_mask = mpc8xxx_irq_mask,
314314
.irq_ack = mpc8xxx_irq_ack,
315+
/* this might get overwritten in mpc8xxx_probe() */
315316
.irq_set_type = mpc8xxx_irq_set_type,
316317
};
317318

318319
static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int irq,
319320
irq_hw_number_t hwirq)
320321
{
321-
struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
322-
323-
if (mpc8xxx_gc->of_dev_id_data)
324-
mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
325-
326322
irq_set_chip_data(irq, h->host_data);
327323
irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_level_irq);
328324

@@ -334,11 +330,32 @@ static const struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
334330
.xlate = irq_domain_xlate_twocell,
335331
};
336332

333+
struct mpc8xxx_gpio_devtype {
334+
int (*gpio_dir_out)(struct gpio_chip *, unsigned int, int);
335+
int (*gpio_get)(struct gpio_chip *, unsigned int);
336+
int (*irq_set_type)(struct irq_data *, unsigned int);
337+
};
338+
339+
static const struct mpc8xxx_gpio_devtype mpc512x_gpio_devtype = {
340+
.gpio_dir_out = mpc5121_gpio_dir_out,
341+
.irq_set_type = mpc512x_irq_set_type,
342+
};
343+
344+
static const struct mpc8xxx_gpio_devtype mpc8572_gpio_devtype = {
345+
.gpio_get = mpc8572_gpio_get,
346+
};
347+
348+
static const struct mpc8xxx_gpio_devtype mpc8xxx_gpio_devtype_default = {
349+
.gpio_dir_out = mpc8xxx_gpio_dir_out,
350+
.gpio_get = mpc8xxx_gpio_get,
351+
.irq_set_type = mpc8xxx_irq_set_type,
352+
};
353+
337354
static const struct of_device_id mpc8xxx_gpio_ids[] = {
338355
{ .compatible = "fsl,mpc8349-gpio", },
339-
{ .compatible = "fsl,mpc8572-gpio", },
356+
{ .compatible = "fsl,mpc8572-gpio", .data = &mpc8572_gpio_devtype, },
340357
{ .compatible = "fsl,mpc8610-gpio", },
341-
{ .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
358+
{ .compatible = "fsl,mpc5121-gpio", .data = &mpc512x_gpio_devtype, },
342359
{ .compatible = "fsl,pq3-gpio", },
343360
{ .compatible = "fsl,qoriq-gpio", },
344361
{}
@@ -351,6 +368,8 @@ static int mpc8xxx_probe(struct platform_device *pdev)
351368
struct of_mm_gpio_chip *mm_gc;
352369
struct gpio_chip *gc;
353370
const struct of_device_id *id;
371+
const struct mpc8xxx_gpio_devtype *devtype =
372+
of_device_get_match_data(&pdev->dev);
354373
int ret;
355374

356375
mpc8xxx_gc = devm_kzalloc(&pdev->dev, sizeof(*mpc8xxx_gc), GFP_KERNEL);
@@ -367,10 +386,18 @@ static int mpc8xxx_probe(struct platform_device *pdev)
367386
mm_gc->save_regs = mpc8xxx_gpio_save_regs;
368387
gc->ngpio = MPC8XXX_GPIO_PINS;
369388
gc->direction_input = mpc8xxx_gpio_dir_in;
370-
gc->direction_output = of_device_is_compatible(np, "fsl,mpc5121-gpio") ?
371-
mpc5121_gpio_dir_out : mpc8xxx_gpio_dir_out;
372-
gc->get = of_device_is_compatible(np, "fsl,mpc8572-gpio") ?
373-
mpc8572_gpio_get : mpc8xxx_gpio_get;
389+
390+
if (!devtype)
391+
devtype = &mpc8xxx_gpio_devtype_default;
392+
393+
/*
394+
* It's assumed that only a single type of gpio controller is available
395+
* on the current machine, so overwriting global data is fine.
396+
*/
397+
mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type;
398+
399+
gc->direction_output = devtype->gpio_dir_out ?: mpc8xxx_gpio_dir_out;
400+
gc->get = devtype->gpio_get ?: mpc8xxx_gpio_get;
374401
gc->set = mpc8xxx_gpio_set;
375402
gc->set_multiple = mpc8xxx_gpio_set_multiple;
376403
gc->to_irq = mpc8xxx_gpio_to_irq;

0 commit comments

Comments
 (0)