From 60e2809a848bccd3a8090d3f2237964670f2780c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 17 Feb 2015 15:29:35 -0700 Subject: dm: spi: Avoid setting the speed with every transfer Only set the speed if it has changed from last time. Since the speed will be 0 when the device is probed it will always be changed on the first transfer after the device is probed. Signed-off-by: Simon Glass --- include/spi.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/spi.h b/include/spi.h index 9495ca53c9b..3f198f87497 100644 --- a/include/spi.h +++ b/include/spi.h @@ -100,6 +100,8 @@ struct dm_spi_slave_platdata { * @dev: SPI slave device * @max_hz: Maximum speed for this slave * @mode: SPI mode to use for this slave (see SPI mode flags) + * @speed: Current bus speed. This is 0 until the bus is first + * claimed. * @bus: ID of the bus that the slave is attached to. For * driver model this is the sequence number of the SPI * bus (bus->seq) so does not need to be stored @@ -117,6 +119,7 @@ struct spi_slave { #ifdef CONFIG_DM_SPI struct udevice *dev; /* struct spi_slave is dev->parentdata */ uint max_hz; + uint speed; uint mode; #else unsigned int bus; -- cgit v1.3.1 From bc5701e1b448e168c84b9e8ed18a0f8217c9e7b2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:12 -0600 Subject: dm: spi: Correct the comment on spi_get_ops() This comment should refer to SPI, not serial. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- include/spi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/spi.h b/include/spi.h index 3f198f87497..f4b93e6a139 100644 --- a/include/spi.h +++ b/include/spi.h @@ -616,7 +616,7 @@ int sandbox_spi_get_emul(struct sandbox_state *state, struct udevice *bus, struct udevice *slave, struct udevice **emulp); -/* Access the serial operations for a device */ +/* Access the operations for a SPI device */ #define spi_get_ops(dev) ((struct dm_spi_ops *)(dev)->driver->ops) #define spi_emul_get_ops(dev) ((struct dm_spi_emul_ops *)(dev)->driver->ops) #endif /* CONFIG_DM_SPI */ -- cgit v1.3.1 From ba3864f8037f58dd1f46cad3b76adc0a84bd33b3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:14 -0600 Subject: dm: i2c: Add functions to read and write a register Add driver model versions of the legacy functions to read and write a single byte register. These are a useful shortcut in many cases. Signed-off-by: Simon Glass Acked-by: Heiko Schocher --- drivers/i2c/i2c-uclass.c | 19 +++++++++++++++++++ include/i2c.h | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+) (limited to 'include') diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index f2e95c0881a..b8eb2d613f2 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -186,6 +186,25 @@ int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, } } +int dm_i2c_reg_read(struct udevice *dev, uint offset) +{ + uint8_t val; + int ret; + + ret = dm_i2c_read(dev, offset, &val, 1); + if (ret < 0) + return ret; + + return val; +} + +int dm_i2c_reg_write(struct udevice *dev, uint offset, uint value) +{ + uint8_t val = value; + + return dm_i2c_write(dev, offset, &val, 1); +} + /** * i2c_probe_chip() - probe for a chip on a bus * diff --git a/include/i2c.h b/include/i2c.h index 6fd73fae4cc..d794057f4b9 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -123,6 +123,27 @@ int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags, struct udevice **devp); +/** + * dm_i2c_reg_read() - Read a value from an I2C register + * + * This reads a single value from the given address in an I2C chip + * + * @addr: Address to read from + * @return value read, or -ve on error + */ +int dm_i2c_reg_read(struct udevice *dev, uint offset); + +/** + * dm_i2c_reg_write() - Write a value to an I2C register + * + * This writes a single value to the given address in an I2C chip + * + * @addr: Address to write to + * @val: Value to write (normally a byte) + * @return 0 on success, -ve on error + */ +int dm_i2c_reg_write(struct udevice *dev, uint offset, unsigned int val); + /** * dm_i2c_set_bus_speed() - set the speed of a bus * -- cgit v1.3.1 From 182bf92d19cf007c2d6b9a264107d6996ae9014f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:15 -0600 Subject: dm: i2c: Add an explicit test mode to the sandbox I2C driver At present this driver has a few test features. They are needed for running the driver model unit tests but are confusing and unnecessary if using sandbox at the command line. Add a flag to enable the test mode, and don't enable it by default. Signed-off-by: Simon Glass --- arch/sandbox/include/asm/test.h | 10 ++++++++++ drivers/i2c/sandbox_i2c.c | 34 +++++++++++++++++++++++----------- include/i2c.h | 1 + test/dm/i2c.c | 8 ++++++++ 4 files changed, 42 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 296589c2826..06e73012680 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -17,6 +17,16 @@ #define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM #define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL +/** + * sandbox_i2c_set_test_mode() - set test mode for running unit tests + * + * See sandbox_i2c_xfer() for the behaviour changes. + * + * @bus: sandbox I2C bus to adjust + * @test_mode: true to select test mode, false to run normally + */ +void sandbox_i2c_set_test_mode(struct udevice *bus, bool test_mode); + enum sandbox_i2c_eeprom_test_mode { SIE_TEST_MODE_NONE, /* Permits read/write of only one byte per I2C transaction */ diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c index 621caecf044..dd1c7e59e4b 100644 --- a/drivers/i2c/sandbox_i2c.c +++ b/drivers/i2c/sandbox_i2c.c @@ -18,8 +18,8 @@ DECLARE_GLOBAL_DATA_PTR; -struct dm_sandbox_i2c_emul_priv { - struct udevice *emul; +struct sandbox_i2c_priv { + bool test_mode; }; static int get_emul(struct udevice *dev, struct udevice **devp, @@ -47,17 +47,25 @@ static int get_emul(struct udevice *dev, struct udevice **devp, return 0; } +void sandbox_i2c_set_test_mode(struct udevice *bus, bool test_mode) +{ + struct sandbox_i2c_priv *priv = dev_get_priv(bus); + + priv->test_mode = test_mode; +} + static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) { struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); + struct sandbox_i2c_priv *priv = dev_get_priv(bus); struct dm_i2c_ops *ops; struct udevice *emul, *dev; bool is_read; int ret; /* Special test code to return success but with no emulation */ - if (msg->addr == SANDBOX_I2C_TEST_ADDR) + if (priv->test_mode && msg->addr == SANDBOX_I2C_TEST_ADDR) return 0; ret = i2c_get_chip(bus, msg->addr, 1, &dev); @@ -68,15 +76,18 @@ static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, if (ret) return ret; - /* - * For testing, don't allow writing above 100KHz for writes and - * 400KHz for reads - */ - is_read = nmsgs > 1; - if (i2c->speed_hz > (is_read ? 400000 : 100000)) { - debug("%s: Max speed exceeded\n", __func__); - return -EINVAL; + if (priv->test_mode) { + /* + * For testing, don't allow writing above 100KHz for writes and + * 400KHz for reads. + */ + is_read = nmsgs > 1; + if (i2c->speed_hz > (is_read ? 400000 : 100000)) { + debug("%s: Max speed exceeded\n", __func__); + return -EINVAL; + } } + return ops->xfer(emul, msg, nmsgs); } @@ -94,4 +105,5 @@ U_BOOT_DRIVER(i2c_sandbox) = { .id = UCLASS_I2C, .of_match = sandbox_i2c_ids, .ops = &sandbox_i2c_ops, + .priv_auto_alloc_size = sizeof(struct sandbox_i2c_priv), }; diff --git a/include/i2c.h b/include/i2c.h index d794057f4b9..1e259861b78 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -54,6 +54,7 @@ struct dm_i2c_chip { uint flags; #ifdef CONFIG_SANDBOX struct udevice *emul; + bool test_mode; #endif }; diff --git a/test/dm/i2c.c b/test/dm/i2c.c index 541b73b8037..c5939a165e9 100644 --- a/test/dm/i2c.c +++ b/test/dm/i2c.c @@ -66,6 +66,9 @@ static int dm_test_i2c_speed(struct dm_test_state *dms) uint8_t buf[5]; ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); + + /* Use test mode so we create the required errors for invalid speeds */ + sandbox_i2c_set_test_mode(bus, true); ut_assertok(i2c_get_chip(bus, chip, 1, &dev)); ut_assertok(dm_i2c_set_bus_speed(bus, 100000)); ut_assertok(dm_i2c_read(dev, 0, buf, 5)); @@ -73,6 +76,7 @@ static int dm_test_i2c_speed(struct dm_test_state *dms) ut_asserteq(400000, dm_i2c_get_bus_speed(bus)); ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_asserteq(-EINVAL, dm_i2c_write(dev, 0, buf, 5)); + sandbox_i2c_set_test_mode(bus, false); return 0; } @@ -100,7 +104,11 @@ static int dm_test_i2c_probe_empty(struct dm_test_state *dms) struct udevice *bus, *dev; ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); + + /* Use test mode so that this chip address will always probe */ + sandbox_i2c_set_test_mode(bus, true); ut_assertok(dm_i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev)); + sandbox_i2c_set_test_mode(bus, false); return 0; } -- cgit v1.3.1 From 199e87c340bdd69a89e22f12e1201d67767e91a8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:17 -0600 Subject: dm: rtc: Rename gregorian day function Change this function name to something more descriptive. Also return a failure code if it cannot calculate a correct value. Signed-off-by: Simon Glass Acked-by: Heiko Schocher --- common/cmd_date.c | 2 +- drivers/rtc/date.c | 9 +++++++-- drivers/rtc/ds1306.c | 2 +- include/rtc.h | 12 +++++++++++- 4 files changed, 20 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/common/cmd_date.c b/common/cmd_date.c index 4a653e5bcfa..dfb93495173 100644 --- a/common/cmd_date.c +++ b/common/cmd_date.c @@ -201,7 +201,7 @@ int mk_date (const char *datestr, struct rtc_time *tmp) tmp->tm_min = val; /* calculate day of week */ - GregorianDay (tmp); + rtc_calc_weekday(tmp); return (0); default: diff --git a/drivers/rtc/date.c b/drivers/rtc/date.c index 15e6db06b2d..20005657360 100644 --- a/drivers/rtc/date.c +++ b/drivers/rtc/date.c @@ -11,6 +11,7 @@ #include #include +#include #include #if defined(CONFIG_CMD_DATE) || defined(CONFIG_TIMESTAMP) @@ -30,13 +31,15 @@ static int month_days[12] = { /* * This only works for the Gregorian calendar - i.e. after 1752 (in the UK) */ -void GregorianDay(struct rtc_time * tm) +int rtc_calc_weekday(struct rtc_time *tm) { int leapsToDate; int lastYear; int day; int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 }; + if (tm->tm_year < 1753) + return -EINVAL; lastYear=tm->tm_year-1; /* @@ -64,6 +67,8 @@ void GregorianDay(struct rtc_time * tm) day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday; tm->tm_wday=day%7; + + return 0; } void to_tm(int tim, struct rtc_time * tm) @@ -101,7 +106,7 @@ void to_tm(int tim, struct rtc_time * tm) /* * Determine the day of week */ - GregorianDay(tm); + rtc_calc_weekday(tm); } /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. diff --git a/drivers/rtc/ds1306.c b/drivers/rtc/ds1306.c index 1ec1837cb4e..3fe6721c136 100644 --- a/drivers/rtc/ds1306.c +++ b/drivers/rtc/ds1306.c @@ -110,7 +110,7 @@ int rtc_get (struct rtc_time *tmp) immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */ udelay (10); - GregorianDay (tmp); /* Determine the day of week */ + rtc_calc_weekday(tmp); /* Determine the day of week */ debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, diff --git a/include/rtc.h b/include/rtc.h index 54e361ea5e8..96c696ad65b 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -45,7 +45,6 @@ int rtc_get (struct rtc_time *); int rtc_set (struct rtc_time *); void rtc_reset (void); -void GregorianDay (struct rtc_time *); void to_tm (int, struct rtc_time *); unsigned long mktime (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); @@ -87,4 +86,15 @@ void rtc_write32(int reg, u32 value); */ void rtc_init(void); +/** + * rtc_calc_weekday() - Work out the weekday from a time + * + * This only works for the Gregorian calendar - i.e. after 1752 (in the UK). + * It sets time->tm_wdaay to the correct day of the week. + * + * @time: Time to inspect. tm_wday is updated + * @return 0 if OK, -EINVAL if the weekday could not be determined + */ +int rtc_calc_weekday(struct rtc_time *time); + #endif /* _RTC_H_ */ -- cgit v1.3.1 From 9f9276c34cbbf67fd1b3788f0be326b47fc69123 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:18 -0600 Subject: dm: rtc: Rename to_tm() to rtc_to_tm() and add error code Rename this function so that it is clear that it is provided by the RTC. Also return an error when it cannot function as expected. This is unlikely to occur since it works for dates since 1752 and many RTCs do not support such old dates. Still it is better to be accurate. Signed-off-by: Simon Glass Acked-by: Heiko Schocher --- common/image.c | 2 +- drivers/rtc/at91sam9_rtt.c | 2 +- drivers/rtc/bfin_rtc.c | 2 +- drivers/rtc/date.c | 8 ++++++-- drivers/rtc/ds1374.c | 2 +- drivers/rtc/ftrtc010.c | 2 +- drivers/rtc/imxdi.c | 2 +- drivers/rtc/mc13xxx-rtc.c | 2 +- drivers/rtc/mcfrtc.c | 2 +- drivers/rtc/mpc8xx.c | 2 +- drivers/rtc/mx27rtc.c | 2 +- drivers/rtc/mxsrtc.c | 2 +- drivers/rtc/pl031.c | 2 +- include/rtc.h | 15 ++++++++++++++- net/sntp.c | 2 +- post/drivers/rtc.c | 6 +++--- 16 files changed, 36 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/common/image.c b/common/image.c index abc0d890f28..fdec496c4bf 100644 --- a/common/image.c +++ b/common/image.c @@ -533,7 +533,7 @@ void genimg_print_time(time_t timestamp) #ifndef USE_HOSTCC struct rtc_time tm; - to_tm(timestamp, &tm); + rtc_to_tm(timestamp, &tm); printf("%4d-%02d-%02d %2d:%02d:%02d UTC\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); diff --git a/drivers/rtc/at91sam9_rtt.c b/drivers/rtc/at91sam9_rtt.c index 714dd2a34f5..d3cdee04ffc 100644 --- a/drivers/rtc/at91sam9_rtt.c +++ b/drivers/rtc/at91sam9_rtt.c @@ -44,7 +44,7 @@ int rtc_get (struct rtc_time *tmp) } while (tim!=tim2); off = readl(&gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]); /* off==0 means time is invalid, but we ignore that */ - to_tm (tim+off, tmp); + rtc_to_tm(tim+off, tmp); return 0; } diff --git a/drivers/rtc/bfin_rtc.c b/drivers/rtc/bfin_rtc.c index 4cf2d834b21..6cb1ebac74c 100644 --- a/drivers/rtc/bfin_rtc.c +++ b/drivers/rtc/bfin_rtc.c @@ -114,7 +114,7 @@ int rtc_get(struct rtc_time *tmp) /* Calculate the total number of seconds since epoch */ time_in_sec = (tm_sec) + MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hr) + DAYS_TO_SECS(tm_day); - to_tm(time_in_sec, tmp); + rtc_to_tm(time_in_sec, tmp); return 0; } diff --git a/drivers/rtc/date.c b/drivers/rtc/date.c index 20005657360..79beb940e5c 100644 --- a/drivers/rtc/date.c +++ b/drivers/rtc/date.c @@ -71,7 +71,7 @@ int rtc_calc_weekday(struct rtc_time *tm) return 0; } -void to_tm(int tim, struct rtc_time * tm) +int rtc_to_tm(int tim, struct rtc_time *tm) { register int i; register long hms, day; @@ -103,10 +103,14 @@ void to_tm(int tim, struct rtc_time * tm) /* Days are what is left over (+1) from all that. */ tm->tm_mday = day + 1; + /* Zero unused fields */ + tm->tm_yday = 0; + tm->tm_isdst = 0; + /* * Determine the day of week */ - rtc_calc_weekday(tm); + return rtc_calc_weekday(tm); } /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. diff --git a/drivers/rtc/ds1374.c b/drivers/rtc/ds1374.c index 427b1eb8d0a..04793b54be6 100644 --- a/drivers/rtc/ds1374.c +++ b/drivers/rtc/ds1374.c @@ -118,7 +118,7 @@ int rtc_get (struct rtc_time *tm){ DEBUGR ("Get RTC s since 1.1.1970: %ld\n", time1); - to_tm(time1, tm); /* To Gregorian Date */ + rtc_to_tm(time1, tm); /* To Gregorian Date */ if (rtc_read(RTC_SR_ADDR) & RTC_SR_BIT_OSF) { printf ("### Warning: RTC oscillator has stopped\n"); diff --git a/drivers/rtc/ftrtc010.c b/drivers/rtc/ftrtc010.c index 713dad274f1..3c5d9559439 100644 --- a/drivers/rtc/ftrtc010.c +++ b/drivers/rtc/ftrtc010.c @@ -86,7 +86,7 @@ int rtc_get(struct rtc_time *tmp) now = ftrtc010_time() + readl(&rtc->record); #endif - to_tm(now, tmp); + rtc_to_tm(now, tmp); return 0; } diff --git a/drivers/rtc/imxdi.c b/drivers/rtc/imxdi.c index 0d7d736eff5..e89034dc0a8 100644 --- a/drivers/rtc/imxdi.c +++ b/drivers/rtc/imxdi.c @@ -192,7 +192,7 @@ int rtc_get(struct rtc_time *tmp) } now = __raw_readl(&data.regs->dtcmr); - to_tm(now, tmp); + rtc_to_tm(now, tmp); err: return rc; diff --git a/drivers/rtc/mc13xxx-rtc.c b/drivers/rtc/mc13xxx-rtc.c index 528247ac86e..30c4e662dd7 100644 --- a/drivers/rtc/mc13xxx-rtc.c +++ b/drivers/rtc/mc13xxx-rtc.c @@ -36,7 +36,7 @@ int rtc_get(struct rtc_time *rtc) tim = day1 * 86400 + time; - to_tm(tim, rtc); + rtc_to_tm(tim, rtc); rtc->tm_yday = 0; rtc->tm_isdst = 0; diff --git a/drivers/rtc/mcfrtc.c b/drivers/rtc/mcfrtc.c index 8961ca4f8b6..e02e29793e0 100644 --- a/drivers/rtc/mcfrtc.c +++ b/drivers/rtc/mcfrtc.c @@ -38,7 +38,7 @@ int rtc_get(struct rtc_time *tmp) tim = (tim * 60) + rtc_mins; tim = (tim * 60) + rtc->seconds; - to_tm(tim, tmp); + rtc_to_tm(tim, tmp); tmp->tm_yday = 0; tmp->tm_isdst = 0; diff --git a/drivers/rtc/mpc8xx.c b/drivers/rtc/mpc8xx.c index d239daee1b0..796295d5b0e 100644 --- a/drivers/rtc/mpc8xx.c +++ b/drivers/rtc/mpc8xx.c @@ -26,7 +26,7 @@ int rtc_get (struct rtc_time *tmp) tim = immr->im_sit.sit_rtc; - to_tm (tim, tmp); + rtc_to_tm(tim, tmp); debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, diff --git a/drivers/rtc/mx27rtc.c b/drivers/rtc/mx27rtc.c index ae6595b8603..7ba74d3b110 100644 --- a/drivers/rtc/mx27rtc.c +++ b/drivers/rtc/mx27rtc.c @@ -30,7 +30,7 @@ int rtc_get(struct rtc_time *time) sec += min * 60 + hour * 3600 + day * 24 * 3600; - to_tm(sec, time); + rtc_to_tm(sec, time); return 0; } diff --git a/drivers/rtc/mxsrtc.c b/drivers/rtc/mxsrtc.c index 32ba8a3062c..82c2fbfde04 100644 --- a/drivers/rtc/mxsrtc.c +++ b/drivers/rtc/mxsrtc.c @@ -43,7 +43,7 @@ int rtc_get(struct rtc_time *time) uint32_t secs; secs = readl(&rtc_regs->hw_rtc_seconds); - to_tm(secs, time); + rtc_to_tm(secs, time); return 0; } diff --git a/drivers/rtc/pl031.c b/drivers/rtc/pl031.c index c4d1259a898..e6c1a6c2710 100644 --- a/drivers/rtc/pl031.c +++ b/drivers/rtc/pl031.c @@ -97,7 +97,7 @@ int rtc_get(struct rtc_time *tmp) tim = RTC_READ_REG(RTC_DR); - to_tm (tim, tmp); + rtc_to_tm(tim, tmp); debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, diff --git a/include/rtc.h b/include/rtc.h index 96c696ad65b..4b7ce6108cf 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -45,7 +45,6 @@ int rtc_get (struct rtc_time *); int rtc_set (struct rtc_time *); void rtc_reset (void); -void to_tm (int, struct rtc_time *); unsigned long mktime (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); @@ -97,4 +96,18 @@ void rtc_init(void); */ int rtc_calc_weekday(struct rtc_time *time); +/** + * rtc_to_tm() - Convert a time_t value into a broken-out time + * + * The following fields are set up by this function: + * tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday + * + * Note that tm_yday and tm_isdst are set to 0. + * + * @time_t: Number of seconds since 1970-01-01 00:00:00 + * @time: Place to put the broken-out time + * @return 0 if OK, -EINVAL if the weekday could not be determined + */ +int rtc_to_tm(int time_t, struct rtc_time *time); + #endif /* _RTC_H_ */ diff --git a/net/sntp.c b/net/sntp.c index 6422eef72ef..d7b9e5563a7 100644 --- a/net/sntp.c +++ b/net/sntp.c @@ -68,7 +68,7 @@ static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip, */ memcpy(&seconds, &rpktp->transmit_timestamp, sizeof(ulong)); - to_tm(ntohl(seconds) - 2208988800UL + net_ntp_time_offset, &tm); + rtc_to_tm(ntohl(seconds) - 2208988800UL + net_ntp_time_offset, &tm); #if defined(CONFIG_CMD_DATE) rtc_set(&tm); #endif diff --git a/post/drivers/rtc.c b/post/drivers/rtc.c index cd19f7568df..8d7a7884bc2 100644 --- a/post/drivers/rtc.c +++ b/post/drivers/rtc.c @@ -63,7 +63,7 @@ static void rtc_post_restore (struct rtc_time *tm, unsigned int sec) tm->tm_min, tm->tm_sec) + sec; struct rtc_time ntm; - to_tm (t, &ntm); + rtc_to_tm(t, &ntm); rtc_set (&ntm); } @@ -119,7 +119,7 @@ int rtc_post_test (int flags) time_t t = mktime (ynl, i + 1, daysnl[i], 23, 59, 59); struct rtc_time tm; - to_tm (t, &tm); + rtc_to_tm(t, &tm); rtc_set (&tm); skipped++; @@ -143,7 +143,7 @@ int rtc_post_test (int flags) time_t t = mktime (yl, i + 1, daysl[i], 23, 59, 59); struct rtc_time tm; - to_tm (t, &tm); + rtc_to_tm(t, &tm); rtc_set (&tm); skipped++; -- cgit v1.3.1 From 714209832db1064886680b138f1abf9ce235b2c3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:19 -0600 Subject: dm: rtc: Rename mktime() and reduce the number of parameters Most callers unpack the structure and pass each member. It seems better to pass the whole structure instead, as with the C library. Also add an rtc_ prefix. Signed-off-by: Simon Glass Acked-by: Heiko Schocher --- drivers/rtc/at91sam9_rtt.c | 3 +-- drivers/rtc/bfin_rtc.c | 3 +-- drivers/rtc/date.c | 23 ++++++++++++----------- drivers/rtc/ds1306.c | 3 +-- drivers/rtc/ds1374.c | 4 +--- drivers/rtc/ftrtc010.c | 3 +-- drivers/rtc/imxdi.c | 3 +-- drivers/rtc/mc13xxx-rtc.c | 3 +-- drivers/rtc/mpc8xx.c | 3 +-- drivers/rtc/mx27rtc.c | 3 +-- drivers/rtc/mxsrtc.c | 3 +-- drivers/rtc/pl031.c | 3 +-- include/rtc.h | 16 +++++++++++++--- post/drivers/rtc.c | 22 ++++++++++++++++++---- 14 files changed, 54 insertions(+), 41 deletions(-) (limited to 'include') diff --git a/drivers/rtc/at91sam9_rtt.c b/drivers/rtc/at91sam9_rtt.c index d3cdee04ffc..a684ad6a6f7 100644 --- a/drivers/rtc/at91sam9_rtt.c +++ b/drivers/rtc/at91sam9_rtt.c @@ -54,8 +54,7 @@ int rtc_set (struct rtc_time *tmp) at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR; ulong tim; - tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + tim = rtc_mktime(tmp); /* clear alarm, set prescaler to 32768, clear counter */ writel(32768+AT91_RTT_RTTRST, &rtt->mr); diff --git a/drivers/rtc/bfin_rtc.c b/drivers/rtc/bfin_rtc.c index 6cb1ebac74c..a079a1d4723 100644 --- a/drivers/rtc/bfin_rtc.c +++ b/drivers/rtc/bfin_rtc.c @@ -67,8 +67,7 @@ int rtc_set(struct rtc_time *tmp) wait_for_complete(); /* Calculate number of seconds this incoming time represents */ - remain = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + remain = rtc_mktime(tmp); /* Figure out how many days since epoch */ days = remain / NUM_SECS_IN_DAY; diff --git a/drivers/rtc/date.c b/drivers/rtc/date.c index 79beb940e5c..8c643a0b460 100644 --- a/drivers/rtc/date.c +++ b/drivers/rtc/date.c @@ -128,22 +128,23 @@ int rtc_to_tm(int tim, struct rtc_time *tm) * machines were long is 32-bit! (However, as time_t is signed, we * will already get problems at other places on 2038-01-19 03:14:08) */ -unsigned long -mktime (unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) +unsigned long rtc_mktime(const struct rtc_time *tm) { - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ + int mon = tm->tm_mon; + int year = tm->tm_year; + int days, hours; + + mon -= 2; + if (0 >= (int)mon) { /* 1..12 -> 11,12,1..10 */ mon += 12; /* Puts Feb last since it has leap day */ year -= 1; } - return ((( - (unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ + days = (unsigned long)(year / 4 - year / 100 + year / 400 + + 367 * mon / 12 + tm->tm_mday) + + year * 365 - 719499; + hours = days * 24 + tm->tm_hour; + return (hours * 60 + tm->tm_min) * 60 + tm->tm_sec; } #endif diff --git a/drivers/rtc/ds1306.c b/drivers/rtc/ds1306.c index 3fe6721c136..7dd3e19028e 100644 --- a/drivers/rtc/ds1306.c +++ b/drivers/rtc/ds1306.c @@ -180,8 +180,7 @@ int rtc_set (struct rtc_time *tmp) { ulong tim; - tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + tim = rtc_mktime(tmp); immap->im_sitk.sitk_rtck = KAPWR_KEY; immap->im_sit.sit_rtc = tim; diff --git a/drivers/rtc/ds1374.c b/drivers/rtc/ds1374.c index 04793b54be6..78473570b9d 100644 --- a/drivers/rtc/ds1374.c +++ b/drivers/rtc/ds1374.c @@ -147,9 +147,7 @@ int rtc_set (struct rtc_time *tmp){ if (tmp->tm_year < 1970 || tmp->tm_year > 2069) printf("WARNING: year should be between 1970 and 2069!\n"); - time = mktime(tmp->tm_year, tmp->tm_mon, - tmp->tm_mday, tmp->tm_hour, - tmp->tm_min, tmp->tm_sec); + time = rtc_mktime(tmp); DEBUGR ("Set RTC s since 1.1.1970: %ld (0x%02lx)\n", time, time); diff --git a/drivers/rtc/ftrtc010.c b/drivers/rtc/ftrtc010.c index 3c5d9559439..7d0cfb3ba8c 100644 --- a/drivers/rtc/ftrtc010.c +++ b/drivers/rtc/ftrtc010.c @@ -104,8 +104,7 @@ int rtc_set(struct rtc_time *tmp) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); - new = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour, - tmp->tm_min, tmp->tm_sec); + new = rtc_mktime(tmp); now = ftrtc010_time(); diff --git a/drivers/rtc/imxdi.c b/drivers/rtc/imxdi.c index e89034dc0a8..17519ce2c05 100644 --- a/drivers/rtc/imxdi.c +++ b/drivers/rtc/imxdi.c @@ -209,8 +209,7 @@ int rtc_set(struct rtc_time *tmp) goto err; } - now = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + now = rtc_mktime(tmp); /* zero the fractional part first */ rc = DI_WRITE_WAIT(0, dtclr); if (rc == 0) diff --git a/drivers/rtc/mc13xxx-rtc.c b/drivers/rtc/mc13xxx-rtc.c index 30c4e662dd7..3e463368b09 100644 --- a/drivers/rtc/mc13xxx-rtc.c +++ b/drivers/rtc/mc13xxx-rtc.c @@ -51,8 +51,7 @@ int rtc_set(struct rtc_time *rtc) if (!p) return -1; - time = mktime(rtc->tm_year, rtc->tm_mon, rtc->tm_mday, - rtc->tm_hour, rtc->tm_min, rtc->tm_sec); + time = rtc_mktime(rtc); day = time / 86400; time %= 86400; diff --git a/drivers/rtc/mpc8xx.c b/drivers/rtc/mpc8xx.c index 796295d5b0e..147a225c6b0 100644 --- a/drivers/rtc/mpc8xx.c +++ b/drivers/rtc/mpc8xx.c @@ -44,8 +44,7 @@ int rtc_set (struct rtc_time *tmp) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); - tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + tim = rtc_mktime(tmp); immr->im_sitk.sitk_rtck = KAPWR_KEY; immr->im_sit.sit_rtc = tim; diff --git a/drivers/rtc/mx27rtc.c b/drivers/rtc/mx27rtc.c index 7ba74d3b110..29ccdf17301 100644 --- a/drivers/rtc/mx27rtc.c +++ b/drivers/rtc/mx27rtc.c @@ -40,8 +40,7 @@ int rtc_set(struct rtc_time *time) struct rtc_regs *rtc_regs = (struct rtc_regs *)IMX_RTC_BASE; uint32_t day, hour, min, sec; - sec = mktime(time->tm_year, time->tm_mon, time->tm_mday, - time->tm_hour, time->tm_min, time->tm_sec); + sec = rtc_mktime(time); day = sec / (24 * 3600); sec = sec % (24 * 3600); diff --git a/drivers/rtc/mxsrtc.c b/drivers/rtc/mxsrtc.c index 82c2fbfde04..6e32154f47b 100644 --- a/drivers/rtc/mxsrtc.c +++ b/drivers/rtc/mxsrtc.c @@ -52,8 +52,7 @@ int rtc_set(struct rtc_time *time) { uint32_t secs; - secs = mktime(time->tm_year, time->tm_mon, time->tm_mday, - time->tm_hour, time->tm_min, time->tm_sec); + secs = rtc_mktime(time); return mxs_rtc_set_time(secs); } diff --git a/drivers/rtc/pl031.c b/drivers/rtc/pl031.c index e6c1a6c2710..fc83049ecd2 100644 --- a/drivers/rtc/pl031.c +++ b/drivers/rtc/pl031.c @@ -72,8 +72,7 @@ int rtc_set(struct rtc_time *tmp) } /* Calculate number of seconds this incoming time represents */ - tim = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + tim = rtc_mktime(tmp); RTC_WRITE_REG(RTC_LR, tim); diff --git a/include/rtc.h b/include/rtc.h index 4b7ce6108cf..b1a4bf05ec3 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -45,9 +45,6 @@ int rtc_get (struct rtc_time *); int rtc_set (struct rtc_time *); void rtc_reset (void); -unsigned long mktime (unsigned int, unsigned int, unsigned int, - unsigned int, unsigned int, unsigned int); - /** * rtc_read8() - Read an 8-bit register * @@ -110,4 +107,17 @@ int rtc_calc_weekday(struct rtc_time *time); */ int rtc_to_tm(int time_t, struct rtc_time *time); +/** + * rtc_mktime() - Convert a broken-out time into a time_t value + * + * The following fields need to be valid for this function to work: + * tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year + * + * Note that tm_wday and tm_yday are ignored. + * + * @time: Broken-out time to convert + * @return corresponding time_t value, seconds since 1970-01-01 00:00:00 + */ +unsigned long rtc_mktime(const struct rtc_time *time); + #endif /* _RTC_H_ */ diff --git a/post/drivers/rtc.c b/post/drivers/rtc.c index 8d7a7884bc2..c2e73917ec5 100644 --- a/post/drivers/rtc.c +++ b/post/drivers/rtc.c @@ -59,8 +59,7 @@ static int rtc_post_skip (ulong * diff) static void rtc_post_restore (struct rtc_time *tm, unsigned int sec) { - time_t t = mktime (tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, - tm->tm_min, tm->tm_sec) + sec; + time_t t = rtc_mktime(tm) + sec; struct rtc_time ntm; rtc_to_tm(t, &ntm); @@ -116,9 +115,16 @@ int rtc_post_test (int flags) rtc_get (&svtm); for (i = 0; i < 12; i++) { - time_t t = mktime (ynl, i + 1, daysnl[i], 23, 59, 59); + time_t t; struct rtc_time tm; + tm.tm_year = ynl; + tm.tm_mon = i + 1; + tm.tm_mday = daysnl[i]; + tm.tm_hour = 23; + tm.tm_min = 59; + tm.tm_sec = 59; + t = rtc_mktime(&tm); rtc_to_tm(t, &tm); rtc_set (&tm); @@ -140,9 +146,17 @@ int rtc_post_test (int flags) } for (i = 0; i < 12; i++) { - time_t t = mktime (yl, i + 1, daysl[i], 23, 59, 59); + time_t t; struct rtc_time tm; + tm.tm_year = yl; + tm.tm_mon = i + 1; + tm.tm_mday = daysl[i]; + tm.tm_hour = 23; + tm.tm_min = 59; + tm.tm_sec = 59; + t = rtc_mktime(&tm); + rtc_to_tm(t, &tm); rtc_set (&tm); -- cgit v1.3.1 From be47aa65225113355d1dbbc870d480d95638a3d5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:20 -0600 Subject: dm: Remove unnecessary types in bcd.h We don't need to use u8, and if we avoid it, it isn't so much of a problem that rtc.h includes this header. With this change we can include rtc.h from sandbox files. Signed-off-by: Simon Glass --- include/bcd.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/bcd.h b/include/bcd.h index af4aa9c7baf..9ecd328284e 100644 --- a/include/bcd.h +++ b/include/bcd.h @@ -10,14 +10,12 @@ #ifndef _BCD_H #define _BCD_H -#include - -static inline unsigned int bcd2bin(u8 val) +static inline unsigned int bcd2bin(unsigned int val) { - return ((val) & 0x0f) + ((val) >> 4) * 10; + return ((val) & 0x0f) + ((val & 0xff) >> 4) * 10; } -static inline u8 bin2bcd (unsigned int val) +static inline unsigned int bin2bcd(unsigned int val) { return (((val / 10) << 4) | (val % 10)); } -- cgit v1.3.1 From aac5119822041febafdab3fc9ab6dbbe6ea96bff Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:21 -0600 Subject: dm: rtc: Split structure definition into its own file Move the definition of struct rtc_time into a separate file so that sandbox can include it without requiring common.h and the like. Signed-off-by: Simon Glass --- include/rtc.h | 26 +------------------------- include/rtc_def.h | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 25 deletions(-) create mode 100644 include/rtc_def.h (limited to 'include') diff --git a/include/rtc.h b/include/rtc.h index b1a4bf05ec3..2566c83b81d 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -15,31 +15,7 @@ * it there instead of in evey single driver */ #include - -/* - * The struct used to pass data from the generic interface code to - * the hardware dependend low-level code ande vice versa. Identical - * to struct rtc_time used by the Linux kernel. - * - * Note that there are small but significant differences to the - * common "struct time": - * - * struct time: struct rtc_time: - * tm_mon 0 ... 11 1 ... 12 - * tm_year years since 1900 years since 0 - */ - -struct rtc_time { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; -}; +#include int rtc_get (struct rtc_time *); int rtc_set (struct rtc_time *); diff --git a/include/rtc_def.h b/include/rtc_def.h new file mode 100644 index 00000000000..61797972670 --- /dev/null +++ b/include/rtc_def.h @@ -0,0 +1,36 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __rtc_def_h +#define __rtc_def_h + +/* + * The struct used to pass data from the generic interface code to + * the hardware dependend low-level code ande vice versa. Identical + * to struct rtc_time used by the Linux kernel. + * + * Note that there are small but significant differences to the + * common "struct time": + * + * struct time: struct rtc_time: + * tm_mon 0 ... 11 1 ... 12 + * tm_year years since 1900 years since 0 + */ + +struct rtc_time { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +#endif -- cgit v1.3.1 From 94eefdee2f5db36d52e817a01b07c8255527e193 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:22 -0600 Subject: dm: sandbox: Add os_localtime() to obtain the system time Add a function to read the system time into U-Boot. Signed-off-by: Simon Glass --- arch/sandbox/cpu/os.c | 18 ++++++++++++++++++ include/os.h | 11 +++++++++++ 2 files changed, 29 insertions(+) (limited to 'include') diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 4d5f8057533..e6dd17e9efc 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -24,6 +24,7 @@ #include #include #include +#include /* Operating System Interface */ @@ -537,3 +538,20 @@ int os_jump_to_image(const void *dest, int size) return unlink(fname); } + +void os_localtime(struct rtc_time *rt) +{ + time_t t = time(NULL); + struct tm *tm; + + tm = localtime(&t); + rt->tm_sec = tm->tm_sec; + rt->tm_min = tm->tm_min; + rt->tm_hour = tm->tm_hour; + rt->tm_mday = tm->tm_mday; + rt->tm_mon = tm->tm_mon + 1; + rt->tm_year = tm->tm_year + 1900; + rt->tm_wday = tm->tm_wday; + rt->tm_yday = tm->tm_yday; + rt->tm_isdst = tm->tm_isdst; +} diff --git a/include/os.h b/include/os.h index a758f099aab..ffbdce84643 100644 --- a/include/os.h +++ b/include/os.h @@ -13,6 +13,7 @@ #include +struct rtc_time; struct sandbox_state; /** @@ -277,4 +278,14 @@ int os_read_ram_buf(const char *fname); */ int os_jump_to_image(const void *dest, int size); +/** + * Read the current system time + * + * This reads the current Local Time and places it into the provided + * structure. + * + * @param rt Place to put system time + */ +void os_localtime(struct rtc_time *rt); + #endif -- cgit v1.3.1 From dbeda5b2255089889788e0dd3478680feec86139 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:23 -0600 Subject: dm: rtc: Add a uclass for real-time clocks Add a uclass for real-time clocks which support getting the current time, setting it and resetting the chip to a known-working state. Some RTCs have additional registers which can be used to store settings, so also provide an interface to these. Signed-off-by: Simon Glass --- drivers/rtc/Kconfig | 8 +++ drivers/rtc/Makefile | 2 + drivers/rtc/rtc-uclass.c | 96 ++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/rtc.h | 132 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 239 insertions(+) create mode 100644 drivers/rtc/rtc-uclass.c (limited to 'include') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index e69de29bb2d..bd63621e371 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -0,0 +1,8 @@ +config DM_RTC + bool "Enable Driver Model for RTC drivers" + depends on DM + help + Enable drver model for real-time-clock drivers. The RTC uclass + then provides the rtc_get()/rtc_set() interface, delegating to + drivers to perform the actual functions. See rtc.h for a + description of the API. diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index fdcbc002953..61373b6fdb3 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -7,6 +7,8 @@ #ccflags-y += -DDEBUG +obj-$(CONFIG_DM_RTC) += rtc-uclass.o + obj-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o obj-$(CONFIG_RTC_BFIN) += bfin_rtc.o obj-y += date.o diff --git a/drivers/rtc/rtc-uclass.c b/drivers/rtc/rtc-uclass.c new file mode 100644 index 00000000000..fe74c69f97e --- /dev/null +++ b/drivers/rtc/rtc-uclass.c @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +int dm_rtc_get(struct udevice *dev, struct rtc_time *time) +{ + struct rtc_ops *ops = rtc_get_ops(dev); + + assert(ops); + if (!ops->get) + return -ENOSYS; + return ops->get(dev, time); +} + +int dm_rtc_set(struct udevice *dev, struct rtc_time *time) +{ + struct rtc_ops *ops = rtc_get_ops(dev); + + assert(ops); + if (!ops->set) + return -ENOSYS; + return ops->set(dev, time); +} + +int dm_rtc_reset(struct udevice *dev) +{ + struct rtc_ops *ops = rtc_get_ops(dev); + + assert(ops); + if (!ops->reset) + return -ENOSYS; + return ops->reset(dev); +} + +int rtc_read8(struct udevice *dev, unsigned int reg) +{ + struct rtc_ops *ops = rtc_get_ops(dev); + + assert(ops); + if (!ops->read8) + return -ENOSYS; + return ops->read8(dev, reg); +} + +int rtc_write8(struct udevice *dev, unsigned int reg, int val) +{ + struct rtc_ops *ops = rtc_get_ops(dev); + + assert(ops); + if (!ops->write8) + return -ENOSYS; + return ops->write8(dev, reg, val); +} + +int rtc_read32(struct udevice *dev, unsigned int reg, u32 *valuep) +{ + u32 value = 0; + int ret; + int i; + + for (i = 0; i < sizeof(value); i++) { + ret = rtc_read8(dev, reg + i); + if (ret) + return ret; + value |= ret << (i << 3); + } + + *valuep = value; + return 0; +} + +int rtc_write32(struct udevice *dev, unsigned int reg, u32 value) +{ + int i, ret; + + for (i = 0; i < sizeof(value); i++) { + ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff); + if (ret) + return ret; + } + + return 0; +} + +UCLASS_DRIVER(rtc) = { + .name = "rtc", + .id = UCLASS_RTC, +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 395e25a4313..08f1bad9385 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -46,6 +46,7 @@ enum uclass_id { UCLASS_USB_DEV_GENERIC, /* USB generic device */ UCLASS_MASS_STORAGE, /* Mass storage device */ UCLASS_CPU, /* CPU, typically part of an SoC */ + UCLASS_RTC, /* Real time clock device */ UCLASS_COUNT, UCLASS_INVALID = -1, diff --git a/include/rtc.h b/include/rtc.h index 2566c83b81d..bd8621d60b9 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -17,6 +17,137 @@ #include #include +#ifdef CONFIG_DM_RTC + +struct rtc_ops { + /** + * get() - get the current time + * + * Returns the current time read from the RTC device. The driver + * is responsible for setting up every field in the structure. + * + * @dev: Device to read from + * @time: Place to put the time that is read + */ + int (*get)(struct udevice *dev, struct rtc_time *time); + + /** + * set() - set the current time + * + * Sets the time in the RTC device. The driver can expect every + * field to be set correctly. + * + * @dev: Device to read from + * @time: Time to write + */ + int (*set)(struct udevice *dev, const struct rtc_time *time); + + /** + * reset() - reset the RTC to a known-good state + * + * This function resets the RTC to a known-good state. The time may + * be unset by this method, so should be set after this method is + * called. + * + * @dev: Device to read from + * @return 0 if OK, -ve on error + */ + int (*reset)(struct udevice *dev); + + /** + * read8() - Read an 8-bit register + * + * @dev: Device to read from + * @reg: Register to read + * @return value read, or -ve on error + */ + int (*read8)(struct udevice *dev, unsigned int reg); + + /** + * write8() - Write an 8-bit register + * + * @dev: Device to write to + * @reg: Register to write + * @value: Value to write + * @return 0 if OK, -ve on error + */ + int (*write8)(struct udevice *dev, unsigned int reg, int val); +}; + +/* Access the operations for an RTC device */ +#define rtc_get_ops(dev) ((struct rtc_ops *)(dev)->driver->ops) + +/** + * dm_rtc_get() - Read the time from an RTC + * + * @dev: Device to read from + * @time: Place to put the current time + * @return 0 if OK, -ve on error + */ +int dm_rtc_get(struct udevice *dev, struct rtc_time *time); + +/** + * dm_rtc_put() - Write a time to an RTC + * + * @dev: Device to read from + * @time: Time to write into the RTC + * @return 0 if OK, -ve on error + */ +int dm_rtc_set(struct udevice *dev, struct rtc_time *time); + +/** + * dm_rtc_reset() - reset the RTC to a known-good state + * + * If the RTC appears to be broken (e.g. it is not counting up in seconds) + * it may need to be reset to a known good state. This function achieves this. + * After resetting the RTC the time should then be set to a known value by + * the caller. + * + * @dev: Device to read from + * @return 0 if OK, -ve on error + */ +int dm_rtc_reset(struct udevice *dev); + +/** + * rtc_read8() - Read an 8-bit register + * + * @dev: Device to read from + * @reg: Register to read + * @return value read, or -ve on error + */ +int rtc_read8(struct udevice *dev, unsigned int reg); + +/** + * rtc_write8() - Write an 8-bit register + * + * @dev: Device to write to + * @reg: Register to write + * @value: Value to write + * @return 0 if OK, -ve on error + */ +int rtc_write8(struct udevice *dev, unsigned int reg, int val); + +/** + * rtc_read32() - Read a 32-bit value from the RTC + * + * @dev: Device to read from + * @reg: Offset to start reading from + * @valuep: Place to put the value that is read + * @return 0 if OK, -ve on error + */ +int rtc_read32(struct udevice *dev, unsigned int reg, u32 *valuep); + +/** + * rtc_write32() - Write a 32-bit value to the RTC + * + * @dev: Device to write to + * @reg: Register to start writing to + * @value: Value to write + * @return 0 if OK, -ve on error + */ +int rtc_write32(struct udevice *dev, unsigned int reg, u32 value); + +#else int rtc_get (struct rtc_time *); int rtc_set (struct rtc_time *); void rtc_reset (void); @@ -57,6 +188,7 @@ void rtc_write32(int reg, u32 value); * rtc_init() - Set up the real time clock ready for use */ void rtc_init(void); +#endif /** * rtc_calc_weekday() - Work out the weekday from a time -- cgit v1.3.1 From 8e7083fc95774017dba66cff85918ba9f0d0f12b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Apr 2015 12:37:29 -0600 Subject: dm: rtc: sandbox: Enable real-time clock support Enable real-time-clock support in sandbox. Signed-off-by: Simon Glass --- configs/sandbox_defconfig | 1 + drivers/rtc/Makefile | 2 -- include/configs/sandbox.h | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 5de7fbedb4e..759f53aaa7c 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -26,3 +26,4 @@ CONFIG_TPM_TIS_SANDBOX=y CONFIG_SOUND=y CONFIG_CMD_SOUND=y CONFIG_SOUND_SANDBOX=y +CONFIG_DM_RTC=y diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 9077bb39f1e..3092de1d9c6 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -52,7 +52,5 @@ obj-$(CONFIG_RTC_RTC4543) += rtc4543.o obj-$(CONFIG_RTC_RV3029) += rv3029.o obj-$(CONFIG_RTC_RX8025) += rx8025.o obj-$(CONFIG_RTC_S3C24X0) += s3c24x0_rtc.o -ifdef CONFIG_DM_RTC obj-$(CONFIG_SANDBOX) += sandbox_rtc.o -endif obj-$(CONFIG_RTC_X1205) += x1205.o diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 3bf45a224d2..ef0efc57959 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -207,5 +207,6 @@ #define CONFIG_CMD_LZMADEC #define CONFIG_CMD_USB +#define CONFIG_CMD_DATE #endif -- cgit v1.3.1 From f78a5c0774da9ca1702df453f974f022580552f4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 5 May 2015 11:54:31 +0200 Subject: dm: usb: Make usb_get_bus easier to use for callers Make usb_get_bus easier to use for callers, by directly returning the bus rather then returning it via a pass-by-ref argument. This also removes the error checking from the current callers, as we already have an assert() for bus not being NULL in usb_get_bus(). Signed-off-by: Hans de Goede Acked-by: Simon Glass --- drivers/usb/host/usb-uclass.c | 17 ++++------------- include/usb.h | 7 +++---- 2 files changed, 7 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index 8dc18236aba..ba7d32a046a 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -476,9 +476,7 @@ int usb_scan_device(struct udevice *parent, int port, *devp = NULL; memset(udev, '\0', sizeof(*udev)); - ret = usb_get_bus(parent, &udev->controller_dev); - if (ret) - return ret; + udev->controller_dev = usb_get_bus(parent); priv = dev_get_uclass_priv(udev->controller_dev); /* @@ -578,35 +576,28 @@ int usb_child_post_bind(struct udevice *dev) return 0; } -int usb_get_bus(struct udevice *dev, struct udevice **busp) +struct udevice *usb_get_bus(struct udevice *dev) { struct udevice *bus; - *busp = NULL; for (bus = dev; bus && device_get_uclass_id(bus) != UCLASS_USB; ) bus = bus->parent; if (!bus) { /* By design this cannot happen */ assert(bus); debug("USB HUB '%s' does not have a controller\n", dev->name); - return -EXDEV; } - *busp = bus; - return 0; + return bus; } int usb_child_pre_probe(struct udevice *dev) { - struct udevice *bus; struct usb_device *udev = dev_get_parentdata(dev); struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); int ret; - ret = usb_get_bus(dev, &bus); - if (ret) - return ret; - udev->controller_dev = bus; + udev->controller_dev = usb_get_bus(dev); udev->dev = dev; udev->devnum = plat->devnum; udev->slot_id = plat->slot_id; diff --git a/include/usb.h b/include/usb.h index 1984e8f590c..6207d369959 100644 --- a/include/usb.h +++ b/include/usb.h @@ -742,11 +742,10 @@ int usb_scan_device(struct udevice *parent, int port, * will be a device with uclass UCLASS_USB. * * @dev: Device to check - * @busp: Returns bus, or NULL if not found - * @return 0 if OK, -EXDEV is somehow this bus does not have a controller (this - * indicates a critical error in the USB stack + * @return The bus, or NULL if not found (this indicates a critical error in + * the USB stack */ -int usb_get_bus(struct udevice *dev, struct udevice **busp); +struct udevice *usb_get_bus(struct udevice *dev); /** * usb_select_config() - Set up a device ready for use -- cgit v1.3.1 From 7f1a07538f71b2b0f37744bdc899be294e0518b5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 5 May 2015 11:54:32 +0200 Subject: dm: usb: Copy over usb_device values from usb_scan_device() to final usb_device Currently we copy over a number of usb_device values stored in the on stack struct usb_device probed in usb_scan_device() to the final driver-model managed struct usb_device in usb_child_pre_probe() through usb_device_platdata, and then call usb_select_config() to fill in the rest. There are 3 problems with this approach: 1) It does not fill in enough fields before calling usb_select_config(), specifically it does not fill in ep0's maxpacketsize causing a div by zero exception in the ehci driver. 2) It unnecessarily redoes a number of usb requests making usb probing slower 3) Calling usb_select_config() a second time fails on some usb-1 devices plugged into usb-2 hubs, causing u-boot to not recognize these devices. This commit fixes these issues by removing (*) the usb_select_config() call from usb_child_pre_probe(), and instead of copying over things field by field through usb_device_platdata, store a pointer to the in stack usb_device (which is still valid when usb_child_pre_probe() gets called) and copy over the entire struct. *) Except for devices which are explictly instantiated through device-tree rather then discovered through usb_scan_device() such as emulated usb devices in the sandbox. Signed-off-by: Hans de Goede Acked-by: Simon Glass --- drivers/usb/host/usb-uclass.c | 43 ++++++++++++++++++++++++++++--------------- include/usb.h | 17 ++++++++++------- 2 files changed, 38 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index ba7d32a046a..c5ece584070 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -533,11 +533,7 @@ int usb_scan_device(struct udevice *parent, int port, plat = dev_get_parent_platdata(dev); debug("%s: Probing '%s', plat=%p\n", __func__, dev->name, plat); plat->devnum = udev->devnum; - plat->speed = udev->speed; - plat->slot_id = udev->slot_id; - plat->portnr = port; - debug("** device '%s': stashing slot_id=%d\n", dev->name, - plat->slot_id); + plat->udev = udev; priv->next_addr++; ret = device_probe(dev); if (ret) { @@ -597,17 +593,34 @@ int usb_child_pre_probe(struct udevice *dev) struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); int ret; - udev->controller_dev = usb_get_bus(dev); - udev->dev = dev; - udev->devnum = plat->devnum; - udev->slot_id = plat->slot_id; - udev->portnr = plat->portnr; - udev->speed = plat->speed; - debug("** device '%s': getting slot_id=%d\n", dev->name, plat->slot_id); + if (plat->udev) { + /* + * Copy over all the values set in the on stack struct + * usb_device in usb_scan_device() to our final struct + * usb_device for this dev. + */ + *udev = *(plat->udev); + /* And clear plat->udev as it will not be valid for long */ + plat->udev = NULL; + udev->dev = dev; + } else { + /* + * This happens with devices which are explicitly bound + * instead of being discovered through usb_scan_device() + * such as sandbox emul devices. + */ + udev->dev = dev; + udev->controller_dev = usb_get_bus(dev); + udev->devnum = plat->devnum; - ret = usb_select_config(udev); - if (ret) - return ret; + /* + * udev did not go through usb_scan_device(), so we need to + * select the config and read the config descriptors. + */ + ret = usb_select_config(udev); + if (ret) + return ret; + } return 0; } diff --git a/include/usb.h b/include/usb.h index 6207d369959..4c210502031 100644 --- a/include/usb.h +++ b/include/usb.h @@ -571,20 +571,23 @@ struct usb_platdata { * This is used by sandbox to provide emulation data also. * * @id: ID used to match this device - * @speed: Stores the speed associated with a USB device * @devnum: Device address on the USB bus - * @slot_id: USB3 slot ID, which is separate from the device address - * @portnr: Port number of this device on its parent hub, numbered from 1 - * (0 mean this device is the root hub) + * @udev: usb-uclass internal use only do NOT use * @strings: List of descriptor strings (for sandbox emulation purposes) * @desc_list: List of descriptors (for sandbox emulation purposes) */ struct usb_dev_platdata { struct usb_device_id id; - enum usb_device_speed speed; int devnum; - int slot_id; - int portnr; /* Hub port number, 1..n */ + /* + * This pointer is used to pass the usb_device used in usb_scan_device, + * to get the usb descriptors before the driver is known, to the + * actual udevice once the driver is known and the udevice is created. + * This will be NULL except during probe, do NOT use. + * + * This should eventually go away. + */ + struct usb_device *udev; #ifdef CONFIG_SANDBOX struct usb_string *strings; /* NULL-terminated list of descriptor pointers */ -- cgit v1.3.1 From ebaa832e9904677e2aea96d20e9c2c669e1ec7df Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Thu, 30 Apr 2015 22:16:09 +0200 Subject: sandbox: Don't try distro_bootcmd by default For the distro_bootcmds to succeed on the sandbox a bit of setup is required (e.g. network configured or host image bound), so running them by default isn't that useful. Add a -b/--boot command to the sandbox binary, which triggers the distro_bootcmds to run after the other command-line commands. Signed-off-by: Sjoerd Simons Acked-by: Simon Glass --- arch/sandbox/cpu/start.c | 20 +++++++++++++++++--- arch/sandbox/include/asm/state.h | 1 + include/configs/sandbox.h | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index ec010402d77..b23d08b5a1b 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -77,12 +77,18 @@ int sandbox_main_loop_init(void) struct sandbox_state *state = state_get_current(); /* Execute command if required */ - if (state->cmd) { - int retval; + if (state->cmd || state->run_distro_boot) { + int retval = 0; cli_init(); - retval = run_command_list(state->cmd, -1, 0); + if (state->cmd) + retval = run_command_list(state->cmd, -1, 0); + + if (state->run_distro_boot) + retval = cli_simple_run_command("run distro_bootcmd", + 0); + if (!state->interactive) os_exit(retval); } @@ -90,6 +96,14 @@ int sandbox_main_loop_init(void) return 0; } +static int sandbox_cmdline_cb_boot(struct sandbox_state *state, + const char *arg) +{ + state->run_distro_boot = true; + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(boot, 'b', 0, "Run distro boot commands"); + static int sandbox_cmdline_cb_command(struct sandbox_state *state, const char *arg) { diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index a0c24ba1e05..a57480a996f 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -42,6 +42,7 @@ struct sandbox_spi_info { struct sandbox_state { const char *cmd; /* Command to execute */ bool interactive; /* Enable cmdline after execute */ + bool run_distro_boot; /* Automatically run distro bootcommands */ const char *fdt_fname; /* Filename of FDT binary */ const char *parse_err; /* Error to report from parsing */ int argc; /* Program arguments */ diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index ef0efc57959..f5361d1091b 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -125,6 +125,8 @@ func(HOST, host, 1) \ func(HOST, host, 0) +#define CONFIG_BOOTCOMMAND "" + #include #define CONFIG_KEEP_SERVERADDR -- cgit v1.3.1 From f56da290b8df14a058b43735494dbbb0f8521a89 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 25 Mar 2015 12:23:07 -0600 Subject: dm: usb: exynos: Drop legacy USB code Drop the code that doesn't use driver model for USB. Signed-off-by: Simon Glass --- drivers/usb/host/ehci-exynos.c | 117 ---------------------------------------- drivers/usb/host/xhci-exynos5.c | 108 ------------------------------------- include/fdtdec.h | 2 - lib/fdtdec.c | 2 - 4 files changed, 229 deletions(-) (limited to 'include') diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 86cf6312feb..18e9251b64f 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -25,14 +25,12 @@ /* Declare global data pointer */ DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_DM_USB struct exynos_ehci_platdata { struct usb_platdata usb_plat; fdt_addr_t hcd_base; fdt_addr_t phy_base; struct gpio_desc vbus_gpio; }; -#endif /** * Contains pointers to register base addresses @@ -42,16 +40,8 @@ struct exynos_ehci { struct ehci_ctrl ctrl; struct exynos_usb_phy *usb; struct ehci_hccr *hcd; -#ifndef CONFIG_DM_USB - struct gpio_desc vbus_gpio; -#endif }; -#ifndef CONFIG_DM_USB -static struct exynos_ehci exynos; -#endif - -#ifdef CONFIG_DM_USB static int ehci_usb_ofdata_to_platdata(struct udevice *dev) { struct exynos_ehci_platdata *plat = dev_get_platdata(dev); @@ -91,55 +81,6 @@ static int ehci_usb_ofdata_to_platdata(struct udevice *dev) return 0; } -#else -static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos) -{ - fdt_addr_t addr; - unsigned int node; - int depth; - - node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS_EHCI); - if (node <= 0) { - debug("EHCI: Can't get device node for ehci\n"); - return -ENODEV; - } - - /* - * Get the base address for EHCI controller from the device node - */ - addr = fdtdec_get_addr(blob, node, "reg"); - if (addr == FDT_ADDR_T_NONE) { - debug("Can't get the EHCI register address\n"); - return -ENXIO; - } - - exynos->hcd = (struct ehci_hccr *)addr; - - /* Vbus gpio */ - gpio_request_by_name_nodev(blob, node, "samsung,vbus-gpio", 0, - &exynos->vbus_gpio, GPIOD_IS_OUT); - - depth = 0; - node = fdtdec_next_compatible_subnode(blob, node, - COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth); - if (node <= 0) { - debug("EHCI: Can't get device node for usb-phy controller\n"); - return -ENODEV; - } - - /* - * Get the base address for usbphy from the device node - */ - exynos->usb = (struct exynos_usb_phy *)fdtdec_get_addr(blob, node, - "reg"); - if (exynos->usb == NULL) { - debug("Can't get the usbphy register address\n"); - return -ENXIO; - } - - return 0; -} -#endif static void exynos5_setup_usb_phy(struct exynos_usb_phy *usb) { @@ -270,63 +211,6 @@ static void reset_usb_phy(struct exynos_usb_phy *usb) set_usbhost_phy_ctrl(POWER_USB_HOST_PHY_CTRL_DISABLE); } -#ifndef CONFIG_DM_USB -/* - * EHCI-initialization - * Create the appropriate control structures to manage - * a new EHCI host controller. - */ -int ehci_hcd_init(int index, enum usb_init_type init, - struct ehci_hccr **hccr, struct ehci_hcor **hcor) -{ - struct exynos_ehci *ctx = &exynos; - -#ifdef CONFIG_OF_CONTROL - if (exynos_usb_parse_dt(gd->fdt_blob, ctx)) { - debug("Unable to parse device tree for ehci-exynos\n"); - return -ENODEV; - } -#else - ctx->usb = (struct exynos_usb_phy *)samsung_get_base_usb_phy(); - ctx->hcd = (struct ehci_hccr *)samsung_get_base_usb_ehci(); -#endif - -#ifdef CONFIG_OF_CONTROL - /* setup the Vbus gpio here */ - if (dm_gpio_is_valid(&ctx->vbus_gpio)) - dm_gpio_set_value(&ctx->vbus_gpio, 1); -#endif - - setup_usb_phy(ctx->usb); - - board_usb_init(index, init); - - *hccr = ctx->hcd; - *hcor = (struct ehci_hcor *)((uint32_t) *hccr - + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); - - debug("Exynos5-ehci: init hccr %x and hcor %x hc_length %d\n", - (uint32_t)*hccr, (uint32_t)*hcor, - (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); - - return 0; -} - -/* - * Destroy the appropriate control structures corresponding - * the EHCI host controller. - */ -int ehci_hcd_stop(int index) -{ - struct exynos_ehci *ctx = &exynos; - - reset_usb_phy(ctx->usb); - - return 0; -} -#endif - -#ifdef CONFIG_DM_USB static int ehci_usb_probe(struct udevice *dev) { struct exynos_ehci_platdata *plat = dev_get_platdata(dev); @@ -377,4 +261,3 @@ U_BOOT_DRIVER(usb_ehci) = { .platdata_auto_alloc_size = sizeof(struct exynos_ehci_platdata), .flags = DM_FLAG_ALLOC_PRIV_DMA, }; -#endif diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c index 23c7ecc5d86..a27a79632b8 100644 --- a/drivers/usb/host/xhci-exynos5.c +++ b/drivers/usb/host/xhci-exynos5.c @@ -33,36 +33,24 @@ /* Declare global data pointer */ DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_DM_USB struct exynos_xhci_platdata { fdt_addr_t hcd_base; fdt_addr_t phy_base; struct gpio_desc vbus_gpio; }; -#endif /** * Contains pointers to register base addresses * for the usb controller. */ struct exynos_xhci { -#ifdef CONFIG_DM_USB struct usb_platdata usb_plat; -#endif struct xhci_ctrl ctrl; struct exynos_usb3_phy *usb3_phy; struct xhci_hccr *hcd; struct dwc3 *dwc3_reg; -#ifndef CONFIG_DM_USB - struct gpio_desc vbus_gpio; -#endif }; -#ifndef CONFIG_DM_USB -static struct exynos_xhci exynos; -#endif - -#ifdef CONFIG_DM_USB static int xhci_usb_ofdata_to_platdata(struct udevice *dev) { struct exynos_xhci_platdata *plat = dev_get_platdata(dev); @@ -102,54 +90,6 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev) return 0; } -#else -static int exynos_usb3_parse_dt(const void *blob, struct exynos_xhci *exynos) -{ - fdt_addr_t addr; - unsigned int node; - int depth; - - node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_XHCI); - if (node <= 0) { - debug("XHCI: Can't get device node for xhci\n"); - return -ENODEV; - } - - /* - * Get the base address for XHCI controller from the device node - */ - addr = fdtdec_get_addr(blob, node, "reg"); - if (addr == FDT_ADDR_T_NONE) { - debug("Can't get the XHCI register base address\n"); - return -ENXIO; - } - exynos->hcd = (struct xhci_hccr *)addr; - - /* Vbus gpio */ - gpio_request_by_name_nodev(blob, node, "samsung,vbus-gpio", 0, - &exynos->vbus_gpio, GPIOD_IS_OUT); - - depth = 0; - node = fdtdec_next_compatible_subnode(blob, node, - COMPAT_SAMSUNG_EXYNOS5_USB3_PHY, &depth); - if (node <= 0) { - debug("XHCI: Can't get device node for usb3-phy controller\n"); - return -ENODEV; - } - - /* - * Get the base address for usbphy from the device node - */ - exynos->usb3_phy = (struct exynos_usb3_phy *)fdtdec_get_addr(blob, node, - "reg"); - if (exynos->usb3_phy == NULL) { - debug("Can't get the usbphy register address\n"); - return -ENXIO; - } - - return 0; -} -#endif static void exynos5_usb3_phy_init(struct exynos_usb3_phy *phy) { @@ -340,53 +280,6 @@ static void exynos_xhci_core_exit(struct exynos_xhci *exynos) exynos5_usb3_phy_exit(exynos->usb3_phy); } -#ifndef CONFIG_DM_USB -int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor) -{ - struct exynos_xhci *ctx = &exynos; - int ret; - -#ifdef CONFIG_OF_CONTROL - exynos_usb3_parse_dt(gd->fdt_blob, ctx); -#else - ctx->usb3_phy = (struct exynos_usb3_phy *)samsung_get_base_usb3_phy(); - ctx->hcd = (struct xhci_hccr *)samsung_get_base_usb_xhci(); -#endif - - ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET); - -#ifdef CONFIG_OF_CONTROL - /* setup the Vbus gpio here */ - if (dm_gpio_is_valid(&ctx->vbus_gpio)) - dm_gpio_set_value(&ctx->vbus_gpio, 1); -#endif - - ret = exynos_xhci_core_init(ctx); - if (ret) { - puts("XHCI: failed to initialize controller\n"); - return -EINVAL; - } - - *hccr = (ctx->hcd); - *hcor = (struct xhci_hcor *)((uint32_t) *hccr - + HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase))); - - debug("Exynos5-xhci: init hccr %x and hcor %x hc_length %d\n", - (uint32_t)*hccr, (uint32_t)*hcor, - (uint32_t)HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase))); - - return 0; -} - -void xhci_hcd_stop(int index) -{ - struct exynos_xhci *ctx = &exynos; - - exynos_xhci_core_exit(ctx); -} -#endif - -#ifdef CONFIG_DM_USB static int xhci_usb_probe(struct udevice *dev) { struct exynos_xhci_platdata *plat = dev_get_platdata(dev); @@ -443,4 +336,3 @@ U_BOOT_DRIVER(usb_xhci) = { .priv_auto_alloc_size = sizeof(struct exynos_xhci), .flags = DM_FLAG_ALLOC_PRIV_DMA, }; -#endif diff --git a/include/fdtdec.h b/include/fdtdec.h index 659047097a1..f11475b5fdd 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -145,8 +145,6 @@ enum fdt_compat_id { COMPAT_SAMSUNG_EXYNOS5_SOUND, /* Exynos Sound */ COMPAT_WOLFSON_WM8994_CODEC, /* Wolfson WM8994 Sound Codec */ COMPAT_GOOGLE_CROS_EC_KEYB, /* Google CROS_EC Keyboard */ - COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */ - COMPAT_SAMSUNG_EXYNOS5_XHCI, /* Exynos5 XHCI controller */ COMPAT_SAMSUNG_EXYNOS_USB_PHY, /* Exynos phy controller for usb2.0 */ COMPAT_SAMSUNG_EXYNOS5_USB3_PHY,/* Exynos phy controller for usb3.0 */ COMPAT_SAMSUNG_EXYNOS_TMU, /* Exynos TMU */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 80b897a21cd..b76d9cad83f 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -44,8 +44,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"), COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"), COMPAT(GOOGLE_CROS_EC_KEYB, "google,cros-ec-keyb"), - COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"), - COMPAT(SAMSUNG_EXYNOS5_XHCI, "samsung,exynos5250-xhci"), COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"), COMPAT(SAMSUNG_EXYNOS5_USB3_PHY, "samsung,exynos5250-usb3-phy"), COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"), -- cgit v1.3.1