Skip to content

Commit

Permalink
pinctrl: spawn U300 pinctrl from the COH901 GPIO
Browse files Browse the repository at this point in the history
This solves the riddle on how the U300 pin controller shall be
able to reference the struct gpio_chip even though these are
two separate drivers: spawn the pinctrl child from the GPIO
driver and pass in the struct gpio_chip as platform data.
In the process we rename the U300 "pinmux-u300" to
"pinctrl-u300" so as not to confuse.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
  • Loading branch information
Linus Walleij committed Feb 22, 2012
1 parent 4ecce45 commit 128a06d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 24 deletions.
30 changes: 15 additions & 15 deletions arch/arm/mach-u300/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1477,7 +1477,7 @@ static struct coh901318_platform coh901318_platform = {
.max_channels = U300_DMA_CHANNELS,
};

static struct resource pinmux_resources[] = {
static struct resource pinctrl_resources[] = {
{
.start = U300_SYSCON_BASE,
.end = U300_SYSCON_BASE + SZ_4K - 1,
Expand Down Expand Up @@ -1506,6 +1506,13 @@ static struct platform_device i2c1_device = {
.resource = i2c1_resources,
};

static struct platform_device pinctrl_device = {
.name = "pinctrl-u300",
.id = -1,
.num_resources = ARRAY_SIZE(pinctrl_resources),
.resource = pinctrl_resources,
};

/*
* The different variants have a few different versions of the
* GPIO block, with different number of ports.
Expand All @@ -1525,6 +1532,7 @@ static struct u300_gpio_platform u300_gpio_plat = {
#endif
.gpio_base = 0,
.gpio_irq_base = IRQ_U300_GPIO_BASE,
.pinctrl_device = &pinctrl_device,
};

static struct platform_device gpio_device = {
Expand Down Expand Up @@ -1597,23 +1605,16 @@ static struct platform_device dma_device = {
},
};

static struct platform_device pinmux_device = {
.name = "pinmux-u300",
.id = -1,
.num_resources = ARRAY_SIZE(pinmux_resources),
.resource = pinmux_resources,
};

/* Pinmux settings */
static struct pinctrl_map __initdata u300_pinmux_map[] = {
/* anonymous maps for chip power and EMIFs */
PIN_MAP_SYS_HOG("POWER", "pinmux-u300", "power"),
PIN_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"),
PIN_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"),
PIN_MAP_SYS_HOG("POWER", "pinctrl-u300", "power"),
PIN_MAP_SYS_HOG("EMIF0", "pinctrl-u300", "emif0"),
PIN_MAP_SYS_HOG("EMIF1", "pinctrl-u300", "emif1"),
/* per-device maps for MMC/SD, SPI and UART */
PIN_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"),
PIN_MAP("SPI", "pinmux-u300", "spi0", "pl022"),
PIN_MAP("UART0", "pinmux-u300", "uart0", "uart0"),
PIN_MAP("MMCSD", "pinctrl-u300", "mmc0", "mmci"),
PIN_MAP("SPI", "pinctrl-u300", "spi0", "pl022"),
PIN_MAP("UART0", "pinctrl-u300", "uart0", "uart0"),
};

struct u300_mux_hog {
Expand Down Expand Up @@ -1676,7 +1677,6 @@ static struct platform_device *platform_devs[] __initdata = {
&gpio_device,
&nand_device,
&wdog_device,
&pinmux_device,
};

/*
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/mach-u300/include/mach/gpio-u300.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ enum u300_gpio_variant {
* @ports: number of GPIO block ports
* @gpio_base: first GPIO number for this block (use a free range)
* @gpio_irq_base: first GPIO IRQ number for this block (use a free range)
* @pinctrl_device: pin control device to spawn as child
*/
struct u300_gpio_platform {
enum u300_gpio_variant variant;
u8 ports;
int gpio_base;
int gpio_irq_base;
struct platform_device *pinctrl_device;
};

#endif /* __MACH_U300_GPIO_U300_H */
10 changes: 8 additions & 2 deletions drivers/pinctrl/pinctrl-coh901.c
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio)
list_for_each_safe(p, n, &gpio->port_list) {
port = list_entry(p, struct u300_gpio_port, node);
list_del(&port->node);
free_irq(port->irq, port);
kfree(port);
}
}
Expand Down Expand Up @@ -861,10 +860,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
goto err_no_chip;
}

/* Spawn pin controller device as child of the GPIO, pass gpio chip */
plat->pinctrl_device->dev.platform_data = &gpio->chip;
err = platform_device_register(plat->pinctrl_device);
if (err)
goto err_no_pinctrl;

platform_set_drvdata(pdev, gpio);

return 0;

err_no_pinctrl:
err = gpiochip_remove(&gpio->chip);
err_no_chip:
err_no_port:
u300_gpio_free_ports(gpio);
Expand Down Expand Up @@ -919,7 +926,6 @@ static struct platform_driver u300_gpio_driver = {
.remove = __exit_p(u300_gpio_remove),
};


static int __init u300_gpio_init(void)
{
return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe);
Expand Down
20 changes: 13 additions & 7 deletions drivers/pinctrl/pinctrl-u300.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
#define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS 0x0100
#define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N 0x0200

#define DRIVER_NAME "pinmux-u300"
#define DRIVER_NAME "pinctrl-u300"

/*
* The DB3350 has 467 pads, I have enumerated the pads clockwise around the
Expand Down Expand Up @@ -1053,13 +1053,16 @@ static struct pinctrl_desc u300_pmx_desc = {
.owner = THIS_MODULE,
};

static int __init u300_pmx_probe(struct platform_device *pdev)
static int __devinit u300_pmx_probe(struct platform_device *pdev)
{
struct u300_pmx *upmx;
struct resource *res;
struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev);
int ret;
int i;

pr_err("U300 PMX PROBE\n");

/* Create state holders etc for this driver */
upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
if (!upmx)
Expand Down Expand Up @@ -1095,12 +1098,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
}

/* We will handle a range of GPIO pins */
for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++)
for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
u300_gpio_ranges[i].gc = gpio_chip;
pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
}

platform_set_drvdata(pdev, upmx);

dev_info(&pdev->dev, "initialized U300 pinmux driver\n");
dev_info(&pdev->dev, "initialized U300 pin control driver\n");

return 0;

Expand All @@ -1115,7 +1120,7 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
return ret;
}

static int __exit u300_pmx_remove(struct platform_device *pdev)
static int __devexit u300_pmx_remove(struct platform_device *pdev)
{
struct u300_pmx *upmx = platform_get_drvdata(pdev);
int i;
Expand All @@ -1136,12 +1141,13 @@ static struct platform_driver u300_pmx_driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
.remove = __exit_p(u300_pmx_remove),
.probe = u300_pmx_probe,
.remove = __devexit_p(u300_pmx_remove),
};

static int __init u300_pmx_init(void)
{
return platform_driver_probe(&u300_pmx_driver, u300_pmx_probe);
return platform_driver_register(&u300_pmx_driver);
}
arch_initcall(u300_pmx_init);

Expand Down

0 comments on commit 128a06d

Please sign in to comment.