FILE
bxtwc_tmu.c
File preview with syntax highlighting.
linux-6.19.14/drivers/platform/x86/intel/bxtwc_tmu.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Intel BXT Whiskey Cove PMIC TMU driver 4 * 5 * Copyright (C) 2016 Intel Corporation. All rights reserved. 6 * 7 * This driver adds TMU (Time Management Unit) support for Intel BXT platform. 8 * It enables the alarm wake-up functionality in the TMU unit of Whiskey Cove 9 * PMIC. 10 */ 11 12#include <linux/module.h> 13#include <linux/mod_devicetable.h> 14#include <linux/interrupt.h> 15#include <linux/platform_device.h> 16#include <linux/mfd/intel_soc_pmic.h> 17 18#define BXTWC_TMUIRQ 0x4fb6 19#define BXTWC_MIRQLVL1 0x4e0e 20#define BXTWC_MTMUIRQ_REG 0x4fb7 21#define BXTWC_MIRQLVL1_MTMU BIT(1) 22#define BXTWC_TMU_WK_ALRM BIT(1) 23#define BXTWC_TMU_SYS_ALRM BIT(2) 24#define BXTWC_TMU_ALRM_MASK (BXTWC_TMU_WK_ALRM | BXTWC_TMU_SYS_ALRM) 25#define BXTWC_TMU_ALRM_IRQ (BXTWC_TMU_WK_ALRM | BXTWC_TMU_SYS_ALRM) 26 27struct wcove_tmu { 28 int irq; 29 struct device *dev; 30 struct regmap *regmap; 31}; 32 33static irqreturn_t bxt_wcove_tmu_irq_handler(int irq, void *data) 34{ 35 struct wcove_tmu *wctmu = data; 36 unsigned int tmu_irq; 37 38 /* Read TMU interrupt reg */ 39 regmap_read(wctmu->regmap, BXTWC_TMUIRQ, &tmu_irq); 40 if (tmu_irq & BXTWC_TMU_ALRM_IRQ) { 41 /* clear TMU irq */ 42 regmap_write(wctmu->regmap, BXTWC_TMUIRQ, tmu_irq); 43 return IRQ_HANDLED; 44 } 45 return IRQ_NONE; 46} 47 48static int bxt_wcove_tmu_probe(struct platform_device *pdev) 49{ 50 struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent); 51 struct wcove_tmu *wctmu; 52 int ret; 53 54 wctmu = devm_kzalloc(&pdev->dev, sizeof(*wctmu), GFP_KERNEL); 55 if (!wctmu) 56 return -ENOMEM; 57 58 wctmu->dev = &pdev->dev; 59 wctmu->regmap = pmic->regmap; 60 61 wctmu->irq = platform_get_irq(pdev, 0); 62 if (wctmu->irq < 0) 63 return wctmu->irq; 64 65 ret = devm_request_threaded_irq(&pdev->dev, wctmu->irq, 66 NULL, bxt_wcove_tmu_irq_handler, 67 IRQF_ONESHOT, "bxt_wcove_tmu", wctmu); 68 if (ret) { 69 dev_err(&pdev->dev, "request irq failed: %d,virq: %d\n", 70 ret, wctmu->irq); 71 return ret; 72 } 73 74 /* Unmask TMU second level Wake & System alarm */ 75 regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG, 76 BXTWC_TMU_ALRM_MASK, 0); 77 78 platform_set_drvdata(pdev, wctmu); 79 return 0; 80} 81 82static void bxt_wcove_tmu_remove(struct platform_device *pdev) 83{ 84 struct wcove_tmu *wctmu = platform_get_drvdata(pdev); 85 unsigned int val; 86 87 /* Mask TMU interrupts */ 88 regmap_read(wctmu->regmap, BXTWC_MIRQLVL1, &val); 89 regmap_write(wctmu->regmap, BXTWC_MIRQLVL1, 90 val | BXTWC_MIRQLVL1_MTMU); 91 regmap_read(wctmu->regmap, BXTWC_MTMUIRQ_REG, &val); 92 regmap_write(wctmu->regmap, BXTWC_MTMUIRQ_REG, 93 val | BXTWC_TMU_ALRM_MASK); 94} 95 96#ifdef CONFIG_PM_SLEEP 97static int bxtwc_tmu_suspend(struct device *dev) 98{ 99 struct wcove_tmu *wctmu = dev_get_drvdata(dev); 100 101 enable_irq_wake(wctmu->irq); 102 return 0; 103} 104 105static int bxtwc_tmu_resume(struct device *dev) 106{ 107 struct wcove_tmu *wctmu = dev_get_drvdata(dev); 108 109 disable_irq_wake(wctmu->irq); 110 return 0; 111} 112#endif 113 114static SIMPLE_DEV_PM_OPS(bxtwc_tmu_pm_ops, bxtwc_tmu_suspend, bxtwc_tmu_resume); 115 116static const struct platform_device_id bxt_wcove_tmu_id_table[] = { 117 { .name = "bxt_wcove_tmu" }, 118 {}, 119}; 120MODULE_DEVICE_TABLE(platform, bxt_wcove_tmu_id_table); 121 122static struct platform_driver bxt_wcove_tmu_driver = { 123 .probe = bxt_wcove_tmu_probe, 124 .remove = bxt_wcove_tmu_remove, 125 .driver = { 126 .name = "bxt_wcove_tmu", 127 .pm = &bxtwc_tmu_pm_ops, 128 }, 129 .id_table = bxt_wcove_tmu_id_table, 130}; 131 132module_platform_driver(bxt_wcove_tmu_driver); 133 134MODULE_LICENSE("GPL v2"); 135MODULE_AUTHOR("Nilesh Bacchewar <nilesh.bacchewar@intel.com>"); 136MODULE_DESCRIPTION("BXT Whiskey Cove TMU Driver");
~/
Read-only file preview.