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);
}
/**
|