aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci/usb.c
blob: 23d2b6d9fa63bd17bd1b81ebd10673f920aaff9e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * USB
 */
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>

#include <linux/usb/musb.h>

#include <mach/common.h>
#include <mach/irqs.h>
#include <mach/cputype.h>
#include <mach/usb.h>

#define DAVINCI_USB_OTG_BASE	0x01c64000

#define DA8XX_USB0_BASE 	0x01e00000
#define DA8XX_USB1_BASE 	0x01e25000

#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
static struct musb_hdrc_eps_bits musb_eps[] = {
	{ "ep1_tx", 8, },
	{ "ep1_rx", 8, },
	{ "ep2_tx", 8, },
	{ "ep2_rx", 8, },
	{ "ep3_tx", 5, },
	{ "ep3_rx", 5, },
	{ "ep4_tx", 5, },
	{ "ep4_rx", 5, },
};

static struct musb_hdrc_config musb_config = {
	.multipoint	= true,
	.dyn_fifo	= true,
	.soft_con	= true,
	.dma		= true,

	.num_eps	= 5,
	.dma_channels	= 8,
	.ram_bits	= 10,
	.eps_bits	= musb_eps,
};

static struct musb_hdrc_platform_data usb_data = {
#if defined(CONFIG_USB_MUSB_OTG)
	/* OTG requires a Mini-AB connector */
	.mode           = MUSB_OTG,
#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
	.mode           = MUSB_PERIPHERAL,
#elif defined(CONFIG_USB_MUSB_HOST)
	.mode           = MUSB_HOST,
#endif
	.clock		= "usb",
	.config		= &musb_config,
};

static struct resource usb_resources[] = {
	{
		/* physical address */
		.start          = DAVINCI_USB_OTG_BASE,
		.end            = DAVINCI_USB_OTG_BASE + 0x5ff,
		.flags          = IORESOURCE_MEM,
	},
	{
		.start          = IRQ_USBINT,
		.flags          = IORESOURCE_IRQ,
		.name		= "mc"
	},
	{
		/* placeholder for the dedicated CPPI IRQ */
		.flags          = IORESOURCE_IRQ,
		.name		= "dma"
	},
};

static u64 usb_dmamask = DMA_BIT_MASK(32);

static struct platform_device usb_dev = {
	.name           = "musb-davinci",
	.id             = -1,
	.dev = {
		.platform_data		= &usb_data,
		.dma_mask		= &usb_dmamask,
		.coherent_dma_mask      = DMA_BIT_MASK(32),
	},
	.resource       = usb_resources,
	.num_resources  = ARRAY_SIZE(usb_resources),
};

void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms)
{
	usb_data.power = mA > 510 ? 255 : mA / 2;
	usb_data.potpgt = (potpgt_ms + 1) / 2;

	if (cpu_is_davinci_dm646x()) {
		/* Override the defaults as DM6467 uses different IRQs. */
		usb_dev.resource[1].start = IRQ_DM646X_USBINT;
		usb_dev.resource[2].start = IRQ_DM646X_USBDMAINT;
	} else	/* other devices don't have dedicated CPPI IRQ */
		usb_dev.num_resources = 2;

	platform_device_register(&usb_dev);
}

#ifdef CONFIG_ARCH_DAVINCI_DA8XX
static struct resource da8xx_usb20_resources[] = {
	{
		.start		= DA8XX_USB0_BASE,
		.end		= DA8XX_USB0_BASE + SZ_64K - 1,
		.flags		= IORESOURCE_MEM,
	},
	{
		.start		= IRQ_DA8XX_USB_INT,
		.flags		= IORESOURCE_IRQ,
		.name		= "mc",
	},
};

int __init da8xx_register_usb20(unsigned mA, unsigned potpgt)
{
	usb_data.clock  = "usb20";
	usb_data.power	= mA > 510 ? 255 : mA / 2;
	usb_data.potpgt = (potpgt + 1) / 2;

	usb_dev.resource = da8xx_usb20_resources;
	usb_dev.num_resources = ARRAY_SIZE(da8xx_usb20_resources);
	usb_dev.name = "musb-da8xx";

	return platform_device_register(&usb_dev);
}
#endif	/* CONFIG_DAVINCI_DA8XX */

#else

void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms)
{
}

#ifdef CONFIG_ARCH_DAVINCI_DA8XX
int __init da8xx_register_usb20(unsigned mA, unsigned potpgt)
{
	return 0;
}
#endif

#endif  /* CONFIG_USB_MUSB_HDRC */

#ifdef	CONFIG_ARCH_DAVINCI_DA8XX
static struct resource da8xx_usb11_resources[] = {
	[0] = {
		.start	= DA8XX_USB1_BASE,
		.end	= DA8XX_USB1_BASE + SZ_4K - 1,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= IRQ_DA8XX_IRQN,
		.end	= IRQ_DA8XX_IRQN,
		.flags	= IORESOURCE_IRQ,
	},
};

static u64 da8xx_usb11_dma_mask = DMA_BIT_MASK(32);

static struct platform_device da8xx_usb11_device = {
	.name		= "ohci",
	.id		= 0,
	.dev = {
		.dma_mask		= &da8xx_usb11_dma_mask,
		.coherent_dma_mask	= DMA_BIT_MASK(32),
	},
	.num_resources	= ARRAY_SIZE(da8xx_usb11_resources),
	.resource	= da8xx_usb11_resources,
};

int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
{
	da8xx_usb11_device.dev.platform_data = pdata;
	return platform_device_register(&da8xx_usb11_device);
}
#endif	/* CONFIG_DAVINCI_DA8XX */
an class="hl opt">, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ {"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ /* Feature Group Strings */ {"Extended Address Space Descriptor", 0} /* * All "optional" feature group strings (features that are implemented * by the host) should be implemented in the host version of * acpi_os_validate_interface and should not be added here. */ }; /******************************************************************************* * * FUNCTION: acpi_ut_osi_implementation * * PARAMETERS: walk_state - Current walk state * * RETURN: Status * * DESCRIPTION: Implementation of the _OSI predefined control method * ******************************************************************************/ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) { acpi_status status; union acpi_operand_object *string_desc; union acpi_operand_object *return_desc; u32 return_value; u32 i; ACPI_FUNCTION_TRACE(ut_osi_implementation); /* Validate the string input argument */ string_desc = walk_state->arguments[0].object; if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { return_ACPI_STATUS(AE_TYPE); } /* Create a return object */ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); if (!return_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Default return value is 0, NOT SUPPORTED */ return_value = 0; /* Compare input string to static table of supported interfaces */ for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { if (!ACPI_STRCMP(string_desc->string.pointer, acpi_interfaces_supported[i].name)) { /* * The interface is supported. * Update the osi_data if necessary. We keep track of the latest * version of Windows that has been requested by the BIOS. */ if (acpi_interfaces_supported[i].value > acpi_gbl_osi_data) { acpi_gbl_osi_data = acpi_interfaces_supported[i].value; } return_value = ACPI_UINT32_MAX; goto exit; } } /* * Did not match the string in the static table, call the host OSL to * check for a match with one of the optional strings (such as * "Module Device", "3.0 Thermal Model", etc.) */ status = acpi_os_validate_interface(string_desc->string.pointer); if (ACPI_SUCCESS(status)) { /* The interface is supported */ return_value = ACPI_UINT32_MAX; } exit: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) is %ssupported\n", string_desc->string.pointer, return_value == 0 ? "not " : "")); /* Complete the return value */ return_desc->integer.value = return_value; walk_state->return_desc = return_desc; return_ACPI_STATUS (AE_OK); } /******************************************************************************* * * FUNCTION: acpi_osi_invalidate * * PARAMETERS: interface_string * * RETURN: Status * * DESCRIPTION: invalidate string in pre-defiend _OSI string list * ******************************************************************************/ acpi_status acpi_osi_invalidate(char *interface) { int i; for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) { *acpi_interfaces_supported[i].name = '\0'; return AE_OK; } } return AE_NOT_FOUND; } /******************************************************************************* * * FUNCTION: acpi_ut_evaluate_object * * PARAMETERS: prefix_node - Starting node * Path - Path to object from starting node * expected_return_types - Bitmap of allowed return types * return_desc - Where a return value is stored * * RETURN: Status * * DESCRIPTION: Evaluates a namespace object and verifies the type of the * return object. Common code that simplifies accessing objects * that have required return objects of fixed types. * * NOTE: Internal function, no parameter validation * ******************************************************************************/ acpi_status acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, char *path, u32 expected_return_btypes, union acpi_operand_object **return_desc) { struct acpi_evaluate_info *info; acpi_status status; u32 return_btype; ACPI_FUNCTION_TRACE(ut_evaluate_object); /* Allocate the evaluation information block */ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); if (!info) { return_ACPI_STATUS(AE_NO_MEMORY); } info->prefix_node = prefix_node; info->pathname = path; /* Evaluate the object/method */ status = acpi_ns_evaluate(info); if (ACPI_FAILURE(status)) { if (status == AE_NOT_FOUND) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n", acpi_ut_get_node_name(prefix_node), path)); } else { ACPI_ERROR_METHOD("Method execution failed", prefix_node, path, status); } goto cleanup; } /* Did we get a return object? */ if (!info->return_object) { if (expected_return_btypes) { ACPI_ERROR_METHOD("No object was returned from", prefix_node, path, AE_NOT_EXIST); status = AE_NOT_EXIST; } goto cleanup; } /* Map the return object type to the bitmapped type */ switch ((info->return_object)->common.type) { case ACPI_TYPE_INTEGER: return_btype = ACPI_BTYPE_INTEGER; break; case ACPI_TYPE_BUFFER: return_btype = ACPI_BTYPE_BUFFER; break; case ACPI_TYPE_STRING: return_btype = ACPI_BTYPE_STRING; break; case ACPI_TYPE_PACKAGE: return_btype = ACPI_BTYPE_PACKAGE; break; default: return_btype = 0; break; } if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { /* * We received a return object, but one was not expected. This can * happen frequently if the "implicit return" feature is enabled. * Just delete the return object and return AE_OK. */ acpi_ut_remove_reference(info->return_object); goto cleanup; } /* Is the return object one of the expected types? */ if (!(expected_return_btypes & return_btype)) { ACPI_ERROR_METHOD("Return object type is incorrect", prefix_node, path, AE_TYPE); ACPI_ERROR((AE_INFO, "Type returned from %s was incorrect: %s, expected Btypes: 0x%X", path, acpi_ut_get_object_type_name(info->return_object), expected_return_btypes)); /* On error exit, we must delete the return object */ acpi_ut_remove_reference(info->return_object); status = AE_TYPE; goto cleanup; } /* Object type is OK, return it */ *return_desc = info->return_object; cleanup: ACPI_FREE(info); return_ACPI_STATUS(status); } /******************************************************************************* * * FUNCTION: acpi_ut_evaluate_numeric_object * * PARAMETERS: object_name - Object name to be evaluated * device_node - Node for the device * Value - Where the value is returned * * RETURN: Status * * DESCRIPTION: Evaluates a numeric namespace object for a selected device * and stores result in *Value. * * NOTE: Internal function, no parameter validation * ******************************************************************************/ acpi_status acpi_ut_evaluate_numeric_object(char *object_name, struct acpi_namespace_node *device_node, u64 *value) { union acpi_operand_object *obj_desc; acpi_status status; ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object); status = acpi_ut_evaluate_object(device_node, object_name, ACPI_BTYPE_INTEGER, &obj_desc); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Get the returned Integer */ *value = obj_desc->integer.value; /* On exit, we must delete the return object */ acpi_ut_remove_reference(obj_desc); return_ACPI_STATUS(status); } /******************************************************************************* * * FUNCTION: acpi_ut_execute_STA * * PARAMETERS: device_node - Node for the device * Flags - Where the status flags are returned * * RETURN: Status * * DESCRIPTION: Executes _STA for selected device and stores results in * *Flags. * * NOTE: Internal function, no parameter validation * ******************************************************************************/ acpi_status acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) { union acpi_operand_object *obj_desc; acpi_status status; ACPI_FUNCTION_TRACE(ut_execute_STA); status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA, ACPI_BTYPE_INTEGER, &obj_desc); if (ACPI_FAILURE(status)) { if (AE_NOT_FOUND == status) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "_STA on %4.4s was not found, assuming device is present\n", acpi_ut_get_node_name(device_node))); *flags = ACPI_UINT32_MAX; status = AE_OK; } return_ACPI_STATUS(status); } /* Extract the status flags */ *flags = (u32) obj_desc->integer.value; /* On exit, we must delete the return object */ acpi_ut_remove_reference(obj_desc); return_ACPI_STATUS(status); } /******************************************************************************* * * FUNCTION: acpi_ut_execute_power_methods * * PARAMETERS: device_node - Node for the device * method_names - Array of power method names * method_count - Number of methods to execute * out_values - Where the power method values are returned * * RETURN: Status, out_values * * DESCRIPTION: Executes the specified power methods for the device and returns * the result(s). * * NOTE: Internal function, no parameter validation * ******************************************************************************/ acpi_status acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, const char **method_names, u8 method_count, u8 *out_values) { union acpi_operand_object *obj_desc; acpi_status status; acpi_status final_status = AE_NOT_FOUND; u32 i; ACPI_FUNCTION_TRACE(ut_execute_power_methods); for (i = 0; i < method_count; i++) { /* * Execute the power method (_sx_d or _sx_w). The only allowable * return type is an Integer. */ status = acpi_ut_evaluate_object(device_node, ACPI_CAST_PTR(char, method_names[i]), ACPI_BTYPE_INTEGER, &obj_desc); if (ACPI_SUCCESS(status)) { out_values[i] = (u8)obj_desc->integer.value; /* Delete the return object */ acpi_ut_remove_reference(obj_desc); final_status = AE_OK; /* At least one value is valid */ continue; } out_values[i] = ACPI_UINT8_MAX; if (status == AE_NOT_FOUND) { continue; /* Ignore if not found */ } ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Failed %s on Device %4.4s, %s\n", ACPI_CAST_PTR(char, method_names[i]), acpi_ut_get_node_name(device_node), acpi_format_exception(status))); } return_ACPI_STATUS(final_status); }