The system control module has several components. On die temperature is a part
of system control module. The system control module driver registers the
temperature sensor as a client. A hwmon driver for temperature sensor to
route the temperature and the thresholds to the user space.

The system control module driver patch depends on the following series
found here: http://comments.gmane.org/gmane.linux.ports.arm.omap/64436


Signed-off-by: Keerthy <[email protected]>
Cc:[email protected] 
---
 drivers/mfd/Kconfig            |    9 +
 drivers/mfd/Makefile           |    2 +-
 drivers/mfd/omap4460plus_scm.c |  581 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 591 insertions(+), 1 deletions(-)
 create mode 100644 drivers/mfd/omap4460plus_scm.c

Index: linux-omap-2.6/drivers/mfd/Kconfig
===================================================================
--- linux-omap-2.6.orig/drivers/mfd/Kconfig     2011-09-22 18:35:25.636575640 
+0530
+++ linux-omap-2.6/drivers/mfd/Kconfig  2011-09-22 18:35:43.412576517 +0530
@@ -212,6 +212,15 @@
          and other features that are often used in portable devices like
          cell phones and PDAs.
 
+config OMAP4460PLUS_SCM
+       bool "Texas Instruments OMAP4460 System control module"
+       depends on ARCH_OMAP && OMAP_SCM_DEV
+       help
+         If you say yes here you get support for the Texas Instruments
+         OMAP4460 system control module. This includes support for
+         on die temperature sensor which is a part of System control
+         module.
+
 config TWL4030_CORE
        bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
        depends on I2C=y && GENERIC_HARDIRQS
Index: linux-omap-2.6/drivers/mfd/Makefile
===================================================================
--- linux-omap-2.6.orig/drivers/mfd/Makefile    2011-09-22 18:35:25.604576115 
+0530
+++ linux-omap-2.6/drivers/mfd/Makefile 2011-09-22 18:35:43.416576975 +0530
@@ -42,7 +42,7 @@
 obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o
 obj-$(CONFIG_MFD_TPS65912_SPI)  += tps65912-spi.o
 obj-$(CONFIG_MENELAUS)         += menelaus.o
-
+obj-$(CONFIG_OMAP4460PLUS_SCM) += omap4460plus_scm.o
 obj-$(CONFIG_TWL4030_CORE)     += twl-core.o twl4030-irq.o twl6030-irq.o
 obj-$(CONFIG_TWL4030_MADC)      += twl4030-madc.o
 obj-$(CONFIG_TWL4030_POWER)    += twl4030-power.o
Index: linux-omap-2.6/drivers/mfd/omap4460plus_scm.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ linux-omap-2.6/drivers/mfd/omap4460plus_scm.c       2011-09-22 
18:53:05.132583900 +0530
@@ -0,0 +1,581 @@
+/*
+ * OMAP4 system control module driver file
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: J Keerthy <[email protected]>
+ * Author: Moiz Sonasath <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <plat/omap_device.h>
+#include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <plat/scm.h>
+
+#define TSHUT_HOT              920     /* 122 deg C */
+#define TSHUT_COLD             866     /* 100 deg C */
+#define T_HOT                  800     /* 73 deg C */
+#define T_COLD                 795     /* 71 deg C */
+#define MAX_FREQ               2000000
+#define MIN_FREQ               1000000
+#define MIN_TEMP               -40000
+#define MAX_TEMP               123000
+#define HYST_VAL               5000
+
+static u32 omap4460plus_scm_readl(struct scm
+                                           *scm_ptr, u32 reg)
+{
+       return __raw_readl(scm_ptr->phy_base + reg);
+}
+
+static void omap4460plus_scm_writel(struct scm *scm_ptr, u32 val, u32 reg)
+{
+       __raw_writel(val, scm_ptr->phy_base + reg);
+}
+
+static int adc_to_temp_conversion(int adc_val)
+{
+       return adc_to_temp[adc_val - OMAP_ADC_START_VALUE];
+}
+
+static int temp_to_adc_conversion(long temp)
+{
+       int high, low, mid;
+
+       if (temp < adc_to_temp[0] ||
+           temp > adc_to_temp[OMAP_ADC_END_VALUE - OMAP_ADC_START_VALUE])
+               return -EINVAL;
+
+       high = OMAP_ADC_END_VALUE - OMAP_ADC_START_VALUE;
+       low = 0;
+       mid = (high + low) / 2;
+
+       while (low < high) {
+               if (temp < adc_to_temp[mid])
+                       high = mid - 1;
+               else
+                       low = mid + 1;
+               mid = (low + high) / 2;
+       }
+
+       return OMAP_ADC_START_VALUE + low;
+}
+
+static void temp_sensor_unmask_interrupts(struct scm *scm_ptr, int id,
+                                         u32 t_hot, u32 t_cold)
+{
+       struct omap_temp_sensor_registers *tsr;
+       u32 temp, reg_val;
+
+       /* Read the current on die temperature */
+       tsr = scm_ptr->registers[id];
+       temp = omap4460plus_scm_readl(scm_ptr, tsr->temp_sensor_ctrl);
+       temp &= tsr->bgap_dtemp_mask;
+
+       reg_val = omap4460plus_scm_readl(scm_ptr, tsr->bgap_mask_ctrl);
+       if (temp < t_hot)
+               reg_val |= tsr->mask_hot_mask;
+       else
+               reg_val &= ~tsr->mask_hot_mask;
+
+       if (t_cold < temp)
+               reg_val |= tsr->mask_cold_mask;
+       else
+               reg_val &= ~tsr->mask_cold_mask;
+
+       omap4460plus_scm_writel(scm_ptr, reg_val, tsr->bgap_mask_ctrl);
+}
+
+static int add_hyst(int adc_val, int hyst_val)
+{
+       int temp = adc_to_temp_conversion(adc_val);
+
+       temp += hyst_val;
+
+       return temp_to_adc_conversion(temp);
+}
+
+static void temp_sensor_configure_thot(struct scm *scm_ptr, int id, int t_hot)
+{
+       int cold, thresh_val;
+       struct omap_temp_sensor_registers *tsr;
+       u32 reg_val;
+
+       tsr = scm_ptr->registers[id];
+       /* obtain the T cold value */
+       thresh_val = omap4460plus_scm_readl(scm_ptr, tsr->bgap_threshold);
+       cold = (thresh_val & tsr->threshold_tcold_mask) >>
+           __ffs(tsr->threshold_tcold_mask);
+
+       if (t_hot <= cold) {
+               /* change the t_cold to t_hot - 5000 millidegrees */
+               cold = add_hyst(t_hot, -HYST_VAL);
+               /* write the new t_cold value */
+               reg_val = thresh_val & (~tsr->threshold_tcold_mask);
+               reg_val |= cold << __ffs(tsr->threshold_tcold_mask);
+               omap4460plus_scm_writel(scm_ptr, reg_val,
+                                       tsr->bgap_threshold);
+               thresh_val = reg_val;
+       }
+
+       /* write the new t_hot value */
+       reg_val = thresh_val & ~tsr->threshold_thot_mask;
+       reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask));
+       omap4460plus_scm_writel(scm_ptr, reg_val, tsr->bgap_threshold);
+       temp_sensor_unmask_interrupts(scm_ptr, id, t_hot, cold);
+}
+
+static void temp_sensor_configure_tcold(struct scm *scm_ptr, int id, int 
t_cold)
+{
+       int hot, thresh_val;
+       u32 reg_val;
+       struct omap_temp_sensor_registers *tsr;
+
+       tsr = scm_ptr->registers[id];
+       /* obtain the T cold value */
+       thresh_val = omap4460plus_scm_readl(scm_ptr, tsr->bgap_threshold);
+       hot = (thresh_val & tsr->threshold_thot_mask) >>
+           __ffs(tsr->threshold_thot_mask);
+
+       if (t_cold >= hot) {
+               /* change the t_hot to t_cold + 5000 millidegrees */
+               hot = add_hyst(t_cold, HYST_VAL);
+               /* write the new t_hot value */
+               reg_val = thresh_val & (~tsr->threshold_thot_mask);
+               reg_val |= hot << __ffs(tsr->threshold_thot_mask);
+               omap4460plus_scm_writel(scm_ptr, reg_val,
+                                       tsr->bgap_threshold);
+               thresh_val = reg_val;
+       }
+
+       /* write the new t_cold value */
+       reg_val = thresh_val & ~tsr->threshold_tcold_mask;
+       reg_val |= (t_cold << __ffs(tsr->threshold_tcold_mask));
+       omap4460plus_scm_writel(scm_ptr, reg_val, tsr->bgap_threshold);
+       temp_sensor_unmask_interrupts(scm_ptr, id, hot, t_cold);
+}
+
+static void configure_temp_sensor_counter(struct scm *scm_ptr, int id,
+                                         u32 counter)
+{
+       u32 val;
+
+       val = omap4460plus_scm_readl(scm_ptr,
+                                    scm_ptr->registers[id]->bgap_counter);
+       val &= ~scm_ptr->registers[id]->counter_mask;
+       val |= counter << __ffs(scm_ptr->registers[id]->counter_mask);
+       omap4460plus_scm_writel(scm_ptr, val,
+                               scm_ptr->registers[id]->bgap_counter);
+
+}
+
+int omap4460plus_scm_show_temp_max(struct scm *scm_ptr, int id)
+{
+       struct omap_temp_sensor_registers *tsr;
+       int temp;
+
+       tsr = scm_ptr->registers[id];
+       temp = omap4460plus_scm_readl(scm_ptr, tsr->bgap_threshold);
+       temp = (temp & tsr->threshold_thot_mask)
+           >> __ffs(tsr->threshold_thot_mask);
+       temp = adc_to_temp_conversion(temp);
+
+       return temp;
+}
+EXPORT_SYMBOL(omap4460plus_scm_show_temp_max);
+
+int omap4460plus_scm_set_temp_max(struct scm *scm_ptr, int id, int val)
+{
+       struct omap_temp_sensor_registers *tsr;
+       u32 t_hot;
+       tsr = scm_ptr->registers[id];
+
+       if (val < MIN_TEMP - HYST_VAL)
+               return -EINVAL;
+       t_hot = temp_to_adc_conversion(val);
+       if (t_hot < 0)
+               return t_hot;
+
+       mutex_lock(&scm_ptr->scm_mutex);
+       temp_sensor_configure_thot(scm_ptr, id, t_hot);
+       mutex_unlock(&scm_ptr->scm_mutex);
+
+       return 0;
+}
+EXPORT_SYMBOL(omap4460plus_scm_set_temp_max);
+
+int omap4460plus_scm_show_temp_max_hyst(struct scm *scm_ptr, int id)
+{
+       struct omap_temp_sensor_registers *tsr;
+       int temp;
+
+       tsr = scm_ptr->registers[id];
+       temp = omap4460plus_scm_readl(scm_ptr, tsr->bgap_threshold);
+       temp = (temp & tsr->threshold_tcold_mask)
+           >> __ffs(tsr->threshold_tcold_mask);
+       temp = adc_to_temp_conversion(temp);
+
+       return temp;
+}
+EXPORT_SYMBOL(omap4460plus_scm_show_temp_max_hyst);
+
+int omap4460plus_scm_set_temp_max_hyst(struct scm *scm_ptr,
+                                      int id, int val)
+{
+       struct omap_temp_sensor_registers *tsr;
+       u32 t_cold;
+       tsr = scm_ptr->registers[id];
+
+       if (val < MIN_TEMP + HYST_VAL)
+               return -EINVAL;
+       t_cold = temp_to_adc_conversion(val);
+       if (t_cold < 0)
+               return t_cold;
+
+       mutex_lock(&scm_ptr->scm_mutex);
+       temp_sensor_configure_tcold(scm_ptr, id, t_cold);
+       mutex_unlock(&scm_ptr->scm_mutex);
+
+       return 0;
+}
+EXPORT_SYMBOL(omap4460plus_scm_set_temp_max_hyst);
+
+void omap4460plus_scm_set_update_interval(struct scm *scm_ptr,
+                                         u32 interval, int id)
+{
+       interval = interval * scm_ptr->clk_rate / 1000;
+       mutex_lock(&scm_ptr->scm_mutex);
+       configure_temp_sensor_counter(scm_ptr, id, interval);
+       mutex_unlock(&scm_ptr->scm_mutex);
+}
+EXPORT_SYMBOL(omap4460plus_scm_set_update_interval);
+
+int omap4460plus_scm_show_update_interval(struct scm *scm_ptr, int id)
+{
+       struct omap_temp_sensor_registers *tsr;
+       int time;
+       tsr = scm_ptr->registers[id];
+
+       time = omap4460plus_scm_readl(scm_ptr, tsr->bgap_counter);
+       time = (time & tsr->counter_mask) >> __ffs(tsr->counter_mask);
+       time = time * 1000 / scm_ptr->clk_rate;
+
+       return time;
+}
+EXPORT_SYMBOL(omap4460plus_scm_show_update_interval);
+
+int omap4460plus_scm_read_temp(struct scm *scm_ptr, int id)
+{
+       struct omap_temp_sensor_registers *tsr;
+       int temp;
+       tsr = scm_ptr->registers[id];
+
+       temp = omap4460plus_scm_readl(scm_ptr, tsr->temp_sensor_ctrl);
+       temp &= tsr->bgap_dtemp_mask;
+
+       /* look up for temperature in the table and return the temperature */
+       if (temp < OMAP_ADC_START_VALUE || temp > OMAP_ADC_END_VALUE)
+               return -EIO;
+
+       return adc_to_temp_conversion(temp);
+}
+EXPORT_SYMBOL(omap4460plus_scm_read_temp);
+
+/**
+ * enable_continuous_mode() - One time enbaling of continuous conversion mode
+ * @scm_ptr - pointer to scm instance
+ */
+static void enable_continuous_mode(struct scm *scm_ptr)
+{
+       u32 val;
+       int i;
+
+       for (i = 0; i < scm_ptr->cnt; i++) {
+               val = omap4460plus_scm_readl(scm_ptr,
+                                            scm_ptr->registers[i]->
+                                            bgap_mode_ctrl);
+
+               val |= 1 << __ffs(scm_ptr->registers[i]->mode_ctrl_mask);
+
+               omap4460plus_scm_writel(scm_ptr, val,
+                                       scm_ptr->registers[i]->bgap_mode_ctrl);
+       }
+}
+
+static irqreturn_t talert_irq_handler(int irq, void *data)
+{
+       struct scm *scm_ptr;
+       int t_hot = 0, t_cold, temp, i;
+       struct omap_temp_sensor_registers *tsr;
+
+       scm_ptr = data;
+       mutex_lock(&scm_ptr->scm_mutex);
+       /* Read the status of t_hot */
+       for (i = 0; i < scm_ptr->cnt; i++) {
+               tsr = scm_ptr->registers[i];
+               t_hot = omap4460plus_scm_readl(scm_ptr, tsr->bgap_status)
+                   & tsr->status_hot_mask;
+
+               /* Read the status of t_cold */
+               t_cold = omap4460plus_scm_readl(scm_ptr, tsr->bgap_status)
+                   & tsr->status_cold_mask;
+
+               temp = omap4460plus_scm_readl(scm_ptr, tsr->bgap_mask_ctrl);
+               /*
+                * One TALERT interrupt: Two sources
+                * If the interrupt is due to t_hot then mask t_hot and
+                * and unmask t_cold else mask t_cold and unmask t_hot
+                */
+               if (t_hot) {
+                       temp &= ~tsr->mask_hot_mask;
+                       temp |= tsr->mask_cold_mask;
+               } else if (t_cold) {
+                       temp &= ~tsr->mask_cold_mask;
+                       temp |= tsr->mask_hot_mask;
+               }
+
+               omap4460plus_scm_writel(scm_ptr, temp, tsr->bgap_mask_ctrl);
+
+               if (t_hot || t_cold)
+                       /* kobject_uvent to user space threshold crossed */
+                       kobject_uevent(&scm_ptr->tsh_ptr[i].pdev->dev.kobj,
+                                      KOBJ_CHANGE);
+       }
+
+       mutex_unlock(&scm_ptr->scm_mutex);
+
+       return IRQ_HANDLED;
+}
+
+void omap4460plus_scm_client_dev_register(struct temp_sensor_hwmon *tsh_ptr,
+                                         int i, const char *name)
+{
+       int ret;
+
+       tsh_ptr->pdev = platform_device_alloc(name, i);
+       if (tsh_ptr->pdev == NULL) {
+               dev_err(tsh_ptr->scm_ptr->dev, "Failed to allocate %s\n", name);
+               return;
+       }
+
+       tsh_ptr->pdev->dev.parent = tsh_ptr->scm_ptr->dev;
+       platform_set_drvdata(tsh_ptr->pdev, tsh_ptr);
+       ret = platform_device_add(tsh_ptr->pdev);
+       if (ret != 0) {
+               dev_err(tsh_ptr->scm_ptr->dev, "Failed to register %s: %d\n",
+                       name, ret);
+               platform_device_put(tsh_ptr->pdev);
+               tsh_ptr->pdev = NULL;
+       }
+}
+
+static int __devinit omap4460plus_scm_probe(struct platform_device *pdev)
+{
+       struct omap4460plus_scm_pdata *pdata = pdev->dev.platform_data;
+       struct scm *scm_ptr;
+       struct resource *mem;
+       int ret = 0, i;
+       int clk_rate;
+       u32 max_freq, min_freq;
+
+       if (!pdata) {
+               dev_err(&pdev->dev, "platform data missing\n");
+               return -EINVAL;
+       }
+
+       scm_ptr = kzalloc(sizeof(*scm_ptr), GFP_KERNEL);
+       if (!scm_ptr) {
+               dev_err(&pdev->dev, "Memory allocation failed\n");
+               return -ENOMEM;
+       }
+
+       scm_ptr->tsh_ptr = kzalloc(sizeof(*scm_ptr->tsh_ptr) * pdata->cnt,
+                                       GFP_KERNEL);
+       if (!scm_ptr) {
+               dev_err(&pdev->dev, "Memory allocation failed for tsh\n");
+               kfree(scm_ptr);
+               return -ENOMEM;
+       }
+
+       mutex_init(&scm_ptr->scm_mutex);
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!mem) {
+               dev_err(&pdev->dev, "no mem resource\n");
+               ret = -ENOMEM;
+               goto plat_res_err;
+       }
+
+       scm_ptr->irq = platform_get_irq_byname(pdev, "thermal_alert");
+       if (scm_ptr->irq < 0) {
+               dev_err(&pdev->dev, "get_irq_byname failed\n");
+               ret = scm_ptr->irq;
+               goto plat_res_err;
+       }
+
+       scm_ptr->phy_base = ioremap(mem->start, resource_size(mem));
+       if (!scm_ptr->phy_base) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+               ret = -ENOMEM;
+               goto plat_res_err;
+       }
+
+       scm_ptr->registers = pdata->registers;
+       scm_ptr->name = pdata->name;
+       scm_ptr->dev = &pdev->dev;
+       scm_ptr->cnt = pdata->cnt;
+
+       if (pdata->max_freq && pdata->min_freq) {
+               max_freq = pdata->max_freq;
+               min_freq = pdata->min_freq;
+       } else {
+               max_freq = MAX_FREQ;
+               min_freq = MIN_FREQ;
+       }
+
+       /*
+        * check if the efuse has a non-zero value if not
+        * it is an untrimmed sample and the temperatures
+        * may not be accurate
+        */
+       if (omap4460plus_scm_readl(scm_ptr, scm_ptr->registers[0]->bgap_efuse))
+               dev_info(&pdev->dev,
+                        "Invalid EFUSE, Non-trimmed BGAP, Temp not 
accurate\n");
+       dev_set_drvdata(&pdev->dev, scm_ptr);
+       scm_ptr->fclock = clk_get(&pdev->dev, "fck");
+       scm_ptr->div_clk = clk_get(&pdev->dev, "div_ck");
+       clk_enable(scm_ptr->fclock);
+
+       clk_rate = clk_round_rate(scm_ptr->div_clk, max_freq);
+       if (clk_rate < min_freq || clk_rate == 0xffffffff) {
+               ret = -ENODEV;
+               goto clken_err;
+       }
+
+       ret = clk_set_rate(scm_ptr->div_clk, clk_rate);
+       if (ret) {
+               dev_err(&pdev->dev, "Cannot set clock rate\n");
+               goto clken_err;
+       }
+
+       scm_ptr->clk_rate = clk_rate;
+
+       enable_continuous_mode(scm_ptr);
+       /* 1 clk cycle */
+       for (i = 0; i < pdata->cnt; i++)
+               configure_temp_sensor_counter(scm_ptr, i, 1);
+
+       /* Wait till the first conversion is done wait for at least 1ms */
+       usleep_range(1000, 2000);
+
+       /* Set 2 seconds time as default counter */
+       for (i = 0; i < pdata->cnt; i++)
+               configure_temp_sensor_counter(scm_ptr, i,
+                                             scm_ptr->clk_rate * 2);
+       for (i = 0; i < pdata->cnt; i++) {
+               scm_ptr->tsh_ptr[i].scm_ptr = scm_ptr;
+               scm_ptr->tsh_ptr[i].name = scm_ptr->name[i];
+               omap4460plus_scm_client_dev_register(&(scm_ptr->tsh_ptr[i]),
+                                                    i, "temp_sensor_hwmon");
+               temp_sensor_configure_thot(scm_ptr, i, T_HOT);
+               temp_sensor_configure_tcold(scm_ptr, i, T_COLD);
+       }
+
+       ret = request_threaded_irq(scm_ptr->irq, NULL,
+                                  talert_irq_handler,
+                                  IRQF_TRIGGER_RISING | IRQF_ONESHOT, "TAlert",
+                                  scm_ptr);
+       if (ret) {
+               dev_err(&pdev->dev, "Request threaded irq failed.\n");
+               goto req_irq_err;
+       }
+
+       mutex_lock(&scm_ptr->scm_mutex);
+
+       for (i = 0; i < pdata->cnt; i++)
+               temp_sensor_unmask_interrupts(scm_ptr, i, OMAP_ADC_END_VALUE,
+                                               OMAP_ADC_START_VALUE);
+
+       mutex_unlock(&scm_ptr->scm_mutex);
+
+       return 0;
+
+req_irq_err:
+       clk_disable(scm_ptr->fclock);
+clken_err:
+       clk_put(scm_ptr->fclock);
+       clk_put(scm_ptr->div_clk);
+       iounmap(scm_ptr->phy_base);
+plat_res_err:
+       dev_set_drvdata(&pdev->dev, NULL);
+       mutex_destroy(&scm_ptr->scm_mutex);
+       kfree(scm_ptr->tsh_ptr);
+       kfree(scm_ptr);
+
+       return ret;
+}
+
+static int __devexit omap4460plus_scm_remove(struct platform_device *pdev)
+{
+       struct scm *scm_ptr = platform_get_drvdata(pdev);
+
+       free_irq(scm_ptr->irq, scm_ptr);
+       clk_disable(scm_ptr->fclock);
+       clk_put(scm_ptr->fclock);
+       clk_put(scm_ptr->div_clk);
+       iounmap(scm_ptr->phy_base);
+       dev_set_drvdata(&pdev->dev, NULL);
+       mutex_destroy(&scm_ptr->scm_mutex);
+       kfree(scm_ptr);
+
+       return 0;
+}
+
+static struct platform_driver omap4460plus_scm_driver = {
+       .probe = omap4460plus_scm_probe,
+       .remove = omap4460plus_scm_remove,
+       .driver = {
+                  .name = "omap4460plus_scm",
+                  },
+};
+
+int __init omap4460plus_scm_init(void)
+{
+       return platform_driver_register(&omap4460plus_scm_driver);
+}
+
+module_init(omap4460plus_scm_init);
+
+static void __exit omap4460plus_scm_exit(void)
+{
+       platform_driver_unregister(&omap4460plus_scm_driver);
+}
+
+module_exit(omap4460plus_scm_exit);
+
+MODULE_DESCRIPTION("OMAP446X plus system control module Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("J Keerthy <[email protected]>");
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to