From 4c62dbbce902cf2afa88cac89ec67c828160f431 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 26 Jun 2015 11:27:41 +0300 Subject: ACPI: Remove FSF mailing addresses There is no need to carry potentially outdated Free Software Foundation mailing address in file headers since the COPYING file includes it. Signed-off-by: Jarkko Nikula Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ac.c | 4 ---- drivers/acpi/acpi_ipmi.c | 4 ---- drivers/acpi/acpi_memhotplug.c | 5 ----- drivers/acpi/acpi_pad.c | 4 ---- drivers/acpi/acpi_video.c | 4 ---- drivers/acpi/apei/apei-base.c | 4 ---- drivers/acpi/apei/einj.c | 4 ---- drivers/acpi/apei/erst-dbg.c | 4 ---- drivers/acpi/apei/erst.c | 4 ---- drivers/acpi/apei/ghes.c | 4 ---- drivers/acpi/apei/hest.c | 4 ---- drivers/acpi/battery.c | 4 ---- drivers/acpi/blacklist.c | 4 ---- drivers/acpi/bus.c | 4 ---- drivers/acpi/button.c | 4 ---- drivers/acpi/cm_sbs.c | 4 ---- drivers/acpi/container.c | 4 ---- drivers/acpi/device_pm.c | 4 ---- drivers/acpi/dock.c | 4 ---- drivers/acpi/ec.c | 4 ---- drivers/acpi/fan.c | 4 ---- drivers/acpi/hed.c | 4 ---- drivers/acpi/internal.h | 3 --- drivers/acpi/numa.c | 4 ---- drivers/acpi/osl.c | 4 ---- drivers/acpi/pci_irq.c | 4 ---- drivers/acpi/pci_link.c | 4 ---- drivers/acpi/pci_root.c | 4 ---- drivers/acpi/pci_slot.c | 4 ---- drivers/acpi/power.c | 4 ---- drivers/acpi/processor_driver.c | 4 ---- drivers/acpi/processor_idle.c | 4 ---- drivers/acpi/processor_perflib.c | 4 ---- drivers/acpi/processor_thermal.c | 4 ---- drivers/acpi/processor_throttling.c | 4 ---- drivers/acpi/resource.c | 4 ---- drivers/acpi/sbs.c | 4 ---- drivers/acpi/tables.c | 4 ---- drivers/acpi/thermal.c | 4 ---- drivers/acpi/utils.c | 4 ---- 40 files changed, 160 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 9b5354a2cd08..f71b756b05c4 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -16,10 +16,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c index ac0f52f6df2b..f77956c3fd45 100644 --- a/drivers/acpi/acpi_ipmi.c +++ b/drivers/acpi/acpi_ipmi.c @@ -17,10 +17,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index ee28f4d15625..6b0d3ef7309c 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -16,11 +16,6 @@ * NON INFRINGEMENT. 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * * ACPI based HotPlug driver that supports Memory Hotplug * This driver fields notifications from firmware for memory add * and remove operations and alerts the VM of the affected memory diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 00b39802d7ec..ae307ff36acb 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -12,10 +12,6 @@ * 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 diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 8c2fe2f2f9fd..5778e8e4313a 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -17,10 +17,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index a85ac07f3da3..a2c8d7adb6eb 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -24,10 +24,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index a095d4f858da..0431883653be 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -18,10 +18,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index 04ab5c9d3ced..6330f557a2c8 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c @@ -17,10 +17,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 3670bbab57a3..6682c5daf742 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -18,10 +18,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 2bfd53cbfe80..23981ac1c6c2 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -23,10 +23,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 06e9b411a0a2..20b3fcf4007c 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -21,10 +21,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b3628cc01a53..b719ab3090bb 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -18,10 +18,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 278dc4be992a..96809cd99ace 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -20,10 +20,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 513e7230e3d0..c8356eb79911 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -15,10 +15,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 6d5d1832a588..5c3b0918d5fd 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -16,10 +16,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 6c9ee68e46fb..d0918d421f90 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c @@ -11,10 +11,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index c8ead9f97375..12c240903c18 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -20,10 +20,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 717afcdb5f4a..d06cd59b5906 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -15,10 +15,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index a688aa243f6c..e8e128dede29 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -17,10 +17,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 9d4761d2f6b7..990446629935 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -22,10 +22,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index bea0bbaafa97..e297a480e135 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -16,10 +16,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c index a322710b5ba4..5c67a6d8f803 100644 --- a/drivers/acpi/hed.c +++ b/drivers/acpi/hed.c @@ -15,10 +15,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 4683a96932b9..8c71cb8335c0 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -13,9 +13,6 @@ * 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. */ #ifndef _ACPI_INTERNAL_H_ diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index acaa3b4ea504..72b6e9ef0ae9 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -15,10 +15,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * */ diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index c262e4acd68d..5e1f1bc5421e 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -19,10 +19,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * */ diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 304eccb0ae5c..25fff35df82c 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -19,10 +19,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index cfd7581cc19f..2f5f84ced85f 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -17,10 +17,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * TBD: diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 1b5569c092c6..393706a5261b 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -16,10 +16,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 139d9e479370..7188e53b6b7c 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c @@ -20,10 +20,6 @@ * 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 diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 93eac53b5110..45b47f2c9f03 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -16,10 +16,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index d9f71581b79b..3af8dc30f129 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -21,10 +21,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index d540f42c9232..175c86bee3a9 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -21,10 +21,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index cfc8aba72f86..53cfe8ba9799 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -20,10 +20,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * */ #include diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index e003663b2f8e..1fed84a092c2 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -19,10 +19,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 84243c32e29c..f170d746336d 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -19,10 +19,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 10561ce16ed1..64ea0d10b788 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -15,10 +15,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 01504c819e8f..cb3dedb1beae 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -17,10 +17,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 2e19189da0ee..17a6fa01a338 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -15,10 +15,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * */ diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 6d4e44ea74ac..fc28b9f5aa84 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -16,10 +16,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * This driver fully implements the ACPI thermal policy as described in the diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 67c548ad3764..475c9079bf85 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -16,10 +16,6 @@ * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -- cgit v1.2.3 From aa57aca8e15a4e11749640e16ac9814f14be24d2 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 16 Jul 2015 02:01:28 +0200 Subject: ACPI / PM: Update the copyright notice and description of power.c The description and copyright notice of drivers/acpi/power.c is out of date, so update it as appropriate. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/power.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 93eac53b5110..ce68ae68840d 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -1,8 +1,10 @@ /* - * acpi_power.c - ACPI Bus Power Management ($Revision: 39 $) + * drivers/acpi/power.c - ACPI Power Resources management. * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2001 - 2015 Intel Corp. + * Author: Andy Grover + * Author: Paul Diefenbaugh + * Author: Rafael J. Wysocki * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * @@ -27,10 +29,11 @@ * ACPI power-managed devices may be controlled in two ways: * 1. via "Device Specific (D-State) Control" * 2. via "Power Resource Control". - * This module is used to manage devices relying on Power Resource Control. + * The code below deals with ACPI Power Resources control. * - * An ACPI "power resource object" describes a software controllable power - * plane, clock plane, or other resource used by a power managed device. + * An ACPI "power resource object" represents a software controllable power + * plane, clock plane, or other resource depended on by a device. + * * A device may rely on multiple power resources, and a power resource * may be shared by multiple devices. */ -- cgit v1.2.3 From c2efefb33abfb245395199137ece3c1e3df47f51 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 17 Jul 2015 22:53:43 +0200 Subject: ACPI / scan: Move sysfs-related device code to a separate file To reduce the size of scan.c and improve the readability of it, move all code related to device sysfs, modalias creation etc. to a new file called device_sysfs.c. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Makefile | 2 +- drivers/acpi/device_sysfs.c | 521 ++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/internal.h | 9 + drivers/acpi/scan.c | 483 +--------------------------------------- 4 files changed, 532 insertions(+), 483 deletions(-) create mode 100644 drivers/acpi/device_sysfs.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 8321430d7f24..08ac1100e2dc 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -24,7 +24,7 @@ acpi-y += nvs.o # Power management related files acpi-y += wakeup.o acpi-$(CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT) += sleep.o -acpi-y += device_pm.o +acpi-y += device_sysfs.o device_pm.o acpi-$(CONFIG_ACPI_SLEEP) += proc.o diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c new file mode 100644 index 000000000000..4ab4582e586b --- /dev/null +++ b/drivers/acpi/device_sysfs.c @@ -0,0 +1,521 @@ +/* + * drivers/acpi/device_sysfs.c - ACPI device sysfs attributes and modalias. + * + * Copyright (C) 2015, Intel Corp. + * Author: Mika Westerberg + * Author: Rafael J. Wysocki + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include + +#include "internal.h" + +/** + * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent + * @acpi_dev: ACPI device object. + * @modalias: Buffer to print into. + * @size: Size of the buffer. + * + * Creates hid/cid(s) string needed for modalias and uevent + * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: + * char *modalias: "acpi:IBM0001:ACPI0001" + * Return: 0: no _HID and no _CID + * -EINVAL: output error + * -ENOMEM: output is truncated +*/ +static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias, + int size) +{ + int len; + int count; + struct acpi_hardware_id *id; + + /* + * Since we skip ACPI_DT_NAMESPACE_HID from the modalias below, 0 should + * be returned if ACPI_DT_NAMESPACE_HID is the only ACPI/PNP ID in the + * device's list. + */ + count = 0; + list_for_each_entry(id, &acpi_dev->pnp.ids, list) + if (strcmp(id->id, ACPI_DT_NAMESPACE_HID)) + count++; + + if (!count) + return 0; + + len = snprintf(modalias, size, "acpi:"); + if (len <= 0) + return len; + + size -= len; + + list_for_each_entry(id, &acpi_dev->pnp.ids, list) { + if (!strcmp(id->id, ACPI_DT_NAMESPACE_HID)) + continue; + + count = snprintf(&modalias[len], size, "%s:", id->id); + if (count < 0) + return -EINVAL; + + if (count >= size) + return -ENOMEM; + + len += count; + size -= count; + } + modalias[len] = '\0'; + return len; +} + +/** + * create_of_modalias - Creates DT compatible string for modalias and uevent + * @acpi_dev: ACPI device object. + * @modalias: Buffer to print into. + * @size: Size of the buffer. + * + * Expose DT compatible modalias as of:NnameTCcompatible. This function should + * only be called for devices having ACPI_DT_NAMESPACE_HID in their list of + * ACPI/PNP IDs. + */ +static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias, + int size) +{ + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; + const union acpi_object *of_compatible, *obj; + int len, count; + int i, nval; + char *c; + + acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf); + /* DT strings are all in lower case */ + for (c = buf.pointer; *c != '\0'; c++) + *c = tolower(*c); + + len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer); + ACPI_FREE(buf.pointer); + + if (len <= 0) + return len; + + of_compatible = acpi_dev->data.of_compatible; + if (of_compatible->type == ACPI_TYPE_PACKAGE) { + nval = of_compatible->package.count; + obj = of_compatible->package.elements; + } else { /* Must be ACPI_TYPE_STRING. */ + nval = 1; + obj = of_compatible; + } + for (i = 0; i < nval; i++, obj++) { + count = snprintf(&modalias[len], size, "C%s", + obj->string.pointer); + if (count < 0) + return -EINVAL; + + if (count >= size) + return -ENOMEM; + + len += count; + size -= count; + } + modalias[len] = '\0'; + return len; +} + +int __acpi_device_uevent_modalias(struct acpi_device *adev, + struct kobj_uevent_env *env) +{ + int len; + + if (!adev) + return -ENODEV; + + if (list_empty(&adev->pnp.ids)) + return 0; + + if (add_uevent_var(env, "MODALIAS=")) + return -ENOMEM; + + len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], + sizeof(env->buf) - env->buflen); + if (len < 0) + return len; + + env->buflen += len; + if (!adev->data.of_compatible) + return 0; + + if (len > 0 && add_uevent_var(env, "MODALIAS=")) + return -ENOMEM; + + len = create_of_modalias(adev, &env->buf[env->buflen - 1], + sizeof(env->buf) - env->buflen); + if (len < 0) + return len; + + env->buflen += len; + + return 0; +} + +/** + * acpi_device_uevent_modalias - uevent modalias for ACPI-enumerated devices. + * + * Create the uevent modalias field for ACPI-enumerated devices. + * + * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with + * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001". + */ +int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) +{ + return __acpi_device_uevent_modalias(acpi_companion_match(dev), env); +} +EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); + +static int __acpi_device_modalias(struct acpi_device *adev, char *buf, int size) +{ + int len, count; + + if (!adev) + return -ENODEV; + + if (list_empty(&adev->pnp.ids)) + return 0; + + len = create_pnp_modalias(adev, buf, size - 1); + if (len < 0) { + return len; + } else if (len > 0) { + buf[len++] = '\n'; + size -= len; + } + if (!adev->data.of_compatible) + return len; + + count = create_of_modalias(adev, buf + len, size - 1); + if (count < 0) { + return count; + } else if (count > 0) { + len += count; + buf[len++] = '\n'; + } + + return len; +} + +/** + * acpi_device_modalias - modalias sysfs attribute for ACPI-enumerated devices. + * + * Create the modalias sysfs attribute for ACPI-enumerated devices. + * + * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with + * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001". + */ +int acpi_device_modalias(struct device *dev, char *buf, int size) +{ + return __acpi_device_modalias(acpi_companion_match(dev), buf, size); +} +EXPORT_SYMBOL_GPL(acpi_device_modalias); + +static ssize_t +acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { + return __acpi_device_modalias(to_acpi_device(dev), buf, 1024); +} +static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); + +static ssize_t real_power_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct acpi_device *adev = to_acpi_device(dev); + int state; + int ret; + + ret = acpi_device_get_power(adev, &state); + if (ret) + return ret; + + return sprintf(buf, "%s\n", acpi_power_state_string(state)); +} + +static DEVICE_ATTR(real_power_state, 0444, real_power_state_show, NULL); + +static ssize_t power_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct acpi_device *adev = to_acpi_device(dev); + + return sprintf(buf, "%s\n", acpi_power_state_string(adev->power.state)); +} + +static DEVICE_ATTR(power_state, 0444, power_state_show, NULL); + +static ssize_t +acpi_eject_store(struct device *d, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct acpi_device *acpi_device = to_acpi_device(d); + acpi_object_type not_used; + acpi_status status; + + if (!count || buf[0] != '1') + return -EINVAL; + + if ((!acpi_device->handler || !acpi_device->handler->hotplug.enabled) + && !acpi_device->driver) + return -ENODEV; + + status = acpi_get_type(acpi_device->handle, ¬_used); + if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) + return -ENODEV; + + get_device(&acpi_device->dev); + status = acpi_hotplug_schedule(acpi_device, ACPI_OST_EC_OSPM_EJECT); + if (ACPI_SUCCESS(status)) + return count; + + put_device(&acpi_device->dev); + acpi_evaluate_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, + ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); + return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; +} + +static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); + +static ssize_t +acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct acpi_device *acpi_dev = to_acpi_device(dev); + + return sprintf(buf, "%s\n", acpi_device_hid(acpi_dev)); +} +static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); + +static ssize_t acpi_device_uid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct acpi_device *acpi_dev = to_acpi_device(dev); + + return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id); +} +static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL); + +static ssize_t acpi_device_adr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct acpi_device *acpi_dev = to_acpi_device(dev); + + return sprintf(buf, "0x%08x\n", + (unsigned int)(acpi_dev->pnp.bus_address)); +} +static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL); + +static ssize_t +acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct acpi_device *acpi_dev = to_acpi_device(dev); + struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; + int result; + + result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); + if (result) + goto end; + + result = sprintf(buf, "%s\n", (char*)path.pointer); + kfree(path.pointer); +end: + return result; +} +static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); + +/* sysfs file that shows description text from the ACPI _STR method */ +static ssize_t description_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct acpi_device *acpi_dev = to_acpi_device(dev); + int result; + + if (acpi_dev->pnp.str_obj == NULL) + return 0; + + /* + * The _STR object contains a Unicode identifier for a device. + * We need to convert to utf-8 so it can be displayed. + */ + result = utf16s_to_utf8s( + (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, + acpi_dev->pnp.str_obj->buffer.length, + UTF16_LITTLE_ENDIAN, buf, + PAGE_SIZE); + + buf[result++] = '\n'; + + return result; +} +static DEVICE_ATTR(description, 0444, description_show, NULL); + +static ssize_t +acpi_device_sun_show(struct device *dev, struct device_attribute *attr, + char *buf) { + struct acpi_device *acpi_dev = to_acpi_device(dev); + acpi_status status; + unsigned long long sun; + + status = acpi_evaluate_integer(acpi_dev->handle, "_SUN", NULL, &sun); + if (ACPI_FAILURE(status)) + return -ENODEV; + + return sprintf(buf, "%llu\n", sun); +} +static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); + +static ssize_t status_show(struct device *dev, struct device_attribute *attr, + char *buf) { + struct acpi_device *acpi_dev = to_acpi_device(dev); + acpi_status status; + unsigned long long sta; + + status = acpi_evaluate_integer(acpi_dev->handle, "_STA", NULL, &sta); + if (ACPI_FAILURE(status)) + return -ENODEV; + + return sprintf(buf, "%llu\n", sta); +} +static DEVICE_ATTR_RO(status); + +/** + * acpi_device_setup_files - Create sysfs attributes of an ACPI device. + * @dev: ACPI device object. + */ +int acpi_device_setup_files(struct acpi_device *dev) +{ + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + acpi_status status; + int result = 0; + + /* + * Devices gotten from FADT don't have a "path" attribute + */ + if (dev->handle) { + result = device_create_file(&dev->dev, &dev_attr_path); + if (result) + goto end; + } + + if (!list_empty(&dev->pnp.ids)) { + result = device_create_file(&dev->dev, &dev_attr_hid); + if (result) + goto end; + + result = device_create_file(&dev->dev, &dev_attr_modalias); + if (result) + goto end; + } + + /* + * If device has _STR, 'description' file is created + */ + if (acpi_has_method(dev->handle, "_STR")) { + status = acpi_evaluate_object(dev->handle, "_STR", + NULL, &buffer); + if (ACPI_FAILURE(status)) + buffer.pointer = NULL; + dev->pnp.str_obj = buffer.pointer; + result = device_create_file(&dev->dev, &dev_attr_description); + if (result) + goto end; + } + + if (dev->pnp.type.bus_address) + result = device_create_file(&dev->dev, &dev_attr_adr); + if (dev->pnp.unique_id) + result = device_create_file(&dev->dev, &dev_attr_uid); + + if (acpi_has_method(dev->handle, "_SUN")) { + result = device_create_file(&dev->dev, &dev_attr_sun); + if (result) + goto end; + } + + if (acpi_has_method(dev->handle, "_STA")) { + result = device_create_file(&dev->dev, &dev_attr_status); + if (result) + goto end; + } + + /* + * If device has _EJ0, 'eject' file is created that is used to trigger + * hot-removal function from userland. + */ + if (acpi_has_method(dev->handle, "_EJ0")) { + result = device_create_file(&dev->dev, &dev_attr_eject); + if (result) + return result; + } + + if (dev->flags.power_manageable) { + result = device_create_file(&dev->dev, &dev_attr_power_state); + if (result) + return result; + + if (dev->power.flags.power_resources) + result = device_create_file(&dev->dev, + &dev_attr_real_power_state); + } + +end: + return result; +} + +/** + * acpi_device_remove_files - Remove sysfs attributes of an ACPI device. + * @dev: ACPI device object. + */ +void acpi_device_remove_files(struct acpi_device *dev) +{ + if (dev->flags.power_manageable) { + device_remove_file(&dev->dev, &dev_attr_power_state); + if (dev->power.flags.power_resources) + device_remove_file(&dev->dev, + &dev_attr_real_power_state); + } + + /* + * If device has _STR, remove 'description' file + */ + if (acpi_has_method(dev->handle, "_STR")) { + kfree(dev->pnp.str_obj); + device_remove_file(&dev->dev, &dev_attr_description); + } + /* + * If device has _EJ0, remove 'eject' file. + */ + if (acpi_has_method(dev->handle, "_EJ0")) + device_remove_file(&dev->dev, &dev_attr_eject); + + if (acpi_has_method(dev->handle, "_SUN")) + device_remove_file(&dev->dev, &dev_attr_sun); + + if (dev->pnp.unique_id) + device_remove_file(&dev->dev, &dev_attr_uid); + if (dev->pnp.type.bus_address) + device_remove_file(&dev->dev, &dev_attr_adr); + device_remove_file(&dev->dev, &dev_attr_modalias); + device_remove_file(&dev->dev, &dev_attr_hid); + if (acpi_has_method(dev->handle, "_STA")) + device_remove_file(&dev->dev, &dev_attr_status); + if (dev->handle) + device_remove_file(&dev->dev, &dev_attr_path); +} diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 4683a96932b9..c529454532dc 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -93,11 +93,20 @@ int acpi_device_add(struct acpi_device *device, void (*release)(struct device *)); void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, int type, unsigned long long sta); +int acpi_device_setup_files(struct acpi_device *dev); +void acpi_device_remove_files(struct acpi_device *dev); void acpi_device_add_finalize(struct acpi_device *device); void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); bool acpi_device_is_present(struct acpi_device *adev); bool acpi_device_is_battery(struct acpi_device *adev); +/* -------------------------------------------------------------------------- + Device Matching and Notification + -------------------------------------------------------------------------- */ +struct acpi_device *acpi_companion_match(const struct device *dev); +int __acpi_device_uevent_modalias(struct acpi_device *adev, + struct kobj_uevent_env *env); + /* -------------------------------------------------------------------------- Power Resource -------------------------------------------------------------------------- */ diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ec256352f423..099831fc8449 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -115,117 +115,6 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, return 0; } -/** - * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent - * @acpi_dev: ACPI device object. - * @modalias: Buffer to print into. - * @size: Size of the buffer. - * - * Creates hid/cid(s) string needed for modalias and uevent - * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: - * char *modalias: "acpi:IBM0001:ACPI0001" - * Return: 0: no _HID and no _CID - * -EINVAL: output error - * -ENOMEM: output is truncated -*/ -static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias, - int size) -{ - int len; - int count; - struct acpi_hardware_id *id; - - /* - * Since we skip ACPI_DT_NAMESPACE_HID from the modalias below, 0 should - * be returned if ACPI_DT_NAMESPACE_HID is the only ACPI/PNP ID in the - * device's list. - */ - count = 0; - list_for_each_entry(id, &acpi_dev->pnp.ids, list) - if (strcmp(id->id, ACPI_DT_NAMESPACE_HID)) - count++; - - if (!count) - return 0; - - len = snprintf(modalias, size, "acpi:"); - if (len <= 0) - return len; - - size -= len; - - list_for_each_entry(id, &acpi_dev->pnp.ids, list) { - if (!strcmp(id->id, ACPI_DT_NAMESPACE_HID)) - continue; - - count = snprintf(&modalias[len], size, "%s:", id->id); - if (count < 0) - return -EINVAL; - - if (count >= size) - return -ENOMEM; - - len += count; - size -= count; - } - modalias[len] = '\0'; - return len; -} - -/** - * create_of_modalias - Creates DT compatible string for modalias and uevent - * @acpi_dev: ACPI device object. - * @modalias: Buffer to print into. - * @size: Size of the buffer. - * - * Expose DT compatible modalias as of:NnameTCcompatible. This function should - * only be called for devices having ACPI_DT_NAMESPACE_HID in their list of - * ACPI/PNP IDs. - */ -static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias, - int size) -{ - struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; - const union acpi_object *of_compatible, *obj; - int len, count; - int i, nval; - char *c; - - acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf); - /* DT strings are all in lower case */ - for (c = buf.pointer; *c != '\0'; c++) - *c = tolower(*c); - - len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer); - ACPI_FREE(buf.pointer); - - if (len <= 0) - return len; - - of_compatible = acpi_dev->data.of_compatible; - if (of_compatible->type == ACPI_TYPE_PACKAGE) { - nval = of_compatible->package.count; - obj = of_compatible->package.elements; - } else { /* Must be ACPI_TYPE_STRING. */ - nval = 1; - obj = of_compatible; - } - for (i = 0; i < nval; i++, obj++) { - count = snprintf(&modalias[len], size, "C%s", - obj->string.pointer); - if (count < 0) - return -EINVAL; - - if (count >= size) - return -ENOMEM; - - len += count; - size -= count; - } - modalias[len] = '\0'; - return len; -} - /* * acpi_companion_match() - Can we match via ACPI companion device * @dev: Device in question @@ -247,7 +136,7 @@ static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias, * resources available from it but they will be matched normally using functions * provided by their bus types (and analogously for their modalias). */ -static struct acpi_device *acpi_companion_match(const struct device *dev) +struct acpi_device *acpi_companion_match(const struct device *dev) { struct acpi_device *adev; struct mutex *physical_node_lock; @@ -276,103 +165,6 @@ static struct acpi_device *acpi_companion_match(const struct device *dev) return adev; } -static int __acpi_device_uevent_modalias(struct acpi_device *adev, - struct kobj_uevent_env *env) -{ - int len; - - if (!adev) - return -ENODEV; - - if (list_empty(&adev->pnp.ids)) - return 0; - - if (add_uevent_var(env, "MODALIAS=")) - return -ENOMEM; - - len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], - sizeof(env->buf) - env->buflen); - if (len < 0) - return len; - - env->buflen += len; - if (!adev->data.of_compatible) - return 0; - - if (len > 0 && add_uevent_var(env, "MODALIAS=")) - return -ENOMEM; - - len = create_of_modalias(adev, &env->buf[env->buflen - 1], - sizeof(env->buf) - env->buflen); - if (len < 0) - return len; - - env->buflen += len; - - return 0; -} - -/* - * Creates uevent modalias field for ACPI enumerated devices. - * Because the other buses does not support ACPI HIDs & CIDs. - * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: - * "acpi:IBM0001:ACPI0001" - */ -int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) -{ - return __acpi_device_uevent_modalias(acpi_companion_match(dev), env); -} -EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); - -static int __acpi_device_modalias(struct acpi_device *adev, char *buf, int size) -{ - int len, count; - - if (!adev) - return -ENODEV; - - if (list_empty(&adev->pnp.ids)) - return 0; - - len = create_pnp_modalias(adev, buf, size - 1); - if (len < 0) { - return len; - } else if (len > 0) { - buf[len++] = '\n'; - size -= len; - } - if (!adev->data.of_compatible) - return len; - - count = create_of_modalias(adev, buf + len, size - 1); - if (count < 0) { - return count; - } else if (count > 0) { - len += count; - buf[len++] = '\n'; - } - - return len; -} - -/* - * Creates modalias sysfs attribute for ACPI enumerated devices. - * Because the other buses does not support ACPI HIDs & CIDs. - * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: - * "acpi:IBM0001:ACPI0001" - */ -int acpi_device_modalias(struct device *dev, char *buf, int size) -{ - return __acpi_device_modalias(acpi_companion_match(dev), buf, size); -} -EXPORT_SYMBOL_GPL(acpi_device_modalias); - -static ssize_t -acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { - return __acpi_device_modalias(to_acpi_device(dev), buf, 1024); -} -static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); - bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent) { struct acpi_device_physical_node *pn; @@ -701,279 +493,6 @@ void acpi_device_hotplug(struct acpi_device *adev, u32 src) unlock_device_hotplug(); } -static ssize_t real_power_state_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct acpi_device *adev = to_acpi_device(dev); - int state; - int ret; - - ret = acpi_device_get_power(adev, &state); - if (ret) - return ret; - - return sprintf(buf, "%s\n", acpi_power_state_string(state)); -} - -static DEVICE_ATTR(real_power_state, 0444, real_power_state_show, NULL); - -static ssize_t power_state_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct acpi_device *adev = to_acpi_device(dev); - - return sprintf(buf, "%s\n", acpi_power_state_string(adev->power.state)); -} - -static DEVICE_ATTR(power_state, 0444, power_state_show, NULL); - -static ssize_t -acpi_eject_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct acpi_device *acpi_device = to_acpi_device(d); - acpi_object_type not_used; - acpi_status status; - - if (!count || buf[0] != '1') - return -EINVAL; - - if ((!acpi_device->handler || !acpi_device->handler->hotplug.enabled) - && !acpi_device->driver) - return -ENODEV; - - status = acpi_get_type(acpi_device->handle, ¬_used); - if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) - return -ENODEV; - - get_device(&acpi_device->dev); - status = acpi_hotplug_schedule(acpi_device, ACPI_OST_EC_OSPM_EJECT); - if (ACPI_SUCCESS(status)) - return count; - - put_device(&acpi_device->dev); - acpi_evaluate_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, - ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); - return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; -} - -static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); - -static ssize_t -acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - - return sprintf(buf, "%s\n", acpi_device_hid(acpi_dev)); -} -static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); - -static ssize_t acpi_device_uid_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - - return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id); -} -static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL); - -static ssize_t acpi_device_adr_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - - return sprintf(buf, "0x%08x\n", - (unsigned int)(acpi_dev->pnp.bus_address)); -} -static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL); - -static ssize_t -acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; - int result; - - result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); - if (result) - goto end; - - result = sprintf(buf, "%s\n", (char*)path.pointer); - kfree(path.pointer); -end: - return result; -} -static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); - -/* sysfs file that shows description text from the ACPI _STR method */ -static ssize_t description_show(struct device *dev, - struct device_attribute *attr, - char *buf) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - int result; - - if (acpi_dev->pnp.str_obj == NULL) - return 0; - - /* - * The _STR object contains a Unicode identifier for a device. - * We need to convert to utf-8 so it can be displayed. - */ - result = utf16s_to_utf8s( - (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, - acpi_dev->pnp.str_obj->buffer.length, - UTF16_LITTLE_ENDIAN, buf, - PAGE_SIZE); - - buf[result++] = '\n'; - - return result; -} -static DEVICE_ATTR(description, 0444, description_show, NULL); - -static ssize_t -acpi_device_sun_show(struct device *dev, struct device_attribute *attr, - char *buf) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - acpi_status status; - unsigned long long sun; - - status = acpi_evaluate_integer(acpi_dev->handle, "_SUN", NULL, &sun); - if (ACPI_FAILURE(status)) - return -ENODEV; - - return sprintf(buf, "%llu\n", sun); -} -static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); - -static ssize_t status_show(struct device *dev, struct device_attribute *attr, - char *buf) { - struct acpi_device *acpi_dev = to_acpi_device(dev); - acpi_status status; - unsigned long long sta; - - status = acpi_evaluate_integer(acpi_dev->handle, "_STA", NULL, &sta); - if (ACPI_FAILURE(status)) - return -ENODEV; - - return sprintf(buf, "%llu\n", sta); -} -static DEVICE_ATTR_RO(status); - -static int acpi_device_setup_files(struct acpi_device *dev) -{ - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_status status; - int result = 0; - - /* - * Devices gotten from FADT don't have a "path" attribute - */ - if (dev->handle) { - result = device_create_file(&dev->dev, &dev_attr_path); - if (result) - goto end; - } - - if (!list_empty(&dev->pnp.ids)) { - result = device_create_file(&dev->dev, &dev_attr_hid); - if (result) - goto end; - - result = device_create_file(&dev->dev, &dev_attr_modalias); - if (result) - goto end; - } - - /* - * If device has _STR, 'description' file is created - */ - if (acpi_has_method(dev->handle, "_STR")) { - status = acpi_evaluate_object(dev->handle, "_STR", - NULL, &buffer); - if (ACPI_FAILURE(status)) - buffer.pointer = NULL; - dev->pnp.str_obj = buffer.pointer; - result = device_create_file(&dev->dev, &dev_attr_description); - if (result) - goto end; - } - - if (dev->pnp.type.bus_address) - result = device_create_file(&dev->dev, &dev_attr_adr); - if (dev->pnp.unique_id) - result = device_create_file(&dev->dev, &dev_attr_uid); - - if (acpi_has_method(dev->handle, "_SUN")) { - result = device_create_file(&dev->dev, &dev_attr_sun); - if (result) - goto end; - } - - if (acpi_has_method(dev->handle, "_STA")) { - result = device_create_file(&dev->dev, &dev_attr_status); - if (result) - goto end; - } - - /* - * If device has _EJ0, 'eject' file is created that is used to trigger - * hot-removal function from userland. - */ - if (acpi_has_method(dev->handle, "_EJ0")) { - result = device_create_file(&dev->dev, &dev_attr_eject); - if (result) - return result; - } - - if (dev->flags.power_manageable) { - result = device_create_file(&dev->dev, &dev_attr_power_state); - if (result) - return result; - - if (dev->power.flags.power_resources) - result = device_create_file(&dev->dev, - &dev_attr_real_power_state); - } - -end: - return result; -} - -static void acpi_device_remove_files(struct acpi_device *dev) -{ - if (dev->flags.power_manageable) { - device_remove_file(&dev->dev, &dev_attr_power_state); - if (dev->power.flags.power_resources) - device_remove_file(&dev->dev, - &dev_attr_real_power_state); - } - - /* - * If device has _STR, remove 'description' file - */ - if (acpi_has_method(dev->handle, "_STR")) { - kfree(dev->pnp.str_obj); - device_remove_file(&dev->dev, &dev_attr_description); - } - /* - * If device has _EJ0, remove 'eject' file. - */ - if (acpi_has_method(dev->handle, "_EJ0")) - device_remove_file(&dev->dev, &dev_attr_eject); - - if (acpi_has_method(dev->handle, "_SUN")) - device_remove_file(&dev->dev, &dev_attr_sun); - - if (dev->pnp.unique_id) - device_remove_file(&dev->dev, &dev_attr_uid); - if (dev->pnp.type.bus_address) - device_remove_file(&dev->dev, &dev_attr_adr); - device_remove_file(&dev->dev, &dev_attr_modalias); - device_remove_file(&dev->dev, &dev_attr_hid); - if (acpi_has_method(dev->handle, "_STA")) - device_remove_file(&dev->dev, &dev_attr_status); - if (dev->handle) - device_remove_file(&dev->dev, &dev_attr_path); -} /* -------------------------------------------------------------------------- ACPI Bus operations -------------------------------------------------------------------------- */ -- cgit v1.2.3 From 68c6b148daa6e45a85b31ef60ed9c9bfd556fff0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 17 Jul 2015 22:53:52 +0200 Subject: ACPI / scan: Move device matching code to bus.c To reduce the size of scan.c and improve the readability of it, move code related device matching into drivers/acpi/bus.c. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/scan.c | 189 -------------------------------------------------- 2 files changed, 194 insertions(+), 189 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 513e7230e3d0..ce805809b00b 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -423,6 +423,200 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) acpi_evaluate_ost(handle, type, ost_code, NULL); } +/* -------------------------------------------------------------------------- + Device Matching + -------------------------------------------------------------------------- */ + +/* + * acpi_companion_match() - Can we match via ACPI companion device + * @dev: Device in question + * + * Check if the given device has an ACPI companion and if that companion has + * a valid list of PNP IDs, and if the device is the first (primary) physical + * device associated with it. Return the companion pointer if that's the case + * or NULL otherwise. + * + * If multiple physical devices are attached to a single ACPI companion, we need + * to be careful. The usage scenario for this kind of relationship is that all + * of the physical devices in question use resources provided by the ACPI + * companion. A typical case is an MFD device where all the sub-devices share + * the parent's ACPI companion. In such cases we can only allow the primary + * (first) physical device to be matched with the help of the companion's PNP + * IDs. + * + * Additional physical devices sharing the ACPI companion can still use + * resources available from it but they will be matched normally using functions + * provided by their bus types (and analogously for their modalias). + */ +struct acpi_device *acpi_companion_match(const struct device *dev) +{ + struct acpi_device *adev; + struct mutex *physical_node_lock; + + adev = ACPI_COMPANION(dev); + if (!adev) + return NULL; + + if (list_empty(&adev->pnp.ids)) + return NULL; + + physical_node_lock = &adev->physical_node_lock; + mutex_lock(physical_node_lock); + if (list_empty(&adev->physical_node_list)) { + adev = NULL; + } else { + const struct acpi_device_physical_node *node; + + node = list_first_entry(&adev->physical_node_list, + struct acpi_device_physical_node, node); + if (node->dev != dev) + adev = NULL; + } + mutex_unlock(physical_node_lock); + + return adev; +} + +/** + * acpi_of_match_device - Match device object using the "compatible" property. + * @adev: ACPI device object to match. + * @of_match_table: List of device IDs to match against. + * + * If @dev has an ACPI companion which has ACPI_DT_NAMESPACE_HID in its list of + * identifiers and a _DSD object with the "compatible" property, use that + * property to match against the given list of identifiers. + */ +static bool acpi_of_match_device(struct acpi_device *adev, + const struct of_device_id *of_match_table) +{ + const union acpi_object *of_compatible, *obj; + int i, nval; + + if (!adev) + return false; + + of_compatible = adev->data.of_compatible; + if (!of_match_table || !of_compatible) + return false; + + if (of_compatible->type == ACPI_TYPE_PACKAGE) { + nval = of_compatible->package.count; + obj = of_compatible->package.elements; + } else { /* Must be ACPI_TYPE_STRING. */ + nval = 1; + obj = of_compatible; + } + /* Now we can look for the driver DT compatible strings */ + for (i = 0; i < nval; i++, obj++) { + const struct of_device_id *id; + + for (id = of_match_table; id->compatible[0]; id++) + if (!strcasecmp(obj->string.pointer, id->compatible)) + return true; + } + + return false; +} + +static bool __acpi_match_device_cls(const struct acpi_device_id *id, + struct acpi_hardware_id *hwid) +{ + int i, msk, byte_shift; + char buf[3]; + + if (!id->cls) + return false; + + /* Apply class-code bitmask, before checking each class-code byte */ + for (i = 1; i <= 3; i++) { + byte_shift = 8 * (3 - i); + msk = (id->cls_msk >> byte_shift) & 0xFF; + if (!msk) + continue; + + sprintf(buf, "%02x", (id->cls >> byte_shift) & msk); + if (strncmp(buf, &hwid->id[(i - 1) * 2], 2)) + return false; + } + return true; +} + +static const struct acpi_device_id *__acpi_match_device( + struct acpi_device *device, + const struct acpi_device_id *ids, + const struct of_device_id *of_ids) +{ + const struct acpi_device_id *id; + struct acpi_hardware_id *hwid; + + /* + * If the device is not present, it is unnecessary to load device + * driver for it. + */ + if (!device || !device->status.present) + return NULL; + + list_for_each_entry(hwid, &device->pnp.ids, list) { + /* First, check the ACPI/PNP IDs provided by the caller. */ + for (id = ids; id->id[0] || id->cls; id++) { + if (id->id[0] && !strcmp((char *) id->id, hwid->id)) + return id; + else if (id->cls && __acpi_match_device_cls(id, hwid)) + return id; + } + + /* + * Next, check ACPI_DT_NAMESPACE_HID and try to match the + * "compatible" property if found. + * + * The id returned by the below is not valid, but the only + * caller passing non-NULL of_ids here is only interested in + * whether or not the return value is NULL. + */ + if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id) + && acpi_of_match_device(device, of_ids)) + return id; + } + return NULL; +} + +/** + * acpi_match_device - Match a struct device against a given list of ACPI IDs + * @ids: Array of struct acpi_device_id object to match against. + * @dev: The device structure to match. + * + * Check if @dev has a valid ACPI handle and if there is a struct acpi_device + * object for that handle and use that object to match against a given list of + * device IDs. + * + * Return a pointer to the first matching ID on success or %NULL on failure. + */ +const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, + const struct device *dev) +{ + return __acpi_match_device(acpi_companion_match(dev), ids, NULL); +} +EXPORT_SYMBOL_GPL(acpi_match_device); + +int acpi_match_device_ids(struct acpi_device *device, + const struct acpi_device_id *ids) +{ + return __acpi_match_device(device, ids, NULL) ? 0 : -ENOENT; +} +EXPORT_SYMBOL(acpi_match_device_ids); + +bool acpi_driver_match_device(struct device *dev, + const struct device_driver *drv) +{ + if (!drv->acpi_match_table) + return acpi_of_match_device(ACPI_COMPANION(dev), + drv->of_match_table); + + return !!__acpi_match_device(acpi_companion_match(dev), + drv->acpi_match_table, drv->of_match_table); +} +EXPORT_SYMBOL_GPL(acpi_driver_match_device); + /* -------------------------------------------------------------------------- Initialization/Cleanup -------------------------------------------------------------------------- */ diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 099831fc8449..68877bc22357 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -115,55 +115,6 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, return 0; } -/* - * acpi_companion_match() - Can we match via ACPI companion device - * @dev: Device in question - * - * Check if the given device has an ACPI companion and if that companion has - * a valid list of PNP IDs, and if the device is the first (primary) physical - * device associated with it. Return the companion pointer if that's the case - * or NULL otherwise. - * - * If multiple physical devices are attached to a single ACPI companion, we need - * to be careful. The usage scenario for this kind of relationship is that all - * of the physical devices in question use resources provided by the ACPI - * companion. A typical case is an MFD device where all the sub-devices share - * the parent's ACPI companion. In such cases we can only allow the primary - * (first) physical device to be matched with the help of the companion's PNP - * IDs. - * - * Additional physical devices sharing the ACPI companion can still use - * resources available from it but they will be matched normally using functions - * provided by their bus types (and analogously for their modalias). - */ -struct acpi_device *acpi_companion_match(const struct device *dev) -{ - struct acpi_device *adev; - struct mutex *physical_node_lock; - - adev = ACPI_COMPANION(dev); - if (!adev) - return NULL; - - if (list_empty(&adev->pnp.ids)) - return NULL; - - physical_node_lock = &adev->physical_node_lock; - mutex_lock(physical_node_lock); - if (list_empty(&adev->physical_node_list)) { - adev = NULL; - } else { - const struct acpi_device_physical_node *node; - - node = list_first_entry(&adev->physical_node_list, - struct acpi_device_physical_node, node); - if (node->dev != dev) - adev = NULL; - } - mutex_unlock(physical_node_lock); - - return adev; -} bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent) { @@ -497,146 +448,6 @@ void acpi_device_hotplug(struct acpi_device *adev, u32 src) ACPI Bus operations -------------------------------------------------------------------------- */ -/** - * acpi_of_match_device - Match device object using the "compatible" property. - * @adev: ACPI device object to match. - * @of_match_table: List of device IDs to match against. - * - * If @dev has an ACPI companion which has ACPI_DT_NAMESPACE_HID in its list of - * identifiers and a _DSD object with the "compatible" property, use that - * property to match against the given list of identifiers. - */ -static bool acpi_of_match_device(struct acpi_device *adev, - const struct of_device_id *of_match_table) -{ - const union acpi_object *of_compatible, *obj; - int i, nval; - - if (!adev) - return false; - - of_compatible = adev->data.of_compatible; - if (!of_match_table || !of_compatible) - return false; - - if (of_compatible->type == ACPI_TYPE_PACKAGE) { - nval = of_compatible->package.count; - obj = of_compatible->package.elements; - } else { /* Must be ACPI_TYPE_STRING. */ - nval = 1; - obj = of_compatible; - } - /* Now we can look for the driver DT compatible strings */ - for (i = 0; i < nval; i++, obj++) { - const struct of_device_id *id; - - for (id = of_match_table; id->compatible[0]; id++) - if (!strcasecmp(obj->string.pointer, id->compatible)) - return true; - } - - return false; -} - -static bool __acpi_match_device_cls(const struct acpi_device_id *id, - struct acpi_hardware_id *hwid) -{ - int i, msk, byte_shift; - char buf[3]; - - if (!id->cls) - return false; - - /* Apply class-code bitmask, before checking each class-code byte */ - for (i = 1; i <= 3; i++) { - byte_shift = 8 * (3 - i); - msk = (id->cls_msk >> byte_shift) & 0xFF; - if (!msk) - continue; - - sprintf(buf, "%02x", (id->cls >> byte_shift) & msk); - if (strncmp(buf, &hwid->id[(i - 1) * 2], 2)) - return false; - } - return true; -} - -static const struct acpi_device_id *__acpi_match_device( - struct acpi_device *device, - const struct acpi_device_id *ids, - const struct of_device_id *of_ids) -{ - const struct acpi_device_id *id; - struct acpi_hardware_id *hwid; - - /* - * If the device is not present, it is unnecessary to load device - * driver for it. - */ - if (!device || !device->status.present) - return NULL; - - list_for_each_entry(hwid, &device->pnp.ids, list) { - /* First, check the ACPI/PNP IDs provided by the caller. */ - for (id = ids; id->id[0] || id->cls; id++) { - if (id->id[0] && !strcmp((char *) id->id, hwid->id)) - return id; - else if (id->cls && __acpi_match_device_cls(id, hwid)) - return id; - } - - /* - * Next, check ACPI_DT_NAMESPACE_HID and try to match the - * "compatible" property if found. - * - * The id returned by the below is not valid, but the only - * caller passing non-NULL of_ids here is only interested in - * whether or not the return value is NULL. - */ - if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id) - && acpi_of_match_device(device, of_ids)) - return id; - } - return NULL; -} - -/** - * acpi_match_device - Match a struct device against a given list of ACPI IDs - * @ids: Array of struct acpi_device_id object to match against. - * @dev: The device structure to match. - * - * Check if @dev has a valid ACPI handle and if there is a struct acpi_device - * object for that handle and use that object to match against a given list of - * device IDs. - * - * Return a pointer to the first matching ID on success or %NULL on failure. - */ -const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, - const struct device *dev) -{ - return __acpi_match_device(acpi_companion_match(dev), ids, NULL); -} -EXPORT_SYMBOL_GPL(acpi_match_device); - -int acpi_match_device_ids(struct acpi_device *device, - const struct acpi_device_id *ids) -{ - return __acpi_match_device(device, ids, NULL) ? 0 : -ENOENT; -} -EXPORT_SYMBOL(acpi_match_device_ids); - -bool acpi_driver_match_device(struct device *dev, - const struct device_driver *drv) -{ - if (!drv->acpi_match_table) - return acpi_of_match_device(ACPI_COMPANION(dev), - drv->of_match_table); - - return !!__acpi_match_device(acpi_companion_match(dev), - drv->acpi_match_table, drv->of_match_table); -} -EXPORT_SYMBOL_GPL(acpi_driver_match_device); - static void acpi_free_power_resources_lists(struct acpi_device *device) { int i; -- cgit v1.2.3 From 5894b0c46e49b5ecc25f22b2d1b8232aab00ce97 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 17 Jul 2015 22:54:01 +0200 Subject: ACPI / scan: Move bus operations and notification routines to bus.c To reduce the size of scan.c and improve the readability of it, move code related to device notification, the definitions of the ACPI bus operations and the driver management code to drivers/acpi/bus.c. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/scan.c | 183 --------------------------------------------------- 2 files changed, 184 insertions(+), 183 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index ce805809b00b..2f50fc4be1d4 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -423,6 +423,65 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) acpi_evaluate_ost(handle, type, ost_code, NULL); } +static void acpi_device_notify(acpi_handle handle, u32 event, void *data) +{ + struct acpi_device *device = data; + + device->driver->ops.notify(device, event); +} + +static void acpi_device_notify_fixed(void *data) +{ + struct acpi_device *device = data; + + /* Fixed hardware devices have no handles */ + acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); +} + +static u32 acpi_device_fixed_event(void *data) +{ + acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data); + return ACPI_INTERRUPT_HANDLED; +} + +static int acpi_device_install_notify_handler(struct acpi_device *device) +{ + acpi_status status; + + if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) + status = + acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, + acpi_device_fixed_event, + device); + else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) + status = + acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, + acpi_device_fixed_event, + device); + else + status = acpi_install_notify_handler(device->handle, + ACPI_DEVICE_NOTIFY, + acpi_device_notify, + device); + + if (ACPI_FAILURE(status)) + return -EINVAL; + return 0; +} + +static void acpi_device_remove_notify_handler(struct acpi_device *device) +{ + if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) + acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, + acpi_device_fixed_event); + else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) + acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, + acpi_device_fixed_event); + else + acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, + acpi_device_notify); +} + /* -------------------------------------------------------------------------- Device Matching -------------------------------------------------------------------------- */ @@ -617,6 +676,131 @@ bool acpi_driver_match_device(struct device *dev, } EXPORT_SYMBOL_GPL(acpi_driver_match_device); +/* -------------------------------------------------------------------------- + ACPI Driver Management + -------------------------------------------------------------------------- */ + +/** + * acpi_bus_register_driver - register a driver with the ACPI bus + * @driver: driver being registered + * + * Registers a driver with the ACPI bus. Searches the namespace for all + * devices that match the driver's criteria and binds. Returns zero for + * success or a negative error status for failure. + */ +int acpi_bus_register_driver(struct acpi_driver *driver) +{ + int ret; + + if (acpi_disabled) + return -ENODEV; + driver->drv.name = driver->name; + driver->drv.bus = &acpi_bus_type; + driver->drv.owner = driver->owner; + + ret = driver_register(&driver->drv); + return ret; +} + +EXPORT_SYMBOL(acpi_bus_register_driver); + +/** + * acpi_bus_unregister_driver - unregisters a driver with the ACPI bus + * @driver: driver to unregister + * + * Unregisters a driver with the ACPI bus. Searches the namespace for all + * devices that match the driver's criteria and unbinds. + */ +void acpi_bus_unregister_driver(struct acpi_driver *driver) +{ + driver_unregister(&driver->drv); +} + +EXPORT_SYMBOL(acpi_bus_unregister_driver); + +/* -------------------------------------------------------------------------- + ACPI Bus operations + -------------------------------------------------------------------------- */ + +static int acpi_bus_match(struct device *dev, struct device_driver *drv) +{ + struct acpi_device *acpi_dev = to_acpi_device(dev); + struct acpi_driver *acpi_drv = to_acpi_driver(drv); + + return acpi_dev->flags.match_driver + && !acpi_match_device_ids(acpi_dev, acpi_drv->ids); +} + +static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + return __acpi_device_uevent_modalias(to_acpi_device(dev), env); +} + +static int acpi_device_probe(struct device *dev) +{ + struct acpi_device *acpi_dev = to_acpi_device(dev); + struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); + int ret; + + if (acpi_dev->handler && !acpi_is_pnp_device(acpi_dev)) + return -EINVAL; + + if (!acpi_drv->ops.add) + return -ENOSYS; + + ret = acpi_drv->ops.add(acpi_dev); + if (ret) + return ret; + + acpi_dev->driver = acpi_drv; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Driver [%s] successfully bound to device [%s]\n", + acpi_drv->name, acpi_dev->pnp.bus_id)); + + if (acpi_drv->ops.notify) { + ret = acpi_device_install_notify_handler(acpi_dev); + if (ret) { + if (acpi_drv->ops.remove) + acpi_drv->ops.remove(acpi_dev); + + acpi_dev->driver = NULL; + acpi_dev->driver_data = NULL; + return ret; + } + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", + acpi_drv->name, acpi_dev->pnp.bus_id)); + get_device(dev); + return 0; +} + +static int acpi_device_remove(struct device * dev) +{ + struct acpi_device *acpi_dev = to_acpi_device(dev); + struct acpi_driver *acpi_drv = acpi_dev->driver; + + if (acpi_drv) { + if (acpi_drv->ops.notify) + acpi_device_remove_notify_handler(acpi_dev); + if (acpi_drv->ops.remove) + acpi_drv->ops.remove(acpi_dev); + } + acpi_dev->driver = NULL; + acpi_dev->driver_data = NULL; + + put_device(dev); + return 0; +} + +struct bus_type acpi_bus_type = { + .name = "acpi", + .match = acpi_bus_match, + .probe = acpi_device_probe, + .remove = acpi_device_remove, + .uevent = acpi_device_uevent, +}; + /* -------------------------------------------------------------------------- Initialization/Cleanup -------------------------------------------------------------------------- */ diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 68877bc22357..f541f689ae80 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -444,10 +444,6 @@ void acpi_device_hotplug(struct acpi_device *adev, u32 src) unlock_device_hotplug(); } -/* -------------------------------------------------------------------------- - ACPI Bus operations - -------------------------------------------------------------------------- */ - static void acpi_free_power_resources_lists(struct acpi_device *device) { int i; @@ -474,144 +470,6 @@ static void acpi_device_release(struct device *dev) kfree(acpi_dev); } -static int acpi_bus_match(struct device *dev, struct device_driver *drv) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = to_acpi_driver(drv); - - return acpi_dev->flags.match_driver - && !acpi_match_device_ids(acpi_dev, acpi_drv->ids); -} - -static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - return __acpi_device_uevent_modalias(to_acpi_device(dev), env); -} - -static void acpi_device_notify(acpi_handle handle, u32 event, void *data) -{ - struct acpi_device *device = data; - - device->driver->ops.notify(device, event); -} - -static void acpi_device_notify_fixed(void *data) -{ - struct acpi_device *device = data; - - /* Fixed hardware devices have no handles */ - acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); -} - -static u32 acpi_device_fixed_event(void *data) -{ - acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data); - return ACPI_INTERRUPT_HANDLED; -} - -static int acpi_device_install_notify_handler(struct acpi_device *device) -{ - acpi_status status; - - if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) - status = - acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, - acpi_device_fixed_event, - device); - else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) - status = - acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, - acpi_device_fixed_event, - device); - else - status = acpi_install_notify_handler(device->handle, - ACPI_DEVICE_NOTIFY, - acpi_device_notify, - device); - - if (ACPI_FAILURE(status)) - return -EINVAL; - return 0; -} - -static void acpi_device_remove_notify_handler(struct acpi_device *device) -{ - if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) - acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, - acpi_device_fixed_event); - else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) - acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, - acpi_device_fixed_event); - else - acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, - acpi_device_notify); -} - -static int acpi_device_probe(struct device *dev) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); - int ret; - - if (acpi_dev->handler && !acpi_is_pnp_device(acpi_dev)) - return -EINVAL; - - if (!acpi_drv->ops.add) - return -ENOSYS; - - ret = acpi_drv->ops.add(acpi_dev); - if (ret) - return ret; - - acpi_dev->driver = acpi_drv; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Driver [%s] successfully bound to device [%s]\n", - acpi_drv->name, acpi_dev->pnp.bus_id)); - - if (acpi_drv->ops.notify) { - ret = acpi_device_install_notify_handler(acpi_dev); - if (ret) { - if (acpi_drv->ops.remove) - acpi_drv->ops.remove(acpi_dev); - - acpi_dev->driver = NULL; - acpi_dev->driver_data = NULL; - return ret; - } - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", - acpi_drv->name, acpi_dev->pnp.bus_id)); - get_device(dev); - return 0; -} - -static int acpi_device_remove(struct device * dev) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = acpi_dev->driver; - - if (acpi_drv) { - if (acpi_drv->ops.notify) - acpi_device_remove_notify_handler(acpi_dev); - if (acpi_drv->ops.remove) - acpi_drv->ops.remove(acpi_dev); - } - acpi_dev->driver = NULL; - acpi_dev->driver_data = NULL; - - put_device(dev); - return 0; -} - -struct bus_type acpi_bus_type = { - .name = "acpi", - .match = acpi_bus_match, - .probe = acpi_device_probe, - .remove = acpi_device_remove, - .uevent = acpi_device_uevent, -}; - static void acpi_device_del(struct acpi_device *device) { mutex_lock(&acpi_device_lock); @@ -858,47 +716,6 @@ struct acpi_device *acpi_get_next_child(struct device *dev, return next == head ? NULL : list_entry(next, struct acpi_device, node); } -/* -------------------------------------------------------------------------- - Driver Management - -------------------------------------------------------------------------- */ -/** - * acpi_bus_register_driver - register a driver with the ACPI bus - * @driver: driver being registered - * - * Registers a driver with the ACPI bus. Searches the namespace for all - * devices that match the driver's criteria and binds. Returns zero for - * success or a negative error status for failure. - */ -int acpi_bus_register_driver(struct acpi_driver *driver) -{ - int ret; - - if (acpi_disabled) - return -ENODEV; - driver->drv.name = driver->name; - driver->drv.bus = &acpi_bus_type; - driver->drv.owner = driver->owner; - - ret = driver_register(&driver->drv); - return ret; -} - -EXPORT_SYMBOL(acpi_bus_register_driver); - -/** - * acpi_bus_unregister_driver - unregisters a driver with the ACPI bus - * @driver: driver to unregister - * - * Unregisters a driver with the ACPI bus. Searches the namespace for all - * devices that match the driver's criteria and unbinds. - */ -void acpi_bus_unregister_driver(struct acpi_driver *driver) -{ - driver_unregister(&driver->drv); -} - -EXPORT_SYMBOL(acpi_bus_unregister_driver); - /* -------------------------------------------------------------------------- Device Enumeration -------------------------------------------------------------------------- */ -- cgit v1.2.3 From 1dcc3d3362b0c97e48290f7786be85b4cec2a147 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 17 Jul 2015 22:54:09 +0200 Subject: ACPI / bus: Move ACPI bus type registration Move the registration of the ACPI bus type to acpi_bus_init() and avoid using ACPI going forward if it fails (too many things depend on the presence of the ACPI bus type). Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 4 +++- drivers/acpi/scan.c | 6 ------ 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 2f50fc4be1d4..7a3ad929f095 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1039,7 +1039,9 @@ static int __init acpi_bus_init(void) */ acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL); - return 0; + result = bus_register(&acpi_bus_type); + if (!result) + return 0; /* Mimic structured exception handling */ error1: diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index f541f689ae80..2fe5a37c385c 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1891,12 +1891,6 @@ int __init acpi_scan_init(void) { int result; - result = bus_register(&acpi_bus_type); - if (result) { - /* We don't want to quit even if we failed to add suspend/resume */ - printk(KERN_ERR PREFIX "Could not register bus type\n"); - } - acpi_pci_root_init(); acpi_pci_link_init(); acpi_processor_init(); -- cgit v1.2.3 From 8ce344c66e3ce122585cfe68be1ef0ffd176380d Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Sun, 19 Jul 2015 18:50:38 +0200 Subject: ACPI / processor: remove leftover __refdata annotations The processor_handler structure does not reference any __init / __exit code or data. Therefore the __refdata annotation is not needed. It used to be prior to commit fe7bf106ebc2 ("acpi: delete __cpuinit usage from all acpi files") due to the __cpuinit annotation of acpi_processor_add(). But with that commit in place that requirement has gone. The same is true for the acpi_cpu_notifier notifier block. acpi_cpu_soft_notify() used to be marked __cpuinit but lost its annotation in the above mentioned commit as well. Therefore the __refdata annotation isn't needed there either. Just drop the unneded __refdata annotations to be able to catch future section mismatches. Signed-off-by: Mathias Krause Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_processor.c | 2 +- drivers/acpi/processor_driver.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 92a5f738e370..985b8a83184e 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -485,7 +485,7 @@ static const struct acpi_device_id processor_device_ids[] = { { } }; -static struct acpi_scan_handler __refdata processor_handler = { +static struct acpi_scan_handler processor_handler = { .ids = processor_device_ids, .attach = acpi_processor_add, #ifdef CONFIG_ACPI_HOTPLUG_CPU diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index d9f71581b79b..cc820d840c61 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -159,7 +159,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __refdata acpi_cpu_notifier = { +static struct notifier_block acpi_cpu_notifier = { .notifier_call = acpi_cpu_soft_notify, }; -- cgit v1.2.3 From b2f8dc4ce6626e25b164e29cf72b70230a1f1711 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 22 Jul 2015 22:11:16 +0200 Subject: ACPI / processor: Drop an unused argument of a cleanup routine acpi_processor_unregister_performance() actually doesn't use its first argument, so drop it and update the callers accordingly. Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- drivers/acpi/processor_perflib.c | 4 +--- drivers/cpufreq/acpi-cpufreq.c | 5 ++--- drivers/cpufreq/e_powersaver.c | 2 +- drivers/cpufreq/ia64-acpi-cpufreq.c | 5 ++--- drivers/cpufreq/powernow-k7.c | 4 ++-- drivers/cpufreq/powernow-k8.c | 5 ++--- drivers/xen/xen-acpi-processor.c | 16 ++++++---------- include/acpi/processor.h | 5 +---- 8 files changed, 17 insertions(+), 29 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index cfc8aba72f86..36b6da2918a6 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -784,9 +784,7 @@ acpi_processor_register_performance(struct acpi_processor_performance EXPORT_SYMBOL(acpi_processor_register_performance); -void -acpi_processor_unregister_performance(struct acpi_processor_performance - *performance, unsigned int cpu) +void acpi_processor_unregister_performance(unsigned int cpu) { struct acpi_processor *pr; diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index de54ce14eb39..ca9d0f6edf08 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -844,7 +844,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) err_freqfree: kfree(data->freq_table); err_unreg: - acpi_processor_unregister_performance(perf, cpu); + acpi_processor_unregister_performance(cpu); err_free_mask: free_cpumask_var(data->freqdomain_cpus); err_free: @@ -862,8 +862,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) if (data) { policy->driver_data = NULL; - acpi_processor_unregister_performance(data->acpi_data, - data->acpi_perf_cpu); + acpi_processor_unregister_performance(data->acpi_perf_cpu); free_cpumask_var(data->freqdomain_cpus); kfree(data->freq_table); kfree(data); diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index a0d2a423cea9..4085244c8a67 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c @@ -78,7 +78,7 @@ static int eps_acpi_init(void) static int eps_acpi_exit(struct cpufreq_policy *policy) { if (eps_acpi_cpu_perf) { - acpi_processor_unregister_performance(eps_acpi_cpu_perf, 0); + acpi_processor_unregister_performance(0); free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map); kfree(eps_acpi_cpu_perf); eps_acpi_cpu_perf = NULL; diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index c30aaa6a54e8..a9c193286ef4 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c @@ -313,7 +313,7 @@ acpi_cpufreq_cpu_init ( err_freqfree: kfree(data->freq_table); err_unreg: - acpi_processor_unregister_performance(&data->acpi_data, cpu); + acpi_processor_unregister_performance(cpu); err_free: kfree(data); acpi_io_data[cpu] = NULL; @@ -332,8 +332,7 @@ acpi_cpufreq_cpu_exit ( if (data) { acpi_io_data[policy->cpu] = NULL; - acpi_processor_unregister_performance(&data->acpi_data, - policy->cpu); + acpi_processor_unregister_performance(policy->cpu); kfree(data); } diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 37c5742482d8..c1ae1999770a 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -421,7 +421,7 @@ static int powernow_acpi_init(void) return 0; err2: - acpi_processor_unregister_performance(acpi_processor_perf, 0); + acpi_processor_unregister_performance(0); err1: free_cpumask_var(acpi_processor_perf->shared_cpu_map); err05: @@ -661,7 +661,7 @@ static int powernow_cpu_exit(struct cpufreq_policy *policy) { #ifdef CONFIG_X86_POWERNOW_K7_ACPI if (acpi_processor_perf) { - acpi_processor_unregister_performance(acpi_processor_perf, 0); + acpi_processor_unregister_performance(0); free_cpumask_var(acpi_processor_perf->shared_cpu_map); kfree(acpi_processor_perf); } diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 5c035d04d827..0b5bf135b090 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -795,7 +795,7 @@ err_out_mem: kfree(powernow_table); err_out: - acpi_processor_unregister_performance(&data->acpi_data, data->cpu); + acpi_processor_unregister_performance(data->cpu); /* data->acpi_data.state_count informs us at ->exit() * whether ACPI was used */ @@ -863,8 +863,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { if (data->acpi_data.state_count) - acpi_processor_unregister_performance(&data->acpi_data, - data->cpu); + acpi_processor_unregister_performance(data->cpu); free_cpumask_var(data->acpi_data.shared_cpu_map); } diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 59fc190f1e92..70fa438000af 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c @@ -560,11 +560,9 @@ static int __init xen_acpi_processor_init(void) return 0; err_unregister: - for_each_possible_cpu(i) { - struct acpi_processor_performance *perf; - perf = per_cpu_ptr(acpi_perf_data, i); - acpi_processor_unregister_performance(perf, i); - } + for_each_possible_cpu(i) + acpi_processor_unregister_performance(i); + err_out: /* Freeing a NULL pointer is OK: alloc_percpu zeroes. */ free_acpi_perf_data(); @@ -579,11 +577,9 @@ static void __exit xen_acpi_processor_exit(void) kfree(acpi_ids_done); kfree(acpi_id_present); kfree(acpi_id_cst_present); - for_each_possible_cpu(i) { - struct acpi_processor_performance *perf; - perf = per_cpu_ptr(acpi_perf_data, i); - acpi_processor_unregister_performance(perf, i); - } + for_each_possible_cpu(i) + acpi_processor_unregister_performance(i); + free_acpi_perf_data(); } diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 4188a4d3b597..aad1f2a3cd2b 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -228,10 +228,7 @@ extern int acpi_processor_preregister_performance(struct extern int acpi_processor_register_performance(struct acpi_processor_performance *performance, unsigned int cpu); -extern void acpi_processor_unregister_performance(struct - acpi_processor_performance - *performance, - unsigned int cpu); +extern void acpi_processor_unregister_performance(unsigned int cpu); /* note: this locks both the calling module and the processor module if a _PPC object exists, rmmod is disallowed then */ -- cgit v1.2.3 From eb87a05223293a915dc97e6966cbbb1baa43cd5f Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:52:05 +0800 Subject: ACPICA: Parser: Reduce parser/namespace divergences for tracer support This patch reduces divergences in parser/namespace components so that the follow-up linuxized ACPICA upstream commits can be directly merged. Including the fix to an indent issue reported and fixed by Zhouyi Zhou. Signed-off-by: Lv Zheng Signed-off-by: Zhouyi Zhou Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsnames.c | 2 +- drivers/acpi/acpica/nsparse.c | 6 +++--- drivers/acpi/acpica/psloop.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index d293d9748036..2e37888f6abe 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -108,7 +108,7 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node, if (index != 0) { ACPI_ERROR((AE_INFO, "Could not construct external pathname; index=%u, size=%u, Path=%s", - (u32) index, (u32) size, &name_buffer[size])); + (u32)index, (u32)size, &name_buffer[size])); return (AE_BAD_PARAMETER); } diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 57a4cfe547e4..9926a67ca6d7 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -70,7 +70,7 @@ acpi_ns_one_complete_parse(u32 pass_number, { union acpi_parse_object *parse_root; acpi_status status; - u32 aml_length; + u32 aml_length; u8 *aml_start; struct acpi_walk_state *walk_state; struct acpi_table_header *table; @@ -110,11 +110,11 @@ acpi_ns_one_complete_parse(u32 pass_number, if (table->length < sizeof(struct acpi_table_header)) { status = AE_BAD_HEADER; } else { - aml_start = (u8 *) table + sizeof(struct acpi_table_header); + aml_start = (u8 *)table + sizeof(struct acpi_table_header); aml_length = table->length - sizeof(struct acpi_table_header); status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, aml_start, aml_length, NULL, - (u8) pass_number); + (u8)pass_number); } /* Found OSDT table, enable the namespace override feature */ diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 90437227d790..6136458d65d2 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -126,9 +126,9 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) && !walk_state->arg_count) { walk_state->aml_offset = - (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml, - walk_state->parser_state. - aml_start); + (u32)ACPI_PTR_DIFF(walk_state->parser_state.aml, + walk_state->parser_state. + aml_start); status = acpi_ps_get_next_arg(walk_state, @@ -499,7 +499,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) if (walk_state->op_info) { ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n", - (u32) op->common.aml_opcode, + (u32)op->common.aml_opcode, walk_state->op_info->name, op, parser_state->aml, op->common.aml_offset)); -- cgit v1.2.3 From 83482f758b0d2d6a20a10be88399da44aa186aed Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:52:11 +0800 Subject: ACPICA: Parser: Cleanup aml_offset in struct acpi_walk_state ACPICA commit d254405814495058276c0c2f9d96794d15a6c91c This patch converts aml_offset in struct acpi_walk_state to AML address. AML offset is actually only used by the debugger, using AML address is more direct and efficient during the parsing stage so that we don't need to calculate it during the parsing stage. On the other hand, we can see several issues in the current parser logic around the aml_offset: 1. union acpi_operand_object.Common.aml_offset is redundantly assigned in acpi_ps_parse_loop(). 2. aml_offset is not an indication of the offset from the table header but the offset from the entry of a list of objects. Sometimes, it indicates an entry for a Method/Package/Buffer, which makes it difficult to be reversely calculated to a table header offset. 3. When being used with method tracers (for example, Linux function trace), it's better to have AML address logged instead of the AML offset because the address is the only attribute that can uniquely identify the opcode. This patch is required to solve the above issues. Lv Zheng. Link: https://github.com/acpica/acpica/commit/d2544058 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acstruct.h | 2 +- drivers/acpi/acpica/dsmethod.c | 9 +++++++-- drivers/acpi/acpica/psloop.c | 15 +++++++++------ drivers/acpi/acpica/psobject.c | 15 +++++++++------ 4 files changed, 26 insertions(+), 15 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index 44997ca02ae2..f9992dced1f9 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h @@ -85,7 +85,7 @@ struct acpi_walk_state { u8 namespace_override; /* Override existing objects */ u8 result_size; /* Total elements for the result stack */ u8 result_count; /* Current number of occupied elements of result stack */ - u32 aml_offset; + u8 *aml; u32 arg_types; u32 method_breakpoint; /* For single stepping */ u32 user_breakpoint; /* User AML breakpoint */ diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 85bb951430d9..bf8c16e379fb 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -214,6 +214,8 @@ acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state, acpi_status acpi_ds_method_error(acpi_status status, struct acpi_walk_state * walk_state) { + u32 aml_offset; + ACPI_FUNCTION_ENTRY(); /* Ignore AE_OK and control exception codes */ @@ -234,13 +236,16 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state * walk_state) * Handler can map the exception code to anything it wants, including * AE_OK, in which case the executing method will not be aborted. */ + aml_offset = (u32)ACPI_PTR_DIFF(walk_state->aml, + walk_state->parser_state. + aml_start); + status = acpi_gbl_exception_handler(status, walk_state->method_node ? walk_state->method_node-> name.integer : 0, walk_state->opcode, - walk_state->aml_offset, - NULL); + aml_offset, NULL); acpi_ex_enter_interpreter(); } diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 6136458d65d2..ce66e73f1f60 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -125,10 +125,7 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, */ while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) && !walk_state->arg_count) { - walk_state->aml_offset = - (u32)ACPI_PTR_DIFF(walk_state->parser_state.aml, - walk_state->parser_state. - aml_start); + walk_state->aml = walk_state->parser_state.aml; status = acpi_ps_get_next_arg(walk_state, @@ -140,7 +137,10 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, } if (arg) { - arg->common.aml_offset = walk_state->aml_offset; + arg->common.aml_offset = + (u32)ACPI_PTR_DIFF(walk_state->aml, + walk_state->parser_state. + aml_start); acpi_ps_append_arg(op, arg); } @@ -494,7 +494,10 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) continue; } - op->common.aml_offset = walk_state->aml_offset; + op->common.aml_offset = + (u32)ACPI_PTR_DIFF(walk_state->aml, + walk_state->parser_state. + aml_start); if (walk_state->op_info) { ACPI_DEBUG_PRINT((ACPI_DB_PARSE, diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c index 2f5ddd806c58..6ba3bb7402a9 100644 --- a/drivers/acpi/acpica/psobject.c +++ b/drivers/acpi/acpica/psobject.c @@ -66,12 +66,11 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state); static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) { + u32 aml_offset; ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state); - walk_state->aml_offset = - (u32)ACPI_PTR_DIFF(walk_state->parser_state.aml, - walk_state->parser_state.aml_start); + walk_state->aml = walk_state->parser_state.aml; walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state)); /* @@ -98,10 +97,14 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) /* The opcode is unrecognized. Complain and skip unknown opcodes */ if (walk_state->pass_number == 2) { + aml_offset = (u32)ACPI_PTR_DIFF(walk_state->aml, + walk_state-> + parser_state.aml_start); + ACPI_ERROR((AE_INFO, "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring", walk_state->opcode, - (u32)(walk_state->aml_offset + + (u32)(aml_offset + sizeof(struct acpi_table_header)))); ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16), @@ -115,14 +118,14 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) acpi_os_printf ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n", walk_state->opcode, - (u32)(walk_state->aml_offset + + (u32)(aml_offset + sizeof(struct acpi_table_header))); /* Dump the context surrounding the invalid opcode */ acpi_ut_dump_buffer(((u8 *)walk_state->parser_state. aml - 16), 48, DB_BYTE_DISPLAY, - (walk_state->aml_offset + + (aml_offset + sizeof(struct acpi_table_header) - 16)); acpi_os_printf(" */\n"); -- cgit v1.2.3 From 950a429cd21638b0c076d135ed279518b21f452b Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:52:18 +0800 Subject: ACPICA: Parser: Cleanup aml_offset in union acpi_operand_object ACPICA commit 61b360074fde2bb8282722579410f5d1fb12f84d This patch converts aml_offset in union acpi_operand_object to AML address. AML offset is actually only used by the debugger, using AML address is more direct and efficient during the parsing stage so that we don't need to calculate the offset during the parsing stage and will not have difficulities in converting it into other offset attributes. Sometimes, aml_offset is not an indication of the offset from the table header but the offset from the entry of a list of terms, which requires additional efforts to convert it into an offset from the table header. By using AML address directly, there is no such difficulty. Thus this patch also deletes a logic in disassembler that is trying to convert the aml_offset from "offset from the start address of Method/Package/Buffer" into the "offset from the start address of the ACPI table" (Sample code deletion can be seen in acpi_dm_deferred_parse(), but the function is not in the Linux kernel). Lv Zheng. Link: https://github.com/acpica/acpica/commit/61b36007 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/aclocal.h | 2 +- drivers/acpi/acpica/psargs.c | 7 +++---- drivers/acpi/acpica/psloop.c | 15 ++++----------- 3 files changed, 8 insertions(+), 16 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index bc600969c6a1..607e62897aff 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -726,7 +726,7 @@ union acpi_parse_value { u8 descriptor_type; /* To differentiate various internal objs */\ u8 flags; /* Type of Op */\ u16 aml_opcode; /* AML opcode */\ - u32 aml_offset; /* Offset of declaration in AML */\ + u8 *aml; /* Address of declaration in AML */\ union acpi_parse_object *next; /* Next op */\ struct acpi_namespace_node *node; /* For use by interpreter */\ union acpi_parse_value value; /* Value or args associated with the opcode */\ diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index 6d038770577b..0bee9466d149 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -484,7 +484,7 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state *parser_state) { - u32 aml_offset; + u8 *aml; union acpi_parse_object *field; union acpi_parse_object *arg = NULL; u16 opcode; @@ -498,8 +498,7 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state ACPI_FUNCTION_TRACE(ps_get_next_field); - aml_offset = - (u32)ACPI_PTR_DIFF(parser_state->aml, parser_state->aml_start); + aml = parser_state->aml; /* Determine field type */ @@ -541,7 +540,7 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state return_PTR(NULL); } - field->common.aml_offset = aml_offset; + field->common.aml = aml; /* Decode the field type */ diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index ce66e73f1f60..d5843830fef8 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -137,10 +137,7 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, } if (arg) { - arg->common.aml_offset = - (u32)ACPI_PTR_DIFF(walk_state->aml, - walk_state->parser_state. - aml_start); + arg->common.aml = walk_state->aml; acpi_ps_append_arg(op, arg); } @@ -494,18 +491,14 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) continue; } - op->common.aml_offset = - (u32)ACPI_PTR_DIFF(walk_state->aml, - walk_state->parser_state. - aml_start); + op->common.aml = walk_state->aml; if (walk_state->op_info) { ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n", + "Opcode %4.4X [%s] Op %p Aml %p\n", (u32)op->common.aml_opcode, walk_state->op_info->name, op, - parser_state->aml, - op->common.aml_offset)); + op->common.aml)); } } -- cgit v1.2.3 From 62eb935b77818a5e4ff3c8d9b97036b59944f649 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:52:24 +0800 Subject: ACPICA: Dispatcher: Cleanup union acpi_operand_object's AML address assignments ACPICA commit afb52611dbe7403551f93504d3798534f5c343f4 This patch cleans up the code of assigning the AML address to the union acpi_operand_object. The idea behind this cleanup is: The AML address of the union acpi_operand_object should always be determined at the point where the object is encountered. It should be started from the first byte of the object. For example, the opcode of the object, the name string of the user_term object, or the first byte of the packaged object (where a pkg_length is prefixed). So it's not cleaner to have it assigned here and there in the entire ACPICA source tree. There are some special cases for the internal opcodes, before cleaning up the internal opcodes, we should also determine the rules for the AML addresses of the internal opcodes: 1. INT_NAMEPATH_OP: the address of the first byte for the name_string. 2. INT_METHODCALL_OP: the address of the first byte for the name_string. 3. INT_BYTELIST_OP: the address of the first byte for the byte_data list. 4. INT_EVAL_SUBTREE_OP: the address of the first byte for the Region/Package/Buffer/bank_field/Field arguments. 5. INT_NAMEDFIELD_OP: the address to the name_seg. 6. INT_RESERVEDFIELD_OP: the address to the 0x00 prefix. 7. INT_ACCESSFIELD_OP: the address to the 0x01 prefix. 8. INT_CONNECTION_OP: the address to the 0x02 prefix. 9: INT_EXTACCESSFIELD_OP: the address to the 0x03 prefix. 10.INT_RETURN_VALUE_OP: the address of the replaced operand. 11.computational_data: the address to the Byte/Word/Dword/Qword/string_prefix. Before cleaning up the internal root scope of the aml_walk, turning it into the term_list, we need to remember the aml_start address as the "Aml" attribute for the union acpi_operand_object created by acpi_ps_create_scope_op(). Finally, we can delete some redundant AML address assignment in psloop.c. Link: https://github.com/acpica/acpica/commit/afb52611 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acparser.h | 4 ++-- drivers/acpi/acpica/dsargs.c | 4 ++-- drivers/acpi/acpica/dsmethod.c | 2 +- drivers/acpi/acpica/dswload.c | 2 +- drivers/acpi/acpica/dswload2.c | 2 +- drivers/acpi/acpica/nsparse.c | 40 +++++++++++++++++++--------------------- drivers/acpi/acpica/psargs.c | 21 ++++++++++++--------- drivers/acpi/acpica/psloop.c | 3 --- drivers/acpi/acpica/psobject.c | 2 +- drivers/acpi/acpica/psparse.c | 12 ++++++++---- drivers/acpi/acpica/psutils.c | 8 +++++--- drivers/acpi/acpica/psxface.c | 2 +- 12 files changed, 53 insertions(+), 49 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index 0cdd2fce493a..6021ccfb0b1c 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h @@ -225,11 +225,11 @@ void acpi_ps_delete_parse_tree(union acpi_parse_object *root); /* * psutils - parser utilities */ -union acpi_parse_object *acpi_ps_create_scope_op(void); +union acpi_parse_object *acpi_ps_create_scope_op(u8 *aml); void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode); -union acpi_parse_object *acpi_ps_alloc_op(u16 opcode); +union acpi_parse_object *acpi_ps_alloc_op(u16 opcode, u8 *aml); void acpi_ps_free_op(union acpi_parse_object *op); diff --git a/drivers/acpi/acpica/dsargs.c b/drivers/acpi/acpica/dsargs.c index 3e6989738e85..e2ab59e39162 100644 --- a/drivers/acpi/acpica/dsargs.c +++ b/drivers/acpi/acpica/dsargs.c @@ -86,7 +86,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node, /* Allocate a new parser op to be the root of the parsed tree */ - op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); + op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start); if (!op) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -129,7 +129,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node, /* Evaluate the deferred arguments */ - op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); + op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start); if (!op) { return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index bf8c16e379fb..4abc2425de4b 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -103,7 +103,7 @@ acpi_ds_auto_serialize_method(struct acpi_namespace_node *node, /* Create/Init a root op for the method parse tree */ - op = acpi_ps_alloc_op(AML_METHOD_OP); + op = acpi_ps_alloc_op(AML_METHOD_OP, obj_desc->method.aml_start); if (!op) { return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 845ff44919c3..097188a6b1c1 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c @@ -388,7 +388,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, /* Create a new op */ - op = acpi_ps_alloc_op(walk_state->opcode); + op = acpi_ps_alloc_op(walk_state->opcode, walk_state->aml); if (!op) { return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index fcaa30c611fb..e2c08cd79aca 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c @@ -335,7 +335,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, /* Create a new op */ - op = acpi_ps_alloc_op(walk_state->opcode); + op = acpi_ps_alloc_op(walk_state->opcode, walk_state->aml); if (!op) { return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 9926a67ca6d7..3736d43b18b9 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -78,6 +78,20 @@ acpi_ns_one_complete_parse(u32 pass_number, ACPI_FUNCTION_TRACE(ns_one_complete_parse); + status = acpi_get_table_by_index(table_index, &table); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Table must consist of at least a complete header */ + + if (table->length < sizeof(struct acpi_table_header)) { + return_ACPI_STATUS(AE_BAD_HEADER); + } + + aml_start = (u8 *)table + sizeof(struct acpi_table_header); + aml_length = table->length - sizeof(struct acpi_table_header); + status = acpi_tb_get_owner_id(table_index, &owner_id); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -85,7 +99,7 @@ acpi_ns_one_complete_parse(u32 pass_number, /* Create and init a Root Node */ - parse_root = acpi_ps_create_scope_op(); + parse_root = acpi_ps_create_scope_op(aml_start); if (!parse_root) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -98,23 +112,12 @@ acpi_ns_one_complete_parse(u32 pass_number, return_ACPI_STATUS(AE_NO_MEMORY); } - status = acpi_get_table_by_index(table_index, &table); + status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, + aml_start, aml_length, NULL, + (u8)pass_number); if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); - acpi_ps_free_op(parse_root); - return_ACPI_STATUS(status); - } - - /* Table must consist of at least a complete header */ - - if (table->length < sizeof(struct acpi_table_header)) { - status = AE_BAD_HEADER; - } else { - aml_start = (u8 *)table + sizeof(struct acpi_table_header); - aml_length = table->length - sizeof(struct acpi_table_header); - status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, - aml_start, aml_length, NULL, - (u8)pass_number); + goto cleanup; } /* Found OSDT table, enable the namespace override feature */ @@ -124,11 +127,6 @@ acpi_ns_one_complete_parse(u32 pass_number, walk_state->namespace_override = TRUE; } - if (ACPI_FAILURE(status)) { - acpi_ds_delete_walk_state(walk_state); - goto cleanup; - } - /* start_node is the default location to load the table */ if (start_node && start_node != acpi_gbl_root_node) { diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index 0bee9466d149..29d8b7b01dca 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -287,7 +287,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, "Control Method - %p Desc %p Path=%p\n", node, method_desc, path)); - name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); + name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start); if (!name_op) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -535,13 +535,11 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state /* Allocate a new field op */ - field = acpi_ps_alloc_op(opcode); + field = acpi_ps_alloc_op(opcode, aml); if (!field) { return_PTR(NULL); } - field->common.aml = aml; - /* Decode the field type */ switch (opcode) { @@ -603,6 +601,7 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state * Argument for Connection operator can be either a Buffer * (resource descriptor), or a name_string. */ + aml = parser_state->aml; if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) { parser_state->aml++; @@ -615,7 +614,8 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state /* Non-empty list */ - arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP); + arg = + acpi_ps_alloc_op(AML_INT_BYTELIST_OP, aml); if (!arg) { acpi_ps_free_op(field); return_PTR(NULL); @@ -664,7 +664,7 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state parser_state->aml = pkg_end; } else { - arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); + arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, aml); if (!arg) { acpi_ps_free_op(field); return_PTR(NULL); @@ -729,7 +729,7 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, /* Constants, strings, and namestrings are all the same size */ - arg = acpi_ps_alloc_op(AML_BYTE_OP); + arg = acpi_ps_alloc_op(AML_BYTE_OP, parser_state->aml); if (!arg) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -776,7 +776,8 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, /* Non-empty list */ - arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP); + arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP, + parser_state->aml); if (!arg) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -806,7 +807,9 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, /* null_name or name_string */ - arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); + arg = + acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, + parser_state->aml); if (!arg) { return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index d5843830fef8..49c60c2671ef 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -137,7 +137,6 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, } if (arg) { - arg->common.aml = walk_state->aml; acpi_ps_append_arg(op, arg); } @@ -491,8 +490,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) continue; } - op->common.aml = walk_state->aml; - if (walk_state->op_info) { ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Opcode %4.4X [%s] Op %p Aml %p\n", diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c index 6ba3bb7402a9..e54bc2aa7a88 100644 --- a/drivers/acpi/acpica/psobject.c +++ b/drivers/acpi/acpica/psobject.c @@ -297,7 +297,7 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state, /* Create Op structure and append to parent's argument list */ walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode); - op = acpi_ps_alloc_op(walk_state->opcode); + op = acpi_ps_alloc_op(walk_state->opcode, aml_op_start); if (!op) { return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index a555f7f7b9a2..b857ad58022a 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -185,7 +185,8 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, * op must be replaced by a placeholder return op */ replacement_op = - acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); + acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP, + op->common.aml); if (!replacement_op) { status = AE_NO_MEMORY; } @@ -209,7 +210,8 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, || (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) { replacement_op = - acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); + acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP, + op->common.aml); if (!replacement_op) { status = AE_NO_MEMORY; } @@ -224,7 +226,8 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, AML_VAR_PACKAGE_OP)) { replacement_op = acpi_ps_alloc_op(op->common. - aml_opcode); + aml_opcode, + op->common.aml); if (!replacement_op) { status = AE_NO_MEMORY; } else { @@ -240,7 +243,8 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, default: replacement_op = - acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); + acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP, + op->common.aml); if (!replacement_op) { status = AE_NO_MEMORY; } diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c index 32440912023a..183cc1efbc51 100644 --- a/drivers/acpi/acpica/psutils.c +++ b/drivers/acpi/acpica/psutils.c @@ -60,11 +60,11 @@ ACPI_MODULE_NAME("psutils") * DESCRIPTION: Create a Scope and associated namepath op with the root name * ******************************************************************************/ -union acpi_parse_object *acpi_ps_create_scope_op(void) +union acpi_parse_object *acpi_ps_create_scope_op(u8 *aml) { union acpi_parse_object *scope_op; - scope_op = acpi_ps_alloc_op(AML_SCOPE_OP); + scope_op = acpi_ps_alloc_op(AML_SCOPE_OP, aml); if (!scope_op) { return (NULL); } @@ -103,6 +103,7 @@ void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode) * FUNCTION: acpi_ps_alloc_op * * PARAMETERS: opcode - Opcode that will be stored in the new Op + * aml - Address of the opcode * * RETURN: Pointer to the new Op, null on failure * @@ -112,7 +113,7 @@ void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode) * ******************************************************************************/ -union acpi_parse_object *acpi_ps_alloc_op(u16 opcode) +union acpi_parse_object *acpi_ps_alloc_op(u16 opcode, u8 *aml) { union acpi_parse_object *op; const struct acpi_opcode_info *op_info; @@ -149,6 +150,7 @@ union acpi_parse_object *acpi_ps_alloc_op(u16 opcode) if (op) { acpi_ps_init_op(op, opcode); + op->common.aml = aml; op->common.flags = flags; } diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index 841a5ea06094..1f3f46d44312 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c @@ -256,7 +256,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) /* Create and init a Root Node */ - op = acpi_ps_create_scope_op(); + op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start); if (!op) { status = AE_NO_MEMORY; goto cleanup; -- cgit v1.2.3 From 07b9c91225055afeb2d75942fc36dd51c5553d90 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:52:31 +0800 Subject: ACPICA: Executer: Add back pointing reference of method operand ACPICA commit 9dcd124e914e87495fbd1786d9484b962e0823e0 This patch adds back pointing reference of the namespace node for a method operand. The namespace node then can be used in acpi_ds_terminate_control_method() to obtain method full path to be used by tracing facilities. Lv Zheng. Link: https://github.com/acpica/acpica/commit/9dcd124e Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acobject.h | 1 + drivers/acpi/acpica/excreate.c | 1 + drivers/acpi/acpica/utdelete.c | 3 +++ 3 files changed, 5 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index c81d98d09cac..0bd02c4a5f75 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -176,6 +176,7 @@ struct acpi_object_method { u8 param_count; u8 sync_level; union acpi_operand_object *mutex; + union acpi_operand_object *node; u8 *aml_start; union { acpi_internal_method implementation; diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index aaeea4840aaa..ccb7219bdcee 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -486,6 +486,7 @@ acpi_ex_create_method(u8 * aml_start, obj_desc->method.aml_start = aml_start; obj_desc->method.aml_length = aml_length; + obj_desc->method.node = operand[0]; /* * Disassemble the method flags. Split off the arg_count, Serialized diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index 71fce389fd48..1638312e3d8f 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -209,6 +209,9 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) acpi_ut_delete_object_desc(object->method.mutex); object->method.mutex = NULL; } + if (object->method.node) { + object->method.node = NULL; + } break; case ACPI_TYPE_REGION: -- cgit v1.2.3 From d1e7ffe50ba588ddf7de520990815c37f31776d8 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:52:39 +0800 Subject: ACPICA: Namespace: Add function to directly return normalized full path ACPICA commit 6e0229bb156d71675f2e07dc7960adb7ec0a60ea This patch adds functions to return normalized full path instead of "external path". The external path contains trailing "_" for each name segment while the normalized full path doesn't contain the trailing "_". Currently this function is used by the method tracing users to specify a none trailing "_" attached name path. Lv Zheng. Note that we need to validate and switch all Linux kernel acpi_get_name() users to use the new name type before removing the old name type from ACPICA. Link: https://github.com/acpica/acpica/commit/6e0229bb Signed-off-by: Lv Zheng Reviewed-by: Ruiyi Zhang Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acnamesp.h | 13 +- drivers/acpi/acpica/exdump.c | 5 +- drivers/acpi/acpica/nsnames.c | 275 +++++++++++++++++++++++------------------ drivers/acpi/acpica/nsutils.c | 2 +- drivers/acpi/acpica/nsxfname.c | 8 +- drivers/acpi/acpica/rscreate.c | 3 +- drivers/acpi/acpica/utmisc.c | 2 +- include/acpi/actypes.h | 3 +- 8 files changed, 178 insertions(+), 133 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 0dd088290d80..ea0d9076d408 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -272,17 +272,20 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, */ u32 acpi_ns_opens_scope(acpi_object_type type); -acpi_status -acpi_ns_build_external_path(struct acpi_namespace_node *node, - acpi_size size, char *name_buffer); - char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node); +u32 +acpi_ns_build_normalized_path(struct acpi_namespace_node *node, + char *full_path, u32 path_size, u8 no_trailing); + +char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node, + u8 no_trailing); + char *acpi_ns_name_of_current_scope(struct acpi_walk_state *walk_state); acpi_status acpi_ns_handle_to_pathname(acpi_handle target_handle, - struct acpi_buffer *buffer); + struct acpi_buffer *buffer, u8 no_trailing); u8 acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for); diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 401e7edcd419..b6495fb552f0 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -995,9 +995,8 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) if (obj_desc->reference.class == ACPI_REFCLASS_NAME) { acpi_os_printf(" %p ", obj_desc->reference.node); - status = - acpi_ns_handle_to_pathname(obj_desc->reference.node, - &ret_buf); + status = acpi_ns_handle_to_pathname(obj_desc->reference.node, + &ret_buf, FALSE); if (ACPI_FAILURE(status)) { acpi_os_printf(" Could not convert name to pathname\n"); } else { diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index 2e37888f6abe..8934b4eddb73 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -49,73 +49,6 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsnames") -/******************************************************************************* - * - * FUNCTION: acpi_ns_build_external_path - * - * PARAMETERS: node - NS node whose pathname is needed - * size - Size of the pathname - * *name_buffer - Where to return the pathname - * - * RETURN: Status - * Places the pathname into the name_buffer, in external format - * (name segments separated by path separators) - * - * DESCRIPTION: Generate a full pathaname - * - ******************************************************************************/ -acpi_status -acpi_ns_build_external_path(struct acpi_namespace_node *node, - acpi_size size, char *name_buffer) -{ - acpi_size index; - struct acpi_namespace_node *parent_node; - - ACPI_FUNCTION_ENTRY(); - - /* Special case for root */ - - index = size - 1; - if (index < ACPI_NAME_SIZE) { - name_buffer[0] = AML_ROOT_PREFIX; - name_buffer[1] = 0; - return (AE_OK); - } - - /* Store terminator byte, then build name backwards */ - - parent_node = node; - name_buffer[index] = 0; - - while ((index > ACPI_NAME_SIZE) && (parent_node != acpi_gbl_root_node)) { - index -= ACPI_NAME_SIZE; - - /* Put the name into the buffer */ - - ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name); - parent_node = parent_node->parent; - - /* Prefix name with the path separator */ - - index--; - name_buffer[index] = ACPI_PATH_SEPARATOR; - } - - /* Overwrite final separator with the root prefix character */ - - name_buffer[index] = AML_ROOT_PREFIX; - - if (index != 0) { - ACPI_ERROR((AE_INFO, - "Could not construct external pathname; index=%u, size=%u, Path=%s", - (u32)index, (u32)size, &name_buffer[size])); - - return (AE_BAD_PARAMETER); - } - - return (AE_OK); -} - /******************************************************************************* * * FUNCTION: acpi_ns_get_external_pathname @@ -130,37 +63,13 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node, * for error and debug statements. * ******************************************************************************/ - char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) { - acpi_status status; char *name_buffer; - acpi_size size; ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node); - /* Calculate required buffer size based on depth below root */ - - size = acpi_ns_get_pathname_length(node); - if (!size) { - return_PTR(NULL); - } - - /* Allocate a buffer to be returned to caller */ - - name_buffer = ACPI_ALLOCATE_ZEROED(size); - if (!name_buffer) { - ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size)); - return_PTR(NULL); - } - - /* Build the path in the allocated buffer */ - - status = acpi_ns_build_external_path(node, size, name_buffer); - if (ACPI_FAILURE(status)) { - ACPI_FREE(name_buffer); - return_PTR(NULL); - } + name_buffer = acpi_ns_get_normalized_pathname(node, FALSE); return_PTR(name_buffer); } @@ -180,33 +89,12 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node) { acpi_size size; - struct acpi_namespace_node *next_node; ACPI_FUNCTION_ENTRY(); - /* - * Compute length of pathname as 5 * number of name segments. - * Go back up the parent tree to the root - */ - size = 0; - next_node = node; + size = acpi_ns_build_normalized_path(node, NULL, 0, FALSE); - while (next_node && (next_node != acpi_gbl_root_node)) { - if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) { - ACPI_ERROR((AE_INFO, - "Invalid Namespace Node (%p) while traversing namespace", - next_node)); - return (0); - } - size += ACPI_PATH_SEGMENT_LENGTH; - next_node = next_node->parent; - } - - if (!size) { - size = 1; /* Root node case */ - } - - return (size + 1); /* +1 for null string terminator */ + return (size); } /******************************************************************************* @@ -216,6 +104,8 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node) * PARAMETERS: target_handle - Handle of named object whose name is * to be found * buffer - Where the pathname is returned + * no_trailing - Remove trailing '_' for each name + * segment * * RETURN: Status, Buffer is filled with pathname if status is AE_OK * @@ -225,7 +115,7 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node) acpi_status acpi_ns_handle_to_pathname(acpi_handle target_handle, - struct acpi_buffer * buffer) + struct acpi_buffer * buffer, u8 no_trailing) { acpi_status status; struct acpi_namespace_node *node; @@ -240,7 +130,8 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle, /* Determine size required for the caller buffer */ - required_size = acpi_ns_get_pathname_length(node); + required_size = + acpi_ns_build_normalized_path(node, NULL, 0, no_trailing); if (!required_size) { return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -254,8 +145,8 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle, /* Build the path in the caller buffer */ - status = - acpi_ns_build_external_path(node, required_size, buffer->pointer); + (void)acpi_ns_build_normalized_path(node, buffer->pointer, + required_size, no_trailing); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -264,3 +155,149 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle, (char *)buffer->pointer, (u32) required_size)); return_ACPI_STATUS(AE_OK); } + +/******************************************************************************* + * + * FUNCTION: acpi_ns_build_normalized_path + * + * PARAMETERS: node - Namespace node + * full_path - Where the path name is returned + * path_size - Size of returned path name buffer + * no_trailing - Remove trailing '_' from each name segment + * + * RETURN: Return 1 if the AML path is empty, otherwise returning (length + * of pathname + 1) which means the 'FullPath' contains a trailing + * null. + * + * DESCRIPTION: Build and return a full namespace pathname. + * Note that if the size of 'FullPath' isn't large enough to + * contain the namespace node's path name, the actual required + * buffer length is returned, and it should be greater than + * 'PathSize'. So callers are able to check the returning value + * to determine the buffer size of 'FullPath'. + * + ******************************************************************************/ + +u32 +acpi_ns_build_normalized_path(struct acpi_namespace_node *node, + char *full_path, u32 path_size, u8 no_trailing) +{ + u32 length = 0, i; + char name[ACPI_NAME_SIZE]; + u8 do_no_trailing; + char c, *left, *right; + struct acpi_namespace_node *next_node; + + ACPI_FUNCTION_TRACE_PTR(ns_build_normalized_path, node); + +#define ACPI_PATH_PUT8(path, size, byte, length) \ + do { \ + if ((length) < (size)) \ + { \ + (path)[(length)] = (byte); \ + } \ + (length)++; \ + } while (0) + + /* + * Make sure the path_size is correct, so that we don't need to + * validate both full_path and path_size. + */ + if (!full_path) { + path_size = 0; + } + + if (!node) { + goto build_trailing_null; + } + + next_node = node; + while (next_node && next_node != acpi_gbl_root_node) { + if (next_node != node) { + ACPI_PATH_PUT8(full_path, path_size, + AML_DUAL_NAME_PREFIX, length); + } + ACPI_MOVE_32_TO_32(name, &next_node->name); + do_no_trailing = no_trailing; + for (i = 0; i < 4; i++) { + c = name[4 - i - 1]; + if (do_no_trailing && c != '_') { + do_no_trailing = FALSE; + } + if (!do_no_trailing) { + ACPI_PATH_PUT8(full_path, path_size, c, length); + } + } + next_node = next_node->parent; + } + ACPI_PATH_PUT8(full_path, path_size, AML_ROOT_PREFIX, length); + + /* Reverse the path string */ + + if (length <= path_size) { + left = full_path; + right = full_path + length - 1; + while (left < right) { + c = *left; + *left++ = *right; + *right-- = c; + } + } + + /* Append the trailing null */ + +build_trailing_null: + ACPI_PATH_PUT8(full_path, path_size, '\0', length); + +#undef ACPI_PATH_PUT8 + + return_UINT32(length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_get_normalized_pathname + * + * PARAMETERS: node - Namespace node whose pathname is needed + * no_trailing - Remove trailing '_' from each name segment + * + * RETURN: Pointer to storage containing the fully qualified name of + * the node, In external format (name segments separated by path + * separators.) + * + * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually + * for error and debug statements. All trailing '_' will be + * removed from the full pathname if 'NoTrailing' is specified.. + * + ******************************************************************************/ + +char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node, + u8 no_trailing) +{ + char *name_buffer; + acpi_size size; + + ACPI_FUNCTION_TRACE_PTR(ns_get_normalized_pathname, node); + + /* Calculate required buffer size based on depth below root */ + + size = acpi_ns_build_normalized_path(node, NULL, 0, no_trailing); + if (!size) { + return_PTR(NULL); + } + + /* Allocate a buffer to be returned to caller */ + + name_buffer = ACPI_ALLOCATE_ZEROED(size); + if (!name_buffer) { + ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size)); + return_PTR(NULL); + } + + /* Build the path in the allocated buffer */ + + (void)acpi_ns_build_normalized_path(node, name_buffer, size, + no_trailing); + + return_PTR(name_buffer); +} diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 8d8104b8bd28..9a34c5f04075 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -83,7 +83,7 @@ acpi_ns_print_node_pathname(struct acpi_namespace_node *node, buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_ns_handle_to_pathname(node, &buffer); + status = acpi_ns_handle_to_pathname(node, &buffer, FALSE); if (ACPI_SUCCESS(status)) { if (message) { acpi_os_printf("%s ", message); diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 9ff643b9553f..4b4d2f43d406 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -172,11 +172,15 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) return (status); } - if (name_type == ACPI_FULL_PATHNAME) { + if (name_type == ACPI_FULL_PATHNAME || + name_type == ACPI_FULL_PATHNAME_NO_TRAILING) { /* Get the full pathname (From the namespace root) */ - status = acpi_ns_handle_to_pathname(handle, buffer); + status = acpi_ns_handle_to_pathname(handle, buffer, + name_type == + ACPI_FULL_PATHNAME ? FALSE : + TRUE); return (status); } diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index 3fa829e96c2a..a5344428f3ae 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c @@ -348,7 +348,8 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, status = acpi_ns_handle_to_pathname((acpi_handle) node, - &path_buffer); + &path_buffer, + FALSE); /* +1 to include null terminator */ diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 71b66537f826..98087ea1cdb3 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -376,7 +376,7 @@ acpi_ut_display_init_pathname(u8 type, /* Get the full pathname to the node */ buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_ns_handle_to_pathname(obj_handle, &buffer); + status = acpi_ns_handle_to_pathname(obj_handle, &buffer, FALSE); if (ACPI_FAILURE(status)) { return; } diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index c2a41d223162..0f3913f9a377 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -985,7 +985,8 @@ struct acpi_buffer { */ #define ACPI_FULL_PATHNAME 0 #define ACPI_SINGLE_NAME 1 -#define ACPI_NAME_TYPE_MAX 1 +#define ACPI_FULL_PATHNAME_NO_TRAILING 2 +#define ACPI_NAME_TYPE_MAX 2 /* * Predefined Namespace items -- cgit v1.2.3 From 0bac4295526c67e87ec24b29762140c38de7c86a Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:52:46 +0800 Subject: ACPICA: Dispatcher: Move stack traversal code to dispatcher ACPICA commit c8275e243b58fd4adfc0362bd704af41ed14bc75 This patch moves parts of acpi_dm_dump_method_info() to the dispatcher component. This patch also makes the new function dependent on ACPI_DEBUG_OUTPUT compile-stage definition so that it can be used by the trace facility. acpi_dm_dump_method_info() traverses method stack when an exception is encountered. Such traversal is needed to support method tracing for the exceptions. When an exception is encountered, the end indications of the aborted methods should be logged in order not to break the user space analysis tool. Lv Zheng. Link: https://github.com/acpica/acpica/commit/c8275e24 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/Makefile | 1 + drivers/acpi/acpica/acdispat.h | 8 ++ drivers/acpi/acpica/dsdebug.c | 222 +++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/dsmethod.c | 7 +- 4 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 drivers/acpi/acpica/dsdebug.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index c1a963581dc0..9f30ed7b1a07 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -11,6 +11,7 @@ obj-y += acpi.o acpi-y := \ dsargs.o \ dscontrol.o \ + dsdebug.o \ dsfield.o \ dsinit.o \ dsmethod.o \ diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h index 408f04bcaab4..7094dc89eb81 100644 --- a/drivers/acpi/acpica/acdispat.h +++ b/drivers/acpi/acpica/acdispat.h @@ -354,4 +354,12 @@ acpi_status acpi_ds_result_push(union acpi_operand_object *object, struct acpi_walk_state *walk_state); +/* + * dsdebug - parser debugging routines + */ +void +acpi_ds_dump_method_stack(acpi_status status, + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + #endif /* _ACDISPAT_H_ */ diff --git a/drivers/acpi/acpica/dsdebug.c b/drivers/acpi/acpica/dsdebug.c new file mode 100644 index 000000000000..21c6cefd267e --- /dev/null +++ b/drivers/acpi/acpica/dsdebug.c @@ -0,0 +1,222 @@ +/****************************************************************************** + * + * Module Name: dsdebug - Parser/Interpreter interface - debugging + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2015, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" +#include "acdispat.h" +#include "acnamesp.h" +#ifdef ACPI_DISASSEMBLER +#include "acdisasm.h" +#endif + +#define _COMPONENT ACPI_DISPATCHER +ACPI_MODULE_NAME("dsdebug") + +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) +/* Local prototypes */ +static void +acpi_ds_print_node_pathname(struct acpi_namespace_node *node, + const char *message); + +/******************************************************************************* + * + * FUNCTION: acpi_ds_print_node_pathname + * + * PARAMETERS: node - Object + * message - Prefix message + * + * DESCRIPTION: Print an object's full namespace pathname + * Manages allocation/freeing of a pathname buffer + * + ******************************************************************************/ + +static void +acpi_ds_print_node_pathname(struct acpi_namespace_node *node, + const char *message) +{ + struct acpi_buffer buffer; + acpi_status status; + + ACPI_FUNCTION_TRACE(ds_print_node_pathname); + + if (!node) { + ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[NULL NAME]")); + return_VOID; + } + + /* Convert handle to full pathname and print it (with supplied message) */ + + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + + status = acpi_ns_handle_to_pathname(node, &buffer, FALSE); + if (ACPI_SUCCESS(status)) { + if (message) { + ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "%s ", + message)); + } + + ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[%s] (Node %p)", + (char *)buffer.pointer, node)); + ACPI_FREE(buffer.pointer); + } + + return_VOID; +} + +/******************************************************************************* + * + * FUNCTION: acpi_ds_dump_method_stack + * + * PARAMETERS: status - Method execution status + * walk_state - Current state of the parse tree walk + * op - Executing parse op + * + * RETURN: None + * + * DESCRIPTION: Called when a method has been aborted because of an error. + * Dumps the method execution stack. + * + ******************************************************************************/ + +void +acpi_ds_dump_method_stack(acpi_status status, + struct acpi_walk_state *walk_state, + union acpi_parse_object *op) +{ + union acpi_parse_object *next; + struct acpi_thread_state *thread; + struct acpi_walk_state *next_walk_state; + struct acpi_namespace_node *previous_method = NULL; + + ACPI_FUNCTION_TRACE(ds_dump_method_stack); + + /* Ignore control codes, they are not errors */ + + if ((status & AE_CODE_MASK) == AE_CODE_CONTROL) { + return_VOID; + } + + /* We may be executing a deferred opcode */ + + if (walk_state->deferred_node) { + ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, + "Executing subtree for Buffer/Package/Region\n")); + return_VOID; + } + + /* + * If there is no Thread, we are not actually executing a method. + * This can happen when the iASL compiler calls the interpreter + * to perform constant folding. + */ + thread = walk_state->thread; + if (!thread) { + return_VOID; + } + + /* Display exception and method name */ + + ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, + "\n**** Exception %s during execution of method ", + acpi_format_exception(status))); + acpi_ds_print_node_pathname(walk_state->method_node, NULL); + + /* Display stack of executing methods */ + + ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, + "\n\nMethod Execution Stack:\n")); + next_walk_state = thread->walk_state_list; + + /* Walk list of linked walk states */ + + while (next_walk_state) { + ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, + " Method [%4.4s] executing: ", + acpi_ut_get_node_name(next_walk_state-> + method_node))); + + /* First method is the currently executing method */ + + if (next_walk_state == walk_state) { + if (op) { + + /* Display currently executing ASL statement */ + + next = op->common.next; + op->common.next = NULL; + +#ifdef ACPI_DISASSEMBLER + acpi_dm_disassemble(next_walk_state, op, + ACPI_UINT32_MAX); +#endif + op->common.next = next; + } + } else { + /* + * This method has called another method + * NOTE: the method call parse subtree is already deleted at this + * point, so we cannot disassemble the method invocation. + */ + ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, + "Call to method ")); + acpi_ds_print_node_pathname(previous_method, NULL); + } + + previous_method = next_walk_state->method_node; + next_walk_state = next_walk_state->next; + ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "\n")); + } + + return_VOID; +} + +#else +void +acpi_ds_dump_method_stack(acpi_status status, + struct acpi_walk_state *walk_state, + union acpi_parse_object *op) +{ + return; +} + +#endif diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 4abc2425de4b..e0ae8f4e9b35 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -251,14 +251,15 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state * walk_state) acpi_ds_clear_implicit_return(walk_state); -#ifdef ACPI_DISASSEMBLER if (ACPI_FAILURE(status)) { + acpi_ds_dump_method_stack(status, walk_state, walk_state->op); /* Display method locals/args if disassembler is present */ - acpi_dm_dump_method_info(status, walk_state, walk_state->op); - } +#ifdef ACPI_DISASSEMBLER + acpi_dm_dump_method_info(status, walk_state); #endif + } return (status); } -- cgit v1.2.3 From a616dc2fe50270f1fa5050fb9cd88a08531a3f25 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:52:53 +0800 Subject: ACPICA: Dispatcher: Add trace support for interpreter ACPICA commit 71299ec8b49054daace0df50268e8e055654ca37 This patch adds trace point at the following point: 1. Begin/end of a control method execution; 2. Begin/end of an opcode execution. The trace point feature can be enabled by defining ACPI_DEBUG_OUTPUT and specifying a debug level that includes ACPI_LV_TRACDE_POINT and the debug layers that include ACPI_PARSER and ACPI_DISPACTCHER. In order to make aml_op_name of union acpi_parse_object usable for tracer, it is enabled for ACPI_DEBUG_OUTPUT in this patch. Lv Zheng. Link: https://github.com/acpica/acpica/commit/71299ec8 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/aclocal.h | 2 +- drivers/acpi/acpica/dsdebug.c | 24 ++++++++++++++++++++++++ drivers/acpi/acpica/dsmethod.c | 31 +++++++++++++++++++++++++++++++ drivers/acpi/acpica/psloop.c | 15 +++++++++++++++ drivers/acpi/acpica/psparse.c | 4 ++++ include/acpi/acoutput.h | 4 +++- 6 files changed, 78 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 607e62897aff..610d001fbb31 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -715,7 +715,7 @@ union acpi_parse_value { union acpi_parse_object *arg; /* arguments and contained ops */ }; -#ifdef ACPI_DISASSEMBLER +#if defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUG_OUTPUT) #define ACPI_DISASM_ONLY_MEMBERS(a) a; #else #define ACPI_DISASM_ONLY_MEMBERS(a) diff --git a/drivers/acpi/acpica/dsdebug.c b/drivers/acpi/acpica/dsdebug.c index 21c6cefd267e..7df9b50e17a7 100644 --- a/drivers/acpi/acpica/dsdebug.c +++ b/drivers/acpi/acpica/dsdebug.c @@ -127,6 +127,8 @@ acpi_ds_dump_method_stack(acpi_status status, struct acpi_thread_state *thread; struct acpi_walk_state *next_walk_state; struct acpi_namespace_node *previous_method = NULL; + union acpi_operand_object *method_desc; + char *pathname = NULL; ACPI_FUNCTION_TRACE(ds_dump_method_stack); @@ -170,6 +172,28 @@ acpi_ds_dump_method_stack(acpi_status status, /* Walk list of linked walk states */ while (next_walk_state) { + method_desc = next_walk_state->method_desc; + if (method_desc && method_desc->method.node) { + pathname = acpi_ns_get_normalized_pathname((struct + acpi_namespace_node + *) + method_desc-> + method.node, + TRUE); + } + if (pathname) { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "End method [0x%p:%s] execution.\n", + method_desc->method.aml_start, + pathname)); + ACPI_FREE(pathname); + pathname = NULL; + } else { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "End method [0x%p] execution.\n", + method_desc->method.aml_start)); + } + ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, " Method [%4.4s] executing: ", acpi_ut_get_node_name(next_walk_state-> diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index e0ae8f4e9b35..0fa6f19aab3a 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -327,6 +327,7 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, struct acpi_walk_state *walk_state) { acpi_status status = AE_OK; + char *pathname = NULL; ACPI_FUNCTION_TRACE_PTR(ds_begin_method_execution, method_node); @@ -334,6 +335,18 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, return_ACPI_STATUS(AE_NULL_ENTRY); } + pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); + if (pathname) { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "Begin method [0x%p:%s] execution.\n", + obj_desc->method.aml_start, pathname)); + ACPI_FREE(pathname); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "Begin method [0x%p] execution.\n", + obj_desc->method.aml_start)); + } + /* Prevent wraparound of thread count */ if (obj_desc->method.thread_count == ACPI_UINT8_MAX) { @@ -695,6 +708,7 @@ void acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, struct acpi_walk_state *walk_state) { + char *pathname = NULL; ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state); @@ -832,5 +846,22 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, } } + if (method_desc->method.node) { + pathname = acpi_ns_get_normalized_pathname((struct + acpi_namespace_node + *)method_desc-> + method.node, TRUE); + } + if (pathname) { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "End method [0x%p:%s] execution.\n", + method_desc->method.aml_start, pathname)); + ACPI_FREE(pathname); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "End method [0x%p] execution.\n", + method_desc->method.aml_start)); + } + return_VOID; } diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 49c60c2671ef..80339ba56cad 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -497,6 +497,21 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) walk_state->op_info->name, op, op->common.aml)); } + + if (walk_state->op_info) { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "Begin opcode: %s[0x%p] Class=0x%02x, Type=0x%02x, Flags=0x%04x.\n", + op->common.aml_op_name, + op->common.aml, + walk_state->op_info->class, + walk_state->op_info->type, + walk_state->op_info->flags)); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "Begin opcode: %s[0x%p].\n", + op->common.aml_op_name, + op->common.aml)); + } } /* diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index b857ad58022a..97ea0e5360f1 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -147,6 +147,10 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, return_ACPI_STATUS(AE_OK); /* OK for now */ } + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "End opcode: %s[0x%p].\n", + op->common.aml_op_name, op->common.aml)); + /* Delete this op and the subtree below it if asked to */ if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index f56de8c5d844..8f89df9c7295 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h @@ -88,7 +88,8 @@ #define ACPI_LV_DEBUG_OBJECT 0x00000002 #define ACPI_LV_INFO 0x00000004 #define ACPI_LV_REPAIR 0x00000008 -#define ACPI_LV_ALL_EXCEPTIONS 0x0000000F +#define ACPI_LV_TRACE_POINT 0x00000010 +#define ACPI_LV_ALL_EXCEPTIONS 0x0000001F /* Trace verbosity level 1 [Standard Trace Level] */ @@ -147,6 +148,7 @@ #define ACPI_DB_DEBUG_OBJECT ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT) #define ACPI_DB_INFO ACPI_DEBUG_LEVEL (ACPI_LV_INFO) #define ACPI_DB_REPAIR ACPI_DEBUG_LEVEL (ACPI_LV_REPAIR) +#define ACPI_DB_TRACE_POINT ACPI_DEBUG_LEVEL (ACPI_LV_TRACE_POINT) #define ACPI_DB_ALL_EXCEPTIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS) /* Trace level -- also used in the global "DebugLevel" */ -- cgit v1.2.3 From ab6c573320768c36ac629be3db79ad62445aae64 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:52:59 +0800 Subject: ACPICA: Executer: Add interpreter tracing mode for method tracing facility ACPICA commit 07fffd02607685b655ed92ee15c160e6a810b60b The acpi_debug_trace() is the mechanism known as ACPI method tracing that is used by Linux as ACPICA debugging message reducer. This facility can be controlled through Linux ACPI subsystem - /sys/module/acpi/parameters. This facility requires CONFIG_ACPI_DEBUG to be enabled to see ACPICA trace logs in the kernel dmesg output. This patch enhances acpi_debug_trace() to make it not only a message reducer, but a real tracer to trace AML interpreter execution. Note that in addition to the AML tracer enabling, this patch also updates the facility with the following enhancements: 1. Allow a full path to be specified by the acpi_debug_trace() API. 2. Allow any method rather than just the entrance of acpi_evaluate_object() to be traced. 3. All interpreter ACPI_LV_TRACE_POINT messages are collected for ACPI_EXECUTER layer. The Makefile of drivers/acpi/acpica is also updated to include exdebug.o and the duplicated stubs are removed after that. Note that since this patch has enhanced the method tracing facility, Linux need also be updated after applying this patch. Lv Zheng. Link: https://github.com/acpica/acpica/commit/07fffd02 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acdebug.h | 2 + drivers/acpi/acpica/acglobal.h | 2 - drivers/acpi/acpica/acinterp.h | 18 +++ drivers/acpi/acpica/dsdebug.c | 25 +--- drivers/acpi/acpica/dsmethod.c | 32 +---- drivers/acpi/acpica/exdebug.c | 271 +++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/psloop.c | 16 +-- drivers/acpi/acpica/psparse.c | 4 +- drivers/acpi/acpica/psxface.c | 121 ++---------------- drivers/acpi/acpica/utinit.c | 2 - include/acpi/acoutput.h | 13 ++ include/acpi/acpixf.h | 6 +- 12 files changed, 327 insertions(+), 185 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 43685dd36c77..88482f75e941 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -102,6 +102,8 @@ void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg); acpi_status acpi_db_sleep(char *object_arg); +void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg); + void acpi_db_display_locks(void); void acpi_db_display_resources(char *object_arg); diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 53f96a370762..5342300719ee 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -290,8 +290,6 @@ ACPI_GLOBAL(u32, acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]); ACPI_GLOBAL(u32, acpi_gbl_original_dbg_level); ACPI_GLOBAL(u32, acpi_gbl_original_dbg_layer); -ACPI_GLOBAL(u32, acpi_gbl_trace_dbg_level); -ACPI_GLOBAL(u32, acpi_gbl_trace_dbg_layer); /***************************************************************************** * diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index 7ac98000b46b..a3c6e2ab93bb 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -131,6 +131,24 @@ void acpi_ex_do_debug_object(union acpi_operand_object *source_desc, u32 level, u32 index); +void +acpi_ex_start_trace_method(struct acpi_namespace_node *method_node, + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state); + +void +acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node, + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state); + +void +acpi_ex_start_trace_opcode(union acpi_parse_object *op, + struct acpi_walk_state *walk_state); + +void +acpi_ex_stop_trace_opcode(union acpi_parse_object *op, + struct acpi_walk_state *walk_state); + /* * exfield - ACPI AML (p-code) execution - field manipulation */ diff --git a/drivers/acpi/acpica/dsdebug.c b/drivers/acpi/acpica/dsdebug.c index 7df9b50e17a7..a651d30133d0 100644 --- a/drivers/acpi/acpica/dsdebug.c +++ b/drivers/acpi/acpica/dsdebug.c @@ -48,6 +48,7 @@ #ifdef ACPI_DISASSEMBLER #include "acdisasm.h" #endif +#include "acinterp.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsdebug") @@ -128,7 +129,6 @@ acpi_ds_dump_method_stack(acpi_status status, struct acpi_walk_state *next_walk_state; struct acpi_namespace_node *previous_method = NULL; union acpi_operand_object *method_desc; - char *pathname = NULL; ACPI_FUNCTION_TRACE(ds_dump_method_stack); @@ -173,25 +173,10 @@ acpi_ds_dump_method_stack(acpi_status status, while (next_walk_state) { method_desc = next_walk_state->method_desc; - if (method_desc && method_desc->method.node) { - pathname = acpi_ns_get_normalized_pathname((struct - acpi_namespace_node - *) - method_desc-> - method.node, - TRUE); - } - if (pathname) { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "End method [0x%p:%s] execution.\n", - method_desc->method.aml_start, - pathname)); - ACPI_FREE(pathname); - pathname = NULL; - } else { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "End method [0x%p] execution.\n", - method_desc->method.aml_start)); + if (method_desc) { + acpi_ex_stop_trace_method((struct acpi_namespace_node *) + method_desc->method.node, + method_desc, walk_state); } ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 0fa6f19aab3a..ea2bdde1227e 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -327,7 +327,6 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, struct acpi_walk_state *walk_state) { acpi_status status = AE_OK; - char *pathname = NULL; ACPI_FUNCTION_TRACE_PTR(ds_begin_method_execution, method_node); @@ -335,17 +334,7 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, return_ACPI_STATUS(AE_NULL_ENTRY); } - pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); - if (pathname) { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "Begin method [0x%p:%s] execution.\n", - obj_desc->method.aml_start, pathname)); - ACPI_FREE(pathname); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "Begin method [0x%p] execution.\n", - obj_desc->method.aml_start)); - } + acpi_ex_start_trace_method(method_node, obj_desc, walk_state); /* Prevent wraparound of thread count */ @@ -708,7 +697,6 @@ void acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, struct acpi_walk_state *walk_state) { - char *pathname = NULL; ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state); @@ -846,22 +834,8 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, } } - if (method_desc->method.node) { - pathname = acpi_ns_get_normalized_pathname((struct - acpi_namespace_node - *)method_desc-> - method.node, TRUE); - } - if (pathname) { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "End method [0x%p:%s] execution.\n", - method_desc->method.aml_start, pathname)); - ACPI_FREE(pathname); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "End method [0x%p] execution.\n", - method_desc->method.aml_start)); - } + acpi_ex_stop_trace_method((struct acpi_namespace_node *)method_desc-> + method.node, method_desc, walk_state); return_VOID; } diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index 815442bbd051..00ba9fc85f47 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c @@ -43,11 +43,15 @@ #include #include "accommon.h" +#include "acnamesp.h" #include "acinterp.h" +#include "acparser.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exdebug") +static union acpi_operand_object *acpi_gbl_trace_method_object = NULL; + #ifndef ACPI_NO_ERROR_MESSAGES /******************************************************************************* * @@ -70,6 +74,7 @@ ACPI_MODULE_NAME("exdebug") * enabled if necessary. * ******************************************************************************/ + void acpi_ex_do_debug_object(union acpi_operand_object *source_desc, u32 level, u32 index) @@ -308,3 +313,269 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, return_VOID; } #endif + +/******************************************************************************* + * + * FUNCTION: acpi_ex_interpreter_trace_enabled + * + * PARAMETERS: name - Whether method name should be matched, + * this should be checked before starting + * the tracer + * + * RETURN: TRUE if interpreter trace is enabled. + * + * DESCRIPTION: Check whether interpreter trace is enabled + * + ******************************************************************************/ + +static u8 acpi_ex_interpreter_trace_enabled(char *name) +{ + + /* Check if tracing is enabled */ + + if (!(acpi_gbl_trace_flags & ACPI_TRACE_ENABLED)) { + return (FALSE); + } + + /* + * Check if tracing is filtered: + * + * 1. If the tracer is started, acpi_gbl_trace_method_object should have + * been filled by the trace starter + * 2. If the tracer is not started, acpi_gbl_trace_method_name should be + * matched if it is specified + * 3. If the tracer is oneshot style, acpi_gbl_trace_method_name should + * not be cleared by the trace stopper during the first match + */ + if (acpi_gbl_trace_method_object) { + return (TRUE); + } + if (name && + (acpi_gbl_trace_method_name && + strcmp(acpi_gbl_trace_method_name, name))) { + return (FALSE); + } + if ((acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) && + !acpi_gbl_trace_method_name) { + return (FALSE); + } + + return (TRUE); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ex_start_trace_method + * + * PARAMETERS: method_node - Node of the method + * obj_desc - The method object + * walk_state - current state, NULL if not yet executing + * a method. + * + * RETURN: None + * + * DESCRIPTION: Start control method execution trace + * + ******************************************************************************/ + +void +acpi_ex_start_trace_method(struct acpi_namespace_node *method_node, + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state) +{ + acpi_status status; + char *pathname = NULL; + u8 enabled = FALSE; + + ACPI_FUNCTION_NAME(ex_start_trace_method); + + if (method_node) { + pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + goto exit; + } + + enabled = acpi_ex_interpreter_trace_enabled(pathname); + if (enabled && !acpi_gbl_trace_method_object) { + acpi_gbl_trace_method_object = obj_desc; + acpi_gbl_original_dbg_level = acpi_dbg_level; + acpi_gbl_original_dbg_layer = acpi_dbg_layer; + acpi_dbg_level = ACPI_TRACE_LEVEL_ALL; + acpi_dbg_layer = ACPI_TRACE_LAYER_ALL; + + if (acpi_gbl_trace_dbg_level) { + acpi_dbg_level = acpi_gbl_trace_dbg_level; + } + if (acpi_gbl_trace_dbg_layer) { + acpi_dbg_layer = acpi_gbl_trace_dbg_layer; + } + } + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + +exit: + if (enabled) { + if (pathname) { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "Begin method [0x%p:%s] execution.\n", + obj_desc->method.aml_start, + pathname)); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "Begin method [0x%p] execution.\n", + obj_desc->method.aml_start)); + } + } + if (pathname) { + ACPI_FREE(pathname); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ex_stop_trace_method + * + * PARAMETERS: method_node - Node of the method + * obj_desc - The method object + * walk_state - current state, NULL if not yet executing + * a method. + * + * RETURN: None + * + * DESCRIPTION: Stop control method execution trace + * + ******************************************************************************/ + +void +acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node, + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state) +{ + acpi_status status; + char *pathname = NULL; + u8 enabled; + + ACPI_FUNCTION_NAME(ex_stop_trace_method); + + if (method_node) { + pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + goto exit_path; + } + + enabled = acpi_ex_interpreter_trace_enabled(NULL); + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + + if (enabled) { + if (pathname) { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "End method [0x%p:%s] execution.\n", + obj_desc->method.aml_start, + pathname)); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "End method [0x%p] execution.\n", + obj_desc->method.aml_start)); + } + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + goto exit_path; + } + + /* Check whether the tracer should be stopped */ + + if (acpi_gbl_trace_method_object == obj_desc) { + + /* Disable further tracing if type is one-shot */ + + if (acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) { + acpi_gbl_trace_method_name = NULL; + } + + acpi_dbg_level = acpi_gbl_original_dbg_level; + acpi_dbg_layer = acpi_gbl_original_dbg_layer; + acpi_gbl_trace_method_object = NULL; + } + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + +exit_path: + if (pathname) { + ACPI_FREE(pathname); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ex_start_trace_opcode + * + * PARAMETERS: op - The parser opcode object + * walk_state - current state, NULL if not yet executing + * a method. + * + * RETURN: None + * + * DESCRIPTION: Start opcode execution trace + * + ******************************************************************************/ + +void +acpi_ex_start_trace_opcode(union acpi_parse_object *op, + struct acpi_walk_state *walk_state) +{ + + ACPI_FUNCTION_NAME(ex_start_trace_opcode); + + if (acpi_ex_interpreter_trace_enabled(NULL)) { + if (walk_state->op_info) { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "Begin opcode: %s[0x%p] Class=0x%02x, Type=0x%02x, Flags=0x%04x.\n", + op->common.aml_op_name, + op->common.aml, + walk_state->op_info->class, + walk_state->op_info->type, + walk_state->op_info->flags)); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "Begin opcode: %s[0x%p].\n", + op->common.aml_op_name, + op->common.aml)); + } + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ex_stop_trace_opcode + * + * PARAMETERS: op - The parser opcode object + * walk_state - current state, NULL if not yet executing + * a method. + * + * RETURN: None + * + * DESCRIPTION: Stop opcode execution trace + * + ******************************************************************************/ + +void +acpi_ex_stop_trace_opcode(union acpi_parse_object *op, + struct acpi_walk_state *walk_state) +{ + + ACPI_FUNCTION_NAME(ex_stop_trace_opcode); + + if (acpi_ex_interpreter_trace_enabled(NULL)) { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "End opcode: %s[0x%p].\n", + op->common.aml_op_name, op->common.aml)); + } +} diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 80339ba56cad..a7de52ee1538 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -51,6 +51,7 @@ #include #include "accommon.h" +#include "acinterp.h" #include "acparser.h" #include "acdispat.h" #include "amlcode.h" @@ -498,20 +499,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) op->common.aml)); } - if (walk_state->op_info) { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "Begin opcode: %s[0x%p] Class=0x%02x, Type=0x%02x, Flags=0x%04x.\n", - op->common.aml_op_name, - op->common.aml, - walk_state->op_info->class, - walk_state->op_info->type, - walk_state->op_info->flags)); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "Begin opcode: %s[0x%p].\n", - op->common.aml_op_name, - op->common.aml)); - } + acpi_ex_start_trace_opcode(op, walk_state); } /* diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index 97ea0e5360f1..98001d7f6f80 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -147,9 +147,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, return_ACPI_STATUS(AE_OK); /* OK for now */ } - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "End opcode: %s[0x%p].\n", - op->common.aml_op_name, op->common.aml)); + acpi_ex_stop_trace_opcode(op, walk_state); /* Delete this op and the subtree below it if asked to */ diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index 1f3f46d44312..4254805dd319 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c @@ -47,15 +47,12 @@ #include "acdispat.h" #include "acinterp.h" #include "actables.h" +#include "acnamesp.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psxface") /* Local Prototypes */ -static void acpi_ps_start_trace(struct acpi_evaluate_info *info); - -static void acpi_ps_stop_trace(struct acpi_evaluate_info *info); - static void acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); @@ -76,7 +73,7 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); ******************************************************************************/ acpi_status -acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags) +acpi_debug_trace(const char *name, u32 debug_level, u32 debug_layer, u32 flags) { acpi_status status; @@ -85,108 +82,14 @@ acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags) return (status); } - /* TBDs: Validate name, allow full path or just nameseg */ - - acpi_gbl_trace_method_name = *ACPI_CAST_PTR(u32, name); + acpi_gbl_trace_method_name = name; acpi_gbl_trace_flags = flags; - - if (debug_level) { - acpi_gbl_trace_dbg_level = debug_level; - } - if (debug_layer) { - acpi_gbl_trace_dbg_layer = debug_layer; - } + acpi_gbl_trace_dbg_level = debug_level; + acpi_gbl_trace_dbg_layer = debug_layer; + status = AE_OK; (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_start_trace - * - * PARAMETERS: info - Method info struct - * - * RETURN: None - * - * DESCRIPTION: Start control method execution trace - * - ******************************************************************************/ - -static void acpi_ps_start_trace(struct acpi_evaluate_info *info) -{ - acpi_status status; - - ACPI_FUNCTION_ENTRY(); - - status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE(status)) { - return; - } - - if ((!acpi_gbl_trace_method_name) || - (acpi_gbl_trace_method_name != info->node->name.integer)) { - goto exit; - } - - acpi_gbl_original_dbg_level = acpi_dbg_level; - acpi_gbl_original_dbg_layer = acpi_dbg_layer; - - acpi_dbg_level = 0x00FFFFFF; - acpi_dbg_layer = ACPI_UINT32_MAX; - - if (acpi_gbl_trace_dbg_level) { - acpi_dbg_level = acpi_gbl_trace_dbg_level; - } - if (acpi_gbl_trace_dbg_layer) { - acpi_dbg_layer = acpi_gbl_trace_dbg_layer; - } - -exit: - (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ps_stop_trace - * - * PARAMETERS: info - Method info struct - * - * RETURN: None - * - * DESCRIPTION: Stop control method execution trace - * - ******************************************************************************/ - -static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) -{ - acpi_status status; - - ACPI_FUNCTION_ENTRY(); - - status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE(status)) { - return; - } - - if ((!acpi_gbl_trace_method_name) || - (acpi_gbl_trace_method_name != info->node->name.integer)) { - goto exit; - } - - /* Disable further tracing if type is one-shot */ - - if (acpi_gbl_trace_flags & 1) { - acpi_gbl_trace_method_name = 0; - acpi_gbl_trace_dbg_level = 0; - acpi_gbl_trace_dbg_layer = 0; - } - - acpi_dbg_level = acpi_gbl_original_dbg_level; - acpi_dbg_layer = acpi_gbl_original_dbg_layer; - -exit: - (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return (status); } /******************************************************************************* @@ -212,7 +115,7 @@ exit: * ******************************************************************************/ -acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) +acpi_status acpi_ps_execute_method(struct acpi_evaluate_info * info) { acpi_status status; union acpi_parse_object *op; @@ -243,10 +146,6 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) */ acpi_ps_update_parameter_list(info, REF_INCREMENT); - /* Begin tracing if requested */ - - acpi_ps_start_trace(info); - /* * Execute the method. Performs parse simultaneously */ @@ -326,10 +225,6 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) cleanup: acpi_ps_delete_parse_tree(op); - /* End optional tracing */ - - acpi_ps_stop_trace(info); - /* Take away the extra reference that we gave the parameters above */ acpi_ps_update_parameter_list(info, REF_DECREMENT); diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index e402e07b4846..7f897c63aa5b 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -204,8 +204,6 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_acpi_hardware_present = TRUE; acpi_gbl_last_owner_id_index = 0; acpi_gbl_next_owner_id_offset = 0; - acpi_gbl_trace_dbg_level = 0; - acpi_gbl_trace_dbg_layer = 0; acpi_gbl_debugger_configuration = DEBUGGER_THREADING; acpi_gbl_osi_mutex = NULL; acpi_gbl_reg_methods_executed = FALSE; diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index 8f89df9c7295..37f46d49a74a 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h @@ -184,6 +184,19 @@ #define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT | ACPI_LV_REPAIR) #define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) +/* + * Global trace flags + */ +#define ACPI_TRACE_ENABLED ((u32) 2) +#define ACPI_TRACE_ONESHOT ((u32) 1) + +/* Defaults for trace debugging level/layer */ + +#define ACPI_TRACE_LEVEL_ALL ACPI_LV_ALL +#define ACPI_TRACE_LAYER_ALL 0x000001FF +#define ACPI_TRACE_LEVEL_DEFAULT ACPI_LV_TRACE_POINT +#define ACPI_TRACE_LAYER_DEFAULT ACPI_EXECUTER + #if defined (ACPI_DEBUG_OUTPUT) || !defined (ACPI_NO_ERROR_MESSAGES) /* * The module name is used primarily for error and debug messages. diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index e8ec18a4a634..9c362cf14264 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -251,7 +251,9 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_reduced_hardware, FALSE); * traced each time it is executed. */ ACPI_INIT_GLOBAL(u32, acpi_gbl_trace_flags, 0); -ACPI_INIT_GLOBAL(acpi_name, acpi_gbl_trace_method_name, 0); +ACPI_INIT_GLOBAL(const char *, acpi_gbl_trace_method_name, NULL); +ACPI_INIT_GLOBAL(u32, acpi_gbl_trace_dbg_level, ACPI_TRACE_LEVEL_DEFAULT); +ACPI_INIT_GLOBAL(u32, acpi_gbl_trace_dbg_layer, ACPI_TRACE_LAYER_DEFAULT); /* * Runtime configuration of debug output control masks. We want the debug @@ -504,7 +506,7 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_object_handler handler, void **data)) ACPI_EXTERNAL_RETURN_STATUS(acpi_status - acpi_debug_trace(char *name, u32 debug_level, + acpi_debug_trace(const char *name, u32 debug_level, u32 debug_layer, u32 flags)) /* -- cgit v1.2.3 From bab0482418885627babfd1a6ca4e57a809712474 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:53:07 +0800 Subject: ACPICA: Executer: Add OSL trace hook support ACPICA commit e8e4a9b19d0b72a7b165398bdc961fc2f6f502ec This patch adds OSL trace hook support. OSPMs are encouraged to use acpi_os_trace_point() with ACPI_USE_SYSTEM_TRACER defined to implement platform specific trace facility. Lv Zheng. Link: https://github.com/acpica/acpica/commit/e8e4a9b1 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acinterp.h | 4 ++ drivers/acpi/acpica/exdebug.c | 125 +++++++++++++++++++++++++++++------------ drivers/acpi/acpica/utdebug.c | 31 +++++++++- include/acpi/acoutput.h | 3 + include/acpi/acpiosxf.h | 6 ++ include/acpi/acpixf.h | 5 ++ include/acpi/actypes.h | 8 +++ 7 files changed, 144 insertions(+), 38 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index a3c6e2ab93bb..e820ed8f173f 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -149,6 +149,10 @@ void acpi_ex_stop_trace_opcode(union acpi_parse_object *op, struct acpi_walk_state *walk_state); +void +acpi_ex_trace_point(acpi_trace_event_type type, + u8 begin, u8 *aml, char *pathname); + /* * exfield - ACPI AML (p-code) execution - field manipulation */ diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index 00ba9fc85f47..708b2aed0145 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c @@ -52,6 +52,12 @@ ACPI_MODULE_NAME("exdebug") static union acpi_operand_object *acpi_gbl_trace_method_object = NULL; +/* Local prototypes */ + +#ifdef ACPI_DEBUG_OUTPUT +static const char *acpi_ex_get_trace_event_name(acpi_trace_event_type type); +#endif + #ifndef ACPI_NO_ERROR_MESSAGES /******************************************************************************* * @@ -363,6 +369,78 @@ static u8 acpi_ex_interpreter_trace_enabled(char *name) return (TRUE); } +/******************************************************************************* + * + * FUNCTION: acpi_ex_get_trace_event_name + * + * PARAMETERS: type - Trace event type + * + * RETURN: Trace event name. + * + * DESCRIPTION: Used to obtain the full trace event name. + * + ******************************************************************************/ + +#ifdef ACPI_DEBUG_OUTPUT + +static const char *acpi_ex_get_trace_event_name(acpi_trace_event_type type) +{ + switch (type) { + case ACPI_TRACE_AML_METHOD: + + return "Method"; + + case ACPI_TRACE_AML_OPCODE: + + return "Opcode"; + + case ACPI_TRACE_AML_REGION: + + return "Region"; + + default: + + return ""; + } +} + +#endif + +/******************************************************************************* + * + * FUNCTION: acpi_ex_trace_point + * + * PARAMETERS: type - Trace event type + * begin - TRUE if before execution + * aml - Executed AML address + * pathname - Object path + * + * RETURN: None + * + * DESCRIPTION: Internal interpreter execution trace. + * + ******************************************************************************/ + +void +acpi_ex_trace_point(acpi_trace_event_type type, + u8 begin, u8 *aml, char *pathname) +{ + + ACPI_FUNCTION_NAME(ex_trace_point); + + if (pathname) { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "%s %s [0x%p:%s] execution.\n", + acpi_ex_get_trace_event_name(type), + begin ? "Begin" : "End", aml, pathname)); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, + "%s %s [0x%p] execution.\n", + acpi_ex_get_trace_event_name(type), + begin ? "Begin" : "End", aml)); + } +} + /******************************************************************************* * * FUNCTION: acpi_ex_start_trace_method @@ -417,16 +495,9 @@ acpi_ex_start_trace_method(struct acpi_namespace_node *method_node, exit: if (enabled) { - if (pathname) { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "Begin method [0x%p:%s] execution.\n", - obj_desc->method.aml_start, - pathname)); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "Begin method [0x%p] execution.\n", - obj_desc->method.aml_start)); - } + ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, TRUE, + obj_desc ? obj_desc->method.aml_start : NULL, + pathname); } if (pathname) { ACPI_FREE(pathname); @@ -473,16 +544,9 @@ acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node, (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (enabled) { - if (pathname) { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "End method [0x%p:%s] execution.\n", - obj_desc->method.aml_start, - pathname)); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "End method [0x%p] execution.\n", - obj_desc->method.aml_start)); - } + ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, FALSE, + obj_desc ? obj_desc->method.aml_start : NULL, + pathname); } status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); @@ -535,20 +599,8 @@ acpi_ex_start_trace_opcode(union acpi_parse_object *op, ACPI_FUNCTION_NAME(ex_start_trace_opcode); if (acpi_ex_interpreter_trace_enabled(NULL)) { - if (walk_state->op_info) { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "Begin opcode: %s[0x%p] Class=0x%02x, Type=0x%02x, Flags=0x%04x.\n", - op->common.aml_op_name, - op->common.aml, - walk_state->op_info->class, - walk_state->op_info->type, - walk_state->op_info->flags)); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "Begin opcode: %s[0x%p].\n", - op->common.aml_op_name, - op->common.aml)); - } + ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, TRUE, + op->common.aml, op->common.aml_op_name); } } @@ -574,8 +626,7 @@ acpi_ex_stop_trace_opcode(union acpi_parse_object *op, ACPI_FUNCTION_NAME(ex_stop_trace_opcode); if (acpi_ex_interpreter_trace_enabled(NULL)) { - ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, - "End opcode: %s[0x%p].\n", - op->common.aml_op_name, op->common.aml)); + ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, FALSE, + op->common.aml, op->common.aml_op_name); } } diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index cd02693841db..4146229103c8 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -45,6 +45,7 @@ #include #include "accommon.h" +#include "acinterp.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utdebug") @@ -560,8 +561,37 @@ acpi_ut_ptr_exit(u32 line_number, } } +/******************************************************************************* + * + * FUNCTION: acpi_trace_point + * + * PARAMETERS: type - Trace event type + * begin - TRUE if before execution + * aml - Executed AML address + * pathname - Object path + * pointer - Pointer to the related object + * + * RETURN: None + * + * DESCRIPTION: Interpreter execution trace. + * + ******************************************************************************/ + +void +acpi_trace_point(acpi_trace_event_type type, u8 begin, u8 *aml, char *pathname) +{ + + ACPI_FUNCTION_ENTRY(); + + acpi_ex_trace_point(type, begin, aml, pathname); + +#ifdef ACPI_USE_SYSTEM_TRACER + acpi_os_trace_point(type, begin, aml, pathname); #endif +} +ACPI_EXPORT_SYMBOL(acpi_trace_point) +#endif #ifdef ACPI_APPLICATION /******************************************************************************* * @@ -575,7 +605,6 @@ acpi_ut_ptr_exit(u32 line_number, * DESCRIPTION: Print error message to the console, used by applications. * ******************************************************************************/ - void ACPI_INTERNAL_VAR_XFACE acpi_log_error(const char *format, ...) { va_list args; diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index 37f46d49a74a..c3f0ac135f68 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h @@ -447,6 +447,8 @@ #define ACPI_DUMP_PATHNAME(a, b, c, d) acpi_ns_dump_pathname(a, b, c, d) #define ACPI_DUMP_BUFFER(a, b) acpi_ut_debug_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT) +#define ACPI_TRACE_POINT(a, b, c, d) acpi_trace_point (a, b, c, d) + #else /* ACPI_DEBUG_OUTPUT */ /* * This is the non-debug case -- make everything go away, @@ -468,6 +470,7 @@ #define ACPI_DUMP_PATHNAME(a, b, c, d) #define ACPI_DUMP_BUFFER(a, b) #define ACPI_IS_DEBUG_ENABLED(level, component) 0 +#define ACPI_TRACE_POINT(a, b, c, d) /* Return macros must have a return statement at the minimum */ diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index d02df0a49d98..a54ad1cc990c 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -430,4 +430,10 @@ long acpi_os_get_file_offset(ACPI_FILE file); acpi_status acpi_os_set_file_offset(ACPI_FILE file, long offset, u8 from); #endif +#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_trace_point +void +acpi_os_trace_point(acpi_trace_event_type type, + u8 begin, u8 *aml, char *pathname); +#endif + #endif /* __ACPIOSXF_H__ */ diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 9c362cf14264..9aa27a3e3716 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -909,6 +909,11 @@ ACPI_DBG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(6) const char *module_name, u32 component_id, const char *format, ...)) + +ACPI_DBG_DEPENDENT_RETURN_VOID(void + acpi_trace_point(acpi_trace_event_type type, + u8 begin, + u8 *aml, char *pathname)) ACPI_APP_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(1) void ACPI_INTERNAL_VAR_XFACE acpi_log_error(const char *format, ...)) diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 0f3913f9a377..531eca49edd4 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -1247,6 +1247,14 @@ struct acpi_memory_list { #endif }; +/* Definitions of trace event types */ + +typedef enum { + ACPI_TRACE_AML_METHOD, + ACPI_TRACE_AML_OPCODE, + ACPI_TRACE_AML_REGION +} acpi_trace_event_type; + /* Definitions of _OSI support */ #define ACPI_VENDOR_STRINGS 0x01 -- cgit v1.2.3 From fb18e8fd08862f5509f3c79e168b24512c7065aa Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:53:15 +0800 Subject: ACPICA: Executer: Add option to bypass opcode tracing ACPICA commit 61e9e20aadfaa03184d0959fbdc1fa5cdfea2551 This patch adds option to bypass opcode tracing. The option can be used to reduce the trace message output. Lv Zheng. Link: https://github.com/acpica/acpica/commit/61e9e20a Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exdebug.c | 6 ++++-- include/acpi/acoutput.h | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index 708b2aed0145..de92458236f5 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c @@ -598,7 +598,8 @@ acpi_ex_start_trace_opcode(union acpi_parse_object *op, ACPI_FUNCTION_NAME(ex_start_trace_opcode); - if (acpi_ex_interpreter_trace_enabled(NULL)) { + if (acpi_ex_interpreter_trace_enabled(NULL) && + (acpi_gbl_trace_flags & ACPI_TRACE_OPCODE)) { ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, TRUE, op->common.aml, op->common.aml_op_name); } @@ -625,7 +626,8 @@ acpi_ex_stop_trace_opcode(union acpi_parse_object *op, ACPI_FUNCTION_NAME(ex_stop_trace_opcode); - if (acpi_ex_interpreter_trace_enabled(NULL)) { + if (acpi_ex_interpreter_trace_enabled(NULL) && + (acpi_gbl_trace_flags & ACPI_TRACE_OPCODE)) { ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, FALSE, op->common.aml, op->common.aml_op_name); } diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index c3f0ac135f68..908d4f9c348c 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h @@ -187,8 +187,9 @@ /* * Global trace flags */ -#define ACPI_TRACE_ENABLED ((u32) 2) -#define ACPI_TRACE_ONESHOT ((u32) 1) +#define ACPI_TRACE_ENABLED ((u32) 4) +#define ACPI_TRACE_ONESHOT ((u32) 2) +#define ACPI_TRACE_OPCODE ((u32) 1) /* Defaults for trace debugging level/layer */ -- cgit v1.2.3 From ec4252a66b1a2cd2fc6fbdbf3d3279640500fb75 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:53:22 +0800 Subject: ACPICA: Parser: Remove redundant opcode execution debugging output ACPICA commit c832b0a9263c560b3ae3ae31d7298ef33988f8d5 This patch removes one redundant debugging output of opcode execution which has already been covered by acpi_ex_start_trace_opcode(). Lv Zheng. Link: https://github.com/acpica/acpica/commit/c832b0a9 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/psloop.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index a7de52ee1538..6b11fd7a93dc 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -491,14 +491,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) continue; } - if (walk_state->op_info) { - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "Opcode %4.4X [%s] Op %p Aml %p\n", - (u32)op->common.aml_opcode, - walk_state->op_info->name, op, - op->common.aml)); - } - acpi_ex_start_trace_opcode(op, walk_state); } -- cgit v1.2.3 From dc67d0fa8612ad49a8ec36040c5d22a9091bdbf6 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 23 Jul 2015 12:53:28 +0800 Subject: ACPICA: Remove extraneous check for null walk_state ACPICA commit f9fd6e8bad0f16ce2b436c5cda36ced0c2d85302 Reported by Markus Elfring. Link: https://github.com/acpica/acpica/commit/f9fd6e8b Signed-off-by: Markus Elfring Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/dsmethod.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index ea2bdde1227e..cb53c44c9644 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -582,9 +582,7 @@ cleanup: /* On error, we must terminate the method properly */ acpi_ds_terminate_control_method(obj_desc, next_walk_state); - if (next_walk_state) { - acpi_ds_delete_walk_state(next_walk_state); - } + acpi_ds_delete_walk_state(next_walk_state); return_ACPI_STATUS(status); } -- cgit v1.2.3 From 53d9edce56de3eb495a3eef77e973e3ea014d999 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 23 Jul 2015 12:53:35 +0800 Subject: ACPICA: iASL: Add new warnings for method local_x and arg_x variables ACPICA commit eb9f8cb9fd65f1149dd335d05944c31cbca41af3 1) Warn if a Local is set but never used 2) Warn if a arg_x is never used (for non-predefined method names) 3) Warn if a arg_x that is used as a local is never used This patch only affects iASL which is not in the kernel source tree. Link: https://github.com/acpica/acpica/commit/eb9f8cb9 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/aclocal.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 610d001fbb31..4758185b2b0b 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -174,8 +174,12 @@ struct acpi_namespace_node { */ #ifdef ACPI_LARGE_NAMESPACE_NODE union acpi_parse_object *op; + void *method_locals; + void *method_args; u32 value; u32 length; + u8 arg_count; + #endif }; -- cgit v1.2.3 From 276291962ebf43abebb491ddcd922009de9fde4b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 23 Jul 2015 12:53:49 +0800 Subject: ACPICA: Cleanup use of all non-ANSI local C library functions ACPICA commit 7c490c28a18b435c543c6b410e7e7c2131fccc78 ACPICA implements all non-ANSI functions locally. However, there are sometimes two or more versions of the same function throughout the ACPICA code. This change fixes this. Adds a new file, utilities/utnonansi.c Link: https://github.com/acpica/acpica/commit/7c490c28 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/Makefile | 1 + drivers/acpi/acpica/acmacros.h | 4 + drivers/acpi/acpica/acutils.h | 23 ++- drivers/acpi/acpica/utnonansi.c | 380 ++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/utstring.c | 342 ------------------------------------ 5 files changed, 396 insertions(+), 354 deletions(-) create mode 100644 drivers/acpi/acpica/utnonansi.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 9f30ed7b1a07..fedcc16b56cc 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -165,6 +165,7 @@ acpi-y += \ utmath.o \ utmisc.o \ utmutex.o \ + utnonansi.o \ utobject.o \ utosi.o \ utownerid.o \ diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index c240bdf824f2..19d40c6c1f32 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -220,6 +220,10 @@ #define ACPI_MUL_32(a) _ACPI_MUL(a, 5) #define ACPI_MOD_32(a) _ACPI_MOD(a, 32) +/* Test for ASCII character */ + +#define ACPI_IS_ASCII(c) ((c) < 0x80) + /* * Rounding macros (Power of two boundaries only) */ diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 6de0d3573037..566ff4df02fd 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -166,6 +166,17 @@ struct acpi_pkg_info { #define DB_DWORD_DISPLAY 4 #define DB_QWORD_DISPLAY 8 +/* + * utnonansi - Non-ANSI C library functions + */ +void acpi_ut_strupr(char *src_string); + +void acpi_ut_strlwr(char *src_string); + +int acpi_ut_stricmp(char *string1, char *string2); + +acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer); + /* * utglobal - Global data structures and procedures */ @@ -205,8 +216,6 @@ acpi_status acpi_ut_hardware_initialize(void); void acpi_ut_subsystem_shutdown(void); -#define ACPI_IS_ASCII(c) ((c) < 0x80) - /* * utcopy - Object construction and conversion interfaces */ @@ -567,16 +576,6 @@ acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag); /* * utstring - String and character utilities */ -void acpi_ut_strupr(char *src_string); - -#ifdef ACPI_ASL_COMPILER -void acpi_ut_strlwr(char *src_string); - -int acpi_ut_stricmp(char *string1, char *string2); -#endif - -acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer); - void acpi_ut_print_string(char *string, u16 max_length); #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP diff --git a/drivers/acpi/acpica/utnonansi.c b/drivers/acpi/acpica/utnonansi.c new file mode 100644 index 000000000000..1d5f6b17b766 --- /dev/null +++ b/drivers/acpi/acpica/utnonansi.c @@ -0,0 +1,380 @@ +/******************************************************************************* + * + * Module Name: utnonansi - Non-ansi C library functions + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2015, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("utnonansi") + +/* + * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit + * version of strtoul. + */ +/******************************************************************************* + * + * FUNCTION: acpi_ut_strlwr (strlwr) + * + * PARAMETERS: src_string - The source string to convert + * + * RETURN: None + * + * DESCRIPTION: Convert a string to lowercase + * + ******************************************************************************/ +void acpi_ut_strlwr(char *src_string) +{ + char *string; + + ACPI_FUNCTION_ENTRY(); + + if (!src_string) { + return; + } + + /* Walk entire string, lowercasing the letters */ + + for (string = src_string; *string; string++) { + *string = (char)tolower((int)*string); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strupr (strupr) + * + * PARAMETERS: src_string - The source string to convert + * + * RETURN: None + * + * DESCRIPTION: Convert a string to uppercase + * + ******************************************************************************/ + +void acpi_ut_strupr(char *src_string) +{ + char *string; + + ACPI_FUNCTION_ENTRY(); + + if (!src_string) { + return; + } + + /* Walk entire string, uppercasing the letters */ + + for (string = src_string; *string; string++) { + *string = (char)toupper((int)*string); + } +} + +/****************************************************************************** + * + * FUNCTION: acpi_ut_stricmp (stricmp) + * + * PARAMETERS: string1 - first string to compare + * string2 - second string to compare + * + * RETURN: int that signifies string relationship. Zero means strings + * are equal. + * + * DESCRIPTION: Case-insensitive string compare. Implementation of the + * non-ANSI stricmp function. + * + ******************************************************************************/ + +int acpi_ut_stricmp(char *string1, char *string2) +{ + int c1; + int c2; + + do { + c1 = tolower((int)*string1); + c2 = tolower((int)*string2); + + string1++; + string2++; + } + while ((c1 == c2) && (c1)); + + return (c1 - c2); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strtoul64 + * + * PARAMETERS: string - Null terminated string + * base - Radix of the string: 16 or ACPI_ANY_BASE; + * ACPI_ANY_BASE means 'in behalf of to_integer' + * ret_integer - Where the converted integer is returned + * + * RETURN: Status and Converted value + * + * DESCRIPTION: Convert a string into an unsigned value. Performs either a + * 32-bit or 64-bit conversion, depending on the current mode + * of the interpreter. + * + * NOTE: Does not support Octal strings, not needed. + * + ******************************************************************************/ + +acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer) +{ + u32 this_digit = 0; + u64 return_value = 0; + u64 quotient; + u64 dividend; + u32 to_integer_op = (base == ACPI_ANY_BASE); + u32 mode32 = (acpi_gbl_integer_byte_width == 4); + u8 valid_digits = 0; + u8 sign_of0x = 0; + u8 term = 0; + + ACPI_FUNCTION_TRACE_STR(ut_stroul64, string); + + switch (base) { + case ACPI_ANY_BASE: + case 16: + + break; + + default: + + /* Invalid Base */ + + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + if (!string) { + goto error_exit; + } + + /* Skip over any white space in the buffer */ + + while ((*string) && (isspace((int)*string) || *string == '\t')) { + string++; + } + + if (to_integer_op) { + /* + * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. + * We need to determine if it is decimal or hexadecimal. + */ + if ((*string == '0') && (tolower((int)*(string + 1)) == 'x')) { + sign_of0x = 1; + base = 16; + + /* Skip over the leading '0x' */ + string += 2; + } else { + base = 10; + } + } + + /* Any string left? Check that '0x' is not followed by white space. */ + + if (!(*string) || isspace((int)*string) || *string == '\t') { + if (to_integer_op) { + goto error_exit; + } else { + goto all_done; + } + } + + /* + * Perform a 32-bit or 64-bit conversion, depending upon the current + * execution mode of the interpreter + */ + dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; + + /* Main loop: convert the string to a 32- or 64-bit integer */ + + while (*string) { + if (isdigit((int)*string)) { + + /* Convert ASCII 0-9 to Decimal value */ + + this_digit = ((u8)*string) - '0'; + } else if (base == 10) { + + /* Digit is out of range; possible in to_integer case only */ + + term = 1; + } else { + this_digit = (u8)toupper((int)*string); + if (isxdigit((int)this_digit)) { + + /* Convert ASCII Hex char to value */ + + this_digit = this_digit - 'A' + 10; + } else { + term = 1; + } + } + + if (term) { + if (to_integer_op) { + goto error_exit; + } else { + break; + } + } else if ((valid_digits == 0) && (this_digit == 0) + && !sign_of0x) { + + /* Skip zeros */ + string++; + continue; + } + + valid_digits++; + + if (sign_of0x + && ((valid_digits > 16) + || ((valid_digits > 8) && mode32))) { + /* + * This is to_integer operation case. + * No any restrictions for string-to-integer conversion, + * see ACPI spec. + */ + goto error_exit; + } + + /* Divide the digit into the correct position */ + + (void)acpi_ut_short_divide((dividend - (u64)this_digit), + base, "ient, NULL); + + if (return_value > quotient) { + if (to_integer_op) { + goto error_exit; + } else { + break; + } + } + + return_value *= base; + return_value += this_digit; + string++; + } + + /* All done, normal exit */ + +all_done: + + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", + ACPI_FORMAT_UINT64(return_value))); + + *ret_integer = return_value; + return_ACPI_STATUS(AE_OK); + +error_exit: + /* Base was set/validated above */ + + if (base == 10) { + return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT); + } else { + return_ACPI_STATUS(AE_BAD_HEX_CONSTANT); + } +} + +#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) +/******************************************************************************* + * + * FUNCTION: acpi_ut_safe_strcpy, acpi_ut_safe_strcat, acpi_ut_safe_strncat + * + * PARAMETERS: Adds a "DestSize" parameter to each of the standard string + * functions. This is the size of the Destination buffer. + * + * RETURN: TRUE if the operation would overflow the destination buffer. + * + * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that + * the result of the operation will not overflow the output string + * buffer. + * + * NOTE: These functions are typically only helpful for processing + * user input and command lines. For most ACPICA code, the + * required buffer length is precisely calculated before buffer + * allocation, so the use of these functions is unnecessary. + * + ******************************************************************************/ + +u8 acpi_ut_safe_strcpy(char *dest, acpi_size dest_size, char *source) +{ + + if (strlen(source) >= dest_size) { + return (TRUE); + } + + strcpy(dest, source); + return (FALSE); +} + +u8 acpi_ut_safe_strcat(char *dest, acpi_size dest_size, char *source) +{ + + if ((strlen(dest) + strlen(source)) >= dest_size) { + return (TRUE); + } + + strcat(dest, source); + return (FALSE); +} + +u8 +acpi_ut_safe_strncat(char *dest, + acpi_size dest_size, + char *source, acpi_size max_transfer_length) +{ + acpi_size actual_transfer_length; + + actual_transfer_length = ACPI_MIN(max_transfer_length, strlen(source)); + + if ((strlen(dest) + actual_transfer_length) >= dest_size) { + return (TRUE); + } + + strncat(dest, source, max_transfer_length); + return (FALSE); +} +#endif diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index 8f3c883dfe0e..4ddd105d9741 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c @@ -48,286 +48,6 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utstring") -/* - * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit - * version of strtoul. - */ -#ifdef ACPI_ASL_COMPILER -/******************************************************************************* - * - * FUNCTION: acpi_ut_strlwr (strlwr) - * - * PARAMETERS: src_string - The source string to convert - * - * RETURN: None - * - * DESCRIPTION: Convert string to lowercase - * - * NOTE: This is not a POSIX function, so it appears here, not in utclib.c - * - ******************************************************************************/ -void acpi_ut_strlwr(char *src_string) -{ - char *string; - - ACPI_FUNCTION_ENTRY(); - - if (!src_string) { - return; - } - - /* Walk entire string, lowercasing the letters */ - - for (string = src_string; *string; string++) { - *string = (char)tolower((int)*string); - } - - return; -} - -/****************************************************************************** - * - * FUNCTION: acpi_ut_stricmp (stricmp) - * - * PARAMETERS: string1 - first string to compare - * string2 - second string to compare - * - * RETURN: int that signifies string relationship. Zero means strings - * are equal. - * - * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare - * strings with no case sensitivity) - * - ******************************************************************************/ - -int acpi_ut_stricmp(char *string1, char *string2) -{ - int c1; - int c2; - - do { - c1 = tolower((int)*string1); - c2 = tolower((int)*string2); - - string1++; - string2++; - } - while ((c1 == c2) && (c1)); - - return (c1 - c2); -} -#endif - -/******************************************************************************* - * - * FUNCTION: acpi_ut_strupr (strupr) - * - * PARAMETERS: src_string - The source string to convert - * - * RETURN: None - * - * DESCRIPTION: Convert string to uppercase - * - * NOTE: This is not a POSIX function, so it appears here, not in utclib.c - * - ******************************************************************************/ - -void acpi_ut_strupr(char *src_string) -{ - char *string; - - ACPI_FUNCTION_ENTRY(); - - if (!src_string) { - return; - } - - /* Walk entire string, uppercasing the letters */ - - for (string = src_string; *string; string++) { - *string = (char)toupper((int)*string); - } - - return; -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_strtoul64 - * - * PARAMETERS: string - Null terminated string - * base - Radix of the string: 16 or ACPI_ANY_BASE; - * ACPI_ANY_BASE means 'in behalf of to_integer' - * ret_integer - Where the converted integer is returned - * - * RETURN: Status and Converted value - * - * DESCRIPTION: Convert a string into an unsigned value. Performs either a - * 32-bit or 64-bit conversion, depending on the current mode - * of the interpreter. - * NOTE: Does not support Octal strings, not needed. - * - ******************************************************************************/ - -acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer) -{ - u32 this_digit = 0; - u64 return_value = 0; - u64 quotient; - u64 dividend; - u32 to_integer_op = (base == ACPI_ANY_BASE); - u32 mode32 = (acpi_gbl_integer_byte_width == 4); - u8 valid_digits = 0; - u8 sign_of0x = 0; - u8 term = 0; - - ACPI_FUNCTION_TRACE_STR(ut_stroul64, string); - - switch (base) { - case ACPI_ANY_BASE: - case 16: - - break; - - default: - - /* Invalid Base */ - - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (!string) { - goto error_exit; - } - - /* Skip over any white space in the buffer */ - - while ((*string) && (isspace((int)*string) || *string == '\t')) { - string++; - } - - if (to_integer_op) { - /* - * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. - * We need to determine if it is decimal or hexadecimal. - */ - if ((*string == '0') && (tolower((int)*(string + 1)) == 'x')) { - sign_of0x = 1; - base = 16; - - /* Skip over the leading '0x' */ - string += 2; - } else { - base = 10; - } - } - - /* Any string left? Check that '0x' is not followed by white space. */ - - if (!(*string) || isspace((int)*string) || *string == '\t') { - if (to_integer_op) { - goto error_exit; - } else { - goto all_done; - } - } - - /* - * Perform a 32-bit or 64-bit conversion, depending upon the current - * execution mode of the interpreter - */ - dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; - - /* Main loop: convert the string to a 32- or 64-bit integer */ - - while (*string) { - if (isdigit((int)*string)) { - - /* Convert ASCII 0-9 to Decimal value */ - - this_digit = ((u8)*string) - '0'; - } else if (base == 10) { - - /* Digit is out of range; possible in to_integer case only */ - - term = 1; - } else { - this_digit = (u8)toupper((int)*string); - if (isxdigit((int)this_digit)) { - - /* Convert ASCII Hex char to value */ - - this_digit = this_digit - 'A' + 10; - } else { - term = 1; - } - } - - if (term) { - if (to_integer_op) { - goto error_exit; - } else { - break; - } - } else if ((valid_digits == 0) && (this_digit == 0) - && !sign_of0x) { - - /* Skip zeros */ - string++; - continue; - } - - valid_digits++; - - if (sign_of0x - && ((valid_digits > 16) - || ((valid_digits > 8) && mode32))) { - /* - * This is to_integer operation case. - * No any restrictions for string-to-integer conversion, - * see ACPI spec. - */ - goto error_exit; - } - - /* Divide the digit into the correct position */ - - (void)acpi_ut_short_divide((dividend - (u64)this_digit), - base, "ient, NULL); - - if (return_value > quotient) { - if (to_integer_op) { - goto error_exit; - } else { - break; - } - } - - return_value *= base; - return_value += this_digit; - string++; - } - - /* All done, normal exit */ - -all_done: - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64(return_value))); - - *ret_integer = return_value; - return_ACPI_STATUS(AE_OK); - -error_exit: - /* Base was set/validated above */ - - if (base == 10) { - return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT); - } else { - return_ACPI_STATUS(AE_BAD_HEX_CONSTANT); - } -} - /******************************************************************************* * * FUNCTION: acpi_ut_print_string @@ -342,7 +62,6 @@ error_exit: * sequences. * ******************************************************************************/ - void acpi_ut_print_string(char *string, u16 max_length) { u32 i; @@ -584,64 +303,3 @@ void ut_convert_backslashes(char *pathname) } } #endif - -#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) -/******************************************************************************* - * - * FUNCTION: acpi_ut_safe_strcpy, acpi_ut_safe_strcat, acpi_ut_safe_strncat - * - * PARAMETERS: Adds a "DestSize" parameter to each of the standard string - * functions. This is the size of the Destination buffer. - * - * RETURN: TRUE if the operation would overflow the destination buffer. - * - * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that - * the result of the operation will not overflow the output string - * buffer. - * - * NOTE: These functions are typically only helpful for processing - * user input and command lines. For most ACPICA code, the - * required buffer length is precisely calculated before buffer - * allocation, so the use of these functions is unnecessary. - * - ******************************************************************************/ - -u8 acpi_ut_safe_strcpy(char *dest, acpi_size dest_size, char *source) -{ - - if (strlen(source) >= dest_size) { - return (TRUE); - } - - strcpy(dest, source); - return (FALSE); -} - -u8 acpi_ut_safe_strcat(char *dest, acpi_size dest_size, char *source) -{ - - if ((strlen(dest) + strlen(source)) >= dest_size) { - return (TRUE); - } - - strcat(dest, source); - return (FALSE); -} - -u8 -acpi_ut_safe_strncat(char *dest, - acpi_size dest_size, - char *source, acpi_size max_transfer_length) -{ - acpi_size actual_transfer_length; - - actual_transfer_length = ACPI_MIN(max_transfer_length, strlen(source)); - - if ((strlen(dest) + actual_transfer_length) >= dest_size) { - return (TRUE); - } - - strncat(dest, source, max_transfer_length); - return (FALSE); -} -#endif -- cgit v1.2.3 From 88606a2b9020993a776df894941b3b07cc1374fe Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 23 Jul 2015 12:53:57 +0800 Subject: ACPICA: Cleanup use of NEGATIVE and POSITIVE defines ACPICA commit f88814201e01043a4f8caa69a69b799af11c44a3 These were defined in two places. Changed to ACPI_SIGN* names and define them once in acmacros.h This patch doesn't affect Linux kernel. Link: https://github.com/acpica/acpica/commit/f8881420 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acmacros.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 19d40c6c1f32..e85366ceb15a 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -224,6 +224,11 @@ #define ACPI_IS_ASCII(c) ((c) < 0x80) +/* Signed integers */ + +#define ACPI_SIGN_POSITIVE 0 +#define ACPI_SIGN_NEGATIVE 1 + /* * Rounding macros (Power of two boundaries only) */ -- cgit v1.2.3 From 02ca26bef8f49a654026f56bedde2ab25e761380 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:54:11 +0800 Subject: ACPICA: Debugger: Reduce structure size for debugger ACPICA commit 310e0ae1c4730f4dadc80125125099ab76851499 arg_types in struct acpi_db_method_info is only referenced by ACPI_DEBUGGER. This patch only affects ACPICA debugger which is only used by a non-kernel tool - acpiexec, so Linux kernel is currently not affected by this patch. Link: https://github.com/acpica/acpica/commit/310e0ae1 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/aclocal.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 4758185b2b0b..a6b68878cdbe 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -1107,6 +1107,9 @@ struct acpi_db_method_info { * Index of current thread inside all them created. */ char init_args; +#ifdef ACPI_DEBUGGER + acpi_object_type arg_types[4]; +#endif char *arguments[4]; char num_threads_str[11]; char id_of_thread_str[11]; -- cgit v1.2.3 From fdd8d831cf43761712d28e5d1ad812eab7dc1480 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 23 Jul 2015 12:54:17 +0800 Subject: ACPICA: Debugger: Move debugger specific APIs to debugger component ACPICA commit 2164923d60429eea7cd5a4a8629b607af7325afa Some disassembler APIs should rather be debugger APIs. This patch moves them to the debugger folder to be ready for debugger porting. Since there is no in-kernel ACPICA debugger in the kernel source tree, this patch doesn't affect the Linux kernel. Link: https://github.com/acpica/acpica/commit/2164923d Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acdebug.h | 17 +++++++++++++++++ drivers/acpi/acpica/dsmethod.c | 12 +++++------- 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 88482f75e941..b5a9c5126209 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -263,6 +263,23 @@ acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op); char *acpi_db_get_next_token(char *string, char **next, acpi_object_type * return_type); +/* + * dbobject + */ +void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc); + +void +acpi_db_display_internal_object(union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state); + +void acpi_db_decode_arguments(struct acpi_walk_state *walk_state); + +void acpi_db_decode_locals(struct acpi_walk_state *walk_state); + +void +acpi_db_dump_method_info(acpi_status status, + struct acpi_walk_state *walk_state); + /* * dbstats - Generation and display of ACPI table statistics */ diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index cb53c44c9644..bc32f3194afe 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -46,11 +46,9 @@ #include "acdispat.h" #include "acinterp.h" #include "acnamesp.h" -#ifdef ACPI_DISASSEMBLER -#include "acdisasm.h" -#endif #include "acparser.h" #include "amlcode.h" +#include "acdebug.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsmethod") @@ -205,7 +203,7 @@ acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state, * RETURN: Status * * DESCRIPTION: Called on method error. Invoke the global exception handler if - * present, dump the method data if the disassembler is configured + * present, dump the method data if the debugger is configured * * Note: Allows the exception handler to change the status code * @@ -254,10 +252,10 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state * walk_state) if (ACPI_FAILURE(status)) { acpi_ds_dump_method_stack(status, walk_state, walk_state->op); - /* Display method locals/args if disassembler is present */ + /* Display method locals/args if debugger is present */ -#ifdef ACPI_DISASSEMBLER - acpi_dm_dump_method_info(status, walk_state); +#ifdef ACPI_DEBUGGER + acpi_db_dump_method_info(status, walk_state); #endif } -- cgit v1.2.3 From 6d9be0a5c459ac30a5b3e7fbe51c55f65a5f4c7c Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 23 Jul 2015 12:54:23 +0800 Subject: ACPICA: iASL/Disassembler: Add prototype verbose mode ACPICA commit add72dca18ab5d02f1bf9b08027570e58da520e8 This mode will emit AML byte code after each ASL statement. This is a prototype only and requires additional development. This patch only affects ACPICA disassembler which is not in the kernel source tree. Link: https://github.com/acpica/acpica/commit/add72dca Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 5342300719ee..79eb35d080a0 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -307,6 +307,7 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_no_resource_disassembly, FALSE); ACPI_INIT_GLOBAL(u8, acpi_gbl_ignore_noop_operator, FALSE); ACPI_INIT_GLOBAL(u8, acpi_gbl_cstyle_disassembly, TRUE); ACPI_INIT_GLOBAL(u8, acpi_gbl_force_aml_disassembly, FALSE); +ACPI_INIT_GLOBAL(union acpi_parse_object *, acpi_gbl_previous_op, NULL); ACPI_GLOBAL(u8, acpi_gbl_db_opt_disasm); ACPI_GLOBAL(u8, acpi_gbl_db_opt_verbose); -- cgit v1.2.3 From 712e960f0ee9337f3473ba3de2bcfc7e87b7c5a4 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 27 Jul 2015 18:03:57 +0300 Subject: ACPI / PM: Attach ACPI power domain only once Some devices, like MFD subdevices, share a single ACPI companion device so that they are able to access their resources and children. However, currently all these subdevices are attached to the ACPI power domain and this might cause that the power methods for the companion device get called more than once. In order to solve this we attach the ACPI power domain only to the first physical device that is bound to the ACPI companion device. In case of MFD devices, this is the parent MFD device itself. Acked-by: Rafael J. Wysocki Signed-off-by: Mika Westerberg Signed-off-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/acpi/device_pm.c | 8 ++++++++ drivers/acpi/internal.h | 2 ++ drivers/acpi/scan.c | 46 ++++++++++++++++++++++++++++++---------------- 3 files changed, 40 insertions(+), 16 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 717afcdb5f4a..08dc3ec7e892 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -1123,6 +1123,14 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) if (dev->pm_domain) return -EEXIST; + /* + * Only attach the power domain to the first device if the + * companion is shared by multiple. This is to prevent doing power + * management twice. + */ + if (!acpi_device_is_first_physical_node(adev, dev)) + return -EBUSY; + acpi_add_pm_notifier(adev, dev, acpi_pm_notify_work_func); dev->pm_domain = &acpi_general_pm_domain; if (power_on) { diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 4683a96932b9..f6aefe984941 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -97,6 +97,8 @@ void acpi_device_add_finalize(struct acpi_device *device); void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); bool acpi_device_is_present(struct acpi_device *adev); bool acpi_device_is_battery(struct acpi_device *adev); +bool acpi_device_is_first_physical_node(struct acpi_device *adev, + const struct device *dev); /* -------------------------------------------------------------------------- Power Resource diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ec256352f423..89ff6d2eef8a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -226,6 +226,35 @@ static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias, return len; } +/** + * acpi_device_is_first_physical_node - Is given dev first physical node + * @adev: ACPI companion device + * @dev: Physical device to check + * + * Function checks if given @dev is the first physical devices attached to + * the ACPI companion device. This distinction is needed in some cases + * where the same companion device is shared between many physical devices. + * + * Note that the caller have to provide valid @adev pointer. + */ +bool acpi_device_is_first_physical_node(struct acpi_device *adev, + const struct device *dev) +{ + bool ret = false; + + mutex_lock(&adev->physical_node_lock); + if (!list_empty(&adev->physical_node_list)) { + const struct acpi_device_physical_node *node; + + node = list_first_entry(&adev->physical_node_list, + struct acpi_device_physical_node, node); + ret = node->dev == dev; + } + mutex_unlock(&adev->physical_node_lock); + + return ret; +} + /* * acpi_companion_match() - Can we match via ACPI companion device * @dev: Device in question @@ -250,7 +279,6 @@ static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias, static struct acpi_device *acpi_companion_match(const struct device *dev) { struct acpi_device *adev; - struct mutex *physical_node_lock; adev = ACPI_COMPANION(dev); if (!adev) @@ -259,21 +287,7 @@ static struct acpi_device *acpi_companion_match(const struct device *dev) if (list_empty(&adev->pnp.ids)) return NULL; - physical_node_lock = &adev->physical_node_lock; - mutex_lock(physical_node_lock); - if (list_empty(&adev->physical_node_list)) { - adev = NULL; - } else { - const struct acpi_device_physical_node *node; - - node = list_first_entry(&adev->physical_node_list, - struct acpi_device_physical_node, node); - if (node->dev != dev) - adev = NULL; - } - mutex_unlock(physical_node_lock); - - return adev; + return acpi_device_is_first_physical_node(adev, dev) ? adev : NULL; } static int __acpi_device_uevent_modalias(struct acpi_device *adev, -- cgit v1.2.3 From e91a398c31cef2d51786642e372c503cd43fba90 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 1 Aug 2015 02:39:43 +0200 Subject: ACPI / bus: Move duplicate code to a separate new function After merging commit 712e960f0ee9 (ACPI / PM: Attach ACPI power domain only once) with commit 1dcc3d3362b0 (ACPI / bus: Move ACPI bus type registration) there is some duplicate code in acpi_device_is_first_physical_node() and acpi_companion_match() that can be moved to a separate routine and called from both places. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Reviewed-by: Hanjun Guo --- drivers/acpi/bus.c | 51 ++++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a23903c8bea9..f39f686ed2df 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -486,6 +486,26 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device) Device Matching -------------------------------------------------------------------------- */ +static struct acpi_device *acpi_primary_dev_companion(struct acpi_device *adev, + const struct device *dev) +{ + struct mutex *physical_node_lock = &adev->physical_node_lock; + + mutex_lock(physical_node_lock); + if (list_empty(&adev->physical_node_list)) { + adev = NULL; + } else { + const struct acpi_device_physical_node *node; + + node = list_first_entry(&adev->physical_node_list, + struct acpi_device_physical_node, node); + if (node->dev != dev) + adev = NULL; + } + mutex_unlock(physical_node_lock); + return adev; +} + /** * acpi_device_is_first_physical_node - Is given dev first physical node * @adev: ACPI companion device @@ -500,19 +520,7 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device) bool acpi_device_is_first_physical_node(struct acpi_device *adev, const struct device *dev) { - bool ret = false; - - mutex_lock(&adev->physical_node_lock); - if (!list_empty(&adev->physical_node_list)) { - const struct acpi_device_physical_node *node; - - node = list_first_entry(&adev->physical_node_list, - struct acpi_device_physical_node, node); - ret = node->dev == dev; - } - mutex_unlock(&adev->physical_node_lock); - - return ret; + return !!acpi_primary_dev_companion(adev, dev); } /* @@ -539,7 +547,6 @@ bool acpi_device_is_first_physical_node(struct acpi_device *adev, struct acpi_device *acpi_companion_match(const struct device *dev) { struct acpi_device *adev; - struct mutex *physical_node_lock; adev = ACPI_COMPANION(dev); if (!adev) @@ -548,21 +555,7 @@ struct acpi_device *acpi_companion_match(const struct device *dev) if (list_empty(&adev->pnp.ids)) return NULL; - physical_node_lock = &adev->physical_node_lock; - mutex_lock(physical_node_lock); - if (list_empty(&adev->physical_node_list)) { - adev = NULL; - } else { - const struct acpi_device_physical_node *node; - - node = list_first_entry(&adev->physical_node_list, - struct acpi_device_physical_node, node); - if (node->dev != dev) - adev = NULL; - } - mutex_unlock(physical_node_lock); - - return adev; + return acpi_primary_dev_companion(adev, dev); } /** -- cgit v1.2.3 From 93d988310bb2f5ed16ba075bbc4281aa06907e72 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 5 Aug 2015 16:23:43 +0800 Subject: ACPI / sysfs: Add ACPI_LV_REPAIR debug level. This patch updates debug_level file, adding ACPI_LV_REPAIR. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sysfs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 0876d77b3206..7ab6ba46866f 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -69,6 +69,7 @@ static const struct acpi_dlevel acpi_debug_levels[] = { ACPI_DEBUG_INIT(ACPI_LV_INIT), ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), ACPI_DEBUG_INIT(ACPI_LV_INFO), + ACPI_DEBUG_INIT(ACPI_LV_REPAIR), ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), ACPI_DEBUG_INIT(ACPI_LV_PARSE), -- cgit v1.2.3 From 7901a052a981691d18f4e8f91fc27e40849b7336 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 5 Aug 2015 16:23:51 +0800 Subject: ACPI / sysfs: Update method tracing facility. This patch updates the method tracing facility as the acpi_debug_trace() API has been updated to allow it to trace AML interpreter execution, the meanings and the usages of the API parameters are changed due to the updates. The new API: 1. Uses ACPI_TRACE_ENABLED flag to indicate the enabling of the tracer; 2. Allows tracer still can be enabled when method name is not specified so that the AML interpreter execution can be traced without knowing the method name, which is useful for kernel boot tracing; 3. Supports arbitrary full path name, it doesn't need to be a name related to an entrance of acpi_evaluate_object(). Note that the sysfs parameters are also updated so that when reading the attribute files, ACPICA internal settings are returned. In order to make the sysfs parameters (acpi.trace_state) available during boot, this patch adds code to bypass ACPICA semaphore/mutex invocations when acpi mutex utilities haven't been initialized. This patch doesn't update documentation of method tracing facility, it will be updated by further patches. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 8 +++ drivers/acpi/sysfs.c | 136 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 108 insertions(+), 36 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 3b8963f21b36..6341cb523dc4 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -83,6 +83,7 @@ static void *acpi_irq_context; static struct workqueue_struct *kacpid_wq; static struct workqueue_struct *kacpi_notify_wq; static struct workqueue_struct *kacpi_hotplug_wq; +static bool acpi_os_initialized; /* * This list of permanent mappings is for memory that may be accessed from @@ -1316,6 +1317,9 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) long jiffies; int ret = 0; + if (!acpi_os_initialized) + return AE_OK; + if (!sem || (units < 1)) return AE_BAD_PARAMETER; @@ -1355,6 +1359,9 @@ acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) { struct semaphore *sem = (struct semaphore *)handle; + if (!acpi_os_initialized) + return AE_OK; + if (!sem || (units < 1)) return AE_BAD_PARAMETER; @@ -1863,6 +1870,7 @@ acpi_status __init acpi_os_initialize(void) rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register); pr_debug(PREFIX "%s: map reset_reg status %d\n", __func__, rv); } + acpi_os_initialized = true; return AE_OK; } diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 7ab6ba46866f..8979e4a8d066 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -70,6 +70,7 @@ static const struct acpi_dlevel acpi_debug_levels[] = { ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), ACPI_DEBUG_INIT(ACPI_LV_INFO), ACPI_DEBUG_INIT(ACPI_LV_REPAIR), + ACPI_DEBUG_INIT(ACPI_LV_TRACE_POINT), ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), ACPI_DEBUG_INIT(ACPI_LV_PARSE), @@ -163,55 +164,118 @@ static const struct kernel_param_ops param_ops_debug_level = { module_param_cb(debug_layer, ¶m_ops_debug_layer, &acpi_dbg_layer, 0644); module_param_cb(debug_level, ¶m_ops_debug_level, &acpi_dbg_level, 0644); -static char trace_method_name[6]; -module_param_string(trace_method_name, trace_method_name, 6, 0644); -static unsigned int trace_debug_layer; -module_param(trace_debug_layer, uint, 0644); -static unsigned int trace_debug_level; -module_param(trace_debug_level, uint, 0644); +static char* trace_method_name; +static bool trace_method_kmalloced; -static int param_set_trace_state(const char *val, struct kernel_param *kp) +int param_set_trace_method_name(const char *val, const struct kernel_param *kp) { - int result = 0; + u32 saved_flags = 0; - if (!strncmp(val, "enable", sizeof("enable") - 1)) { - result = acpi_debug_trace(trace_method_name, trace_debug_level, - trace_debug_layer, 0); - if (result) - result = -EBUSY; - goto exit; + if (strlen(val) > 1024) { + pr_err("%s: string parameter too long\n", kp->name); + return -ENOSPC; } - if (!strncmp(val, "disable", sizeof("disable") - 1)) { - int name = 0; - result = acpi_debug_trace((char *)&name, trace_debug_level, - trace_debug_layer, 0); - if (result) - result = -EBUSY; - goto exit; - } + /* + * It's not safe to update acpi_gbl_trace_method_name without + * having the tracer stopped, so we save the original tracer + * state and disable it. + */ + saved_flags = acpi_gbl_trace_flags; + (void)acpi_debug_trace(NULL, + acpi_gbl_trace_dbg_level, + acpi_gbl_trace_dbg_layer, + 0); + + if (trace_method_kmalloced) + kfree(trace_method_name); + trace_method_name = NULL; + trace_method_kmalloced = false; + + /* This is a hack. We can't kmalloc in early boot. */ + if (slab_is_available()) { + trace_method_name = kstrdup(val, GFP_KERNEL); + if (!trace_method_name) + return -ENOMEM; + trace_method_kmalloced = true; + } else + trace_method_name = (char *)val; - if (!strncmp(val, "1", 1)) { - result = acpi_debug_trace(trace_method_name, trace_debug_level, - trace_debug_layer, 1); - if (result) - result = -EBUSY; - goto exit; - } + /* Restore the original tracer state */ + (void)acpi_debug_trace(trace_method_name, + acpi_gbl_trace_dbg_level, + acpi_gbl_trace_dbg_layer, + saved_flags); - result = -EINVAL; -exit: - return result; + return 0; +} + +static int param_get_trace_method_name(char *buffer, const struct kernel_param *kp) +{ + return scnprintf(buffer, PAGE_SIZE, "%s", acpi_gbl_trace_method_name); +} + +static const struct kernel_param_ops param_ops_trace_method = { + .set = param_set_trace_method_name, + .get = param_get_trace_method_name, +}; + +static const struct kernel_param_ops param_ops_trace_attrib = { + .set = param_set_uint, + .get = param_get_uint, +}; + +module_param_cb(trace_method_name, ¶m_ops_trace_method, &trace_method_name, 0644); +module_param_cb(trace_debug_layer, ¶m_ops_trace_attrib, &acpi_gbl_trace_dbg_layer, 0644); +module_param_cb(trace_debug_level, ¶m_ops_trace_attrib, &acpi_gbl_trace_dbg_level, 0644); + +static int param_set_trace_state(const char *val, struct kernel_param *kp) +{ + acpi_status status; + const char *method = trace_method_name; + u32 flags = 0; + +/* So "xxx-once" comparison should go prior than "xxx" comparison */ +#define acpi_compare_param(val, key) \ + strncmp((val), (key), sizeof(key) - 1) + + if (!acpi_compare_param(val, "enable")) { + method = NULL; + flags = ACPI_TRACE_ENABLED; + } else if (!acpi_compare_param(val, "disable")) + method = NULL; + else if (!acpi_compare_param(val, "method-once")) + flags = ACPI_TRACE_ENABLED | ACPI_TRACE_ONESHOT; + else if (!acpi_compare_param(val, "method")) + flags = ACPI_TRACE_ENABLED; + else if (!acpi_compare_param(val, "opcode-once")) + flags = ACPI_TRACE_ENABLED | ACPI_TRACE_ONESHOT | ACPI_TRACE_OPCODE; + else if (!acpi_compare_param(val, "opcode")) + flags = ACPI_TRACE_ENABLED | ACPI_TRACE_OPCODE; + else + return -EINVAL; + + status = acpi_debug_trace(method, + acpi_gbl_trace_dbg_level, + acpi_gbl_trace_dbg_layer, + flags); + if (ACPI_FAILURE(status)) + return -EBUSY; + + return 0; } static int param_get_trace_state(char *buffer, struct kernel_param *kp) { - if (!acpi_gbl_trace_method_name) + if (!(acpi_gbl_trace_flags & ACPI_TRACE_ENABLED)) return sprintf(buffer, "disable"); else { - if (acpi_gbl_trace_flags & 1) - return sprintf(buffer, "1"); - else + if (acpi_gbl_trace_method_name) { + if (acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) + return sprintf(buffer, "method-once"); + else + return sprintf(buffer, "method"); + } else return sprintf(buffer, "enable"); } return 0; -- cgit v1.2.3 From a0186bcf7c21907c78ab2b4bc50f3fb2b5047806 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 5 Aug 2015 16:23:57 +0800 Subject: ACPI / sysfs: Add support to allow leading "\" missing in trace_method_name. Since _SB.PCI0 can be used as relative path from root and can be easily converted into internal trace_method_name format, we allow users to specify trace_method_name using relative paths from root. Note this is useful for grub2 for which users failed to pass "\" from the grub configuration file. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sysfs.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 8979e4a8d066..40a42655227c 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -164,14 +164,18 @@ static const struct kernel_param_ops param_ops_debug_level = { module_param_cb(debug_layer, ¶m_ops_debug_layer, &acpi_dbg_layer, 0644); module_param_cb(debug_level, ¶m_ops_debug_level, &acpi_dbg_level, 0644); -static char* trace_method_name; -static bool trace_method_kmalloced; +static char trace_method_name[1024]; int param_set_trace_method_name(const char *val, const struct kernel_param *kp) { u32 saved_flags = 0; + bool is_abs_path = true; - if (strlen(val) > 1024) { + if (*val != '\\') + is_abs_path = false; + + if ((is_abs_path && strlen(val) > 1023) || + (!is_abs_path && strlen(val) > 1022)) { pr_err("%s: string parameter too long\n", kp->name); return -ENOSPC; } @@ -187,19 +191,13 @@ int param_set_trace_method_name(const char *val, const struct kernel_param *kp) acpi_gbl_trace_dbg_layer, 0); - if (trace_method_kmalloced) - kfree(trace_method_name); - trace_method_name = NULL; - trace_method_kmalloced = false; - /* This is a hack. We can't kmalloc in early boot. */ - if (slab_is_available()) { - trace_method_name = kstrdup(val, GFP_KERNEL); - if (!trace_method_name) - return -ENOMEM; - trace_method_kmalloced = true; - } else - trace_method_name = (char *)val; + if (is_abs_path) + strcpy(trace_method_name, val); + else { + trace_method_name[0] = '\\'; + strcpy(trace_method_name+1, val); + } /* Restore the original tracer state */ (void)acpi_debug_trace(trace_method_name, -- cgit v1.2.3 From 10742619ac63641bcce0a7c07f0dc7509201ed72 Mon Sep 17 00:00:00 2001 From: Nicolas Iooss Date: Sat, 1 Aug 2015 21:32:17 +0800 Subject: ACPI: fix acpi_debugfs_init prototype acpi_debugfs_init function is declared with return type int in drivers/acpi/internal.h when CONFIG_DEBUG_FS is enabled, but its definition in drivers/acpi/debugfs.c has return type void. This is due to commit aecad432fd68 ("ACPI: Cleanup custom_method debug stuff"), which changed the return type from int to void without updating the declaration. Fix this inconsistency by updating acpi_debugfs_init prototype. While at it, include internal.h in debugfs.c so that the compiler can check that the declaration and definition remain compatible. Signed-off-by: Nicolas Iooss Signed-off-by: Rafael J. Wysocki --- drivers/acpi/debugfs.c | 2 ++ drivers/acpi/internal.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 6b1919f6bd82..68bb305b977f 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c @@ -7,6 +7,8 @@ #include #include +#include "internal.h" + #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("debugfs"); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 8c71cb8335c0..daf0974d863c 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -67,7 +67,7 @@ void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val); #ifdef CONFIG_DEBUG_FS extern struct dentry *acpi_debugfs_dir; -int acpi_debugfs_init(void); +void acpi_debugfs_init(void); #else static inline void acpi_debugfs_init(void) { return; } #endif -- cgit v1.2.3 From 02b771b64b73226052d6e731a0987db3b47281e9 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 12 Aug 2015 11:12:02 +0800 Subject: ACPI / EC: Fix an issue caused by the serialized _Qxx evaluations It is proven that Windows evaluates _Qxx handlers in a parallel way. This patch follows this fact, splits _Qxx evaluations from the NOTIFY queue to form a separate queue, so that _Qxx evaluations can be queued up on different CPUs rather than being queued up on a CPU0 bound queue. Event handling related callbacks are also renamed and sorted in this patch. Link: https://bugzilla.kernel.org/show_bug.cgi?id=94411 Reported-and-tested-by: Gabriele Mazzotta Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 82 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 22 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 9d4761d2f6b7..3e57ee7c890f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -165,8 +165,16 @@ struct transaction { u8 flags; }; +struct acpi_ec_query { + struct transaction transaction; + struct work_struct work; + struct acpi_ec_query_handler *handler; +}; + static int acpi_ec_query(struct acpi_ec *ec, u8 *data); static void advance_transaction(struct acpi_ec *ec); +static void acpi_ec_event_handler(struct work_struct *work); +static void acpi_ec_event_processor(struct work_struct *work); struct acpi_ec *boot_ec, *first_ec; EXPORT_SYMBOL(first_ec); @@ -978,60 +986,90 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) } EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); -static void acpi_ec_run(void *cxt) +static struct acpi_ec_query *acpi_ec_create_query(u8 *pval) { - struct acpi_ec_query_handler *handler = cxt; + struct acpi_ec_query *q; + struct transaction *t; + + q = kzalloc(sizeof (struct acpi_ec_query), GFP_KERNEL); + if (!q) + return NULL; + INIT_WORK(&q->work, acpi_ec_event_processor); + t = &q->transaction; + t->command = ACPI_EC_COMMAND_QUERY; + t->rdata = pval; + t->rlen = 1; + return q; +} + +static void acpi_ec_delete_query(struct acpi_ec_query *q) +{ + if (q) { + if (q->handler) + acpi_ec_put_query_handler(q->handler); + kfree(q); + } +} + +static void acpi_ec_event_processor(struct work_struct *work) +{ + struct acpi_ec_query *q = container_of(work, struct acpi_ec_query, work); + struct acpi_ec_query_handler *handler = q->handler; - if (!handler) - return; ec_dbg_evt("Query(0x%02x) started", handler->query_bit); if (handler->func) handler->func(handler->data); else if (handler->handle) acpi_evaluate_object(handler->handle, NULL, NULL, NULL); ec_dbg_evt("Query(0x%02x) stopped", handler->query_bit); - acpi_ec_put_query_handler(handler); + acpi_ec_delete_query(q); } static int acpi_ec_query(struct acpi_ec *ec, u8 *data) { u8 value = 0; int result; - acpi_status status; struct acpi_ec_query_handler *handler; - struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, - .wdata = NULL, .rdata = &value, - .wlen = 0, .rlen = 1}; + struct acpi_ec_query *q; + + q = acpi_ec_create_query(&value); + if (!q) + return -ENOMEM; /* * Query the EC to find out which _Qxx method we need to evaluate. * Note that successful completion of the query causes the ACPI_EC_SCI * bit to be cleared (and thus clearing the interrupt source). */ - result = acpi_ec_transaction(ec, &t); - if (result) - return result; - if (data) - *data = value; + result = acpi_ec_transaction(ec, &q->transaction); if (!value) - return -ENODATA; + result = -ENODATA; + if (result) + goto err_exit; mutex_lock(&ec->mutex); list_for_each_entry(handler, &ec->list, node) { if (value == handler->query_bit) { - /* have custom handler for this bit */ - handler = acpi_ec_get_query_handler(handler); + q->handler = acpi_ec_get_query_handler(handler); ec_dbg_evt("Query(0x%02x) scheduled", - handler->query_bit); - status = acpi_os_execute((handler->func) ? - OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, - acpi_ec_run, handler); - if (ACPI_FAILURE(status)) + q->handler->query_bit); + /* + * It is reported that _Qxx are evaluated in a + * parallel way on Windows: + * https://bugzilla.kernel.org/show_bug.cgi?id=94411 + */ + if (!schedule_work(&q->work)) result = -EBUSY; break; } } mutex_unlock(&ec->mutex); + +err_exit: + if (result && q) + acpi_ec_delete_query(q); + if (data) + *data = value; return result; } -- cgit v1.2.3 From 3277b4ea216e5cd7d3f6095ff40f1a9e574f37b3 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 17 Aug 2015 17:28:46 +0300 Subject: ACPI / osl: replace custom implementation of readq / writeq The readq() and writeq() helpers are available in the asm-generic/io-64-nonatomic-hi-lo.h and asm-generic/io-64-nonatomic-lo-hi.h headers. Replace custom implementation by the generic helpers. Signed-off-by: Andy Shevchenko Reviewed-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 3b8963f21b36..64077e87477a 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -47,6 +47,7 @@ #include #include +#include #include "internal.h" @@ -947,21 +948,6 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width) EXPORT_SYMBOL(acpi_os_write_port); -#ifdef readq -static inline u64 read64(const volatile void __iomem *addr) -{ - return readq(addr); -} -#else -static inline u64 read64(const volatile void __iomem *addr) -{ - u64 l, h; - l = readl(addr); - h = readl(addr+4); - return l | (h << 32); -} -#endif - acpi_status acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) { @@ -994,7 +980,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) *(u32 *) value = readl(virt_addr); break; case 64: - *(u64 *) value = read64(virt_addr); + *(u64 *) value = readq(virt_addr); break; default: BUG(); @@ -1008,19 +994,6 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) return AE_OK; } -#ifdef writeq -static inline void write64(u64 val, volatile void __iomem *addr) -{ - writeq(val, addr); -} -#else -static inline void write64(u64 val, volatile void __iomem *addr) -{ - writel(val, addr); - writel(val>>32, addr+4); -} -#endif - acpi_status acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width) { @@ -1049,7 +1022,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width) writel(value, virt_addr); break; case 64: - write64(value, virt_addr); + writeq(value, virt_addr); break; default: BUG(); -- cgit v1.2.3 From 239708a3af44064366f1af0eea02dc1e8991c11b Mon Sep 17 00:00:00 2001 From: Ashwin Chaugule Date: Wed, 5 Aug 2015 09:40:25 -0400 Subject: ACPI: Split out ACPI PSS from ACPI Processor driver The ACPI processor driver is currently tied too closely to the ACPI P-states (PSS) and other related constructs for controlling CPU performance. The newer ACPI specification (v5.1 onwards) introduces alternative methods to PSS. These new mechanisms are described within each ACPI Processor object and so they need to be scanned whenever a new Processor object is detected. This patch introduces a new Kconfig symbol to allow for finer configurability among the two options for controlling performance states. There is no change in functionality and the option is auto-selected by the architectures which support it. A future commit will introduce support for CPPC: A newer method of controlling CPU performance. The OS is not expected to support CPPC and PSS at the same time, so the Kconfig option lets us make the two mutually exclusive at compile time. Signed-off-by: Ashwin Chaugule [ rjw: Changelog ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Kconfig | 15 ++++--- drivers/acpi/Makefile | 5 ++- drivers/acpi/processor_driver.c | 86 +++++++++++++++++++++++++++-------------- include/acpi/processor.h | 28 +++++++++++++- 4 files changed, 96 insertions(+), 38 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 114cf48085ab..d6e2a869033c 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -189,17 +189,20 @@ config ACPI_DOCK This driver supports ACPI-controlled docking stations and removable drive bays such as the IBM Ultrabay and the Dell Module Bay. +config ACPI_CPU_FREQ_PSS + bool + select THERMAL + config ACPI_PROCESSOR tristate "Processor" - select THERMAL - select CPU_IDLE depends on X86 || IA64 + select CPU_IDLE + select ACPI_CPU_FREQ_PSS default y help - This driver installs ACPI as the idle handler for Linux and uses - ACPI C2 and C3 processor states to save power on systems that - support it. It is required by several flavors of cpufreq - performance-state drivers. + This driver adds support for the ACPI Processor package. It is required + by several flavors of cpufreq performance-state, thermal, throttling and + idle drivers. To compile this driver as a module, choose M here: the module will be called processor. diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 8321430d7f24..7e97aef373ae 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -80,8 +80,9 @@ obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o obj-$(CONFIG_ACPI_BGRT) += bgrt.o # processor has its own "processor." module_param namespace -processor-y := processor_driver.o processor_throttling.o -processor-y += processor_idle.o processor_thermal.o +processor-y := processor_driver.o processor_idle.o +processor-$(CONFIG_ACPI_CPU_FREQ_PSS) += processor_throttling.o \ + processor_thermal.o processor-$(CONFIG_CPU_FREQ) += processor_perflib.o obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index cc820d840c61..3fea539aa43e 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -163,34 +163,24 @@ static struct notifier_block acpi_cpu_notifier = { .notifier_call = acpi_cpu_soft_notify, }; -static int __acpi_processor_start(struct acpi_device *device) +#ifdef CONFIG_ACPI_CPU_FREQ_PSS +static int acpi_pss_perf_init(struct acpi_processor *pr, + struct acpi_device *device) { - struct acpi_processor *pr = acpi_driver_data(device); - acpi_status status; int result = 0; - if (!pr) - return -ENODEV; - - if (pr->flags.need_hotplug_init) - return 0; - -#ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr, 0); -#endif + acpi_processor_get_throttling_info(pr); if (pr->flags.throttling) pr->flags.limit = 1; - if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) - acpi_processor_power_init(pr); - pr->cdev = thermal_cooling_device_register("Processor", device, &processor_cooling_ops); if (IS_ERR(pr->cdev)) { result = PTR_ERR(pr->cdev); - goto err_power_exit; + return result; } dev_dbg(&device->dev, "registered as cooling_device%d\n", @@ -204,6 +194,7 @@ static int __acpi_processor_start(struct acpi_device *device) "Failed to create sysfs link 'thermal_cooling'\n"); goto err_thermal_unregister; } + result = sysfs_create_link(&pr->cdev->device.kobj, &device->dev.kobj, "device"); @@ -213,17 +204,61 @@ static int __acpi_processor_start(struct acpi_device *device) goto err_remove_sysfs_thermal; } - status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, - acpi_processor_notify, device); - if (ACPI_SUCCESS(status)) - return 0; - sysfs_remove_link(&pr->cdev->device.kobj, "device"); err_remove_sysfs_thermal: sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); err_thermal_unregister: thermal_cooling_device_unregister(pr->cdev); - err_power_exit: + + return result; +} + +static void acpi_pss_perf_exit(struct acpi_processor *pr, + struct acpi_device *device) +{ + if (pr->cdev) { + sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); + sysfs_remove_link(&pr->cdev->device.kobj, "device"); + thermal_cooling_device_unregister(pr->cdev); + pr->cdev = NULL; + } +} +#else +static inline int acpi_pss_perf_init(struct acpi_processor *pr, + struct acpi_device *device) +{ + return 0; +} + +static inline void acpi_pss_perf_exit(struct acpi_processor *pr, + struct acpi_device *device) {} +#endif /* CONFIG_ACPI_CPU_FREQ_PSS */ + +static int __acpi_processor_start(struct acpi_device *device) +{ + struct acpi_processor *pr = acpi_driver_data(device); + acpi_status status; + int result = 0; + + if (!pr) + return -ENODEV; + + if (pr->flags.need_hotplug_init) + return 0; + + if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) + acpi_processor_power_init(pr); + + result = acpi_pss_perf_init(pr, device); + if (result) + goto err_power_exit; + + status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, + acpi_processor_notify, device); + if (ACPI_SUCCESS(status)) + return 0; + +err_power_exit: acpi_processor_power_exit(pr); return result; } @@ -252,15 +287,10 @@ static int acpi_processor_stop(struct device *dev) pr = acpi_driver_data(device); if (!pr) return 0; - acpi_processor_power_exit(pr); - if (pr->cdev) { - sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); - sysfs_remove_link(&pr->cdev->device.kobj, "device"); - thermal_cooling_device_unregister(pr->cdev); - pr->cdev = NULL; - } + acpi_pss_perf_exit(pr, device); + return 0; } diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 4188a4d3b597..b6c917835805 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -318,6 +318,7 @@ int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id); void acpi_processor_set_pdc(acpi_handle handle); /* in processor_throttling.c */ +#ifdef CONFIG_ACPI_CPU_FREQ_PSS int acpi_processor_tstate_has_changed(struct acpi_processor *pr); int acpi_processor_get_throttling_info(struct acpi_processor *pr); extern int acpi_processor_set_throttling(struct acpi_processor *pr, @@ -330,6 +331,29 @@ extern void acpi_processor_reevaluate_tstate(struct acpi_processor *pr, unsigned long action); extern const struct file_operations acpi_processor_throttling_fops; extern void acpi_processor_throttling_init(void); +#else +static inline int acpi_processor_tstate_has_changed(struct acpi_processor *pr) +{ + return 0; +} + +static inline int acpi_processor_get_throttling_info(struct acpi_processor *pr) +{ + return -ENODEV; +} + +static inline int acpi_processor_set_throttling(struct acpi_processor *pr, + int state, bool force) +{ + return -ENODEV; +} + +static inline void acpi_processor_reevaluate_tstate(struct acpi_processor *pr, + unsigned long action) {} + +static inline void acpi_processor_throttling_init(void) {} +#endif /* CONFIG_ACPI_CPU_FREQ_PSS */ + /* in processor_idle.c */ int acpi_processor_power_init(struct acpi_processor *pr); int acpi_processor_power_exit(struct acpi_processor *pr); @@ -348,7 +372,7 @@ static inline void acpi_processor_syscore_exit(void) {} /* in processor_thermal.c */ int acpi_processor_get_limit_info(struct acpi_processor *pr); extern const struct thermal_cooling_device_ops processor_cooling_ops; -#ifdef CONFIG_CPU_FREQ +#if defined(CONFIG_ACPI_CPU_FREQ_PSS) & defined(CONFIG_CPU_FREQ) void acpi_thermal_cpufreq_init(void); void acpi_thermal_cpufreq_exit(void); #else @@ -360,6 +384,6 @@ static inline void acpi_thermal_cpufreq_exit(void) { return; } -#endif +#endif /* CONFIG_ACPI_CPU_FREQ_PSS */ #endif -- cgit v1.2.3 From 5f05586c609dfc737e2e00c757a51c7dbb415e51 Mon Sep 17 00:00:00 2001 From: Ashwin Chaugule Date: Wed, 5 Aug 2015 09:40:26 -0400 Subject: ACPI: Decouple ACPI idle and ACPI processor drivers This patch introduces a new Kconfig symbol, ACPI_PROCESSOR_IDLE, which is auto selected by architectures which support the ACPI based C states for CPU Idle management. The processor_idle driver in its present form contains declarations specific to X86 and IA64. Since there are no reasonable defaults for other architectures e.g. ARM64, the driver is selected only for X86 or IA64. This helps in decoupling the ACPI processor_driver from the ACPI processor_idle driver which is useful for the upcoming alternative patchwork for controlling CPU Performance (CPPC) and CPU Idle (LPI). Signed-off-by: Ashwin Chaugule Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Kconfig | 6 +++++- drivers/acpi/Makefile | 3 ++- include/acpi/processor.h | 26 ++++++++++++++++++++++++-- 3 files changed, 31 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index d6e2a869033c..54e9729f9634 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -193,10 +193,14 @@ config ACPI_CPU_FREQ_PSS bool select THERMAL +config ACPI_PROCESSOR_IDLE + bool + select CPU_IDLE + config ACPI_PROCESSOR tristate "Processor" depends on X86 || IA64 - select CPU_IDLE + select ACPI_PROCESSOR_IDLE select ACPI_CPU_FREQ_PSS default y help diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 7e97aef373ae..3ea59ae85c19 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -80,7 +80,8 @@ obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o obj-$(CONFIG_ACPI_BGRT) += bgrt.o # processor has its own "processor." module_param namespace -processor-y := processor_driver.o processor_idle.o +processor-y := processor_driver.o +processor-$(CONFIG_ACPI_PROCESSOR_IDLE) += processor_idle.o processor-$(CONFIG_ACPI_CPU_FREQ_PSS) += processor_throttling.o \ processor_thermal.o processor-$(CONFIG_CPU_FREQ) += processor_perflib.o diff --git a/include/acpi/processor.h b/include/acpi/processor.h index b6c917835805..2c4e7a9c1725 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -355,13 +355,35 @@ static inline void acpi_processor_throttling_init(void) {} #endif /* CONFIG_ACPI_CPU_FREQ_PSS */ /* in processor_idle.c */ +extern struct cpuidle_driver acpi_idle_driver; +#ifdef CONFIG_ACPI_PROCESSOR_IDLE int acpi_processor_power_init(struct acpi_processor *pr); int acpi_processor_power_exit(struct acpi_processor *pr); int acpi_processor_cst_has_changed(struct acpi_processor *pr); int acpi_processor_hotplug(struct acpi_processor *pr); -extern struct cpuidle_driver acpi_idle_driver; +#else +static inline int acpi_processor_power_init(struct acpi_processor *pr) +{ + return -ENODEV; +} + +static inline int acpi_processor_power_exit(struct acpi_processor *pr) +{ + return -ENODEV; +} + +static inline int acpi_processor_cst_has_changed(struct acpi_processor *pr) +{ + return -ENODEV; +} + +static inline int acpi_processor_hotplug(struct acpi_processor *pr) +{ + return -ENODEV; +} +#endif /* CONFIG_ACPI_PROCESSOR_IDLE */ -#ifdef CONFIG_PM_SLEEP +#if defined(CONFIG_PM_SLEEP) & defined(CONFIG_ACPI_PROCESSOR_IDLE) void acpi_processor_syscore_init(void); void acpi_processor_syscore_exit(void); #else -- cgit v1.2.3 From 4712f71b609d1805b958c0c355b16a995b11ab6e Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:28:26 +0800 Subject: ACPICA: Correctly cleanup after a ACPI table load failure ACPICA commit ed7769e832de6c7ba90615480d916c85fd100422 If a table load fails, delete all namespace objects created by the table, otherwise these objects will be uninitialized, causing problems later. This appears to be a very rare problem. Also handle the unitialized node problem to prevent possible faults. ACPICA BZ 1185. Link: https://github.com/acpica/acpica/commit/ed7769e8 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exresnte.c | 2 +- drivers/acpi/acpica/exresolv.c | 16 +++++++++++----- drivers/acpi/acpica/nseval.c | 1 + drivers/acpi/acpica/nsload.c | 16 +++++++++++++++- drivers/acpi/acpica/tbxfload.c | 29 ++++++++++++++++++++++++++--- include/acpi/acexcep.h | 7 +++++-- 6 files changed, 59 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index c7e3b929aa85..1b372ef69308 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c @@ -126,7 +126,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, if (!source_desc) { ACPI_ERROR((AE_INFO, "No object attached to node [%4.4s] %p", node->name.ascii, node)); - return_ACPI_STATUS(AE_AML_NO_OPERAND); + return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE); } /* diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index b6b7f3af29e4..7b109128b035 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c @@ -337,8 +337,9 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, acpi_object_type * return_type, union acpi_operand_object **return_desc) { - union acpi_operand_object *obj_desc = (void *)operand; - struct acpi_namespace_node *node; + union acpi_operand_object *obj_desc = ACPI_CAST_PTR(void, operand); + struct acpi_namespace_node *node = + ACPI_CAST_PTR(struct acpi_namespace_node, operand); acpi_object_type type; acpi_status status; @@ -355,9 +356,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, case ACPI_DESC_TYPE_NAMED: type = ((struct acpi_namespace_node *)obj_desc)->type; - obj_desc = - acpi_ns_get_attached_object((struct acpi_namespace_node *) - obj_desc); + obj_desc = acpi_ns_get_attached_object(node); /* If we had an Alias node, use the attached object for type info */ @@ -368,6 +367,13 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, acpi_namespace_node *) obj_desc); } + + if (!obj_desc) { + ACPI_ERROR((AE_INFO, + "[%4.4s] Node is unresolved or uninitialized", + acpi_ut_get_node_name(node))); + return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE); + } break; default: diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 80670cb32b5a..88822b7a958f 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -274,6 +274,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) acpi_ex_exit_interpreter(); if (ACPI_FAILURE(status)) { + info->return_object = NULL; goto cleanup; } diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index bd6cd4a81316..14ab83668207 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -111,7 +111,21 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) if (ACPI_SUCCESS(status)) { acpi_tb_set_table_loaded_flag(table_index, TRUE); } else { - (void)acpi_tb_release_owner_id(table_index); + /* + * On error, delete any namespace objects created by this table. + * We cannot initialize these objects, so delete them. There are + * a couple of expecially bad cases: + * AE_ALREADY_EXISTS - namespace collision. + * AE_NOT_FOUND - the target of a Scope operator does not + * exist. This target of Scope must already exist in the + * namespace, as per the ACPI specification. + */ + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list. + tables[table_index].owner_id); + acpi_tb_release_owner_id(table_index); + + return_ACPI_STATUS(status); } unlock: diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 9682d40ca6ff..7862cf04a164 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -102,6 +102,8 @@ static acpi_status acpi_tb_load_namespace(void) acpi_status status; u32 i; struct acpi_table_header *new_dsdt; + u32 tables_loaded = 0; + u32 tables_failed = 0; ACPI_FUNCTION_TRACE(tb_load_namespace); @@ -159,7 +161,10 @@ static acpi_status acpi_tb_load_namespace(void) status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed")); + tables_failed++; + } else { + tables_loaded++; } /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ @@ -187,11 +192,29 @@ static acpi_status acpi_tb_load_namespace(void) /* Ignore errors while loading tables, get as many as possible */ (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - (void)acpi_ns_load_table(i, acpi_gbl_root_node); + status = acpi_ns_load_table(i, acpi_gbl_root_node); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "[%4.4s] table load failed", + &acpi_gbl_root_table_list.tables[i]. + signature.ascii[0])); + tables_failed++; + } else { + tables_loaded++; + } + (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); } - ACPI_INFO((AE_INFO, "All ACPI Tables successfully acquired")); + if (!tables_failed) { + ACPI_INFO((AE_INFO, + "All (%u) ACPI AML tables successfully loaded", + tables_loaded)); + } else { + ACPI_ERROR((AE_INFO, + "%u ACPI AML tables loaded, %u failed", + tables_loaded, tables_failed)); + } unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 11c3a011dcbf..9f20eb4acaa6 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -192,8 +192,9 @@ struct acpi_exception_info { #define AE_AML_BAD_RESOURCE_LENGTH EXCEP_AML (0x001F) #define AE_AML_ILLEGAL_ADDRESS EXCEP_AML (0x0020) #define AE_AML_INFINITE_LOOP EXCEP_AML (0x0021) +#define AE_AML_UNINITIALIZED_NODE EXCEP_AML (0x0022) -#define AE_CODE_AML_MAX 0x0021 +#define AE_CODE_AML_MAX 0x0022 /* * Internal exceptions used for control @@ -355,7 +356,9 @@ static const struct acpi_exception_info acpi_gbl_exception_names_aml[] = { EXCEP_TXT("AE_AML_ILLEGAL_ADDRESS", "A memory, I/O, or PCI configuration address is invalid"), EXCEP_TXT("AE_AML_INFINITE_LOOP", - "An apparent infinite AML While loop, method was aborted") + "An apparent infinite AML While loop, method was aborted"), + EXCEP_TXT("AE_AML_UNINITIALIZED_NODE", + "A namespace node is uninitialized or unresolved") }; static const struct acpi_exception_info acpi_gbl_exception_names_ctrl[] = { -- cgit v1.2.3 From 3534969721ba011b8c2bcb5686819852df7aa971 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:28:32 +0800 Subject: ACPICA: Disassembler: Remove duplicate code in _PLD processing. ACPICA commit 6d9c827b540837b6e54059e17756a06985e4a196 ACPICA BZ 1176. Link: https://bugs.acpica.org/show_bug.cgi?id=1176 Link: https://github.com/acpica/acpica/commit/6d9c827b Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utxface.c | 5 +++-- include/acpi/acbuffer.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 51cf52d52243..c2bd5e2485a4 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -517,7 +517,8 @@ acpi_decode_pld_buffer(u8 *in_buffer, /* Parameter validation */ - if (!in_buffer || !return_buffer || (length < 16)) { + if (!in_buffer || !return_buffer + || (length < ACPI_PLD_REV1_BUFFER_SIZE)) { return (AE_BAD_PARAMETER); } @@ -567,7 +568,7 @@ acpi_decode_pld_buffer(u8 *in_buffer, pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword); pld_info->order = ACPI_PLD_GET_ORDER(&dword); - if (length >= ACPI_PLD_BUFFER_SIZE) { + if (length >= ACPI_PLD_REV2_BUFFER_SIZE) { /* Fifth 32-bit DWord (Revision 2 of _PLD) */ diff --git a/include/acpi/acbuffer.h b/include/acpi/acbuffer.h index 6b040f4ddfab..fcf9080eae85 100644 --- a/include/acpi/acbuffer.h +++ b/include/acpi/acbuffer.h @@ -147,6 +147,7 @@ struct acpi_pld_info { * (Intended for BIOS use only) */ #define ACPI_PLD_REV1_BUFFER_SIZE 16 /* For Revision 1 of the buffer (From ACPI spec) */ +#define ACPI_PLD_REV2_BUFFER_SIZE 20 /* For Revision 2 of the buffer (From ACPI spec) */ #define ACPI_PLD_BUFFER_SIZE 20 /* For Revision 2 of the buffer (From ACPI spec) */ /* First 32-bit dword, bits 0:32 */ -- cgit v1.2.3 From 9f41fd8a175ff87ba610fc387a6922b0f49f8e19 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:28:39 +0800 Subject: ACPICA: Update parameter validation for data_table_region and load_table ACPICA commit 51ab555e60b4a3de3cc4a846e86d0de255be441a Add additional validation for the table signature and the OEM strings. Eliminates buffer read overrun in data_table_region. ACPICA BZ 1184. Link: https://bugs.acpica.org/show_bug.cgi?id=1184 Link: https://github.com/acpica/acpica/commit/51ab555e Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/actables.h | 2 ++ drivers/acpi/acpica/dsopcode.c | 31 ++++++++++++++++++++----------- drivers/acpi/acpica/exconfig.c | 8 -------- drivers/acpi/acpica/tbfind.c | 15 ++++++++++++++- drivers/acpi/acpica/tbutils.c | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 20 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 7e0b6f1bec9c..58497b7e3347 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -164,4 +164,6 @@ acpi_tb_install_fixed_table(acpi_physical_address address, acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); +u8 acpi_is_valid_signature(char *signature); + #endif /* __ACTABLES_H__ */ diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index ea0cc4e08f80..81d7b9863e32 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -480,8 +480,8 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, union acpi_operand_object **operand; struct acpi_namespace_node *node; union acpi_parse_object *next_op; - u32 table_index; struct acpi_table_header *table; + u32 table_index; ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); @@ -504,6 +504,8 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, return_ACPI_STATUS(status); } + operand = &walk_state->operands[0]; + /* * Resolve the Signature string, oem_id string, * and oem_table_id string operands @@ -511,32 +513,34 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, status = acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto cleanup; } - operand = &walk_state->operands[0]; - /* Find the ACPI table */ status = acpi_tb_find_table(operand[0]->string.pointer, operand[1]->string.pointer, operand[2]->string.pointer, &table_index); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + if (status == AE_NOT_FOUND) { + ACPI_ERROR((AE_INFO, + "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT", + operand[0]->string.pointer, + operand[1]->string.pointer, + operand[2]->string.pointer)); + } + goto cleanup; } - acpi_ut_remove_reference(operand[0]); - acpi_ut_remove_reference(operand[1]); - acpi_ut_remove_reference(operand[2]); - status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto cleanup; } obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { - return_ACPI_STATUS(AE_NOT_EXIST); + status = AE_NOT_EXIST; + goto cleanup; } obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table); @@ -551,6 +555,11 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, obj_desc->region.flags |= AOPOBJ_DATA_VALID; +cleanup: + acpi_ut_remove_reference(operand[0]); + acpi_ut_remove_reference(operand[1]); + acpi_ut_remove_reference(operand[2]); + return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 24a4c5c2b124..b540913c11ac 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -162,14 +162,6 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, ACPI_FUNCTION_TRACE(ex_load_table_op); - /* Validate lengths for the Signature, oem_id, and oem_table_id strings */ - - if ((operand[0]->string.length > ACPI_NAME_SIZE) || - (operand[1]->string.length > ACPI_OEM_ID_SIZE) || - (operand[2]->string.length > ACPI_OEM_TABLE_ID_SIZE)) { - return_ACPI_STATUS(AE_AML_STRING_LIMIT); - } - /* Find the ACPI table in the RSDT/XSDT */ status = acpi_tb_find_table(operand[0]->string.pointer, diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index 119c84ad9833..405529d49a1a 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c @@ -68,12 +68,25 @@ acpi_status acpi_tb_find_table(char *signature, char *oem_id, char *oem_table_id, u32 *table_index) { - u32 i; acpi_status status; struct acpi_table_header header; + u32 i; ACPI_FUNCTION_TRACE(tb_find_table); + /* Validate the input table signature */ + + if (!acpi_is_valid_signature(signature)) { + return_ACPI_STATUS(AE_BAD_SIGNATURE); + } + + /* Don't allow the OEM strings to be too long */ + + if ((strlen(oem_id) > ACPI_OEM_ID_SIZE) || + (strlen(oem_table_id) > ACPI_OEM_TABLE_ID_SIZE)) { + return_ACPI_STATUS(AE_AML_STRING_LIMIT); + } + /* Normalize the input strings */ memset(&header, 0, sizeof(struct acpi_table_header)); diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 568ac0e4a3c6..db7f2aa9a457 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -412,3 +412,36 @@ next_table: return_ACPI_STATUS(AE_OK); } + +/******************************************************************************* + * + * FUNCTION: acpi_is_valid_signature + * + * PARAMETERS: signature - Sig string to be validated + * + * RETURN: TRUE if signature is correct length and has valid characters + * + * DESCRIPTION: Validate an ACPI table signature. + * + ******************************************************************************/ + +u8 acpi_is_valid_signature(char *signature) +{ + u32 i; + + /* Validate the signature length */ + + if (strlen(signature) != ACPI_NAME_SIZE) { + return (FALSE); + } + + /* Validate each character in the signature */ + + for (i = 0; i < ACPI_NAME_SIZE; i++) { + if (!acpi_ut_valid_acpi_char(signature[i], i)) { + return (FALSE); + } + } + + return (TRUE); +} -- cgit v1.2.3 From 2aabfad7c6680178ffa8f02957287178a58a46ca Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:28:47 +0800 Subject: ACPICA: Disassembler: Update for new listing mode ACPICA commit 2ed09bb7619d25f5a5c065c33a8a775a6db3a856 ACPICA commit 2fefacf73825b0ec96bbfc4f70a256735b715d6c This mode emits AML code along with the ASL code. A new global was needed to ensure the listing mode is completely separate from the debugger verbose mode. Emits the correct AML offset for the AML code. The -l option now works for both the compiler and disassembler. Linux kernel is not affected by this commit. Link: https://github.com/acpica/acpica/commit/2fefacf7 Link: https://github.com/acpica/acpica/commit/2ed09bb7 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 79eb35d080a0..1283b19e29e8 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -307,9 +307,9 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_no_resource_disassembly, FALSE); ACPI_INIT_GLOBAL(u8, acpi_gbl_ignore_noop_operator, FALSE); ACPI_INIT_GLOBAL(u8, acpi_gbl_cstyle_disassembly, TRUE); ACPI_INIT_GLOBAL(u8, acpi_gbl_force_aml_disassembly, FALSE); -ACPI_INIT_GLOBAL(union acpi_parse_object *, acpi_gbl_previous_op, NULL); ACPI_GLOBAL(u8, acpi_gbl_db_opt_disasm); +ACPI_GLOBAL(u8, acpi_gbl_dm_opt_listing); ACPI_GLOBAL(u8, acpi_gbl_db_opt_verbose); ACPI_GLOBAL(u8, acpi_gbl_num_external_methods); ACPI_GLOBAL(u32, acpi_gbl_resolved_external_methods); -- cgit v1.2.3 From 92b21a9502ea3a83464aea885b3c65c528b10190 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:28:54 +0800 Subject: ACPICA: Update info messages during ACPICA init ACPICA commit 4ccf8a1cc499ec8f00345f662a5887483980e1dd Small cleanup of messages. Link: https://github.com/acpica/acpica/commit/4ccf8a1c Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/dsinit.c | 9 +++++++++ drivers/acpi/acpica/tbxfload.c | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index 95779e8ec3bb..bbf52f0dc046 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -237,6 +237,15 @@ acpi_ds_initialize_objects(u32 table_index, return_ACPI_STATUS(status); } + /* DSDT is always the first AML table */ + + if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT)) { + ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, + "\nInitializing Namespace objects:\n")); + } + + /* Summary of objects initialized */ + ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Table [%4.4s] (id %4.4X) - %4u Objects with %3u Devices, " "%3u Regions, %3u Methods (%u/%u/%u Serial/Non/Cvt)\n", diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 7862cf04a164..6cbb2f7a35e8 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -208,11 +208,11 @@ static acpi_status acpi_tb_load_namespace(void) if (!tables_failed) { ACPI_INFO((AE_INFO, - "All (%u) ACPI AML tables successfully loaded", + "%u ACPI AML tables successfully acquired and loaded", tables_loaded)); } else { ACPI_ERROR((AE_INFO, - "%u ACPI AML tables loaded, %u failed", + "%u ACPI AML tables successfully acquired and loaded, %u failed", tables_loaded, tables_failed)); } -- cgit v1.2.3 From 8ec3f459073e67e5c6d78507dec693064b3040a2 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 25 Aug 2015 10:29:01 +0800 Subject: ACPICA: Tables: Fix global table list issues by removing fixed table indexes ACPICA commit c0b38b4c3982c2336ee92a2a14716107248bd941 The fixed table indexes leave holes in the global table list: 1. One hole can be seen when there is only 1 FACS provided by the BIOS. 2. Tow holes can be seen when it is a reduced hardware platform. The holes do not break OSPMs but have broken ACPI debugger "tables" command. Also the "fixed table indexes" mechanism may make the descriptors of the standard tables installed earlier than DSDT to be overwritten by the descriptors of the fixed tables. For example, FACP disappears from the global table list after DSDT is installed. This patch fixes all above issues by removing the "fixed table indexes" mechanism which is too complicated to be maintained in a regression safe manner. After removal, the table loader will determine the indexes of the fixed tables. Lv Zheng. Link: https://github.com/acpica/acpica/commit/c0b38b4c Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 3 +++ drivers/acpi/acpica/aclocal.h | 6 ++---- drivers/acpi/acpica/actables.h | 7 +++---- drivers/acpi/acpica/tbfadt.c | 6 +++--- drivers/acpi/acpica/tbinstal.c | 40 +++++++++++++++++++++------------------- drivers/acpi/acpica/tbutils.c | 37 ++++++++++++++----------------------- drivers/acpi/acpica/tbxfload.c | 10 +++++----- 7 files changed, 51 insertions(+), 58 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 1283b19e29e8..e78667ee5d0b 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -58,6 +58,9 @@ ACPI_GLOBAL(struct acpi_table_list, acpi_gbl_root_table_list); ACPI_GLOBAL(struct acpi_table_header *, acpi_gbl_DSDT); ACPI_GLOBAL(struct acpi_table_header, acpi_gbl_original_dsdt_header); +ACPI_INIT_GLOBAL(u32, acpi_gbl_dsdt_index, ACPI_INVALID_TABLE_INDEX); +ACPI_INIT_GLOBAL(u32, acpi_gbl_facs_index, ACPI_INVALID_TABLE_INDEX); +ACPI_INIT_GLOBAL(u32, acpi_gbl_xfacs_index, ACPI_INVALID_TABLE_INDEX); #if (!ACPI_REDUCED_HARDWARE) ACPI_GLOBAL(struct acpi_table_facs *, acpi_gbl_FACS); diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index a6b68878cdbe..92cbaeef3f34 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -213,11 +213,9 @@ struct acpi_table_list { #define ACPI_ROOT_ORIGIN_ALLOCATED (1) #define ACPI_ROOT_ALLOW_RESIZE (2) -/* Predefined (fixed) table indexes */ +/* Predefined table indexes */ -#define ACPI_TABLE_INDEX_DSDT (0) -#define ACPI_TABLE_INDEX_FACS (1) -#define ACPI_TABLE_INDEX_X_FACS (2) +#define ACPI_INVALID_TABLE_INDEX (0xFFFFFFFF) struct acpi_find_context { char *search_for; diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 58497b7e3347..ab7f3a03f179 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -154,13 +154,12 @@ void acpi_tb_check_dsdt_header(void); struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index); void -acpi_tb_install_table_with_override(u32 table_index, - struct acpi_table_desc *new_table_desc, - u8 override); +acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc, + u8 override, u32 *table_index); acpi_status acpi_tb_install_fixed_table(acpi_physical_address address, - char *signature, u32 table_index); + char *signature, u32 *table_index); acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 6253001b6375..455a0700db39 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -345,7 +345,7 @@ void acpi_tb_parse_fadt(u32 table_index) /* Obtain the DSDT and FACS tables via their addresses within the FADT */ acpi_tb_install_fixed_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, - ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); + ACPI_SIG_DSDT, &acpi_gbl_dsdt_index); /* If Hardware Reduced flag is set, there is no FACS */ @@ -354,13 +354,13 @@ void acpi_tb_parse_fadt(u32 table_index) acpi_tb_install_fixed_table((acpi_physical_address) acpi_gbl_FADT.facs, ACPI_SIG_FACS, - ACPI_TABLE_INDEX_FACS); + &acpi_gbl_facs_index); } if (acpi_gbl_FADT.Xfacs) { acpi_tb_install_fixed_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, ACPI_SIG_FACS, - ACPI_TABLE_INDEX_X_FACS); + &acpi_gbl_xfacs_index); } } } diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 15ea98e0068d..6319b42420c6 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -100,9 +100,9 @@ acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index) * * FUNCTION: acpi_tb_install_table_with_override * - * PARAMETERS: table_index - Index into root table array - * new_table_desc - New table descriptor to install + * PARAMETERS: new_table_desc - New table descriptor to install * override - Whether override should be performed + * table_index - Where the table index is returned * * RETURN: None * @@ -114,12 +114,14 @@ acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index) ******************************************************************************/ void -acpi_tb_install_table_with_override(u32 table_index, - struct acpi_table_desc *new_table_desc, - u8 override) +acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc, + u8 override, u32 *table_index) { + u32 i; + acpi_status status; - if (table_index >= acpi_gbl_root_table_list.current_table_count) { + status = acpi_tb_get_next_table_descriptor(&i, NULL); + if (ACPI_FAILURE(status)) { return; } @@ -134,8 +136,7 @@ acpi_tb_install_table_with_override(u32 table_index, acpi_tb_override_table(new_table_desc); } - acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list. - tables[table_index], + acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.tables[i], new_table_desc->address, new_table_desc->flags, new_table_desc->pointer); @@ -143,9 +144,13 @@ acpi_tb_install_table_with_override(u32 table_index, acpi_tb_print_table_header(new_table_desc->address, new_table_desc->pointer); + /* This synchronizes acpi_gbl_dsdt_index */ + + *table_index = i; + /* Set the global integer width (based upon revision of the DSDT) */ - if (table_index == ACPI_TABLE_INDEX_DSDT) { + if (i == acpi_gbl_dsdt_index) { acpi_ut_set_integer_width(new_table_desc->pointer->revision); } } @@ -157,7 +162,7 @@ acpi_tb_install_table_with_override(u32 table_index, * PARAMETERS: address - Physical address of DSDT or FACS * signature - Table signature, NULL if no need to * match - * table_index - Index into root table array + * table_index - Where the table index is returned * * RETURN: Status * @@ -168,7 +173,7 @@ acpi_tb_install_table_with_override(u32 table_index, acpi_status acpi_tb_install_fixed_table(acpi_physical_address address, - char *signature, u32 table_index) + char *signature, u32 *table_index) { struct acpi_table_desc new_table_desc; acpi_status status; @@ -200,7 +205,9 @@ acpi_tb_install_fixed_table(acpi_physical_address address, goto release_and_exit; } - acpi_tb_install_table_with_override(table_index, &new_table_desc, TRUE); + /* Add the table to the global root table list */ + + acpi_tb_install_table_with_override(&new_table_desc, TRUE, table_index); release_and_exit: @@ -355,13 +362,8 @@ acpi_tb_install_standard_table(acpi_physical_address address, /* Add the table to the global root table list */ - status = acpi_tb_get_next_table_descriptor(&i, NULL); - if (ACPI_FAILURE(status)) { - goto release_and_exit; - } - - *table_index = i; - acpi_tb_install_table_with_override(i, &new_table_desc, override); + acpi_tb_install_table_with_override(&new_table_desc, override, + table_index); release_and_exit: diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index db7f2aa9a457..b1d500e47bdb 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -74,22 +74,20 @@ acpi_status acpi_tb_initialize_facs(void) if (acpi_gbl_reduced_hardware) { acpi_gbl_FACS = NULL; return (AE_OK); - } - - (void)acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, - ACPI_CAST_INDIRECT_PTR(struct - acpi_table_header, - &acpi_gbl_facs32)); - (void)acpi_get_table_by_index(ACPI_TABLE_INDEX_X_FACS, - ACPI_CAST_INDIRECT_PTR(struct - acpi_table_header, - &acpi_gbl_facs64)); - - if (acpi_gbl_facs64 - && (!acpi_gbl_facs32 || !acpi_gbl_use32_bit_facs_addresses)) { - acpi_gbl_FACS = acpi_gbl_facs64; - } else if (acpi_gbl_facs32) { + } else if (acpi_gbl_FADT.Xfacs && + (!acpi_gbl_FADT.facs + || !acpi_gbl_use32_bit_facs_addresses)) { + (void)acpi_get_table_by_index(acpi_gbl_xfacs_index, + ACPI_CAST_INDIRECT_PTR(struct + acpi_table_header, + &acpi_gbl_facs32)); acpi_gbl_FACS = acpi_gbl_facs32; + } else if (acpi_gbl_FADT.facs) { + (void)acpi_get_table_by_index(acpi_gbl_facs_index, + ACPI_CAST_INDIRECT_PTR(struct + acpi_table_header, + &acpi_gbl_facs64)); + acpi_gbl_FACS = acpi_gbl_facs64; } /* If there is no FACS, just continue. There was already an error msg */ @@ -192,7 +190,7 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) acpi_tb_uninstall_table(table_desc); acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT], + tables[acpi_gbl_dsdt_index], ACPI_PTR_TO_PHYSADDR(new_table), ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, new_table); @@ -369,13 +367,6 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) table_entry_size); table_entry = ACPI_ADD_PTR(u8, table, sizeof(struct acpi_table_header)); - /* - * First three entries in the table array are reserved for the DSDT - * and 32bit/64bit FACS, which are not actually present in the - * RSDT/XSDT - they come from the FADT - */ - acpi_gbl_root_table_list.current_table_count = 3; - /* Initialize the root table array from the RSDT/XSDT */ for (i = 0; i < table_count; i++) { diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 6cbb2f7a35e8..fb4d4e64f8aa 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -116,12 +116,12 @@ static acpi_status acpi_tb_load_namespace(void) if (!acpi_gbl_root_table_list.current_table_count || !ACPI_COMPARE_NAME(& (acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT].signature), + tables[acpi_gbl_dsdt_index].signature), ACPI_SIG_DSDT) || ACPI_FAILURE(acpi_tb_validate_table (&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT]))) { + tables[acpi_gbl_dsdt_index]))) { status = AE_NO_ACPI_TABLES; goto unlock_and_exit; } @@ -133,7 +133,7 @@ static acpi_status acpi_tb_load_namespace(void) * .Pointer field is not validated until after call to acpi_tb_validate_table. */ acpi_gbl_DSDT = - acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; + acpi_gbl_root_table_list.tables[acpi_gbl_dsdt_index].pointer; /* * Optionally copy the entire DSDT to local memory (instead of simply @@ -142,7 +142,7 @@ static acpi_status acpi_tb_load_namespace(void) * the DSDT. */ if (acpi_gbl_copy_dsdt_locally) { - new_dsdt = acpi_tb_copy_dsdt(ACPI_TABLE_INDEX_DSDT); + new_dsdt = acpi_tb_copy_dsdt(acpi_gbl_dsdt_index); if (new_dsdt) { acpi_gbl_DSDT = new_dsdt; } @@ -159,7 +159,7 @@ static acpi_status acpi_tb_load_namespace(void) /* Load and parse tables */ - status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); + status = acpi_ns_load_table(acpi_gbl_dsdt_index, acpi_gbl_root_node); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed")); tables_failed++; -- cgit v1.2.3 From 7484619bff495c30e977dafe2ff735477bd569ff Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 25 Aug 2015 10:29:08 +0800 Subject: ACPICA: Tables: Cleanup to reduce FACS globals ACPICA commit 3f42ba76e2a0453976d3108296d5f656fdf2bd6e In this patch, FACS table mapping is also tuned a bit so that only the selected FACS table will be mapped by the OSPM (mapped on demand) and the FACS related global variables can be reduced. Lv Zheng. Link: https://github.com/acpica/acpica/commit/3f42ba76 Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 2 -- drivers/acpi/acpica/hwxfsleep.c | 15 ++------------- drivers/acpi/acpica/tbutils.c | 9 +++++---- 3 files changed, 7 insertions(+), 19 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index e78667ee5d0b..95ed861e8632 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -64,8 +64,6 @@ ACPI_INIT_GLOBAL(u32, acpi_gbl_xfacs_index, ACPI_INVALID_TABLE_INDEX); #if (!ACPI_REDUCED_HARDWARE) ACPI_GLOBAL(struct acpi_table_facs *, acpi_gbl_FACS); -ACPI_GLOBAL(struct acpi_table_facs *, acpi_gbl_facs32); -ACPI_GLOBAL(struct acpi_table_facs *, acpi_gbl_facs64); #endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index 52dfd0d050fa..d62a61612b3f 100644 --- a/drivers/acpi/acpica/hwxfsleep.c +++ b/drivers/acpi/acpica/hwxfsleep.c @@ -160,19 +160,8 @@ acpi_set_firmware_waking_vectors(acpi_physical_address physical_address, ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vectors); - /* If Hardware Reduced flag is set, there is no FACS */ - - if (acpi_gbl_reduced_hardware) { - return_ACPI_STATUS (AE_OK); - } - - if (acpi_gbl_facs32) { - (void)acpi_hw_set_firmware_waking_vectors(acpi_gbl_facs32, - physical_address, - physical_address64); - } - if (acpi_gbl_facs64) { - (void)acpi_hw_set_firmware_waking_vectors(acpi_gbl_facs64, + if (acpi_gbl_FACS) { + (void)acpi_hw_set_firmware_waking_vectors(acpi_gbl_FACS, physical_address, physical_address64); } diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index b1d500e47bdb..4337990127cc 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -68,6 +68,7 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); acpi_status acpi_tb_initialize_facs(void) { + struct acpi_table_facs *facs; /* If Hardware Reduced flag is set, there is no FACS */ @@ -80,14 +81,14 @@ acpi_status acpi_tb_initialize_facs(void) (void)acpi_get_table_by_index(acpi_gbl_xfacs_index, ACPI_CAST_INDIRECT_PTR(struct acpi_table_header, - &acpi_gbl_facs32)); - acpi_gbl_FACS = acpi_gbl_facs32; + &facs)); + acpi_gbl_FACS = facs; } else if (acpi_gbl_FADT.facs) { (void)acpi_get_table_by_index(acpi_gbl_facs_index, ACPI_CAST_INDIRECT_PTR(struct acpi_table_header, - &acpi_gbl_facs64)); - acpi_gbl_FACS = acpi_gbl_facs64; + &facs)); + acpi_gbl_FACS = facs; } /* If there is no FACS, just continue. There was already an error msg */ -- cgit v1.2.3 From 17dd4dcfadffba93cf18652eb16b345526b04ce1 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:29:25 +0800 Subject: ACPICA: acpinames: Add new options and wildcard support ACPICA commit 0ecf5b5a41c3d2e09af48f0fdbc9ae784f631788 - Add wilcard support for input filenames. - Add -l option to load tables and exit, no display. This is useful for validation of the namespace during BIOS generation. - Add -x option for specifying debug level. Linux kernel is not affected by this commit. Link: https://github.com/acpica/acpica/commit/0ecf5b5a Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acutils.h | 2 +- drivers/acpi/acpica/utmisc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 566ff4df02fd..fb2aa5066f3f 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -517,7 +517,7 @@ const struct acpi_exception_info *acpi_ut_validate_exception(acpi_status u8 acpi_ut_is_pci_root_bridge(char *id); -#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP) +#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_NAMES_APP) u8 acpi_ut_is_aml_table(struct acpi_table_header *table); #endif diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 98087ea1cdb3..517a5ec47742 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -75,7 +75,7 @@ u8 acpi_ut_is_pci_root_bridge(char *id) return (FALSE); } -#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP) +#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_NAMES_APP) /******************************************************************************* * * FUNCTION: acpi_ut_is_aml_table -- cgit v1.2.3 From 93cdafa071bd436596a0501fd43f4fab89c2be78 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:29:33 +0800 Subject: ACPICA: acpiexec/acpinames: Support very large number of ACPI tables ACPICA commit ca3bd4c5cdc39a9009280032adbbc20f34e94c47 Fix a couple of issues with >40 ACPI tables. Return exit error for acpinames to enable use with BIOS builds. The new exported function is used by acpinames. For Linux kernel, this change is a no-op. Link: https://github.com/acpica/acpica/commit/ca3bd4c5 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/actables.h | 5 +++++ drivers/acpi/acpica/tbxfload.c | 17 ++++++++++++----- drivers/acpi/acpica/utfileio.c | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index ab7f3a03f179..f7731f260c31 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -165,4 +165,9 @@ acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); u8 acpi_is_valid_signature(char *signature); +/* + * tbxfload + */ +acpi_status acpi_tb_load_namespace(void); + #endif /* __ACTABLES_H__ */ diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index fb4d4e64f8aa..96b82a818d76 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -51,9 +51,6 @@ #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbxfload") -/* Local prototypes */ -static acpi_status acpi_tb_load_namespace(void); - /******************************************************************************* * * FUNCTION: acpi_load_tables @@ -65,7 +62,6 @@ static acpi_status acpi_tb_load_namespace(void); * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT * ******************************************************************************/ - acpi_status __init acpi_load_tables(void) { acpi_status status; @@ -75,6 +71,13 @@ acpi_status __init acpi_load_tables(void) /* Load the namespace from the tables */ status = acpi_tb_load_namespace(); + + /* Don't let single failures abort the load */ + + if (status == AE_CTRL_TERMINATE) { + status = AE_OK; + } + if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "While loading namespace from ACPI tables")); @@ -97,7 +100,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables) * the RSDT/XSDT. * ******************************************************************************/ -static acpi_status acpi_tb_load_namespace(void) +acpi_status acpi_tb_load_namespace(void) { acpi_status status; u32 i; @@ -214,6 +217,10 @@ static acpi_status acpi_tb_load_namespace(void) ACPI_ERROR((AE_INFO, "%u ACPI AML tables successfully acquired and loaded, %u failed", tables_loaded, tables_failed)); + + /* Indicate at least one failure */ + + status = AE_CTRL_TERMINATE; } unlock_and_exit: diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c index 857af824337b..75a94f52b4be 100644 --- a/drivers/acpi/acpica/utfileio.c +++ b/drivers/acpi/acpica/utfileio.c @@ -312,7 +312,7 @@ acpi_ut_read_table_from_file(char *filename, struct acpi_table_header ** table) /* Get the entire file */ fprintf(stderr, - "Reading ACPI table from file %10s - Length %.8u (0x%06X)\n", + "Reading ACPI table from file %12s - Length %.8u (0x%06X)\n", filename, file_size, file_size); status = acpi_ut_read_table(file, table, &table_length); -- cgit v1.2.3 From 3c0503dd289eb6658f16d77fa12b3a30a4072be3 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:29:39 +0800 Subject: ACPICA: Table handling: Cleanup and update debug output for tools ACPICA commit 93862bd7a227543bc617d822ef5c4f8a5d68b519 Add output of table OEM ID along with signature to support lots of SSDTs. Cleanup use of table pointers. Link: https://github.com/acpica/acpica/commit/93862bd7 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/dsinit.c | 11 +++++---- drivers/acpi/acpica/tbxfload.c | 53 +++++++++++++++++++----------------------- 2 files changed, 30 insertions(+), 34 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index bbf52f0dc046..920f1b199bc6 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -247,11 +247,12 @@ acpi_ds_initialize_objects(u32 table_index, /* Summary of objects initialized */ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - "Table [%4.4s] (id %4.4X) - %4u Objects with %3u Devices, " - "%3u Regions, %3u Methods (%u/%u/%u Serial/Non/Cvt)\n", - table->signature, owner_id, info.object_count, - info.device_count, info.op_region_count, - info.method_count, info.serial_method_count, + "Table [%4.4s:%8.8s] (id %.2X) - %4u Objects with %3u Devices, " + "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n", + table->signature, table->oem_table_id, owner_id, + info.object_count, info.device_count, + info.op_region_count, info.method_count, + info.serial_method_count, info.non_serial_method_count, info.serialized_method_count)); diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 96b82a818d76..55ee14ca9418 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -105,6 +105,7 @@ acpi_status acpi_tb_load_namespace(void) acpi_status status; u32 i; struct acpi_table_header *new_dsdt; + struct acpi_table_desc *table; u32 tables_loaded = 0; u32 tables_failed = 0; @@ -116,15 +117,11 @@ acpi_status acpi_tb_load_namespace(void) * Load the namespace. The DSDT is required, but any SSDT and * PSDT tables are optional. Verify the DSDT. */ + table = &acpi_gbl_root_table_list.tables[acpi_gbl_dsdt_index]; + if (!acpi_gbl_root_table_list.current_table_count || - !ACPI_COMPARE_NAME(& - (acpi_gbl_root_table_list. - tables[acpi_gbl_dsdt_index].signature), - ACPI_SIG_DSDT) - || - ACPI_FAILURE(acpi_tb_validate_table - (&acpi_gbl_root_table_list. - tables[acpi_gbl_dsdt_index]))) { + !ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_DSDT) || + ACPI_FAILURE(acpi_tb_validate_table(table))) { status = AE_NO_ACPI_TABLES; goto unlock_and_exit; } @@ -135,8 +132,7 @@ acpi_status acpi_tb_load_namespace(void) * array can change dynamically as tables are loaded at run-time. Note: * .Pointer field is not validated until after call to acpi_tb_validate_table. */ - acpi_gbl_DSDT = - acpi_gbl_root_table_list.tables[acpi_gbl_dsdt_index].pointer; + acpi_gbl_DSDT = table->pointer; /* * Optionally copy the entire DSDT to local memory (instead of simply @@ -174,21 +170,15 @@ acpi_status acpi_tb_load_namespace(void) (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { + table = &acpi_gbl_root_table_list.tables[i]; + if (!acpi_gbl_root_table_list.tables[i].address || - (!ACPI_COMPARE_NAME - (&(acpi_gbl_root_table_list.tables[i].signature), - ACPI_SIG_SSDT) - && - !ACPI_COMPARE_NAME(& - (acpi_gbl_root_table_list.tables[i]. - signature), ACPI_SIG_PSDT) - && - !ACPI_COMPARE_NAME(& - (acpi_gbl_root_table_list.tables[i]. - signature), ACPI_SIG_OSDT)) - || - ACPI_FAILURE(acpi_tb_validate_table - (&acpi_gbl_root_table_list.tables[i]))) { + (!ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_SSDT) + && !ACPI_COMPARE_NAME(table->signature.ascii, + ACPI_SIG_PSDT) + && !ACPI_COMPARE_NAME(table->signature.ascii, + ACPI_SIG_OSDT)) + || ACPI_FAILURE(acpi_tb_validate_table(table))) { continue; } @@ -198,10 +188,15 @@ acpi_status acpi_tb_load_namespace(void) status = acpi_ns_load_table(i, acpi_gbl_root_node); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, - "[%4.4s] table load failed", - &acpi_gbl_root_table_list.tables[i]. - signature.ascii[0])); + "(%4.4s:%8.8s) while loading table", + table->signature.ascii, + table->pointer->oem_table_id)); tables_failed++; + + ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, + "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n", + table->signature.ascii, + table->pointer->oem_table_id)); } else { tables_loaded++; } @@ -215,8 +210,8 @@ acpi_status acpi_tb_load_namespace(void) tables_loaded)); } else { ACPI_ERROR((AE_INFO, - "%u ACPI AML tables successfully acquired and loaded, %u failed", - tables_loaded, tables_failed)); + "%u table load failures, %u successful", + tables_failed, tables_loaded)); /* Indicate at least one failure */ -- cgit v1.2.3 From 25823e784aac78964ada0e49efe2766d2aeb9fa4 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:29:45 +0800 Subject: ACPICA: Add additional debug info/statements ACPICA commit 74094ca9f51e2652a9b5f01722d8640a653cc75a For _REG methods and module-level code blocks. For acpiexec, add deletion of module-level blocks in case of an early abort. Link: https://github.com/acpica/acpica/commit/74094ca9 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/aclocal.h | 7 +++++++ drivers/acpi/acpica/evregion.c | 22 ++++++++++++++++++---- drivers/acpi/acpica/nseval.c | 3 ++- drivers/acpi/acpica/nsutils.c | 17 +++++++++++++++++ drivers/acpi/acpica/psloop.c | 14 +++++++++++++- 5 files changed, 57 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 92cbaeef3f34..acbf68baa04c 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -406,6 +406,13 @@ struct acpi_simple_repair_info { #define ACPI_NUM_RTYPES 5 /* Number of actual object types */ +/* Info for running the _REG methods */ + +struct acpi_reg_walk_info { + acpi_adr_space_type space_id; + u32 reg_run_count; +}; + /***************************************************************************** * * Event typedefs and structs diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 2ba28a63fb68..5ee79a16fe33 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -626,9 +626,17 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, acpi_adr_space_type space_id) { acpi_status status; + struct acpi_reg_walk_info info; ACPI_FUNCTION_TRACE(ev_execute_reg_methods); + info.space_id = space_id; + info.reg_run_count = 0; + + ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES, + " Running _REG methods for SpaceId %s\n", + acpi_ut_get_region_name(info.space_id))); + /* * Run all _REG methods for all Operation Regions for this space ID. This * is a separate walk in order to handle any interdependencies between @@ -637,7 +645,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, */ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, - NULL, &space_id, NULL); + NULL, &info, NULL); /* Special case for EC: handle "orphan" _REG methods with no region */ @@ -645,6 +653,11 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, acpi_ev_orphan_ec_reg_method(node); } + ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES, + " Executed %u _REG methods for SpaceId %s\n", + info.reg_run_count, + acpi_ut_get_region_name(info.space_id))); + return_ACPI_STATUS(status); } @@ -664,10 +677,10 @@ acpi_ev_reg_run(acpi_handle obj_handle, { union acpi_operand_object *obj_desc; struct acpi_namespace_node *node; - acpi_adr_space_type space_id; acpi_status status; + struct acpi_reg_walk_info *info; - space_id = *ACPI_CAST_PTR(acpi_adr_space_type, context); + info = ACPI_CAST_PTR(struct acpi_reg_walk_info, context); /* Convert and validate the device handle */ @@ -696,13 +709,14 @@ acpi_ev_reg_run(acpi_handle obj_handle, /* Object is a Region */ - if (obj_desc->region.space_id != space_id) { + if (obj_desc->region.space_id != info->space_id) { /* This region is for a different address space, just ignore it */ return (AE_OK); } + info->reg_run_count++; status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT); return (status); } diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 88822b7a958f..7eba578d36f3 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -465,7 +465,8 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj, status = acpi_ns_evaluate(info); - ACPI_DEBUG_PRINT((ACPI_DB_INIT, "Executed module-level code at %p\n", + ACPI_DEBUG_PRINT((ACPI_DB_INIT_NAMES, + "Executed module-level code at %p\n", method_obj->method.aml_start)); /* Delete a possible implicit return value (in slack mode) */ diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 9a34c5f04075..d1261fe374d5 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -596,6 +596,23 @@ void acpi_ns_terminate(void) ACPI_FUNCTION_TRACE(ns_terminate); +#ifdef ACPI_EXEC_APP + { + union acpi_operand_object *prev; + union acpi_operand_object *next; + + /* Delete any module-level code blocks */ + + next = acpi_gbl_module_code_list; + while (next) { + prev = next; + next = next->method.mutex; + prev->method.mutex = NULL; /* Clear the Mutex (cheated) field */ + acpi_ut_remove_reference(prev); + } + } +#endif + /* * Free the entire namespace -- all nodes and all objects * attached to the nodes diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 6b11fd7a93dc..03ac8c9a67ab 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -321,6 +321,8 @@ acpi_ps_link_module_code(union acpi_parse_object *parent_op, union acpi_operand_object *method_obj; struct acpi_namespace_node *parent_node; + ACPI_FUNCTION_TRACE(ps_link_module_code); + /* Get the tail of the list */ prev = next = acpi_gbl_module_code_list; @@ -340,9 +342,13 @@ acpi_ps_link_module_code(union acpi_parse_object *parent_op, method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); if (!method_obj) { - return; + return_VOID; } + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Create/Link new code block: %p\n", + method_obj)); + if (parent_op->common.node) { parent_node = parent_op->common.node; } else { @@ -367,8 +373,14 @@ acpi_ps_link_module_code(union acpi_parse_object *parent_op, prev->method.mutex = method_obj; } } else { + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Appending to existing code block: %p\n", + prev)); + prev->method.aml_length += aml_length; } + + return_VOID; } /******************************************************************************* -- cgit v1.2.3 From e69ab9a99e1d112045dd87902e467daec0d189da Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:29:52 +0800 Subject: ACPICA: Debugger: Add option to display namespace summary/counts ACPICA commit bba222c15c2ce79076eb3a5e9d4d5f7120db8a00 If "Objects" command is invoked with no arguments, the counts for each object type are displayed. Linux kernel is not affected by this commit as currently debugger is not enabled in the Linux kernel. Link: https://github.com/acpica/acpica/commit/bba222c1 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 4 ++-- drivers/acpi/acpica/aclocal.h | 4 ++++ include/acpi/actypes.h | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 95ed861e8632..c5971923cba4 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -346,8 +346,8 @@ ACPI_GLOBAL(char, acpi_gbl_db_debug_filename[ACPI_DB_LINE_BUFFER_SIZE]); /* * Statistic globals */ -ACPI_GLOBAL(u16, acpi_gbl_obj_type_count[ACPI_TYPE_NS_NODE_MAX + 1]); -ACPI_GLOBAL(u16, acpi_gbl_node_type_count[ACPI_TYPE_NS_NODE_MAX + 1]); +ACPI_GLOBAL(u16, acpi_gbl_obj_type_count[ACPI_TOTAL_TYPES]); +ACPI_GLOBAL(u16, acpi_gbl_node_type_count[ACPI_TOTAL_TYPES]); ACPI_GLOBAL(u16, acpi_gbl_obj_type_count_misc); ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc); ACPI_GLOBAL(u32, acpi_gbl_num_nodes); diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index acbf68baa04c..6f708267ad8c 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -1131,6 +1131,10 @@ struct acpi_integrity_info { #define ACPI_DB_CONSOLE_OUTPUT 0x02 #define ACPI_DB_DUPLICATE_OUTPUT 0x03 +struct acpi_object_info { + u32 types[ACPI_TOTAL_TYPES]; +}; + /***************************************************************************** * * Debug diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 531eca49edd4..f914958c4adb 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -662,6 +662,7 @@ typedef u32 acpi_object_type; #define ACPI_TYPE_DEBUG_OBJECT 0x10 #define ACPI_TYPE_EXTERNAL_MAX 0x10 +#define ACPI_NUM_TYPES (ACPI_TYPE_EXTERNAL_MAX + 1) /* * These are object types that do not map directly to the ACPI @@ -683,6 +684,7 @@ typedef u32 acpi_object_type; #define ACPI_TYPE_LOCAL_SCOPE 0x1B /* 1 Name, multiple object_list Nodes */ #define ACPI_TYPE_NS_NODE_MAX 0x1B /* Last typecode used within a NS Node */ +#define ACPI_TOTAL_TYPES (ACPI_TYPE_NS_NODE_MAX + 1) /* * These are special object types that never appear in -- cgit v1.2.3 From 47cdf8c692d5a64855a7aff83800d5bc5c925d7c Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 25 Aug 2015 10:30:00 +0800 Subject: ACPICA: Make the max-number-of-loops runtime configurable ACPICA commit a9d9c2d0c2d077bb3175ec9c252cf0e5da3efd45 Was previously compile-time only. Add support option for acpiexec. Link: https://github.com/acpica/acpica/commit/a9d9c2d0 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 4 ++++ drivers/acpi/acpica/dscontrol.c | 2 +- drivers/acpi/acpica/utinit.c | 1 + include/acpi/acconfig.h | 4 ---- 4 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index c5971923cba4..03c443b87c76 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -236,6 +236,10 @@ ACPI_INIT_GLOBAL(u32, acpi_gbl_nesting_level, 0); ACPI_GLOBAL(struct acpi_thread_state *, acpi_gbl_current_walk_list); +/* Maximum number of While() loop iterations before forced abort */ + +ACPI_GLOBAL(u16, acpi_gbl_max_loop_iterations); + /* Control method single step flag */ ACPI_GLOBAL(u8, acpi_gbl_cm_single_step); diff --git a/drivers/acpi/acpica/dscontrol.c b/drivers/acpi/acpica/dscontrol.c index 39da9da62bbf..435fc16e2f83 100644 --- a/drivers/acpi/acpica/dscontrol.c +++ b/drivers/acpi/acpica/dscontrol.c @@ -212,7 +212,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, */ control_state->control.loop_count++; if (control_state->control.loop_count > - ACPI_MAX_LOOP_ITERATIONS) { + acpi_gbl_max_loop_iterations) { status = AE_AML_INFINITE_LOOP; break; } diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index 7f897c63aa5b..28ab3a1d5ec1 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -207,6 +207,7 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_debugger_configuration = DEBUGGER_THREADING; acpi_gbl_osi_mutex = NULL; acpi_gbl_reg_methods_executed = FALSE; + acpi_gbl_max_loop_iterations = 0xFFFF; /* Hardware oriented */ diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 03aacfb3e98b..e11611ca72a4 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -136,10 +136,6 @@ #define ACPI_ROOT_TABLE_SIZE_INCREMENT 4 -/* Maximum number of While() loop iterations before forced abort */ - -#define ACPI_MAX_LOOP_ITERATIONS 0xFFFF - /* Maximum sleep allowed via Sleep() operator */ #define ACPI_MAX_SLEEP 2000 /* 2000 millisec == two seconds */ -- cgit v1.2.3 From f8fb4c383e7342731b77693edde9c6ea02ab0365 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 25 Aug 2015 10:30:19 +0800 Subject: ACPICA: Debugger: Split debugger initialization/termination APIs ACPICA commit 7a3f22baab000b186779dac64ad71d9776b8f432 It is likely that the debugger is enabled only when a userspace program explicitly tells a kernel to do so, so it shouldn't be initialized as early as current implementation. The only tool requiring ACPI_DEBUGGER is acpiexec, so acpiexec need to call the new APIs by itself. And BSD developers may also get notified to invoke the APIs for DDB enabling. Lv Zheng. This patch doesn't affect Linux kernel as debugger is currently not enabled in the Linux kernel. Link: https://github.com/acpica/acpica/commit/7a3f22ba Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acdebug.h | 4 ---- drivers/acpi/acpica/utxface.c | 7 ------- drivers/acpi/acpica/utxfinit.c | 11 ----------- include/acpi/acpixf.h | 3 +++ 4 files changed, 3 insertions(+), 22 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index b5a9c5126209..447f6d3b0c81 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -77,10 +77,6 @@ struct acpi_db_execute_walk { /* * dbxface - external debugger interfaces */ -acpi_status acpi_db_initialize(void); - -void acpi_db_terminate(void); - acpi_status acpi_db_single_step(struct acpi_walk_state *walk_state, union acpi_parse_object *op, u32 op_type); diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index c2bd5e2485a4..4f332815db00 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -92,13 +92,6 @@ acpi_status __init acpi_terminate(void) acpi_ut_mutex_terminate(); -#ifdef ACPI_DEBUGGER - - /* Shut down the debugger */ - - acpi_db_terminate(); -#endif - /* Now we can shutdown the OS-dependent layer */ status = acpi_os_terminate(); diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c index 42a32a66ef22..a7137ec28447 100644 --- a/drivers/acpi/acpica/utxfinit.c +++ b/drivers/acpi/acpica/utxfinit.c @@ -124,17 +124,6 @@ acpi_status __init acpi_initialize_subsystem(void) return_ACPI_STATUS(status); } - /* If configured, initialize the AML debugger */ - -#ifdef ACPI_DEBUGGER - status = acpi_db_initialize(); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "During Debugger initialization")); - return_ACPI_STATUS(status); - } -#endif - return_ACPI_STATUS(AE_OK); } diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index f2e232717770..d3d7ea051275 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -917,6 +917,9 @@ ACPI_DBG_DEPENDENT_RETURN_VOID(void ACPI_APP_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(1) void ACPI_INTERNAL_VAR_XFACE acpi_log_error(const char *format, ...)) + acpi_status acpi_initialize_debugger(void); + +void acpi_terminate_debugger(void); /* * Divergences -- cgit v1.2.3 From 1bdc63bf05096afac4b1e5361417fb730d77dfc7 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 25 Aug 2015 10:30:27 +0800 Subject: ACPICA: Disassembler: Cleanup acpi_gbl_db_opt_disasm ACPICA commit 969989cf7f85e2a2a0cd048cd25fc706246a48a2 This patch cleans up the following global variable - acpi_gbl_db_opt_disasm: The setting is used to control the full disassembly feature for iasl. ACPI debugger (acpiexec) shall have nothing to do with it. Actually, acpiexec never links to ad_aml_disassemble(). This patch thus renames this global option to acpi_gbl_dm_opt_disasm and removes all acpiexec and debugger references on it. Lv Zheng. This patch doesn't affect Linux kernel. Link: https://github.com/acpica/acpica/commit/969989cf Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 03c443b87c76..0007eb7f3a85 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -313,7 +313,7 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_ignore_noop_operator, FALSE); ACPI_INIT_GLOBAL(u8, acpi_gbl_cstyle_disassembly, TRUE); ACPI_INIT_GLOBAL(u8, acpi_gbl_force_aml_disassembly, FALSE); -ACPI_GLOBAL(u8, acpi_gbl_db_opt_disasm); +ACPI_GLOBAL(u8, acpi_gbl_dm_opt_disasm); ACPI_GLOBAL(u8, acpi_gbl_dm_opt_listing); ACPI_GLOBAL(u8, acpi_gbl_db_opt_verbose); ACPI_GLOBAL(u8, acpi_gbl_num_external_methods); -- cgit v1.2.3 From a2352db584d6402c044a07b5b252b7f133ab70cf Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 25 Aug 2015 10:30:34 +0800 Subject: ACPICA: Disassembler: Cleanup acpi_gbl_db_opt_verbose acpiexec usage ACPICA commit 42d7ad7bfb1cfb95183c1386c77509f2036f521d When acpi_gbl_db_opt_verbose is used in acpi_dm_descending_op() (invoked by acpi_dm_disassemble()), it is actually exported by the disassembler but used by the debugger to distinguish the output of the disassembler for different debugger commands. It is by default TRUE but is set to FALSE for control method disassembly command - "disassemble". So it's initialization should be a part of the ACPI_DISASSEMBLER conditioned code. This patch uses ACPI_INIT_GLOBAL to achieve a clean manner so that when ACPI_DISASSEMBLER is not defined, ACPI_DEBUGGER conditioned code needn't link to this option. Since it is a disassembler exported variable, it is renamed to acpi_gbl_dm_opt_Verbose in this patch. As VERBOSE_PRINT() macro has only one user, this patch also removes the definition of this macro. Lv Zheng. This patch doesn't affect Linux kernel. Link: https://github.com/acpica/acpica/commit/42d7ad7b Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acdebug.h | 3 --- drivers/acpi/acpica/acglobal.h | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 447f6d3b0c81..eb2e926d8218 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -67,9 +67,6 @@ struct acpi_db_execute_walk { }; #define PARAM_LIST(pl) pl -#define DBTEST_OUTPUT_LEVEL(lvl) if (acpi_gbl_db_opt_verbose) -#define VERBOSE_PRINT(fp) DBTEST_OUTPUT_LEVEL(lvl) {\ - acpi_os_printf PARAM_LIST(fp);} #define EX_NO_SINGLE_STEP 1 #define EX_SINGLE_STEP 2 diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 0007eb7f3a85..09f37b516808 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -312,10 +312,10 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_no_resource_disassembly, FALSE); ACPI_INIT_GLOBAL(u8, acpi_gbl_ignore_noop_operator, FALSE); ACPI_INIT_GLOBAL(u8, acpi_gbl_cstyle_disassembly, TRUE); ACPI_INIT_GLOBAL(u8, acpi_gbl_force_aml_disassembly, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_dm_opt_verbose, TRUE); ACPI_GLOBAL(u8, acpi_gbl_dm_opt_disasm); ACPI_GLOBAL(u8, acpi_gbl_dm_opt_listing); -ACPI_GLOBAL(u8, acpi_gbl_db_opt_verbose); ACPI_GLOBAL(u8, acpi_gbl_num_external_methods); ACPI_GLOBAL(u32, acpi_gbl_resolved_external_methods); ACPI_GLOBAL(struct acpi_external_list *, acpi_gbl_external_list); -- cgit v1.2.3 From 2e5321cb62ca1b29941d483c21b41f71b4dc8c78 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 25 Aug 2015 10:30:41 +0800 Subject: ACPICA: Debugger: Cleanup debugging outputs to dump name path without trailing underscores ACPICA commit 51a49c2fb4a73f302a6df2b8ddc1350dd261684d It is better to use unified ASL path name to interact with the developers. There are following acpi_ns_build_normalized_pathname() users invoking it for debugging purposes (acpiexec test results are attached): 1. acpi_ut_display_init_pathname (acpi_ns_handle_to_pathname): --------------------------------------------- Initializing Region \_SB.H_EC.ECF2 --------------------------------------------- 2. acpi_ns_print_node_pathname (acpi_ns_handle_to_pathname): --------------------------------------------- - ex \_SB.H_EC._STA Evaluating \_SB.H_EC._STA --------------------------------------------- 3. acpi_ds_print_node_pathname (acpi_ns_handle_to_pathname): --------------------------------------------- - level 211b console - execute \M1 ... **** Exception AE_AML_UNINITIALIZED_ARG during execution of method [\M1] (Node 009CB6B8) --------------------------------------------- 4. acpi_ex_dump_reference_obj (acpi_ns_handle_to_pathname): --------------------------------------------- - dump \_TZ.FAN4._PR0 ... [00] 00835E98 [Object Reference] Type [Named Object] 05 00828878 \_TZ.FN04 --------------------------------------------- 5. acpi_db_bus_walk (acpi_ns_handle_to_pathname): --------------------------------------------- - businfo \_SB.PCI0 Type 6 ... --------------------------------------------- 6. acpi_db_walk_and_match_name (acpi_ns_handle_to_pathname): --------------------------------------------- - find _PR0 \_TZ.FAN4._PR0 Package 002D8DF8 01 Elements 01 --------------------------------------------- 7. acpi_db_walk_for_specific_objects (acpi_ns_handle_to_pathname): --------------------------------------------- - methods ... \_SB.PCI0._PRT Method 0026D918 01 Args 0 Len 0005 Aml 0026B199 ... --------------------------------------------- 8. acpi_db_decode_and_dispaly_object (acpi_get_name): --------------------------------------------- - gpes Block 0 - Info 003AC7B0 device_node 003A0E08 [\_GPE] - FADT-defined GPE block ... --------------------------------------------- 9. acpi_db_display_gpes (acpi_get_name): --------------------------------------------- - dump \_GPE Object (003A0E08) Pathname: \_GPE --------------------------------------------- 10.ae_miscellaneous_tests (acpi_get_name): No output available This patch cleans up all of the above usages. ACPICA BZ 1178, Lv Zheng. Linux kernel's ACPICA debugging messages may also be changed. Link: https://github.com/acpica/acpica/commit/51a49c2f Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/dsdebug.c | 2 +- drivers/acpi/acpica/exdump.c | 2 +- drivers/acpi/acpica/nsutils.c | 2 +- drivers/acpi/acpica/utmisc.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/dsdebug.c b/drivers/acpi/acpica/dsdebug.c index a651d30133d0..309556efc553 100644 --- a/drivers/acpi/acpica/dsdebug.c +++ b/drivers/acpi/acpica/dsdebug.c @@ -89,7 +89,7 @@ acpi_ds_print_node_pathname(struct acpi_namespace_node *node, buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_ns_handle_to_pathname(node, &buffer, FALSE); + status = acpi_ns_handle_to_pathname(node, &buffer, TRUE); if (ACPI_SUCCESS(status)) { if (message) { ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "%s ", diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index b6495fb552f0..d836f888bb16 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -996,7 +996,7 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) acpi_os_printf(" %p ", obj_desc->reference.node); status = acpi_ns_handle_to_pathname(obj_desc->reference.node, - &ret_buf, FALSE); + &ret_buf, TRUE); if (ACPI_FAILURE(status)) { acpi_os_printf(" Could not convert name to pathname\n"); } else { diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index d1261fe374d5..de325ae04ce1 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -83,7 +83,7 @@ acpi_ns_print_node_pathname(struct acpi_namespace_node *node, buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_ns_handle_to_pathname(node, &buffer, FALSE); + status = acpi_ns_handle_to_pathname(node, &buffer, TRUE); if (ACPI_SUCCESS(status)) { if (message) { acpi_os_printf("%s ", message); diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 517a5ec47742..bd4443bdcbad 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -376,7 +376,7 @@ acpi_ut_display_init_pathname(u8 type, /* Get the full pathname to the node */ buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_ns_handle_to_pathname(obj_handle, &buffer, FALSE); + status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE); if (ACPI_FAILURE(status)) { return; } -- cgit v1.2.3 From 7dc59dc938f034c69dcf9080d45b936882b7ffa3 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 10 Aug 2015 19:56:48 +0300 Subject: device property: attach 'else if' to the proper 'if' Obviously in the current place the 'else' keyword is redundant, though it seems quite correct when we check if nval is in allowed range. Reattach the condition branch there. Signed-off-by: Andy Shevchenko Reviewed-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- drivers/acpi/property.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 7836e2e980f4..6d99450549c5 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -528,13 +528,14 @@ int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, if (!val) return obj->package.count; - else if (nval <= 0) - return -EINVAL; if (nval > obj->package.count) return -EOVERFLOW; + else if (nval <= 0) + return -EINVAL; items = obj->package.elements; + switch (proptype) { case DEV_PROP_U8: ret = acpi_copy_property_array_u8(items, (u8 *)val, nval); -- cgit v1.2.3 From 5d0ddfebb93069061880fc57ee4ba7246bd1e1ee Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 21 Aug 2015 15:36:23 +0800 Subject: ACPI, PCI: Penalize legacy IRQ used by ACPI SCI Nick Meier reported a regression with HyperV that " After rebooting the VM, the following messages are logged in syslog when trying to load the tulip driver: tulip: Linux Tulip drivers version 1.1.15 (Feb 27, 2007) tulip: 0000:00:0a.0: PCI INT A: failed to register GSI tulip: Cannot enable tulip board #0, aborting tulip: probe of 0000:00:0a.0 failed with error -16 Errors occur in 3.19.0 kernel Works in 3.17 kernel. " According to the ACPI dump file posted by Nick at https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1440072 The ACPI MADT table includes an interrupt source overridden entry for ACPI SCI: [236h 0566 1] Subtable Type : 02 [237h 0567 1] Length : 0A [238h 0568 1] Bus : 00 [239h 0569 1] Source : 09 [23Ah 0570 4] Interrupt : 00000009 [23Eh 0574 2] Flags (decoded below) : 000D Polarity : 1 Trigger Mode : 3 And in DSDT table, we have _PRT method to define PCI interrupts, which eventually goes to: Name (PRSA, ResourceTemplate () { IRQ (Level, ActiveLow, Shared, ) {3,4,5,7,9,10,11,12,14,15} }) Name (PRSB, ResourceTemplate () { IRQ (Level, ActiveLow, Shared, ) {3,4,5,7,9,10,11,12,14,15} }) Name (PRSC, ResourceTemplate () { IRQ (Level, ActiveLow, Shared, ) {3,4,5,7,9,10,11,12,14,15} }) Name (PRSD, ResourceTemplate () { IRQ (Level, ActiveLow, Shared, ) {3,4,5,7,9,10,11,12,14,15} }) According to the MADT and DSDT tables, IRQ 9 may be used for: 1) ACPI SCI in level, high mode 2) PCI legacy IRQ in level, low mode So there's a conflict in polarity setting for IRQ 9. Prior to commit cd68f6bd53cf ("x86, irq, acpi: Get rid of special handling of GSI for ACPI SCI"), ACPI SCI is handled specially and there's no check for conflicts between ACPI SCI and PCI legagy IRQ. And it seems that the HyperV hypervisor doesn't make use of the polarity configuration in IOAPIC entry, so it just works. Commit cd68f6bd53cf gets rid of the specially handling of ACPI SCI, and then the pin attribute checking code discloses the conflicts between ACPI SCI and PCI legacy IRQ on HyperV virtual machine, and rejects the request to assign IRQ9 to PCI devices. So penalize legacy IRQ used by ACPI SCI and mark it unusable if ACPI SCI attributes conflict with PCI IRQ attributes. Please refer to following links for more information: https://bugzilla.kernel.org/show_bug.cgi?id=101301 https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1440072 Fixes: cd68f6bd53cf ("x86, irq, acpi: Get rid of special handling of GSI for ACPI SCI") Reported-and-tested-by: Nick Meier Acked-by: Thomas Gleixner Cc: 3.19+ # 3.19+ Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- arch/x86/kernel/acpi/boot.c | 1 + drivers/acpi/pci_link.c | 16 ++++++++++++++++ include/linux/acpi.h | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index e49ee24da85e..9393896717d0 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -445,6 +445,7 @@ static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK; mp_override_legacy_irq(bus_irq, polarity, trigger, gsi); + acpi_penalize_sci_irq(bus_irq, trigger, polarity); /* * stash over-ride to indicate we've been here diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index cfd7581cc19f..b09ad554430a 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -825,6 +825,22 @@ void acpi_penalize_isa_irq(int irq, int active) } } +/* + * Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict with + * PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be use for + * PCI IRQs. + */ +void acpi_penalize_sci_irq(int irq, int trigger, int polarity) +{ + if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) { + if (trigger != ACPI_MADT_TRIGGER_LEVEL || + polarity != ACPI_MADT_POLARITY_ACTIVE_LOW) + acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_ALWAYS; + else + acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING; + } +} + /* * Over-ride default table to reserve additional IRQs for use by ISA * e.g. acpi_irq_isa=5 diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d2445fa9999f..0b2394f61af4 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -221,7 +221,7 @@ struct pci_dev; int acpi_pci_irq_enable (struct pci_dev *dev); void acpi_penalize_isa_irq(int irq, int active); - +void acpi_penalize_sci_irq(int irq, int trigger, int polarity); void acpi_pci_irq_disable (struct pci_dev *dev); extern int ec_read(u8 addr, u8 *val); -- cgit v1.2.3 From b00855aecbb166428c67b26e1bfeb675463a0212 Mon Sep 17 00:00:00 2001 From: Srinidhi Kasagar Date: Thu, 27 Aug 2015 21:30:55 +0530 Subject: ACPI / LPSS: Ignore 10ms delay for Braswell LPSS devices in Braswell does not need the default 10ms d3_delay imposed by PCI specification. Removing this unnecessary delay significantly reduces the resume time approximately upto 200ms on this platform. Signed-off-by: Srinidhi Kasagar Acked-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_lpss.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 46b58abb08c5..10020e04f574 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -60,6 +60,7 @@ ACPI_MODULE_NAME("acpi_lpss"); #define LPSS_CLK_DIVIDER BIT(2) #define LPSS_LTR BIT(3) #define LPSS_SAVE_CTX BIT(4) +#define LPSS_NO_D3_DELAY BIT(5) struct lpss_private_data; @@ -156,6 +157,10 @@ static const struct lpss_device_desc byt_pwm_dev_desc = { .flags = LPSS_SAVE_CTX, }; +static const struct lpss_device_desc bsw_pwm_dev_desc = { + .flags = LPSS_SAVE_CTX | LPSS_NO_D3_DELAY, +}; + static const struct lpss_device_desc byt_uart_dev_desc = { .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, .clk_con_id = "baudclk", @@ -163,6 +168,14 @@ static const struct lpss_device_desc byt_uart_dev_desc = { .setup = lpss_uart_setup, }; +static const struct lpss_device_desc bsw_uart_dev_desc = { + .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX + | LPSS_NO_D3_DELAY, + .clk_con_id = "baudclk", + .prv_offset = 0x800, + .setup = lpss_uart_setup, +}; + static const struct lpss_device_desc byt_spi_dev_desc = { .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, .prv_offset = 0x400, @@ -178,8 +191,15 @@ static const struct lpss_device_desc byt_i2c_dev_desc = { .setup = byt_i2c_setup, }; +static const struct lpss_device_desc bsw_i2c_dev_desc = { + .flags = LPSS_CLK | LPSS_SAVE_CTX | LPSS_NO_D3_DELAY, + .prv_offset = 0x800, + .setup = byt_i2c_setup, +}; + static struct lpss_device_desc bsw_spi_dev_desc = { - .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, + .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX + | LPSS_NO_D3_DELAY, .prv_offset = 0x400, .setup = lpss_deassert_reset, }; @@ -214,11 +234,12 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { { "INT33FC", }, /* Braswell LPSS devices */ - { "80862288", LPSS_ADDR(byt_pwm_dev_desc) }, - { "8086228A", LPSS_ADDR(byt_uart_dev_desc) }, + { "80862288", LPSS_ADDR(bsw_pwm_dev_desc) }, + { "8086228A", LPSS_ADDR(bsw_uart_dev_desc) }, { "8086228E", LPSS_ADDR(bsw_spi_dev_desc) }, - { "808622C1", LPSS_ADDR(byt_i2c_dev_desc) }, + { "808622C1", LPSS_ADDR(bsw_i2c_dev_desc) }, + /* Broadwell LPSS devices */ { "INT3430", LPSS_ADDR(lpt_dev_desc) }, { "INT3431", LPSS_ADDR(lpt_dev_desc) }, { "INT3432", LPSS_ADDR(lpt_i2c_dev_desc) }, @@ -558,9 +579,14 @@ static void acpi_lpss_restore_ctx(struct device *dev, * The following delay is needed or the subsequent write operations may * fail. The LPSS devices are actually PCI devices and the PCI spec * expects 10ms delay before the device can be accessed after D3 to D0 - * transition. + * transition. However some platforms like BSW does not need this delay. */ - msleep(10); + unsigned int delay = 10; /* default 10ms delay */ + + if (pdata->dev_desc->flags & LPSS_NO_D3_DELAY) + delay = 0; + + msleep(delay); for (i = 0; i < LPSS_PRV_REG_COUNT; i++) { unsigned long offset = i * sizeof(u32); -- cgit v1.2.3 From 6bfb7c7434f75d29241413dc7e784295ba56de98 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 3 Aug 2015 08:36:14 +0530 Subject: cpufreq: remove redundant CPUFREQ_INCOMPATIBLE notifier event What's being done from CPUFREQ_INCOMPATIBLE, can also be done with CPUFREQ_ADJUST. There is nothing special with CPUFREQ_INCOMPATIBLE notifier. Kill CPUFREQ_INCOMPATIBLE and fix its usage sites. This also updates the numbering of notifier events to remove holes. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/cpu-freq/core.txt | 7 ++----- drivers/acpi/processor_perflib.c | 2 +- drivers/cpufreq/cpufreq.c | 4 ---- drivers/cpufreq/ppc_cbe_cpufreq_pmi.c | 4 ++-- drivers/video/fbdev/pxafb.c | 1 - drivers/video/fbdev/sa1100fb.c | 1 - include/linux/cpufreq.h | 9 ++++----- 7 files changed, 9 insertions(+), 19 deletions(-) (limited to 'drivers/acpi') diff --git a/Documentation/cpu-freq/core.txt b/Documentation/cpu-freq/core.txt index 70933eadc308..ba78e7c2a069 100644 --- a/Documentation/cpu-freq/core.txt +++ b/Documentation/cpu-freq/core.txt @@ -55,16 +55,13 @@ transition notifiers. ---------------------------- These are notified when a new policy is intended to be set. Each -CPUFreq policy notifier is called three times for a policy transition: +CPUFreq policy notifier is called twice for a policy transition: 1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if they see a need for this - may it be thermal considerations or hardware limitations. -2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid - hardware failure. - -3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy +2.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy - if two hardware drivers failed to agree on a new policy before this stage, the incompatible hardware shall be shut down, and the user informed of this. diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 36b6da2918a6..91941f1cdecb 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -87,7 +87,7 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb, if (ignore_ppc) return 0; - if (event != CPUFREQ_INCOMPATIBLE) + if (event != CPUFREQ_ADJUST) return 0; mutex_lock(&performance_mutex); diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 76a26609d96b..293f47b814bf 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2206,10 +2206,6 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST, new_policy); - /* adjust if necessary - hardware incompatibility*/ - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_INCOMPATIBLE, new_policy); - /* * verify the cpu speed can be set within this limit, which might be * different to the first one diff --git a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c index d29e8da396a0..7969f7690498 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c @@ -97,8 +97,8 @@ static int pmi_notifier(struct notifier_block *nb, struct cpufreq_frequency_table *cbe_freqs; u8 node; - /* Should this really be called for CPUFREQ_ADJUST, CPUFREQ_INCOMPATIBLE - * and CPUFREQ_NOTIFY policy events?) + /* Should this really be called for CPUFREQ_ADJUST and CPUFREQ_NOTIFY + * policy events?) */ if (event == CPUFREQ_START) return 0; diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c index 7245611ec963..94813af97f09 100644 --- a/drivers/video/fbdev/pxafb.c +++ b/drivers/video/fbdev/pxafb.c @@ -1668,7 +1668,6 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data) switch (val) { case CPUFREQ_ADJUST: - case CPUFREQ_INCOMPATIBLE: pr_debug("min dma period: %d ps, " "new clock %d kHz\n", pxafb_display_dma_period(var), policy->max); diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index 89dd7e02197f..dcf774c15889 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -1042,7 +1042,6 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val, switch (val) { case CPUFREQ_ADJUST: - case CPUFREQ_INCOMPATIBLE: dev_dbg(fbi->dev, "min dma period: %d ps, " "new clock %d kHz\n", sa1100fb_min_dma_period(fbi), policy->max); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index bde1e567b3a9..bedcc90c0757 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -369,11 +369,10 @@ static inline void cpufreq_resume(void) {} /* Policy Notifiers */ #define CPUFREQ_ADJUST (0) -#define CPUFREQ_INCOMPATIBLE (1) -#define CPUFREQ_NOTIFY (2) -#define CPUFREQ_START (3) -#define CPUFREQ_CREATE_POLICY (4) -#define CPUFREQ_REMOVE_POLICY (5) +#define CPUFREQ_NOTIFY (1) +#define CPUFREQ_START (2) +#define CPUFREQ_CREATE_POLICY (3) +#define CPUFREQ_REMOVE_POLICY (4) #ifdef CONFIG_CPU_FREQ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); -- cgit v1.2.3