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

simtec-usb.c (2657B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Copyright 2004-2005 Simtec Electronics
      4//   Ben Dooks <ben@simtec.co.uk>
      5//
      6// http://www.simtec.co.uk/products/EB2410ITX/
      7//
      8// Simtec BAST and Thorcom VR1000 USB port support functions
      9
     10#define DEBUG
     11
     12#include <linux/kernel.h>
     13#include <linux/types.h>
     14#include <linux/interrupt.h>
     15#include <linux/list.h>
     16#include <linux/gpio.h>
     17#include <linux/timer.h>
     18#include <linux/init.h>
     19#include <linux/device.h>
     20#include <linux/io.h>
     21
     22#include <asm/mach/arch.h>
     23#include <asm/mach/map.h>
     24#include <asm/mach/irq.h>
     25
     26#include "gpio-samsung.h"
     27#include "irqs.h"
     28#include <asm/irq.h>
     29
     30#include <linux/platform_data/usb-ohci-s3c2410.h>
     31#include "devs.h"
     32
     33#include "bast.h"
     34#include "simtec.h"
     35
     36/* control power and monitor over-current events on various Simtec
     37 * designed boards.
     38*/
     39
     40static unsigned int power_state[2];
     41
     42static void
     43usb_simtec_powercontrol(int port, int to)
     44{
     45	pr_debug("usb_simtec_powercontrol(%d,%d)\n", port, to);
     46
     47	power_state[port] = to;
     48
     49	if (power_state[0] && power_state[1])
     50		gpio_set_value(S3C2410_GPB(4), 0);
     51	else
     52		gpio_set_value(S3C2410_GPB(4), 1);
     53}
     54
     55static irqreturn_t
     56usb_simtec_ocirq(int irq, void *pw)
     57{
     58	struct s3c2410_hcd_info *info = pw;
     59
     60	if (gpio_get_value(S3C2410_GPG(10)) == 0) {
     61		pr_debug("usb_simtec: over-current irq (oc detected)\n");
     62		s3c2410_usb_report_oc(info, 3);
     63	} else {
     64		pr_debug("usb_simtec: over-current irq (oc cleared)\n");
     65		s3c2410_usb_report_oc(info, 0);
     66	}
     67
     68	return IRQ_HANDLED;
     69}
     70
     71static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on)
     72{
     73	int ret;
     74
     75	if (on) {
     76		ret = request_irq(BAST_IRQ_USBOC, usb_simtec_ocirq,
     77				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
     78				  "USB Over-current", info);
     79		if (ret != 0) {
     80			printk(KERN_ERR "failed to request usb oc irq\n");
     81		}
     82	} else {
     83		free_irq(BAST_IRQ_USBOC, info);
     84	}
     85}
     86
     87static struct s3c2410_hcd_info usb_simtec_info __initdata = {
     88	.port[0]	= {
     89		.flags	= S3C_HCDFLG_USED
     90	},
     91	.port[1]	= {
     92		.flags	= S3C_HCDFLG_USED
     93	},
     94
     95	.power_control	= usb_simtec_powercontrol,
     96	.enable_oc	= usb_simtec_enableoc,
     97};
     98
     99
    100int __init usb_simtec_init(void)
    101{
    102	int ret;
    103
    104	printk("USB Power Control, Copyright 2004 Simtec Electronics\n");
    105
    106	ret = gpio_request(S3C2410_GPB(4), "USB power control");
    107	if (ret < 0) {
    108		pr_err("%s: failed to get GPB4\n", __func__);
    109		return ret;
    110	}
    111
    112	ret = gpio_request(S3C2410_GPG(10), "USB overcurrent");
    113	if (ret < 0) {
    114		pr_err("%s: failed to get GPG10\n", __func__);
    115		gpio_free(S3C2410_GPB(4));
    116		return ret;
    117	}
    118
    119	/* turn power on */
    120	gpio_direction_output(S3C2410_GPB(4), 1);
    121	gpio_direction_input(S3C2410_GPG(10));
    122
    123	s3c_ohci_set_platdata(&usb_simtec_info);
    124	return 0;
    125}