diff options
Diffstat (limited to 'drivers/gpio/gpio-pxa.c')
| -rw-r--r-- | drivers/gpio/gpio-pxa.c | 151 | 
1 files changed, 95 insertions, 56 deletions
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 2d3af981641..d7a5c9d7552 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -85,20 +85,61 @@ struct pxa_gpio_chip {  #endif  }; -enum { +enum pxa_gpio_type {  	PXA25X_GPIO = 0,  	PXA26X_GPIO,  	PXA27X_GPIO,  	PXA3XX_GPIO,  	PXA93X_GPIO,  	MMP_GPIO = 0x10, +	MMP2_GPIO, +}; + +struct pxa_gpio_id { +	enum pxa_gpio_type	type; +	int			gpio_nums;  };  static DEFINE_SPINLOCK(gpio_lock);  static struct pxa_gpio_chip *pxa_gpio_chips; -static int gpio_type; +static enum pxa_gpio_type gpio_type;  static void __iomem *gpio_reg_base; +static struct pxa_gpio_id pxa25x_id = { +	.type		= PXA25X_GPIO, +	.gpio_nums	= 85, +}; + +static struct pxa_gpio_id pxa26x_id = { +	.type		= PXA26X_GPIO, +	.gpio_nums	= 90, +}; + +static struct pxa_gpio_id pxa27x_id = { +	.type		= PXA27X_GPIO, +	.gpio_nums	= 121, +}; + +static struct pxa_gpio_id pxa3xx_id = { +	.type		= PXA3XX_GPIO, +	.gpio_nums	= 128, +}; + +static struct pxa_gpio_id pxa93x_id = { +	.type		= PXA93X_GPIO, +	.gpio_nums	= 192, +}; + +static struct pxa_gpio_id mmp_id = { +	.type		= MMP_GPIO, +	.gpio_nums	= 128, +}; + +static struct pxa_gpio_id mmp2_id = { +	.type		= MMP2_GPIO, +	.gpio_nums	= 192, +}; +  #define for_each_gpio_chip(i, c)			\  	for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) @@ -431,47 +472,39 @@ static struct irq_chip pxa_muxed_gpio_chip = {  	.irq_set_wake	= pxa_gpio_set_wake,  }; -static int pxa_gpio_nums(void) +static int pxa_gpio_nums(struct platform_device *pdev)  { +	const struct platform_device_id *id = platform_get_device_id(pdev); +	struct pxa_gpio_id *pxa_id = (struct pxa_gpio_id *)id->driver_data;  	int count = 0; -#ifdef CONFIG_ARCH_PXA -	if (cpu_is_pxa25x()) { -#ifdef CONFIG_CPU_PXA26x -		count = 89; -		gpio_type = PXA26X_GPIO; -#elif defined(CONFIG_PXA25x) -		count = 84; -		gpio_type = PXA26X_GPIO; -#endif /* CONFIG_CPU_PXA26x */ -	} else if (cpu_is_pxa27x()) { -		count = 120; -		gpio_type = PXA27X_GPIO; -	} else if (cpu_is_pxa93x()) { -		count = 191; -		gpio_type = PXA93X_GPIO; -	} else if (cpu_is_pxa3xx()) { -		count = 127; -		gpio_type = PXA3XX_GPIO; -	} -#endif /* CONFIG_ARCH_PXA */ - -#ifdef CONFIG_ARCH_MMP -	if (cpu_is_pxa168() || cpu_is_pxa910()) { -		count = 127; -		gpio_type = MMP_GPIO; -	} else if (cpu_is_mmp2()) { -		count = 191; -		gpio_type = MMP_GPIO; +	switch (pxa_id->type) { +	case PXA25X_GPIO: +	case PXA26X_GPIO: +	case PXA27X_GPIO: +	case PXA3XX_GPIO: +	case PXA93X_GPIO: +	case MMP_GPIO: +	case MMP2_GPIO: +		gpio_type = pxa_id->type; +		count = pxa_id->gpio_nums - 1; +		break; +	default: +		count = -EINVAL; +		break;  	} -#endif /* CONFIG_ARCH_MMP */  	return count;  }  #ifdef CONFIG_OF  static struct of_device_id pxa_gpio_dt_ids[] = { -	{ .compatible = "mrvl,pxa-gpio" }, -	{ .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, +	{ .compatible = "intel,pxa25x-gpio",	.data = &pxa25x_id, }, +	{ .compatible = "intel,pxa26x-gpio",	.data = &pxa26x_id, }, +	{ .compatible = "intel,pxa27x-gpio",	.data = &pxa27x_id, }, +	{ .compatible = "intel,pxa3xx-gpio",	.data = &pxa3xx_id, }, +	{ .compatible = "marvell,pxa93x-gpio",	.data = &pxa93x_id, }, +	{ .compatible = "marvell,mmp-gpio",	.data = &mmp_id, }, +	{ .compatible = "marvell,mmp2-gpio",	.data = &mmp2_id, },  	{}  }; @@ -491,16 +524,18 @@ const struct irq_domain_ops pxa_irq_domain_ops = {  static int pxa_gpio_probe_dt(struct platform_device *pdev)  { -	int ret, nr_banks, nr_gpios; +	int ret, nr_gpios;  	struct device_node *prev, *next, *np = pdev->dev.of_node;  	const struct of_device_id *of_id =  				of_match_device(pxa_gpio_dt_ids, &pdev->dev); +	const struct pxa_gpio_id *gpio_id; -	if (!of_id) { +	if (!of_id || !of_id->data) {  		dev_err(&pdev->dev, "Failed to find gpio controller\n");  		return -EFAULT;  	} -	gpio_type = (int)of_id->data; +	gpio_id = of_id->data; +	gpio_type = gpio_id->type;  	next = of_get_next_child(np, NULL);  	prev = next; @@ -509,14 +544,8 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)  		ret = -EINVAL;  		goto err;  	} -	for (nr_banks = 1; ; nr_banks++) { -		next = of_get_next_child(np, prev); -		if (!next) -			break; -		prev = next; -	}  	of_node_put(prev); -	nr_gpios = nr_banks << 5; +	nr_gpios = gpio_id->gpio_nums;  	pxa_last_gpio = nr_gpios - 1;  	irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); @@ -545,19 +574,18 @@ static int pxa_gpio_probe(struct platform_device *pdev)  	int gpio, irq, ret, use_of = 0;  	int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; -	ret = pxa_gpio_probe_dt(pdev); -	if (ret < 0) { -		pxa_last_gpio = pxa_gpio_nums(); -#ifdef CONFIG_ARCH_PXA -		if (gpio_is_pxa_type(gpio_type)) -			irq_base = PXA_GPIO_TO_IRQ(0); -#endif -#ifdef CONFIG_ARCH_MMP -		if (gpio_is_mmp_type(gpio_type)) -			irq_base = MMP_GPIO_TO_IRQ(0); -#endif +	info = dev_get_platdata(&pdev->dev); +	if (info) { +		irq_base = info->irq_base; +		if (irq_base <= 0) +			return -EINVAL; +		pxa_last_gpio = pxa_gpio_nums(pdev);  	} else { +		irq_base = 0;  		use_of = 1; +		ret = pxa_gpio_probe_dt(pdev); +		if (ret < 0) +			return -EINVAL;  	}  	if (!pxa_last_gpio) @@ -594,7 +622,6 @@ static int pxa_gpio_probe(struct platform_device *pdev)  	}  	/* Initialize GPIO chips */ -	info = dev_get_platdata(&pdev->dev);  	pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);  	/* clear all GPIO edge detects */ @@ -634,12 +661,24 @@ static int pxa_gpio_probe(struct platform_device *pdev)  	return 0;  } +static const struct platform_device_id gpio_id_table[] = { +	{ "pxa25x-gpio",	(unsigned long)&pxa25x_id }, +	{ "pxa26x-gpio",	(unsigned long)&pxa26x_id }, +	{ "pxa27x-gpio",	(unsigned long)&pxa27x_id }, +	{ "pxa3xx-gpio",	(unsigned long)&pxa3xx_id }, +	{ "pxa93x-gpio",	(unsigned long)&pxa93x_id }, +	{ "mmp-gpio",		(unsigned long)&mmp_id }, +	{ "mmp2-gpio",		(unsigned long)&mmp2_id }, +	{ }, +}; +  static struct platform_driver pxa_gpio_driver = {  	.probe		= pxa_gpio_probe,  	.driver		= {  		.name	= "pxa-gpio",  		.of_match_table = of_match_ptr(pxa_gpio_dt_ids),  	}, +	.id_table	= gpio_id_table,  };  static int __init pxa_gpio_init(void)  |