Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/platform/intel/pmc_atom: Export accessors to PMC registers

Export the pmc_atom_read() and pmc_atom_write() accessors to the PMC
registers. On early initcall stages the functions will return
-ENODEV, and caller has to wait when it will be available.

Additionally make absence of debugfs a non-fatal error.

The patch will be useful for the upcoming fixes regarding to the
LPSS block found on Intel BayTrail-T and Braswell.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Aubrey Li <aubrey.li@linux.intel.com>
Cc: Kumar P Mahesh <mahesh.kumar.p@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rafael J . Wysocki <rafael.j.wysocki@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1436192944-56496-2-git-send-email-andriy.shevchenko@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Andy Shevchenko and committed by
Ingo Molnar
68872eb9 1c4c7159

+38 -15
+4
arch/x86/include/asm/pmc_atom.h
··· 126 126 #define SLEEP_TYPE_MASK 0xFFFFECFF 127 127 #define SLEEP_TYPE_S5 0x1C00 128 128 #define SLEEP_ENABLE 0x2000 129 + 130 + extern int pmc_atom_read(int offset, u32 *value); 131 + extern int pmc_atom_write(int offset, u32 value); 132 + 129 133 #endif /* PMC_ATOM_H */
+34 -15
arch/x86/kernel/pmc_atom.c
··· 31 31 #ifdef CONFIG_DEBUG_FS 32 32 struct dentry *dbgfs_dir; 33 33 #endif /* CONFIG_DEBUG_FS */ 34 + bool init; 34 35 }; 35 36 36 37 static struct pmc_dev pmc_device; ··· 111 110 { 112 111 writel(val, pmc->regmap + reg_offset); 113 112 } 113 + 114 + int pmc_atom_read(int offset, u32 *value) 115 + { 116 + struct pmc_dev *pmc = &pmc_device; 117 + 118 + if (!pmc->init) 119 + return -ENODEV; 120 + 121 + *value = pmc_reg_read(pmc, offset); 122 + return 0; 123 + } 124 + EXPORT_SYMBOL_GPL(pmc_atom_read); 125 + 126 + int pmc_atom_write(int offset, u32 value) 127 + { 128 + struct pmc_dev *pmc = &pmc_device; 129 + 130 + if (!pmc->init) 131 + return -ENODEV; 132 + 133 + pmc_reg_write(pmc, offset, value); 134 + return 0; 135 + } 136 + EXPORT_SYMBOL_GPL(pmc_atom_write); 114 137 115 138 static void pmc_power_off(void) 116 139 { ··· 275 250 debugfs_remove_recursive(pmc->dbgfs_dir); 276 251 } 277 252 278 - static int pmc_dbgfs_register(struct pmc_dev *pmc, struct pci_dev *pdev) 253 + static int pmc_dbgfs_register(struct pmc_dev *pmc) 279 254 { 280 255 struct dentry *dir, *f; 281 256 ··· 287 262 288 263 f = debugfs_create_file("dev_state", S_IFREG | S_IRUGO, 289 264 dir, pmc, &pmc_dev_state_ops); 290 - if (!f) { 291 - dev_err(&pdev->dev, "dev_state register failed\n"); 265 + if (!f) 292 266 goto err; 293 - } 294 267 295 268 f = debugfs_create_file("pss_state", S_IFREG | S_IRUGO, 296 269 dir, pmc, &pmc_pss_state_ops); 297 - if (!f) { 298 - dev_err(&pdev->dev, "pss_state register failed\n"); 270 + if (!f) 299 271 goto err; 300 - } 301 272 302 273 f = debugfs_create_file("sleep_state", S_IFREG | S_IRUGO, 303 274 dir, pmc, &pmc_sleep_tmr_ops); 304 - if (!f) { 305 - dev_err(&pdev->dev, "sleep_state register failed\n"); 275 + if (!f) 306 276 goto err; 307 - } 308 277 309 278 return 0; 310 279 err: ··· 306 287 return -ENODEV; 307 288 } 308 289 #else 309 - static int pmc_dbgfs_register(struct pmc_dev *pmc, struct pci_dev *pdev) 290 + static int pmc_dbgfs_register(struct pmc_dev *pmc) 310 291 { 311 292 return 0; 312 293 } ··· 337 318 /* PMC hardware registers setup */ 338 319 pmc_hw_reg_setup(pmc); 339 320 340 - ret = pmc_dbgfs_register(pmc, pdev); 341 - if (ret) { 342 - iounmap(pmc->regmap); 343 - } 321 + ret = pmc_dbgfs_register(pmc); 322 + if (ret) 323 + dev_warn(&pdev->dev, "debugfs register failed\n"); 344 324 325 + pmc->init = true; 345 326 return ret; 346 327 } 347 328