summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-sa1100/neponset.c43
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);