diff options
Diffstat (limited to 'arch/arm/mach-sa1100/neponset.c')
-rw-r--r-- | arch/arm/mach-sa1100/neponset.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 6876bc1e33b4..2b2fff442ba7 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -2,10 +2,13 @@ /* * linux/arch/arm/mach-sa1100/neponset.c */ +#include <linux/clk-provider.h> +#include <linux/clkdev.h> #include <linux/err.h> #include <linux/gpio/driver.h> #include <linux/gpio/gpio-reg.h> #include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> #include <linux/init.h> #include <linux/ioport.h> #include <linux/irq.h> @@ -79,6 +82,9 @@ struct neponset_drvdata { struct platform_device *smc91x; unsigned irq_base; struct gpio_chip *gpio[4]; + struct clk_hw *enet_osc_ck; + struct clk_hw *enet_osc_gate; + struct clk_lookup *enet_osc_cl; }; static struct gpiod_lookup_table neponset_uart1_gpio_table = { @@ -218,6 +224,38 @@ static int neponset_init_gpio(struct gpio_chip **gcp, return 0; } +static int neponset_init_enet(struct device *dev, struct neponset_drvdata *d) +{ + struct gpio_desc *gpio; + int ret; + + d->enet_osc_ck = clk_hw_register_fixed_rate(dev, "nep_enet_osc", + NULL, 0, 20000000); + if (IS_ERR(d->enet_osc_ck)) + return PTR_ERR(d->enet_osc_ck); + + gpio = gpio_to_desc(d->gpio[0]->base + 3); + d->enet_osc_gate = clk_hw_register_gpio_gate(dev, "nep_enet_gate", + "nep_enet_osc", gpio, 0); + if (IS_ERR(d->enet_osc_gate)) { + ret = PTR_ERR(d->enet_osc_gate); + goto err; + } + + d->enet_osc_cl = clkdev_hw_create(d->enet_osc_gate, NULL, "smc91x.0"); + if (!d->enet_osc_cl) { + ret = -ENOMEM; + goto err; + } + + return 0; + +err: + if (d->enet_osc_ck) + clk_hw_unregister_fixed_rate(d->enet_osc_ck); + return ret; +} + static struct sa1111_platform_data sa1111_info = { .disable_devs = SA1111_DEVID_PS2_MSE, }; @@ -337,6 +375,8 @@ static int neponset_probe(struct platform_device *dev) gpiod_add_lookup_table(&neponset_uart3_gpio_table); gpiod_add_lookup_table(&neponset_pcmcia_table); + neponset_init_enet(&dev->dev, d); + /* * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately * something on the Neponset activates this IRQ on sleep (eth?) @@ -386,6 +426,9 @@ static int neponset_remove(struct platform_device *dev) if (!IS_ERR(d->smc91x)) platform_device_unregister(d->smc91x); + clkdev_drop(d->enet_osc_cl); + clk_hw_unregister_fixed_rate(d->enet_osc_ck); + gpiod_remove_lookup_table(&neponset_pcmcia_table); gpiod_remove_lookup_table(&neponset_uart3_gpio_table); gpiod_remove_lookup_table(&neponset_uart1_gpio_table); |