cregit-Linux how code gets into the kernel

Release 4.14 drivers/hwtracing/intel_th/pti.c

/*
 * Intel(R) Trace Hub PTI output driver
 *
 * Copyright (C) 2014-2016 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 */


#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt

#include <linux/types.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/sizes.h>
#include <linux/printk.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/io.h>

#include "intel_th.h"
#include "pti.h"


struct pti_device {
	
void __iomem		*base;
	
struct intel_th_device	*thdev;
	
unsigned int		mode;
	
unsigned int		freeclk;
	
unsigned int		clkdiv;
	
unsigned int		patgen;
	
unsigned int		lpp_dest_mask;
	
unsigned int		lpp_dest;
};

/* map PTI widths to MODE settings of PTI_CTL register */

static const unsigned int pti_mode[] = {
	0, 4, 8, 0, 12, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
};


static int pti_width_mode(unsigned int width) { int i; for (i = 0; i < ARRAY_SIZE(pti_mode); i++) if (pti_mode[i] == width) return i; return -EINVAL; }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin45100.00%1100.00%
Total45100.00%1100.00%


static ssize_t mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pti_device *pti = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%d\n", pti_mode[pti->mode]); }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin47100.00%1100.00%
Total47100.00%1100.00%


static ssize_t mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct pti_device *pti = dev_get_drvdata(dev); unsigned long val; int ret; ret = kstrtoul(buf, 10, &val); if (ret) return ret; ret = pti_width_mode(val); if (ret < 0) return ret; pti->mode = ret; return size; }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin85100.00%1100.00%
Total85100.00%1100.00%

static DEVICE_ATTR_RW(mode);
static ssize_t freerunning_clock_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pti_device *pti = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%d\n", pti->freeclk); }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin44100.00%1100.00%
Total44100.00%1100.00%


static ssize_t freerunning_clock_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct pti_device *pti = dev_get_drvdata(dev); unsigned long val; int ret; ret = kstrtoul(buf, 10, &val); if (ret) return ret; pti->freeclk = !!val; return size; }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin71100.00%1100.00%
Total71100.00%1100.00%

static DEVICE_ATTR_RW(freerunning_clock);
static ssize_t clock_divider_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pti_device *pti = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%d\n", 1u << pti->clkdiv); }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin46100.00%1100.00%
Total46100.00%1100.00%


static ssize_t clock_divider_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct pti_device *pti = dev_get_drvdata(dev); unsigned long val; int ret; ret = kstrtoul(buf, 10, &val); if (ret) return ret; if (!is_power_of_2(val) || val > 8 || !val) return -EINVAL; pti->clkdiv = val; return size; }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin88100.00%1100.00%
Total88100.00%1100.00%

static DEVICE_ATTR_RW(clock_divider); static struct attribute *pti_output_attrs[] = { &dev_attr_mode.attr, &dev_attr_freerunning_clock.attr, &dev_attr_clock_divider.attr, NULL, }; static struct attribute_group pti_output_group = { .attrs = pti_output_attrs, };
static int intel_th_pti_activate(struct intel_th_device *thdev) { struct pti_device *pti = dev_get_drvdata(&thdev->dev); u32 ctl = PTI_EN; if (pti->patgen) ctl |= pti->patgen << __ffs(PTI_PATGENMODE); if (pti->freeclk) ctl |= PTI_FCEN; ctl |= pti->mode << __ffs(PTI_MODE); ctl |= pti->clkdiv << __ffs(PTI_CLKDIV); ctl |= pti->lpp_dest << __ffs(LPP_DEST); iowrite32(ctl, pti->base + REG_PTI_CTL); intel_th_trace_enable(thdev); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin108100.00%2100.00%
Total108100.00%2100.00%


static void intel_th_pti_deactivate(struct intel_th_device *thdev) { struct pti_device *pti = dev_get_drvdata(&thdev->dev); intel_th_trace_disable(thdev); iowrite32(0, pti->base + REG_PTI_CTL); }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin40100.00%1100.00%
Total40100.00%1100.00%


static void read_hw_config(struct pti_device *pti) { u32 ctl = ioread32(pti->base + REG_PTI_CTL); pti->mode = (ctl & PTI_MODE) >> __ffs(PTI_MODE); pti->clkdiv = (ctl & PTI_CLKDIV) >> __ffs(PTI_CLKDIV); pti->freeclk = !!(ctl & PTI_FCEN); if (!pti_mode[pti->mode]) pti->mode = pti_width_mode(4); if (!pti->clkdiv) pti->clkdiv = 1; if (pti->thdev->output.type == GTH_LPP) { if (ctl & LPP_PTIPRESENT) pti->lpp_dest_mask |= LPP_DEST_PTI; if (ctl & LPP_BSSBPRESENT) pti->lpp_dest_mask |= LPP_DEST_EXI; if (ctl & LPP_DEST) pti->lpp_dest = 1; } }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin147100.00%2100.00%
Total147100.00%2100.00%


static int intel_th_pti_probe(struct intel_th_device *thdev) { struct device *dev = &thdev->dev; struct resource *res; struct pti_device *pti; void __iomem *base; res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; base = devm_ioremap(dev, res->start, resource_size(res)); if (!base) return -ENOMEM; pti = devm_kzalloc(dev, sizeof(*pti), GFP_KERNEL); if (!pti) return -ENOMEM; pti->thdev = thdev; pti->base = base; read_hw_config(pti); dev_set_drvdata(dev, pti); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin12997.73%150.00%
Dan Carpenter32.27%150.00%
Total132100.00%2100.00%


static void intel_th_pti_remove(struct intel_th_device *thdev) { }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin10100.00%2100.00%
Total10100.00%2100.00%

static struct intel_th_driver intel_th_pti_driver = { .probe = intel_th_pti_probe, .remove = intel_th_pti_remove, .activate = intel_th_pti_activate, .deactivate = intel_th_pti_deactivate, .attr_group = &pti_output_group, .driver = { .name = "pti", .owner = THIS_MODULE, }, }; static const char * const lpp_dest_str[] = { "pti", "exi" };
static ssize_t lpp_dest_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pti_device *pti = dev_get_drvdata(dev); ssize_t ret = 0; int i; for (i = ARRAY_SIZE(lpp_dest_str) - 1; i >= 0; i--) { const char *fmt = pti->lpp_dest == i ? "[%s] " : "%s "; if (!(pti->lpp_dest_mask & BIT(i))) continue; ret += scnprintf(buf + ret, PAGE_SIZE - ret, fmt, lpp_dest_str[i]); } if (ret) buf[ret - 1] = '\n'; return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin124100.00%1100.00%
Total124100.00%1100.00%


static ssize_t lpp_dest_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct pti_device *pti = dev_get_drvdata(dev); ssize_t ret = -EINVAL; int i; for (i = 0; i < ARRAY_SIZE(lpp_dest_str); i++) if (sysfs_streq(buf, lpp_dest_str[i])) break; if (i < ARRAY_SIZE(lpp_dest_str) && pti->lpp_dest_mask & BIT(i)) { pti->lpp_dest = i; ret = size; } return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin105100.00%1100.00%
Total105100.00%1100.00%

static DEVICE_ATTR_RW(lpp_dest); static struct attribute *lpp_output_attrs[] = { &dev_attr_mode.attr, &dev_attr_freerunning_clock.attr, &dev_attr_clock_divider.attr, &dev_attr_lpp_dest.attr, NULL, }; static struct attribute_group lpp_output_group = { .attrs = lpp_output_attrs, }; static struct intel_th_driver intel_th_lpp_driver = { .probe = intel_th_pti_probe, .remove = intel_th_pti_remove, .activate = intel_th_pti_activate, .deactivate = intel_th_pti_deactivate, .attr_group = &lpp_output_group, .driver = { .name = "lpp", .owner = THIS_MODULE, }, };
static int __init intel_th_pti_lpp_init(void) { int err; err = intel_th_driver_register(&intel_th_pti_driver); if (err) return err; err = intel_th_driver_register(&intel_th_lpp_driver); if (err) { intel_th_driver_unregister(&intel_th_pti_driver); return err; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin53100.00%2100.00%
Total53100.00%2100.00%

module_init(intel_th_pti_lpp_init);
static void __exit intel_th_pti_lpp_exit(void) { intel_th_driver_unregister(&intel_th_pti_driver); intel_th_driver_unregister(&intel_th_lpp_driver); }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin21100.00%2100.00%
Total21100.00%2100.00%

module_exit(intel_th_pti_lpp_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Intel(R) Trace Hub PTI/LPP output driver"); MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>");

Overall Contributors

PersonTokensPropCommitsCommitProp
Alexander Shishkin152299.80%375.00%
Dan Carpenter30.20%125.00%
Total1525100.00%4100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.