|
@@ -226,3 +226,125 @@ static irqreturn_t usbhsf_interrupt(int irq, void *data)
|
|
{
|
|
{
|
|
struct platform_device *pdev = data;
|
|
struct platform_device *pdev = data;
|
|
|
|
|
|
|
|
+ renesas_usbhs_call_notify_hotplug(pdev);
|
|
|
|
+
|
|
|
|
+ return IRQ_HANDLED;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void usbhsf_hardware_exit(struct platform_device *pdev)
|
|
|
|
+{
|
|
|
|
+ struct usbhsf_private *priv = usbhsf_get_priv(pdev);
|
|
|
|
+
|
|
|
|
+ if (!IS_ERR(priv->phy))
|
|
|
|
+ clk_put(priv->phy);
|
|
|
|
+ if (!IS_ERR(priv->usb24))
|
|
|
|
+ clk_put(priv->usb24);
|
|
|
|
+ if (!IS_ERR(priv->pci))
|
|
|
|
+ clk_put(priv->pci);
|
|
|
|
+ if (!IS_ERR(priv->host))
|
|
|
|
+ clk_put(priv->host);
|
|
|
|
+ if (!IS_ERR(priv->func))
|
|
|
|
+ clk_put(priv->func);
|
|
|
|
+ if (priv->usbh_base)
|
|
|
|
+ iounmap(priv->usbh_base);
|
|
|
|
+
|
|
|
|
+ priv->phy = NULL;
|
|
|
|
+ priv->usb24 = NULL;
|
|
|
|
+ priv->pci = NULL;
|
|
|
|
+ priv->host = NULL;
|
|
|
|
+ priv->func = NULL;
|
|
|
|
+ priv->usbh_base = NULL;
|
|
|
|
+
|
|
|
|
+ free_irq(IRQ7, pdev);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int usbhsf_hardware_init(struct platform_device *pdev)
|
|
|
|
+{
|
|
|
|
+ struct usbhsf_private *priv = usbhsf_get_priv(pdev);
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ priv->phy = clk_get(&pdev->dev, "phy");
|
|
|
|
+ priv->usb24 = clk_get(&pdev->dev, "usb24");
|
|
|
|
+ priv->pci = clk_get(&pdev->dev, "pci");
|
|
|
|
+ priv->func = clk_get(&pdev->dev, "func");
|
|
|
|
+ priv->host = clk_get(&pdev->dev, "host");
|
|
|
|
+ priv->usbh_base = ioremap_nocache(USBH, 0x20000);
|
|
|
|
+
|
|
|
|
+ if (IS_ERR(priv->phy) ||
|
|
|
|
+ IS_ERR(priv->usb24) ||
|
|
|
|
+ IS_ERR(priv->pci) ||
|
|
|
|
+ IS_ERR(priv->host) ||
|
|
|
|
+ IS_ERR(priv->func) ||
|
|
|
|
+ !priv->usbh_base) {
|
|
|
|
+ dev_err(&pdev->dev, "USB clock setting failed\n");
|
|
|
|
+ usbhsf_hardware_exit(pdev);
|
|
|
|
+ return -EIO;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = request_irq(IRQ7, usbhsf_interrupt, IRQF_TRIGGER_NONE,
|
|
|
|
+ dev_name(&pdev->dev), pdev);
|
|
|
|
+ if (ret) {
|
|
|
|
+ dev_err(&pdev->dev, "request_irq err\n");
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+ irq_set_irq_type(IRQ7, IRQ_TYPE_EDGE_BOTH);
|
|
|
|
+
|
|
|
|
+ /* usb24 use 1/1 of parent clock (= usb24s = 24MHz) */
|
|
|
|
+ clk_set_rate(priv->usb24,
|
|
|
|
+ clk_get_rate(clk_get_parent(priv->usb24)));
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static struct usbhsf_private usbhsf_private = {
|
|
|
|
+ .info = {
|
|
|
|
+ .platform_callback = {
|
|
|
|
+ .get_id = usbhsf_get_id,
|
|
|
|
+ .get_vbus = usbhsf_get_vbus,
|
|
|
|
+ .hardware_init = usbhsf_hardware_init,
|
|
|
|
+ .hardware_exit = usbhsf_hardware_exit,
|
|
|
|
+ .power_ctrl = usbhsf_power_ctrl,
|
|
|
|
+ },
|
|
|
|
+ .driver_param = {
|
|
|
|
+ .buswait_bwait = 5,
|
|
|
|
+ .detection_delay = 5,
|
|
|
|
+ .d0_rx_id = SHDMA_SLAVE_USBHS_RX,
|
|
|
|
+ .d1_tx_id = SHDMA_SLAVE_USBHS_TX,
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct resource usbhsf_resources[] = {
|
|
|
|
+ {
|
|
|
|
+ .name = "USBHS",
|
|
|
|
+ .start = 0xe6890000,
|
|
|
|
+ .end = 0xe6890104 - 1,
|
|
|
|
+ .flags = IORESOURCE_MEM,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ .start = evt2irq(0x0A20),
|
|
|
|
+ .flags = IORESOURCE_IRQ,
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct platform_device usbhsf_device = {
|
|
|
|
+ .name = "renesas_usbhs",
|
|
|
|
+ .dev = {
|
|
|
|
+ .platform_data = &usbhsf_private.info,
|
|
|
|
+ },
|
|
|
|
+ .id = -1,
|
|
|
|
+ .num_resources = ARRAY_SIZE(usbhsf_resources),
|
|
|
|
+ .resource = usbhsf_resources,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/* Ether */
|
|
|
|
+static struct sh_eth_plat_data sh_eth_platdata = {
|
|
|
|
+ .phy = 0x00, /* LAN8710A */
|
|
|
|
+ .edmac_endian = EDMAC_LITTLE_ENDIAN,
|
|
|
|
+ .register_type = SH_ETH_REG_GIGABIT,
|
|
|
|
+ .phy_interface = PHY_INTERFACE_MODE_MII,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct resource sh_eth_resources[] = {
|
|
|
|
+ {
|
|
|
|
+ .start = 0xe9a00000,
|