drivers/usb/host/ehci-ps3.c

Source file repositories/reference/linux-study-clean/drivers/usb/host/ehci-ps3.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/host/ehci-ps3.c
Extension
.c
Size
6372 bytes
Lines
255
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 *  PS3 EHCI Host Controller driver
 *
 *  Copyright (C) 2006 Sony Computer Entertainment Inc.
 *  Copyright 2006 Sony Corp.
 */

#include <asm/firmware.h>
#include <asm/ps3.h>

static void ps3_ehci_setup_insnreg(struct ehci_hcd *ehci)
{
	/* PS3 HC internal setup register offsets. */

	enum ps3_ehci_hc_insnreg {
		ps3_ehci_hc_insnreg01 = 0x084,
		ps3_ehci_hc_insnreg02 = 0x088,
		ps3_ehci_hc_insnreg03 = 0x08c,
	};

	/* PS3 EHCI HC errata fix 316 - The PS3 EHCI HC will reset its
	 * internal INSNREGXX setup regs back to the chip default values
	 * on Host Controller Reset (CMD_RESET) or Light Host Controller
	 * Reset (CMD_LRESET).  The work-around for this is for the HC
	 * driver to re-initialise these regs when ever the HC is reset.
	 */

	/* Set burst transfer counts to 256 out, 32 in. */

	writel_be(0x01000020, (void __iomem *)ehci->regs +
		ps3_ehci_hc_insnreg01);

	/* Enable burst transfer counts. */

	writel_be(0x00000001, (void __iomem *)ehci->regs +
		ps3_ehci_hc_insnreg03);
}

static int ps3_ehci_hc_reset(struct usb_hcd *hcd)
{
	int result;
	struct ehci_hcd *ehci = hcd_to_ehci(hcd);

	ehci->big_endian_mmio = 1;
	ehci->caps = hcd->regs;

	result = ehci_setup(hcd);
	if (result)
		return result;

	ps3_ehci_setup_insnreg(ehci);

	return result;
}

static const struct hc_driver ps3_ehci_hc_driver = {
	.description		= hcd_name,
	.product_desc		= "PS3 EHCI Host Controller",
	.hcd_priv_size		= sizeof(struct ehci_hcd),
	.irq			= ehci_irq,
	.flags			= HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,
	.reset			= ps3_ehci_hc_reset,
	.start			= ehci_run,
	.stop			= ehci_stop,
	.shutdown		= ehci_shutdown,
	.urb_enqueue		= ehci_urb_enqueue,
	.urb_dequeue		= ehci_urb_dequeue,
	.endpoint_disable	= ehci_endpoint_disable,
	.endpoint_reset		= ehci_endpoint_reset,
	.get_frame_number	= ehci_get_frame,
	.hub_status_data	= ehci_hub_status_data,
	.hub_control		= ehci_hub_control,
#if defined(CONFIG_PM)
	.bus_suspend		= ehci_bus_suspend,
	.bus_resume		= ehci_bus_resume,
#endif
	.relinquish_port	= ehci_relinquish_port,
	.port_handed_over	= ehci_port_handed_over,

	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
};

static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
{
	int result;
	struct usb_hcd *hcd;
	unsigned int virq;
	static u64 dummy_mask;

Annotation

Implementation Notes