On Tue, 26 Jul 2005, Fukumoto Akira wrote:
> Last first:
> brw-rw---- 1 root root 8, 1 Jan 1 00:00 /dev/sda1
>
Thanks.
> /sys/bus/platform/devices # ls
> FEC.0 isp116x-hcd.0
>
> /sys/bus/platform/drivers # ls
> FEC isp116x-hcd <- without .0 is different
> to yours
This may still be OK, because for drivers I was asking
about /sys/bus/platform/drivers/isp116x-hcd/isp116x-hcd.0/
>
> Possibly the way to register plattform-Code with module_init is wrong ?
>
Using module_init() probably isn't the right way to call
it, though I don't think this is the problem.
> If you look inside /usb/host/ uhci-hcd.c or ohci_hcd.c or sl811-hcd.c you
> will find the function:
>
> usb_hcd_register_root_hub() -> usb_new_device() ->
>
> This way delivers the messages what you have around usb: and hub:
>
> On what way you will get this on your configuration?
Good catch! Could you please try the attached patch, which
reintroduces usb_hcd_register_root_hub().
> Are there any influences from plattform ppc what I have?
Ah yes, MPC852T is a PPC. There are so many ARM derivatives
that I assumed for some reason that it is ARM too. The
difference is that PPC is (always?) big endian. The driver
has been used on a big endian system earlier at least by one
person, but the driver has seen a number of changes since
then and there may be surprises. I hope not :)
Olav
diff -purN linux-2.6.12-ispweb-1/drivers/usb/host/isp116x-hcd.c
linux-2.6.12-isprc3-1/drivers/usb/host/isp116x-hcd.c
--- linux-2.6.12-ispweb-1/drivers/usb/host/isp116x-hcd.c 2005-07-27
07:41:04.920283119 +0300
+++ linux-2.6.12-isprc3-1/drivers/usb/host/isp116x-hcd.c 2005-07-27
07:23:26.623173770 +0300
@@ -641,7 +641,8 @@ static irqreturn_t isp116x_irq(struct us
}
if (intstat & HCINT_RD) {
DBG("---- remote wakeup\n");
- schedule_work(&isp116x->rh_resume);
+ if (hcd->state != HC_STATE_QUIESCING)
+ usb_hcd_resume_root_hub(hcd);
ret = IRQ_HANDLED;
}
irqstat &= ~HCuPINT_OPR;
@@ -1213,11 +1214,6 @@ static int isp116x_hub_resume(struct usb
case HCCONTROL_USB_RESUME:
break;
case HCCONTROL_USB_OPER:
- /* Without setting power_state here the
- SUSPENDED state won't be removed from
- sysfs/usbN/power.state as a response to remote
- wakeup. Maybe in the future. */
- hcd->self.root_hub->dev.power.power_state = PMSG_ON;
ret = 0;
break;
default:
@@ -1251,29 +1247,16 @@ static int isp116x_hub_resume(struct usb
isp116x_write_reg32(isp116x, HCCONTROL,
(val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
spin_unlock_irq(&isp116x->lock);
- /* see analogous comment above */
- hcd->self.root_hub->dev.power.power_state = PMSG_ON;
hcd->state = HC_STATE_RUNNING;
return 0;
}
-static void isp116x_rh_resume(void *_hcd)
-{
- struct usb_hcd *hcd = _hcd;
-
- usb_resume_device(hcd->self.root_hub);
-}
-
#else
#define isp116x_hub_suspend NULL
#define isp116x_hub_resume NULL
-static void isp116x_rh_resume(void *_hcd)
-{
-}
-
#endif
/*-----------------------------------------------------------------*/
@@ -1547,6 +1530,7 @@ static int isp116x_start(struct usb_hcd
{
struct isp116x *isp116x = hcd_to_isp116x(hcd);
struct isp116x_platform_data *board = isp116x->board;
+ struct usb_device *udev;
u32 val;
unsigned long flags;
@@ -1608,9 +1592,24 @@ static int isp116x_start(struct usb_hcd
isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf);
+ spin_unlock_irqrestore(&isp116x->lock, flags);
+
+ udev = usb_alloc_dev(NULL, &hcd->self, 0);
+ if (!udev) {
+ isp116x_stop(hcd);
+ return -ENOMEM;
+ }
+ udev->speed = USB_SPEED_FULL;
hcd->state = HC_STATE_RUNNING;
+ if (usb_hcd_register_root_hub(udev, hcd) != 0) {
+ isp116x_stop(hcd);
+ usb_put_dev(udev);
+ return -ENODEV;
+ }
+
+ spin_lock_irqsave(&isp116x->lock, flags);
/* Set up interrupts */
isp116x->intenb = HCINT_MIE | HCINT_RHSC | HCINT_UE;
if (board->remote_wakeup_enable)
@@ -1755,7 +1754,6 @@ static int __init isp116x_probe(struct d
isp116x->addr_reg = addr_reg;
spin_lock_init(&isp116x->lock);
INIT_LIST_HEAD(&isp116x->async);
- INIT_WORK(&isp116x->rh_resume, isp116x_rh_resume, hcd);
isp116x->board = dev->platform_data;
if (!isp116x->board) {
@@ -1801,13 +1799,21 @@ static int isp116x_suspend(struct device
{
int ret = 0;
struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct isp116x *isp116x = hcd_to_isp116x(hcd);
VDBG("%s: state %x, phase %x\n", __func__, state, phase);
- if (phase != SUSPEND_DISABLE && phase != SUSPEND_POWER_DOWN)
+ // if (isp116x->hc_inaccessible
+
+ if (phase != SUSPEND_DISABLE && phase != SUSPEND_POWER_DOWN)
return 0;
- ret = usb_suspend_device(hcd->self.root_hub, state);
+#ifndef CONFIG_USB_SUSPEND
+ usb_lock_device(hcd->self.root_hub);
+ ret = isp116x_hub_suspend(hcd);
+ usb_unlock_device(hcd->self.root_hub);
+#endif
+
if (!ret) {
dev->power.power_state = state;
INFO("%s suspended\n", (char *)hcd_name);
@@ -1830,7 +1836,12 @@ static int isp116x_resume(struct device
if (phase != RESUME_POWER_ON)
return 0;
- ret = usb_resume_device(hcd->self.root_hub);
+#ifndef CONFIG_USB_SUSPEND
+ usb_lock_device(hcd->self.root_hub);
+ ret = isp116x_hub_resume(hcd);
+ usb_unlock_device(hcd->self.root_hub);
+#endif
+
if (!ret) {
dev->power.power_state = PMSG_ON;
VDBG("%s resumed\n", (char *)hcd_name);
diff -purN linux-2.6.12-ispweb-1/drivers/usb/host/isp116x.h
linux-2.6.12-isprc3-1/drivers/usb/host/isp116x.h
--- linux-2.6.12-ispweb-1/drivers/usb/host/isp116x.h 2005-07-27
07:13:30.594556215 +0300
+++ linux-2.6.12-isprc3-1/drivers/usb/host/isp116x.h 2005-07-27
07:23:39.539868328 +0300
@@ -251,11 +251,23 @@ static const int cc_to_error[16] = {
#define LOG2_PERIODIC_SIZE 5 /* arbitrary; this matches OHCI
*/
#define PERIODIC_SIZE (1 << LOG2_PERIODIC_SIZE)
+/*
+ * States for the root hub.
+ */
+enum isp116x_rh_state {
+ ISP116X_RH_RESET,
+ ISP116X_RH_SUSPENDED,
+ ISP116X_RH_RUNNING,
+};
+
struct isp116x {
spinlock_t lock;
- struct work_struct rh_resume;
- void __iomem *addr_reg;
+ enum isp116x_rh_state rh_state;
+ /* HC is suspended or dead */
+ unsigned hc_inaccessible:1;
+
+ void __iomem *addr_reg;
void __iomem *data_reg;
struct isp116x_platform_data *board;