Commit 5496eab2 authored by Grant Likely's avatar Grant Likely

powerpc/5200: Rework GPT driver to also be an IRQ controller

This patch adds IRQ controller support to the MPC5200 General
Purpose Timer (GPT) device driver.  With this patch the mpc5200-gpt
driver supports both GPIO and IRQ functions.

The GPT driver was contained within the mpc52xx_gpio.c file, but this
patch moves it out into a new file (mpc52xx_gpt.c) since it has more
than just GPIO functionality now and it was only grouped with the
mpc52xx-gpio drivers as a matter of convenience before.  Also, this
driver will most likely get extended again to also provide support
for the timer function.

Implementation note: Alternately, I could have tried to implement
the IRQ support as a separate driver and left the GPIO portion alone.
However, multiple functions of this device (ie. GPIO input+interrupt
controller, or timer+GPIO) can be active at the same time and the
registers are shared so it is safer to contain all functionality
within a single driver.
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Reviewed-by: default avatarWolfram Sang <w.sang@pengutronix.de>
parent 8f2558de
#
# Makefile for 52xx based boards
#
obj-y += mpc52xx_pic.o mpc52xx_common.o
obj-y += mpc52xx_pic.o mpc52xx_common.o mpc52xx_gpt.o
obj-$(CONFIG_PCI) += mpc52xx_pci.o
obj-$(CONFIG_PPC_MPC5200_SIMPLE) += mpc5200_simple.o
......
......@@ -354,88 +354,6 @@ static struct of_platform_driver mpc52xx_simple_gpiochip_driver = {
.remove = mpc52xx_gpiochip_remove,
};
/*
* GPIO LIB API implementation for gpt GPIOs.
*
* Each gpt only has a single GPIO.
*/
static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
return (in_be32(&regs->status) & (1 << (31 - 23))) ? 1 : 0;
}
static void
mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
{
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
if (val)
out_be32(&regs->mode, 0x34);
else
out_be32(&regs->mode, 0x24);
pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
}
static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
{
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
out_be32(&regs->mode, 0x04);
return 0;
}
static int
mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
{
mpc52xx_gpt_gpio_set(gc, gpio, val);
pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
return 0;
}
static int __devinit mpc52xx_gpt_gpiochip_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
struct of_mm_gpio_chip *mmchip;
struct of_gpio_chip *chip;
mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
if (!mmchip)
return -ENOMEM;
chip = &mmchip->of_gc;
chip->gpio_cells = 2;
chip->gc.ngpio = 1;
chip->gc.direction_input = mpc52xx_gpt_gpio_dir_in;
chip->gc.direction_output = mpc52xx_gpt_gpio_dir_out;
chip->gc.get = mpc52xx_gpt_gpio_get;
chip->gc.set = mpc52xx_gpt_gpio_set;
return of_mm_gpiochip_add(ofdev->node, mmchip);
}
static const struct of_device_id mpc52xx_gpt_gpiochip_match[] = {
{
.compatible = "fsl,mpc5200-gpt-gpio",
},
{}
};
static struct of_platform_driver mpc52xx_gpt_gpiochip_driver = {
.name = "gpio_gpt",
.match_table = mpc52xx_gpt_gpiochip_match,
.probe = mpc52xx_gpt_gpiochip_probe,
.remove = mpc52xx_gpiochip_remove,
};
static int __init mpc52xx_gpio_init(void)
{
if (of_register_platform_driver(&mpc52xx_wkup_gpiochip_driver))
......@@ -444,9 +362,6 @@ static int __init mpc52xx_gpio_init(void)
if (of_register_platform_driver(&mpc52xx_simple_gpiochip_driver))
printk(KERN_ERR "Unable to register simple GPIO driver\n");
if (of_register_platform_driver(&mpc52xx_gpt_gpiochip_driver))
printk(KERN_ERR "Unable to register gpt GPIO driver\n");
return 0;
}
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment