Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pmu.c
Go to the documentation of this file.
1 /*
2  * OMAP2 ARM Performance Monitoring Unit (PMU) Support
3  *
4  * Copyright (C) 2012 Texas Instruments, Inc.
5  *
6  * Contacts:
7  * Jon Hunter <[email protected]>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  */
14 #include <linux/pm_runtime.h>
15 
16 #include <asm/pmu.h>
17 
18 #include <plat/omap_hwmod.h>
19 #include <plat/omap_device.h>
20 
21 static char *omap2_pmu_oh_names[] = {"mpu"};
22 static char *omap3_pmu_oh_names[] = {"mpu", "debugss"};
23 static char *omap4430_pmu_oh_names[] = {"l3_main_3", "l3_instr", "debugss"};
24 static struct platform_device *omap_pmu_dev;
25 
35 static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[])
36 {
37  int i;
38  struct omap_hwmod *oh[3];
39  char *dev_name = "arm-pmu";
40 
41  if ((!oh_num) || (oh_num > 3))
42  return -EINVAL;
43 
44  for (i = 0; i < oh_num; i++) {
45  oh[i] = omap_hwmod_lookup(oh_names[i]);
46  if (!oh[i]) {
47  pr_err("Could not look up %s hwmod\n", oh_names[i]);
48  return -ENODEV;
49  }
50  }
51 
52  omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0,
53  NULL, 0, 0);
54  WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
55  dev_name);
56 
57  if (IS_ERR(omap_pmu_dev))
58  return PTR_ERR(omap_pmu_dev);
59 
60  pm_runtime_enable(&omap_pmu_dev->dev);
61 
62  return 0;
63 }
64 
65 static int __init omap_init_pmu(void)
66 {
67  unsigned oh_num;
68  char **oh_names;
69 
70  /*
71  * To create an ARM-PMU device the following HWMODs
72  * are required for the various OMAP2+ devices.
73  *
74  * OMAP24xx: mpu
75  * OMAP3xxx: mpu, debugss
76  * OMAP4430: l3_main_3, l3_instr, debugss
77  * OMAP4460/70: mpu, debugss
78  */
79  if (cpu_is_omap443x()) {
80  oh_num = ARRAY_SIZE(omap4430_pmu_oh_names);
81  oh_names = omap4430_pmu_oh_names;
82  /* XXX Remove the next two lines when CTI driver available */
83  pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n");
84  return 0;
85  } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
86  oh_num = ARRAY_SIZE(omap3_pmu_oh_names);
87  oh_names = omap3_pmu_oh_names;
88  } else {
89  oh_num = ARRAY_SIZE(omap2_pmu_oh_names);
90  oh_names = omap2_pmu_oh_names;
91  }
92 
93  return omap2_init_pmu(oh_num, oh_names);
94 }
95 subsys_initcall(omap_init_pmu);