summaryrefslogtreecommitdiff
path: root/drivers/mfd/db8500-prcmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/db8500-prcmu.c')
-rw-r--r--drivers/mfd/db8500-prcmu.c140
1 files changed, 111 insertions, 29 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 0f99b01afa88..21434beb420a 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -33,7 +33,7 @@
#include <linux/regulator/machine.h>
#include <linux/cpufreq.h>
#include <linux/platform_data/ux500_wdt.h>
-#include <mach/irqs.h>
+#include <linux/platform_data/db8500_thermal.h>
#include "dbx500-prcmu-regs.h"
/* Index of different voltages to be used when accessing AVSData */
@@ -273,8 +273,34 @@ static struct irq_domain *db8500_irq_domain;
* the bits in the bit field are not. (The bits also have a tendency to move
* around, to further complicate matters.)
*/
-#define IRQ_INDEX(_name) ((IRQ_PRCMU_##_name) - IRQ_PRCMU_BASE)
+#define IRQ_INDEX(_name) ((IRQ_PRCMU_##_name))
#define IRQ_ENTRY(_name)[IRQ_INDEX(_name)] = (WAKEUP_BIT_##_name)
+
+#define IRQ_PRCMU_RTC 0
+#define IRQ_PRCMU_RTT0 1
+#define IRQ_PRCMU_RTT1 2
+#define IRQ_PRCMU_HSI0 3
+#define IRQ_PRCMU_HSI1 4
+#define IRQ_PRCMU_CA_WAKE 5
+#define IRQ_PRCMU_USB 6
+#define IRQ_PRCMU_ABB 7
+#define IRQ_PRCMU_ABB_FIFO 8
+#define IRQ_PRCMU_ARM 9
+#define IRQ_PRCMU_MODEM_SW_RESET_REQ 10
+#define IRQ_PRCMU_GPIO0 11
+#define IRQ_PRCMU_GPIO1 12
+#define IRQ_PRCMU_GPIO2 13
+#define IRQ_PRCMU_GPIO3 14
+#define IRQ_PRCMU_GPIO4 15
+#define IRQ_PRCMU_GPIO5 16
+#define IRQ_PRCMU_GPIO6 17
+#define IRQ_PRCMU_GPIO7 18
+#define IRQ_PRCMU_GPIO8 19
+#define IRQ_PRCMU_CA_SLEEP 20
+#define IRQ_PRCMU_HOTMON_LOW 21
+#define IRQ_PRCMU_HOTMON_HIGH 22
+#define NUM_PRCMU_WAKEUPS 23
+
static u32 prcmu_irq_bit[NUM_PRCMU_WAKEUPS] = {
IRQ_ENTRY(RTC),
IRQ_ENTRY(RTT0),
@@ -2649,14 +2675,13 @@ static struct irq_domain_ops db8500_irq_ops = {
.xlate = irq_domain_xlate_twocell,
};
-static int db8500_irq_init(struct device_node *np)
+static int db8500_irq_init(struct device_node *np, int irq_base)
{
- int irq_base = 0;
int i;
/* In the device tree case, just take some IRQs */
- if (!np)
- irq_base = IRQ_PRCMU_BASE;
+ if (np)
+ irq_base = 0;
db8500_irq_domain = irq_domain_add_simple(
np, NUM_PRCMU_WAKEUPS, irq_base,
@@ -2988,18 +3013,57 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
},
};
-static struct resource ab8500_resources[] = {
- [0] = {
- .start = IRQ_DB8500_AB8500,
- .end = IRQ_DB8500_AB8500,
- .flags = IORESOURCE_IRQ
- }
-};
-
static struct ux500_wdt_data db8500_wdt_pdata = {
.timeout = 600, /* 10 minutes */
.has_28_bits_resolution = true,
};
+/*
+ * Thermal Sensor
+ */
+
+static struct resource db8500_thsens_resources[] = {
+ {
+ .name = "IRQ_HOTMON_LOW",
+ .start = IRQ_PRCMU_HOTMON_LOW,
+ .end = IRQ_PRCMU_HOTMON_LOW,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "IRQ_HOTMON_HIGH",
+ .start = IRQ_PRCMU_HOTMON_HIGH,
+ .end = IRQ_PRCMU_HOTMON_HIGH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct db8500_thsens_platform_data db8500_thsens_data = {
+ .trip_points[0] = {
+ .temp = 70000,
+ .type = THERMAL_TRIP_ACTIVE,
+ .cdev_name = {
+ [0] = "thermal-cpufreq-0",
+ },
+ },
+ .trip_points[1] = {
+ .temp = 75000,
+ .type = THERMAL_TRIP_ACTIVE,
+ .cdev_name = {
+ [0] = "thermal-cpufreq-0",
+ },
+ },
+ .trip_points[2] = {
+ .temp = 80000,
+ .type = THERMAL_TRIP_ACTIVE,
+ .cdev_name = {
+ [0] = "thermal-cpufreq-0",
+ },
+ },
+ .trip_points[3] = {
+ .temp = 85000,
+ .type = THERMAL_TRIP_CRITICAL,
+ },
+ .num_trips = 4,
+};
static struct mfd_cell db8500_prcmu_devs[] = {
{
@@ -3021,11 +3085,10 @@ static struct mfd_cell db8500_prcmu_devs[] = {
.id = -1,
},
{
- .name = "ab8500-core",
- .of_compatible = "stericsson,ab8500",
- .num_resources = ARRAY_SIZE(ab8500_resources),
- .resources = ab8500_resources,
- .id = AB8500_VERSION_AB8500,
+ .name = "db8500-thermal",
+ .num_resources = ARRAY_SIZE(db8500_thsens_resources),
+ .resources = db8500_thsens_resources,
+ .platform_data = &db8500_thsens_data,
},
};
@@ -3037,6 +3100,24 @@ static void db8500_prcmu_update_cpufreq(void)
}
}
+static int db8500_prcmu_register_ab8500(struct device *parent,
+ struct ab8500_platform_data *pdata,
+ int irq)
+{
+ struct resource ab8500_resource = DEFINE_RES_IRQ(irq);
+ struct mfd_cell ab8500_cell = {
+ .name = "ab8500-core",
+ .of_compatible = "stericsson,ab8500",
+ .id = AB8500_VERSION_AB8500,
+ .platform_data = pdata,
+ .pdata_size = sizeof(struct ab8500_platform_data),
+ .resources = &ab8500_resource,
+ .num_resources = 1,
+ };
+
+ return mfd_add_devices(parent, 0, &ab8500_cell, 1, NULL, 0, NULL);
+}
+
/**
* prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
*
@@ -3045,7 +3126,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct prcmu_pdata *pdata = dev_get_platdata(&pdev->dev);
- int irq = 0, err = 0, i;
+ int irq = 0, err = 0;
struct resource *res;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu");
@@ -3086,26 +3167,27 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
goto no_irq_return;
}
- db8500_irq_init(np);
-
- for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) {
- if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) {
- db8500_prcmu_devs[i].platform_data = pdata->ab_platdata;
- db8500_prcmu_devs[i].pdata_size = sizeof(struct ab8500_platform_data);
- }
- }
+ db8500_irq_init(np, pdata->irq_base);
prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
db8500_prcmu_update_cpufreq();
err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs,
- ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL);
+ ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, db8500_irq_domain);
if (err) {
pr_err("prcmu: Failed to add subdevices\n");
return err;
}
+ err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata,
+ pdata->ab_irq);
+ if (err) {
+ mfd_remove_devices(&pdev->dev);
+ pr_err("prcmu: Failed to add ab8500 subdevice\n");
+ goto no_irq_return;
+ }
+
pr_info("DB8500 PRCMU initialized\n");
no_irq_return: