Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2153f949 authored by Johan Hovold's avatar Johan Hovold Committed by Linus Torvalds
Browse files

rtc: omap: add structured device-type info



Add structured device-type info to encode IP-block revision differences.

Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Benot Cousson <bcousson@baylibre.com>
Cc: Lokesh Vutla <lokeshvutla@ti.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Tero Kristo <t-kristo@ti.com>
Cc: Keerthy J <j-keerthy@ti.com>
Tested-by: default avatarFelipe Balbi <balbi@ti.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a430ca22
Loading
Loading
Loading
Loading
+51 −52
Original line number Original line Diff line number Diff line
@@ -102,19 +102,11 @@
#define	KICK0_VALUE			0x83e70b13
#define	KICK0_VALUE			0x83e70b13
#define	KICK1_VALUE			0x95a4f1e0
#define	KICK1_VALUE			0x95a4f1e0


#define	OMAP_RTC_HAS_KICKER		BIT(0)
struct omap_rtc_device_type {

	bool has_32kclk_en;
/*
	bool has_kicker;
 * Few RTC IP revisions has special WAKE-EN Register to enable Wakeup
	bool has_irqwakeen;
 * generation for event Alarm.
};
 */
#define	OMAP_RTC_HAS_IRQWAKEEN		BIT(1)

/*
 * Some RTC IP revisions (like those in AM335x and DRA7x) need
 * the 32KHz clock to be explicitly enabled.
 */
#define OMAP_RTC_HAS_32KCLK_EN		BIT(2)


struct omap_rtc {
struct omap_rtc {
	struct rtc_device *rtc;
	struct rtc_device *rtc;
@@ -122,7 +114,7 @@ struct omap_rtc {
	int irq_alarm;
	int irq_alarm;
	int irq_timer;
	int irq_timer;
	u8 interrupts_reg;
	u8 interrupts_reg;
	unsigned long flags;
	const struct omap_rtc_device_type *type;
};
};


static inline u8 rtc_read(struct omap_rtc *rtc, unsigned int reg)
static inline u8 rtc_read(struct omap_rtc *rtc, unsigned int reg)
@@ -190,7 +182,7 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
	local_irq_disable();
	local_irq_disable();
	rtc_wait_not_busy(rtc);
	rtc_wait_not_busy(rtc);
	reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
	reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
	if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN)
	if (rtc->type->has_irqwakeen)
		irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN);
		irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN);


	if (enabled) {
	if (enabled) {
@@ -202,7 +194,7 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
	}
	}
	rtc_wait_not_busy(rtc);
	rtc_wait_not_busy(rtc);
	rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg);
	rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg);
	if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN)
	if (rtc->type->has_irqwakeen)
		rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg);
		rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg);
	local_irq_enable();
	local_irq_enable();


@@ -326,7 +318,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
	rtc_write(rtc, OMAP_RTC_ALARM_SECONDS_REG, alm->time.tm_sec);
	rtc_write(rtc, OMAP_RTC_ALARM_SECONDS_REG, alm->time.tm_sec);


	reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
	reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
	if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN)
	if (rtc->type->has_irqwakeen)
		irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN);
		irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN);


	if (alm->enabled) {
	if (alm->enabled) {
@@ -337,7 +329,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
		irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
		irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
	}
	}
	rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg);
	rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg);
	if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN)
	if (rtc->type->has_irqwakeen)
		rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg);
		rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg);


	local_irq_enable();
	local_irq_enable();
@@ -353,34 +345,45 @@ static struct rtc_class_ops omap_rtc_ops = {
	.alarm_irq_enable = omap_rtc_alarm_irq_enable,
	.alarm_irq_enable = omap_rtc_alarm_irq_enable,
};
};


#define	OMAP_RTC_DATA_AM3352_IDX	1
static const struct omap_rtc_device_type omap_rtc_default_type = {
#define	OMAP_RTC_DATA_DA830_IDX		2
};

static const struct omap_rtc_device_type omap_rtc_am3352_type = {
	.has_32kclk_en	= true,
	.has_kicker	= true,
	.has_irqwakeen	= true,
};

static const struct omap_rtc_device_type omap_rtc_da830_type = {
	.has_kicker	= true,
};


static const struct platform_device_id omap_rtc_devtype[] = {
static const struct platform_device_id omap_rtc_id_table[] = {
	{
	{
		.name	= "omap_rtc",
		.name	= "omap_rtc",
	},
		.driver_data = (kernel_ulong_t)&omap_rtc_default_type,
	[OMAP_RTC_DATA_AM3352_IDX] = {
	}, {
		.name	= "am3352-rtc",
		.name	= "am3352-rtc",
		.driver_data = OMAP_RTC_HAS_KICKER | OMAP_RTC_HAS_IRQWAKEEN |
		.driver_data = (kernel_ulong_t)&omap_rtc_am3352_type,
			       OMAP_RTC_HAS_32KCLK_EN,
	}, {
	},
	[OMAP_RTC_DATA_DA830_IDX] = {
		.name	= "da830-rtc",
		.name	= "da830-rtc",
		.driver_data = OMAP_RTC_HAS_KICKER,
		.driver_data = (kernel_ulong_t)&omap_rtc_da830_type,
	},
	}, {
	{},
		/* sentinel */
	}
};
};
MODULE_DEVICE_TABLE(platform, omap_rtc_devtype);
MODULE_DEVICE_TABLE(platform, omap_rtc_id_table);


static const struct of_device_id omap_rtc_of_match[] = {
static const struct of_device_id omap_rtc_of_match[] = {
	{	.compatible	= "ti,da830-rtc",
	{
		.data		= &omap_rtc_devtype[OMAP_RTC_DATA_DA830_IDX],
		.compatible	= "ti,am3352-rtc",
	},
		.data		= &omap_rtc_am3352_type,
	{	.compatible	= "ti,am3352-rtc",
	}, {
		.data		= &omap_rtc_devtype[OMAP_RTC_DATA_AM3352_IDX],
		.compatible	= "ti,da830-rtc",
	},
		.data		= &omap_rtc_da830_type,
	{},
	}, {
		/* sentinel */
	}
};
};
MODULE_DEVICE_TABLE(of, omap_rtc_of_match);
MODULE_DEVICE_TABLE(of, omap_rtc_of_match);


@@ -398,17 +401,13 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
		return -ENOMEM;
		return -ENOMEM;


	of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
	of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
	if (of_id)
	if (of_id) {
		pdev->id_entry = of_id->data;
		rtc->type = of_id->data;

	} else {
		id_entry = platform_get_device_id(pdev);
		id_entry = platform_get_device_id(pdev);
	if (!id_entry) {
		rtc->type = (void *)id_entry->driver_data;
		dev_err(&pdev->dev, "no matching device entry\n");
		return -ENODEV;
	}
	}


	rtc->flags = id_entry->driver_data;

	rtc->irq_timer = platform_get_irq(pdev, 0);
	rtc->irq_timer = platform_get_irq(pdev, 0);
	if (rtc->irq_timer <= 0)
	if (rtc->irq_timer <= 0)
		return -ENOENT;
		return -ENOENT;
@@ -428,7 +427,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
	pm_runtime_enable(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);


	if (rtc->flags & OMAP_RTC_HAS_KICKER) {
	if (rtc->type->has_kicker) {
		rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE);
		rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE);
		rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE);
		rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE);
	}
	}
@@ -441,7 +440,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
	rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, 0);
	rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, 0);


	/* enable RTC functional clock */
	/* enable RTC functional clock */
	if (rtc->flags & OMAP_RTC_HAS_32KCLK_EN) {
	if (rtc->type->has_32kclk_en) {
		reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
		reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
		rtc_writel(rtc, OMAP_RTC_OSC_REG,
		rtc_writel(rtc, OMAP_RTC_OSC_REG,
				reg | OMAP_RTC_OSC_32KCLK_EN);
				reg | OMAP_RTC_OSC_32KCLK_EN);
@@ -511,7 +510,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)


err:
err:
	device_init_wakeup(&pdev->dev, false);
	device_init_wakeup(&pdev->dev, false);
	if (rtc->flags & OMAP_RTC_HAS_KICKER)
	if (rtc->type->has_kicker)
		rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0);
		rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0);
	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
@@ -528,7 +527,7 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
	/* leave rtc running, but disable irqs */
	/* leave rtc running, but disable irqs */
	rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0);
	rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0);


	if (rtc->flags & OMAP_RTC_HAS_KICKER)
	if (rtc->type->has_kicker)
		rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0);
		rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0);


	/* Disable the clock/module */
	/* Disable the clock/module */
@@ -594,7 +593,7 @@ static struct platform_driver omap_rtc_driver = {
		.pm	= &omap_rtc_pm_ops,
		.pm	= &omap_rtc_pm_ops,
		.of_match_table = omap_rtc_of_match,
		.of_match_table = omap_rtc_of_match,
	},
	},
	.id_table	= omap_rtc_devtype,
	.id_table	= omap_rtc_id_table,
};
};


module_platform_driver_probe(omap_rtc_driver, omap_rtc_probe);
module_platform_driver_probe(omap_rtc_driver, omap_rtc_probe);