cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ulpi.c (9947B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * ulpi.c - USB ULPI PHY bus
      4 *
      5 * Copyright (C) 2015 Intel Corporation
      6 *
      7 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
      8 */
      9
     10#include <linux/ulpi/interface.h>
     11#include <linux/ulpi/driver.h>
     12#include <linux/ulpi/regs.h>
     13#include <linux/module.h>
     14#include <linux/slab.h>
     15#include <linux/acpi.h>
     16#include <linux/debugfs.h>
     17#include <linux/of.h>
     18#include <linux/of_device.h>
     19#include <linux/clk/clk-conf.h>
     20
     21/* -------------------------------------------------------------------------- */
     22
     23int ulpi_read(struct ulpi *ulpi, u8 addr)
     24{
     25	return ulpi->ops->read(ulpi->dev.parent, addr);
     26}
     27EXPORT_SYMBOL_GPL(ulpi_read);
     28
     29int ulpi_write(struct ulpi *ulpi, u8 addr, u8 val)
     30{
     31	return ulpi->ops->write(ulpi->dev.parent, addr, val);
     32}
     33EXPORT_SYMBOL_GPL(ulpi_write);
     34
     35/* -------------------------------------------------------------------------- */
     36
     37static int ulpi_match(struct device *dev, struct device_driver *driver)
     38{
     39	struct ulpi_driver *drv = to_ulpi_driver(driver);
     40	struct ulpi *ulpi = to_ulpi_dev(dev);
     41	const struct ulpi_device_id *id;
     42
     43	/*
     44	 * Some ULPI devices don't have a vendor id
     45	 * or provide an id_table so rely on OF match.
     46	 */
     47	if (ulpi->id.vendor == 0 || !drv->id_table)
     48		return of_driver_match_device(dev, driver);
     49
     50	for (id = drv->id_table; id->vendor; id++)
     51		if (id->vendor == ulpi->id.vendor &&
     52		    id->product == ulpi->id.product)
     53			return 1;
     54
     55	return 0;
     56}
     57
     58static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env)
     59{
     60	struct ulpi *ulpi = to_ulpi_dev(dev);
     61	int ret;
     62
     63	ret = of_device_uevent_modalias(dev, env);
     64	if (ret != -ENODEV)
     65		return ret;
     66
     67	if (add_uevent_var(env, "MODALIAS=ulpi:v%04xp%04x",
     68			   ulpi->id.vendor, ulpi->id.product))
     69		return -ENOMEM;
     70	return 0;
     71}
     72
     73static int ulpi_probe(struct device *dev)
     74{
     75	struct ulpi_driver *drv = to_ulpi_driver(dev->driver);
     76	int ret;
     77
     78	ret = of_clk_set_defaults(dev->of_node, false);
     79	if (ret < 0)
     80		return ret;
     81
     82	return drv->probe(to_ulpi_dev(dev));
     83}
     84
     85static void ulpi_remove(struct device *dev)
     86{
     87	struct ulpi_driver *drv = to_ulpi_driver(dev->driver);
     88
     89	if (drv->remove)
     90		drv->remove(to_ulpi_dev(dev));
     91}
     92
     93static struct bus_type ulpi_bus = {
     94	.name = "ulpi",
     95	.match = ulpi_match,
     96	.uevent = ulpi_uevent,
     97	.probe = ulpi_probe,
     98	.remove = ulpi_remove,
     99};
    100
    101/* -------------------------------------------------------------------------- */
    102
    103static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
    104			     char *buf)
    105{
    106	int len;
    107	struct ulpi *ulpi = to_ulpi_dev(dev);
    108
    109	len = of_device_modalias(dev, buf, PAGE_SIZE);
    110	if (len != -ENODEV)
    111		return len;
    112
    113	return sprintf(buf, "ulpi:v%04xp%04x\n",
    114		       ulpi->id.vendor, ulpi->id.product);
    115}
    116static DEVICE_ATTR_RO(modalias);
    117
    118static struct attribute *ulpi_dev_attrs[] = {
    119	&dev_attr_modalias.attr,
    120	NULL
    121};
    122
    123static const struct attribute_group ulpi_dev_attr_group = {
    124	.attrs = ulpi_dev_attrs,
    125};
    126
    127static const struct attribute_group *ulpi_dev_attr_groups[] = {
    128	&ulpi_dev_attr_group,
    129	NULL
    130};
    131
    132static void ulpi_dev_release(struct device *dev)
    133{
    134	of_node_put(dev->of_node);
    135	kfree(to_ulpi_dev(dev));
    136}
    137
    138static const struct device_type ulpi_dev_type = {
    139	.name = "ulpi_device",
    140	.groups = ulpi_dev_attr_groups,
    141	.release = ulpi_dev_release,
    142};
    143
    144/* -------------------------------------------------------------------------- */
    145
    146/**
    147 * __ulpi_register_driver - register a driver with the ULPI bus
    148 * @drv: driver being registered
    149 * @module: ends up being THIS_MODULE
    150 *
    151 * Registers a driver with the ULPI bus.
    152 */
    153int __ulpi_register_driver(struct ulpi_driver *drv, struct module *module)
    154{
    155	if (!drv->probe)
    156		return -EINVAL;
    157
    158	drv->driver.owner = module;
    159	drv->driver.bus = &ulpi_bus;
    160
    161	return driver_register(&drv->driver);
    162}
    163EXPORT_SYMBOL_GPL(__ulpi_register_driver);
    164
    165/**
    166 * ulpi_unregister_driver - unregister a driver with the ULPI bus
    167 * @drv: driver to unregister
    168 *
    169 * Unregisters a driver with the ULPI bus.
    170 */
    171void ulpi_unregister_driver(struct ulpi_driver *drv)
    172{
    173	driver_unregister(&drv->driver);
    174}
    175EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
    176
    177/* -------------------------------------------------------------------------- */
    178
    179static int ulpi_of_register(struct ulpi *ulpi)
    180{
    181	struct device_node *np = NULL, *child;
    182	struct device *parent;
    183
    184	/* Find a ulpi bus underneath the parent or the grandparent */
    185	parent = ulpi->dev.parent;
    186	if (parent->of_node)
    187		np = of_get_child_by_name(parent->of_node, "ulpi");
    188	else if (parent->parent && parent->parent->of_node)
    189		np = of_get_child_by_name(parent->parent->of_node, "ulpi");
    190	if (!np)
    191		return 0;
    192
    193	child = of_get_next_available_child(np, NULL);
    194	of_node_put(np);
    195	if (!child)
    196		return -EINVAL;
    197
    198	ulpi->dev.of_node = child;
    199
    200	return 0;
    201}
    202
    203static int ulpi_read_id(struct ulpi *ulpi)
    204{
    205	int ret;
    206
    207	/* Test the interface */
    208	ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
    209	if (ret < 0)
    210		goto err;
    211
    212	ret = ulpi_read(ulpi, ULPI_SCRATCH);
    213	if (ret < 0)
    214		return ret;
    215
    216	if (ret != 0xaa)
    217		goto err;
    218
    219	ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW);
    220	ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8;
    221
    222	ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
    223	ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
    224
    225	/* Some ULPI devices don't have a vendor id so rely on OF match */
    226	if (ulpi->id.vendor == 0)
    227		goto err;
    228
    229	request_module("ulpi:v%04xp%04x", ulpi->id.vendor, ulpi->id.product);
    230	return 0;
    231err:
    232	of_device_request_module(&ulpi->dev);
    233	return 0;
    234}
    235
    236static int ulpi_regs_read(struct seq_file *seq, void *data)
    237{
    238	struct ulpi *ulpi = seq->private;
    239
    240#define ulpi_print(name, reg) do { \
    241	int ret = ulpi_read(ulpi, reg); \
    242	if (ret < 0) \
    243		return ret; \
    244	seq_printf(seq, name " %.02x\n", ret); \
    245} while (0)
    246
    247	ulpi_print("Vendor ID Low               ", ULPI_VENDOR_ID_LOW);
    248	ulpi_print("Vendor ID High              ", ULPI_VENDOR_ID_HIGH);
    249	ulpi_print("Product ID Low              ", ULPI_PRODUCT_ID_LOW);
    250	ulpi_print("Product ID High             ", ULPI_PRODUCT_ID_HIGH);
    251	ulpi_print("Function Control            ", ULPI_FUNC_CTRL);
    252	ulpi_print("Interface Control           ", ULPI_IFC_CTRL);
    253	ulpi_print("OTG Control                 ", ULPI_OTG_CTRL);
    254	ulpi_print("USB Interrupt Enable Rising ", ULPI_USB_INT_EN_RISE);
    255	ulpi_print("USB Interrupt Enable Falling", ULPI_USB_INT_EN_FALL);
    256	ulpi_print("USB Interrupt Status        ", ULPI_USB_INT_STS);
    257	ulpi_print("USB Interrupt Latch         ", ULPI_USB_INT_LATCH);
    258	ulpi_print("Debug                       ", ULPI_DEBUG);
    259	ulpi_print("Scratch Register            ", ULPI_SCRATCH);
    260	ulpi_print("Carkit Control              ", ULPI_CARKIT_CTRL);
    261	ulpi_print("Carkit Interrupt Delay      ", ULPI_CARKIT_INT_DELAY);
    262	ulpi_print("Carkit Interrupt Enable     ", ULPI_CARKIT_INT_EN);
    263	ulpi_print("Carkit Interrupt Status     ", ULPI_CARKIT_INT_STS);
    264	ulpi_print("Carkit Interrupt Latch      ", ULPI_CARKIT_INT_LATCH);
    265	ulpi_print("Carkit Pulse Control        ", ULPI_CARKIT_PLS_CTRL);
    266	ulpi_print("Transmit Positive Width     ", ULPI_TX_POS_WIDTH);
    267	ulpi_print("Transmit Negative Width     ", ULPI_TX_NEG_WIDTH);
    268	ulpi_print("Receive Polarity Recovery   ", ULPI_POLARITY_RECOVERY);
    269
    270	return 0;
    271}
    272
    273static int ulpi_regs_open(struct inode *inode, struct file *f)
    274{
    275	struct ulpi *ulpi = inode->i_private;
    276
    277	return single_open(f, ulpi_regs_read, ulpi);
    278}
    279
    280static const struct file_operations ulpi_regs_ops = {
    281	.owner = THIS_MODULE,
    282	.open = ulpi_regs_open,
    283	.release = single_release,
    284	.read = seq_read,
    285	.llseek = seq_lseek
    286};
    287
    288#define ULPI_ROOT debugfs_lookup(KBUILD_MODNAME, NULL)
    289
    290static int ulpi_register(struct device *dev, struct ulpi *ulpi)
    291{
    292	int ret;
    293	struct dentry *root;
    294
    295	ulpi->dev.parent = dev; /* needed early for ops */
    296	ulpi->dev.bus = &ulpi_bus;
    297	ulpi->dev.type = &ulpi_dev_type;
    298	dev_set_name(&ulpi->dev, "%s.ulpi", dev_name(dev));
    299
    300	ACPI_COMPANION_SET(&ulpi->dev, ACPI_COMPANION(dev));
    301
    302	ret = ulpi_of_register(ulpi);
    303	if (ret)
    304		return ret;
    305
    306	ret = ulpi_read_id(ulpi);
    307	if (ret) {
    308		of_node_put(ulpi->dev.of_node);
    309		return ret;
    310	}
    311
    312	ret = device_register(&ulpi->dev);
    313	if (ret) {
    314		put_device(&ulpi->dev);
    315		return ret;
    316	}
    317
    318	root = debugfs_create_dir(dev_name(dev), ULPI_ROOT);
    319	debugfs_create_file("regs", 0444, root, ulpi, &ulpi_regs_ops);
    320
    321	dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n",
    322		ulpi->id.vendor, ulpi->id.product);
    323
    324	return 0;
    325}
    326
    327/**
    328 * ulpi_register_interface - instantiate new ULPI device
    329 * @dev: USB controller's device interface
    330 * @ops: ULPI register access
    331 *
    332 * Allocates and registers a ULPI device and an interface for it. Called from
    333 * the USB controller that provides the ULPI interface.
    334 */
    335struct ulpi *ulpi_register_interface(struct device *dev,
    336				     const struct ulpi_ops *ops)
    337{
    338	struct ulpi *ulpi;
    339	int ret;
    340
    341	ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL);
    342	if (!ulpi)
    343		return ERR_PTR(-ENOMEM);
    344
    345	ulpi->ops = ops;
    346
    347	ret = ulpi_register(dev, ulpi);
    348	if (ret) {
    349		kfree(ulpi);
    350		return ERR_PTR(ret);
    351	}
    352
    353	return ulpi;
    354}
    355EXPORT_SYMBOL_GPL(ulpi_register_interface);
    356
    357/**
    358 * ulpi_unregister_interface - unregister ULPI interface
    359 * @ulpi: struct ulpi_interface
    360 *
    361 * Unregisters a ULPI device and it's interface that was created with
    362 * ulpi_create_interface().
    363 */
    364void ulpi_unregister_interface(struct ulpi *ulpi)
    365{
    366	debugfs_remove_recursive(debugfs_lookup(dev_name(&ulpi->dev),
    367						ULPI_ROOT));
    368	device_unregister(&ulpi->dev);
    369}
    370EXPORT_SYMBOL_GPL(ulpi_unregister_interface);
    371
    372/* -------------------------------------------------------------------------- */
    373
    374static int __init ulpi_init(void)
    375{
    376	int ret;
    377	struct dentry *root;
    378
    379	root = debugfs_create_dir(KBUILD_MODNAME, NULL);
    380	ret = bus_register(&ulpi_bus);
    381	if (ret)
    382		debugfs_remove(root);
    383	return ret;
    384}
    385subsys_initcall(ulpi_init);
    386
    387static void __exit ulpi_exit(void)
    388{
    389	bus_unregister(&ulpi_bus);
    390	debugfs_remove_recursive(ULPI_ROOT);
    391}
    392module_exit(ulpi_exit);
    393
    394MODULE_AUTHOR("Intel Corporation");
    395MODULE_LICENSE("GPL v2");
    396MODULE_DESCRIPTION("USB ULPI PHY bus");