rendered paste bodyIndex: asic3_base.c===================================================================RCS file: /cvs/linux/kernel26/drivers/soc/asic3_base.c,vretrieving revision 1.31diff -u -r1.31 asic3_base.c--- asic3_base.c 22 Dec 2006 00:05:03 -0000 1.31+++ asic3_base.c 22 Dec 2006 12:39:03 -0000@@ -24,6 +24,8 @@ #include <linux/delay.h> #include <linux/init.h> #include <linux/irq.h>+#include <linux/clk.h>+#include <asm/arch/clock.h> #include <asm/hardware.h> #include <asm/irq.h>@@ -253,6 +255,119 @@ } EXPORT_SYMBOL (asic3_set_clock_cdex); +static void+asic3_clock_cdex_enable (struct clk *clk)+{+ struct asic3_data *asic = clk->parent->priv;+ unsigned long flags, val;++ local_irq_save (flags);++ val = __asic3_read_register (asic, _IPAQ_ASIC3_CLOCK_Base + _IPAQ_ASIC3_CLOCK_CDEX);+ val |= clk->priv;+ __asic3_write_register (asic, _IPAQ_ASIC3_CLOCK_Base + _IPAQ_ASIC3_CLOCK_CDEX, val);++ local_irq_restore (flags);+}++static void+asic3_clock_cdex_disable (struct clk *clk)+{+ struct asic3_data *asic = clk->parent->priv;+ unsigned long flags, val;++ local_irq_save (flags);++ val = __asic3_read_register (asic, _IPAQ_ASIC3_CLOCK_Base + _IPAQ_ASIC3_CLOCK_CDEX);+ val &= ~clk->priv;+ __asic3_write_register (asic, _IPAQ_ASIC3_CLOCK_Base + _IPAQ_ASIC3_CLOCK_CDEX, val);++ local_irq_restore (flags);+}++/* base clocks */++static struct clk clk_g = {+ .name = "gclk",+ .rate = 0,+ .parent = NULL,+};++/* clock definitions */++static struct clk asic3_clocks[] = {+ {+ .name = "spi"+ .parent = &clk_g,+ .enable = asic3_clock_cdex_enable,+ .disable = asic3_clock_cdex_disable,+ .priv = CLOCK_CDEX_SPI,+ },+ {+ .name = "ds1wm"+ .parent = &clk_g,+ .enable = asic3_clock_cdex_enable,+ .disable = asic3_clock_cdex_disable,+ .priv = CLOCK_CDEX_OWM,+ },+ {+ .name = "pwm0"+ .parent = &clk_g,+ .enable = asic3_clock_cdex_enable,+ .disable = asic3_clock_cdex_disable,+ .priv = CLOCK_CDEX_pwm0,+ },+ {+ .name = "pwm1"+ .parent = &clk_g,+ .enable = asic3_clock_cdex_enable,+ .disable = asic3_clock_cdex_disable,+ .priv = CLOCK_CDEX_PWM1,+ },+ {+ .name = "led0"+ .parent = &clk_g,+ .enable = asic3_clock_cdex_enable,+ .disable = asic3_clock_cdex_disable,+ .priv = CLOCK_CDEX_LED0,+ },+ {+ .name = "led1"+ .parent = &g_clk,+ .enable = asic3_clock_cdex_enable,+ .disable = asic3_clock_cdex_disable,+ .priv = CLOCK_CDEX_LED1,+ },+ {+ .name = "led2"+ .parent = &clk_g,+ .enable = asic3_clock_cdex_enable,+ .disable = asic3_clock_cdex_disable,+ .priv = CLOCK_CDEX_LED2,+ },+ {+ .name = "smbus"+ .parent = &clk_g,+ .enable = asic3_clock_cdex_enable,+ .disable = asic3_clock_cdex_disable,+ .priv = CLOCK_CDEX_SMBUS,+ },+ {+ .name = "ex0"+ .parent = &clk_g,+ .enable = asic3_clock_cdex_enable,+ .disable = asic3_clock_cdex_disable,+ .priv = CLOCK_CDEX_EX0,+ },+ {+ .name = "ex1"+ .parent = &clk_g,+ .enable = asic3_clock_cdex_enable,+ .disable = asic3_clock_cdex_disable,+ .priv = CLOCK_CDEX_EX1,+ },+};+ void asic3_set_extcf_select (struct device *dev, unsigned long bits, unsigned long val) {@@ -618,7 +733,7 @@ memset (sdev, 0, sizeof (*sdev)); if (asic3_pdata->tmio_mmc_hwconfig) {- memcpy(mmc_config, asic3_pdata->tmio_mmc_hwconfig, sizeof (*mmc_config));+ memcpy(mmc_config, asic3_pdata->tmio_mmc_hwconfig, sizeof (*mmc_config)); } else { memset(mmc_config, 0, sizeof (*mmc_config)); }@@ -678,6 +793,7 @@ struct asic3_data *asic; struct device *dev = &pdev->dev; unsigned long clksel;+ int i, rc; asic = kmalloc (sizeof (struct asic3_data), GFP_KERNEL); if (!asic)@@ -704,6 +820,20 @@ clksel = 0; __asic3_write_register (asic, _IPAQ_ASIC3_CLOCK_Base + _IPAQ_ASIC3_CLOCK_SEL, clksel); + /* Register ASIC3's clocks. */+// clk_g.rate = hamcop_gclk(hamcop);+ clk_g.priv = asic;++ if (clk_register(&clk_g) < 0)+ printk(KERN_ERR "failed to register ASIC3 gclk\n");++ for (i = 0; i < ARRAY_SIZE(asic3_clocks); i++) {+ rc = clk_register(&asic3_clocks[i]);+ if (rc < 0)+ printk(KERN_ERR "Failed to register clock %s (%d)\n",+ asic3_clocks[i].name, rc);+ }+ __asic3_write_register (asic, _IPAQ_ASIC3_GPIO_A_Base + _IPAQ_ASIC3_GPIO_Mask, 0xffff); __asic3_write_register (asic, _IPAQ_ASIC3_GPIO_B_Base + _IPAQ_ASIC3_GPIO_Mask, 0xffff); __asic3_write_register (asic, _IPAQ_ASIC3_GPIO_C_Base + _IPAQ_ASIC3_GPIO_Mask, 0xffff);@@ -818,9 +948,9 @@ { struct asic3_platform_data *pdata = pdev->dev.platform_data; struct asic3_data *asic = platform_get_drvdata(pdev);+ int i; if (pdata && pdata->child_platform_devs && pdata->num_child_platform_devs != 0) {- int i; for (i = 0; i < pdata->num_child_platform_devs; i++) { platform_device_unregister (pdata->child_platform_devs[i]); }@@ -843,6 +973,10 @@ if (asic->mmc_dev) asic3_unregister_mmc(&pdev->dev);+ + for (i = 0; i < ARRAY_SIZE(asic3_clocks); i++)+ clk_unregister(&asic3_clocks[i]);+ clk_unregister(&clk_g); __asic3_write_register (asic, _IPAQ_ASIC3_CLOCK_Base + _IPAQ_ASIC3_CLOCK_SEL, 0); __asic3_write_register (asic, _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask, 0);