Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c59b0b7 authored by Magnus Damm's avatar Magnus Damm Committed by Paul Mundt
Browse files

usb: m66592-udc platform data on_chip support



Convert the m66592-udc driver to use the on_chip flag
from platform data to enable on chip behaviour instead
of relying on CONFIG_SUPERH_BUILT_IN_M66592 ugliness.

This makes the code cleaner and also allows us to support
both external and internal m66592 with the same kernel.

It also makes the Kconfig part more future proof since
we with this patch can add support for new processors
with on-chip m66592 without modifying the Kconfig.

The patch adds a m66592 header file for platform data
and ties in platform data to the existing m66592 devices.

Signed-off-by: default avatarMagnus Damm <damm@igel.co.jp>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent cf4f1e76
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/usb/r8a66597.h>
#include <linux/usb/m66592.h>
#include <net/ax88796.h>
#include <asm/machvec.h>
#include <mach/highlander.h>
@@ -60,6 +61,11 @@ static struct platform_device r8a66597_usb_host_device = {
	.resource	= r8a66597_usb_host_resources,
};

static struct m66592_platdata usbf_platdata = {
	.xtal = M66592_PLATDATA_XTAL_24MHZ,
	.vif = 1,
};

static struct resource m66592_usb_peripheral_resources[] = {
	[0] = {
		.name	= "m66592_udc",
@@ -81,6 +87,7 @@ static struct platform_device m66592_usb_peripheral_device = {
	.dev = {
		.dma_mask		= NULL,		/* don't use dma */
		.coherent_dma_mask	= 0xffffffff,
		.platform_data		= &usbf_platdata,
	},
	.num_resources	= ARRAY_SIZE(m66592_usb_peripheral_resources),
	.resource	= m66592_usb_peripheral_resources,
+7 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/usb/r8a66597.h>
#include <linux/usb/m66592.h>
#include <asm/ilsel.h>

static struct resource heartbeat_resources[] = {
@@ -89,6 +90,11 @@ static struct platform_device r8a66597_usb_host_device = {
	.resource	= r8a66597_usb_host_resources,
};

static struct m66592_platdata usbf_platdata = {
	.xtal = M66592_PLATDATA_XTAL_24MHZ,
	.vif = 1,
};

static struct resource m66592_usb_peripheral_resources[] = {
	[0] = {
		.name	= "m66592_udc",
@@ -109,6 +115,7 @@ static struct platform_device m66592_usb_peripheral_device = {
	.dev = {
		.dma_mask		= NULL,		/* don't use dma */
		.coherent_dma_mask	= 0xffffffff,
		.platform_data		= &usbf_platdata,
	},
	.num_resources	= ARRAY_SIZE(m66592_usb_peripheral_resources),
	.resource	= m66592_usb_peripheral_resources,
+7 −1
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/serial_sci.h>
#include <linux/mm.h>
#include <linux/uio_driver.h>
#include <linux/usb/m66592.h>
#include <linux/sh_timer.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
@@ -47,9 +48,13 @@ static struct platform_device rtc_device = {
	.resource	= rtc_resources,
};

static struct m66592_platdata usbf_platdata = {
	.on_chip = 1,
};

static struct resource usbf_resources[] = {
	[0] = {
		.name	= "m66592_udc",
		.name	= "USBF",
		.start	= 0x04480000,
		.end	= 0x044800FF,
		.flags	= IORESOURCE_MEM,
@@ -67,6 +72,7 @@ static struct platform_device usbf_device = {
	.dev = {
		.dma_mask		= NULL,
		.coherent_dma_mask	= 0xffffffff,
		.platform_data		= &usbf_platdata,
	},
	.num_resources	= ARRAY_SIZE(usbf_resources),
	.resource	= usbf_resources,
+0 −10
Original line number Diff line number Diff line
@@ -360,16 +360,6 @@ config USB_M66592
	default USB_GADGET
	select USB_GADGET_SELECTED

config SUPERH_BUILT_IN_M66592
	boolean "Enable SuperH built-in USB like the M66592"
	depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
	help
	   SH7722 has USB like the M66592.

	   The transfer rate is very slow when use "Ethernet Gadget".
	   However, this problem is improved if change a value of
	   NET_IP_ALIGN to 4.

#
# Controllers available only in discrete form (and all PCI controllers)
#
+147 −105
Original line number Diff line number Diff line
@@ -31,38 +31,12 @@

#include "m66592-udc.h"


MODULE_DESCRIPTION("M66592 USB gadget driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yoshihiro Shimoda");
MODULE_ALIAS("platform:m66592_udc");

#define DRIVER_VERSION	"26 Jun 2009"

/* module parameters */
#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
static unsigned short endian = M66592_LITTLE;
module_param(endian, ushort, 0644);
MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)");
#else
static unsigned short clock = M66592_XTAL24;
module_param(clock, ushort, 0644);
MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
		"(default=16384)");

static unsigned short vif = M66592_LDRV;
module_param(vif, ushort, 0644);
MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)");

static unsigned short endian;
module_param(endian, ushort, 0644);
MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");

static unsigned short irq_sense = M66592_INTL;
module_param(irq_sense, ushort, 0644);
MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 "
		"(default=2)");
#endif
#define DRIVER_VERSION	"21 July 2009"

static const char udc_name[] = "m66592_udc";
static const char *m66592_ep_name[] = {
@@ -244,6 +218,7 @@ static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum)
static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
{
	struct m66592_ep *ep = m66592->pipenum2ep[pipenum];
	unsigned short mbw;

	if (ep->use_dma)
		return;
@@ -252,7 +227,12 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum)

	ndelay(450);

	m66592_bset(m66592, M66592_MBW, ep->fifosel);
	if (m66592->pdata->on_chip)
		mbw = M66592_MBW_32;
	else
		mbw = M66592_MBW_16;

	m66592_bset(m66592, mbw, ep->fifosel);
}

static int pipe_buffer_setting(struct m66592 *m66592,
@@ -332,6 +312,7 @@ static void pipe_buffer_release(struct m66592 *m66592,
static void pipe_initialize(struct m66592_ep *ep)
{
	struct m66592 *m66592 = ep->m66592;
	unsigned short mbw;

	m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel);

@@ -343,7 +324,12 @@ static void pipe_initialize(struct m66592_ep *ep)

		ndelay(450);

		m66592_bset(m66592, M66592_MBW, ep->fifosel);
		if (m66592->pdata->on_chip)
			mbw = M66592_MBW_32;
		else
			mbw = M66592_MBW_16;

		m66592_bset(m66592, mbw, ep->fifosel);
	}
}

@@ -359,15 +345,13 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep,
			ep->fifosel = M66592_D0FIFOSEL;
			ep->fifoctr = M66592_D0FIFOCTR;
			ep->fifotrn = M66592_D0FIFOTRN;
#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
		} else if (m66592->num_dma == 1) {
		} else if (!m66592->pdata->on_chip && m66592->num_dma == 1) {
			m66592->num_dma++;
			ep->use_dma = 1;
			ep->fifoaddr = M66592_D1FIFO;
			ep->fifosel = M66592_D1FIFOSEL;
			ep->fifoctr = M66592_D1FIFOCTR;
			ep->fifotrn = M66592_D1FIFOTRN;
#endif
		} else {
			ep->use_dma = 0;
			ep->fifoaddr = M66592_CFIFO;
@@ -612,9 +596,16 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req)
	}
}

#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
static void init_controller(struct m66592 *m66592)
{
	unsigned int endian;

	if (m66592->pdata->on_chip) {
		if (m66592->pdata->endian)
			endian = 0; /* big endian */
		else
			endian = M66592_LITTLE; /* little endian */

		m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);	/* High spd */
		m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
		m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
@@ -631,15 +622,52 @@ static void init_controller(struct m66592 *m66592)
		m66592_write(m66592, 0, M66592_D0FBCFG);
		m66592_bset(m66592, endian, M66592_CFBCFG);
		m66592_bset(m66592, endian, M66592_D0FBCFG);
	} else {
		unsigned int clock, vif, irq_sense;

		if (m66592->pdata->endian)
			endian = M66592_BIGEND; /* big endian */
		else
			endian = 0; /* little endian */

		if (m66592->pdata->vif)
			vif = M66592_LDRV; /* 3.3v */
		else
			vif = 0; /* 1.5v */

		switch (m66592->pdata->xtal) {
		case M66592_PLATDATA_XTAL_12MHZ:
			clock = M66592_XTAL12;
			break;
		case M66592_PLATDATA_XTAL_24MHZ:
			clock = M66592_XTAL24;
			break;
		case M66592_PLATDATA_XTAL_48MHZ:
			clock = M66592_XTAL48;
			break;
		default:
			pr_warning("m66592-udc: xtal configuration error\n");
			clock = 0;
		}
#else	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
static void init_controller(struct m66592 *m66592)
{
	m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND),

		switch (m66592->irq_trigger) {
		case IRQF_TRIGGER_LOW:
			irq_sense = M66592_INTL;
			break;
		case IRQF_TRIGGER_FALLING:
			irq_sense = 0;
			break;
		default:
			pr_warning("m66592-udc: irq trigger config error\n");
			irq_sense = 0;
		}

		m66592_bset(m66592,
			    (vif & M66592_LDRV) | (endian & M66592_BIGEND),
			    M66592_PINCFG);
		m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);	/* High spd */
	m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG);

		m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL,
			    M66592_SYSCFG);
		m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
		m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
		m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
@@ -658,11 +686,11 @@ static void init_controller(struct m66592 *m66592)
		m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
			     M66592_DMA0CFG);
	}
#endif	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
}

static void disable_controller(struct m66592 *m66592)
{
#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
	if (!m66592->pdata->on_chip) {
		m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
		udelay(1);
		m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
@@ -670,18 +698,18 @@ static void disable_controller(struct m66592 *m66592)
		m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
		udelay(1);
		m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
#endif
	}
}

static void m66592_start_xclock(struct m66592 *m66592)
{
#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
	u16 tmp;

	if (!m66592->pdata->on_chip) {
		tmp = m66592_read(m66592, M66592_SYSCFG);
		if (!(tmp & M66592_XCKE))
			m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
#endif
	}
}

/*-------------------------------------------------------------------------*/
@@ -1169,8 +1197,7 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
	intsts0 = m66592_read(m66592, M66592_INTSTS0);
	intenb0 = m66592_read(m66592, M66592_INTENB0);

#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
	if (!intsts0 && !intenb0) {
	if (m66592->pdata->on_chip && !intsts0 && !intenb0) {
		/*
		 * When USB clock stops, it cannot read register. Even if a
		 * clock stops, the interrupt occurs. So this driver turn on
@@ -1180,7 +1207,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
		intsts0 = m66592_read(m66592, M66592_INTSTS0);
		intenb0 = m66592_read(m66592, M66592_INTENB0);
	}
#endif

	savepipe = m66592_read(m66592, M66592_CFIFOSEL);

@@ -1526,9 +1552,11 @@ static int __exit m66592_remove(struct platform_device *pdev)
	iounmap(m66592->reg);
	free_irq(platform_get_irq(pdev, 0), m66592);
	m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
#ifdef CONFIG_HAVE_CLK
	if (m66592->pdata->on_chip) {
		clk_disable(m66592->clk);
		clk_put(m66592->clk);
	}
#endif
	kfree(m66592);
	return 0;
@@ -1540,11 +1568,10 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r)

static int __init m66592_probe(struct platform_device *pdev)
{
	struct resource *res;
	int irq;
	struct resource *res, *ires;
	void __iomem *reg = NULL;
	struct m66592 *m66592 = NULL;
#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
#ifdef CONFIG_HAVE_CLK
	char clk_name[8];
#endif
	int ret = 0;
@@ -1557,10 +1584,11 @@ static int __init m66592_probe(struct platform_device *pdev)
		goto clean_up;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!ires) {
		ret = -ENODEV;
		pr_err("platform_get_irq error.\n");
		dev_err(&pdev->dev,
			"platform_get_resource IORESOURCE_IRQ error.\n");
		goto clean_up;
	}

@@ -1571,6 +1599,12 @@ static int __init m66592_probe(struct platform_device *pdev)
		goto clean_up;
	}

	if (pdev->dev.platform_data == NULL) {
		dev_err(&pdev->dev, "no platform data\n");
		ret = -ENODEV;
		goto clean_up;
	}

	/* initialize ucd */
	m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
	if (m66592 == NULL) {
@@ -1578,6 +1612,9 @@ static int __init m66592_probe(struct platform_device *pdev)
		goto clean_up;
	}

	m66592->pdata = pdev->dev.platform_data;
	m66592->irq_trigger = ires->flags & IRQF_TRIGGER_MASK;

	spin_lock_init(&m66592->lock);
	dev_set_drvdata(&pdev->dev, m66592);

@@ -1595,22 +1632,25 @@ static int __init m66592_probe(struct platform_device *pdev)
	m66592->timer.data = (unsigned long)m66592;
	m66592->reg = reg;

	ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
	ret = request_irq(ires->start, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
			udc_name, m66592);
	if (ret < 0) {
		pr_err("request_irq error (%d)\n", ret);
		goto clean_up;
	}

#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
#ifdef CONFIG_HAVE_CLK
	if (m66592->pdata->on_chip) {
		snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
		m66592->clk = clk_get(&pdev->dev, clk_name);
		if (IS_ERR(m66592->clk)) {
		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
			dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
				clk_name);
			ret = PTR_ERR(m66592->clk);
			goto clean_up2;
		}
		clk_enable(m66592->clk);
	}
#endif
	INIT_LIST_HEAD(&m66592->gadget.ep_list);
	m66592->gadget.ep0 = &m66592->ep[0].ep;
@@ -1652,12 +1692,14 @@ static int __init m66592_probe(struct platform_device *pdev)
	return 0;

clean_up3:
#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
#ifdef CONFIG_HAVE_CLK
	if (m66592->pdata->on_chip) {
		clk_disable(m66592->clk);
		clk_put(m66592->clk);
	}
clean_up2:
#endif
	free_irq(irq, m66592);
	free_irq(ires->start, m66592);
clean_up:
	if (m66592) {
		if (m66592->ep0_req)
Loading