usb: chipidea: move otg related things to otg file
Move otg related things to otg file. Tested-by: Marek Vasut <marex@denx.de> Signed-off-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>hifive-unleashed-5.1
parent
c344b51800
commit
cbec6bd55a
|
@ -294,40 +294,6 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ci_otg_role - pick role based on ID pin state
|
|
||||||
* @ci: the controller
|
|
||||||
*/
|
|
||||||
static enum ci_role ci_otg_role(struct ci_hdrc *ci)
|
|
||||||
{
|
|
||||||
u32 sts = hw_read(ci, OP_OTGSC, ~0);
|
|
||||||
enum ci_role role = sts & OTGSC_ID
|
|
||||||
? CI_ROLE_GADGET
|
|
||||||
: CI_ROLE_HOST;
|
|
||||||
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ci_role_work - perform role changing based on ID pin
|
|
||||||
* @work: work struct
|
|
||||||
*/
|
|
||||||
static void ci_role_work(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
|
|
||||||
enum ci_role role = ci_otg_role(ci);
|
|
||||||
|
|
||||||
if (role != ci->role) {
|
|
||||||
dev_dbg(ci->dev, "switching from %s to %s\n",
|
|
||||||
ci_role(ci)->name, ci->roles[role]->name);
|
|
||||||
|
|
||||||
ci_role_stop(ci);
|
|
||||||
ci_role_start(ci, role);
|
|
||||||
}
|
|
||||||
|
|
||||||
enable_irq(ci->irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t ci_irq(int irq, void *data)
|
static irqreturn_t ci_irq(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct ci_hdrc *ci = data;
|
struct ci_hdrc *ci = data;
|
||||||
|
@ -430,6 +396,8 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
|
||||||
{
|
{
|
||||||
ci_hdrc_gadget_destroy(ci);
|
ci_hdrc_gadget_destroy(ci);
|
||||||
ci_hdrc_host_destroy(ci);
|
ci_hdrc_host_destroy(ci);
|
||||||
|
if (ci->is_otg)
|
||||||
|
ci_hdrc_otg_destroy(ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ci_get_otg_capable(struct ci_hdrc *ci)
|
static void ci_get_otg_capable(struct ci_hdrc *ci)
|
||||||
|
@ -494,13 +462,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_WORK(&ci->work, ci_role_work);
|
|
||||||
ci->wq = create_singlethread_workqueue("ci_otg");
|
|
||||||
if (!ci->wq) {
|
|
||||||
dev_err(dev, "can't create workqueue\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
ci_get_otg_capable(ci);
|
ci_get_otg_capable(ci);
|
||||||
|
|
||||||
if (!ci->platdata->phy_mode)
|
if (!ci->platdata->phy_mode)
|
||||||
|
@ -530,8 +491,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
|
if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
|
||||||
dev_err(dev, "no supported roles\n");
|
dev_err(dev, "no supported roles\n");
|
||||||
ret = -ENODEV;
|
return -ENODEV;
|
||||||
goto rm_wq;
|
}
|
||||||
|
|
||||||
|
if (ci->is_otg) {
|
||||||
|
ret = ci_hdrc_otg_init(ci);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "init otg fails, ret = %d\n", ret);
|
||||||
|
goto stop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
|
if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
|
||||||
|
@ -542,7 +510,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
|
||||||
*/
|
*/
|
||||||
mdelay(2);
|
mdelay(2);
|
||||||
ci->role = ci_otg_role(ci);
|
ci->role = ci_otg_role(ci);
|
||||||
ci_hdrc_otg_init(ci);
|
ci_enable_otg_interrupt(ci, OTGSC_IDIE);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* If the controller is not OTG capable, but support
|
* If the controller is not OTG capable, but support
|
||||||
|
@ -560,7 +528,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
|
||||||
ret = ci_role_start(ci, ci->role);
|
ret = ci_role_start(ci, ci->role);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "can't start %s role\n", ci_role(ci)->name);
|
dev_err(dev, "can't start %s role\n", ci_role(ci)->name);
|
||||||
goto rm_wq;
|
goto stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, ci);
|
platform_set_drvdata(pdev, ci);
|
||||||
|
@ -576,9 +544,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
|
||||||
free_irq(ci->irq, ci);
|
free_irq(ci->irq, ci);
|
||||||
stop:
|
stop:
|
||||||
ci_role_destroy(ci);
|
ci_role_destroy(ci);
|
||||||
rm_wq:
|
|
||||||
flush_workqueue(ci->wq);
|
|
||||||
destroy_workqueue(ci->wq);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -588,8 +553,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
|
||||||
struct ci_hdrc *ci = platform_get_drvdata(pdev);
|
struct ci_hdrc *ci = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
dbg_remove_files(ci);
|
dbg_remove_files(ci);
|
||||||
flush_workqueue(ci->wq);
|
|
||||||
destroy_workqueue(ci->wq);
|
|
||||||
free_irq(ci->irq, ci);
|
free_irq(ci->irq, ci);
|
||||||
ci_role_destroy(ci);
|
ci_role_destroy(ci);
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,65 @@
|
||||||
#include "otg.h"
|
#include "otg.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ci_hdrc_otg_init - initialize otgsc bits
|
* ci_otg_role - pick role based on ID pin state
|
||||||
|
* @ci: the controller
|
||||||
|
*/
|
||||||
|
enum ci_role ci_otg_role(struct ci_hdrc *ci)
|
||||||
|
{
|
||||||
|
u32 sts = hw_read(ci, OP_OTGSC, ~0);
|
||||||
|
enum ci_role role = sts & OTGSC_ID
|
||||||
|
? CI_ROLE_GADGET
|
||||||
|
: CI_ROLE_HOST;
|
||||||
|
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ci_role_work - perform role changing based on ID pin
|
||||||
|
* @work: work struct
|
||||||
|
*/
|
||||||
|
static void ci_role_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
|
||||||
|
enum ci_role role = ci_otg_role(ci);
|
||||||
|
|
||||||
|
if (role != ci->role) {
|
||||||
|
dev_dbg(ci->dev, "switching from %s to %s\n",
|
||||||
|
ci_role(ci)->name, ci->roles[role]->name);
|
||||||
|
|
||||||
|
ci_role_stop(ci);
|
||||||
|
ci_role_start(ci, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_irq(ci->irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ci_hdrc_otg_init - initialize otg struct
|
||||||
* ci: the controller
|
* ci: the controller
|
||||||
*/
|
*/
|
||||||
int ci_hdrc_otg_init(struct ci_hdrc *ci)
|
int ci_hdrc_otg_init(struct ci_hdrc *ci)
|
||||||
{
|
{
|
||||||
ci_enable_otg_interrupt(ci, OTGSC_IDIE);
|
INIT_WORK(&ci->work, ci_role_work);
|
||||||
|
ci->wq = create_singlethread_workqueue("ci_otg");
|
||||||
|
if (!ci->wq) {
|
||||||
|
dev_err(ci->dev, "can't create workqueue\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ci_hdrc_otg_destroy - destroy otg struct
|
||||||
|
* ci: the controller
|
||||||
|
*/
|
||||||
|
void ci_hdrc_otg_destroy(struct ci_hdrc *ci)
|
||||||
|
{
|
||||||
|
if (ci->wq) {
|
||||||
|
flush_workqueue(ci->wq);
|
||||||
|
destroy_workqueue(ci->wq);
|
||||||
|
}
|
||||||
|
ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
|
||||||
|
ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
|
||||||
|
}
|
||||||
|
|
|
@ -28,5 +28,7 @@ static inline void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
int ci_hdrc_otg_init(struct ci_hdrc *ci);
|
int ci_hdrc_otg_init(struct ci_hdrc *ci);
|
||||||
|
void ci_hdrc_otg_destroy(struct ci_hdrc *ci);
|
||||||
|
enum ci_role ci_otg_role(struct ci_hdrc *ci);
|
||||||
|
|
||||||
#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
|
#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
|
||||||
|
|
Loading…
Reference in New Issue