From: <he...@us...> - 2005-04-25 19:34:59
|
Update of /cvsroot/gc-linux/linux/arch/ppc/platforms In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28400/arch/ppc/platforms Modified Files: gcn-rtc.c Log Message: set_rtc_time may be called from interrupt context. The RTC driver now deals with that case. Index: gcn-rtc.c =================================================================== RCS file: /cvsroot/gc-linux/linux/arch/ppc/platforms/gcn-rtc.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- gcn-rtc.c 13 Mar 2005 21:51:39 -0000 1.3 +++ gcn-rtc.c 25 Apr 2005 19:34:48 -0000 1.4 @@ -62,6 +62,7 @@ /* * Loads the SRAM contents. + * Context: user. */ static void sram_load(struct exi_device *dev) { @@ -70,63 +71,75 @@ u32 req; /* select the SRAM device */ - exi_dev_select(dev); - - /* send the appropriate command */ - req = 0x20000100; - exi_dev_write(dev, &req, sizeof(req)); + if (exi_dev_select(dev) == 0) { + /* send the appropriate command */ + req = 0x20000100; + exi_dev_write(dev, &req, sizeof(req)); - /* read the SRAM data */ - exi_dev_read(dev, sram, sizeof(*sram)); + /* read the SRAM data */ + exi_dev_read(dev, sram, sizeof(*sram)); - /* deselect the SRAM device */ - exi_dev_deselect(dev); + /* deselect the SRAM device */ + exi_dev_deselect(dev); + } return; } /* * Gets the hardware clock date and time. + * Context: user. */ static unsigned long rtc_get_time(struct exi_device *dev) { - unsigned long a; + unsigned long a = 0; /* select the RTC device */ - exi_dev_select(dev); - - /* send the appropriate command */ - a = 0x20000000; - exi_dev_write(dev, &a, sizeof(a)); + if (exi_dev_select(dev) == 0) { + /* send the appropriate command */ + a = 0x20000000; + exi_dev_write(dev, &a, sizeof(a)); - /* read the time and date value */ - exi_dev_read(dev, &a, sizeof(a)); + /* read the time and date value */ + exi_dev_read(dev, &a, sizeof(a)); - /* deselect the RTC device */ - exi_dev_deselect(dev); + /* deselect the RTC device */ + exi_dev_deselect(dev); + } return a; } /* * Sets the hardware clock date and time to @aval. + * Context: user, interrupt (adjtimex). */ -static void rtc_set_time(struct exi_device *dev, unsigned long aval) +static int rtc_set_time(struct exi_device *dev, unsigned long aval) { u32 req; + int retval; - /* select the RTC device */ - exi_dev_select(dev); + /* + * We may get called from the timer interrupt. In that case, + * we could fail if the exi channel used to access the RTC + * is busy. If this happens, we just return an error. The timer + * interrupt code is prepared to deal with such case. + */ - /* send the appropriate command */ - req = 0xa0000000; - exi_dev_write(dev, &req, sizeof(req)); + /* select the RTC device */ + retval = exi_dev_select(dev); + if (!retval) { + /* send the appropriate command */ + req = 0xa0000000; + exi_dev_write(dev, &req, sizeof(req)); - /* set the new time and date value */ - exi_dev_write(dev, &aval, sizeof(aval)); + /* set the new time and date value */ + exi_dev_write(dev, &aval, sizeof(aval)); - /* deselect the RTC device */ - exi_dev_deselect(dev); + /* deselect the RTC device */ + exi_dev_deselect(dev); + } + return retval; } /** @@ -147,9 +160,7 @@ { struct rtc_private *priv = &rtc_private; - rtc_set_time(priv->dev, nowtime - RTC_OFFSET - priv->sram.bias); - - return 1; + return rtc_set_time(priv->dev, nowtime - RTC_OFFSET - priv->sram.bias); } /** |