All of lore.kernel.org
 help / color / mirror / Atom feed
From: Carlos Aguiar <carlos.aguiar@indt.org.br>
To: Pierre Ossman <drzeus-list@drzeus.cx>
Cc: Tony Lindgren <tony@atomide.com>, linux-kernel@vger.kernel.org
Subject: [PATCH 06/18] MMC: OMAP: Add back cover switch support
Date: Mon, 28 Jan 2008 15:07:27 -0400	[thread overview]
Message-ID: <479E27EF.5000000@indt.org.br> (raw)

From: Juha Yrjola <juha.yrjola@solidboot.com>

This patch adds back MMC cover switch support in a way that
supports multiple slots.

Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
Signed-off-by: Jarkko Lavinen <jarkko.lavinen@nokia.com>
Signed-off-by: Carlos Eduardo Aguiar <carlos.aguiar@indt.org.br>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/mmc/host/omap.c |   85 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 84 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 35719e7..c6dac7e 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -107,6 +107,10 @@ struct mmc_omap_slot {
 	unsigned int		fclk_freq;
 	unsigned		powered:1;
 
+	struct work_struct      switch_work;
+	struct timer_list       switch_timer;
+	unsigned		cover_open;
+
 	struct mmc_request      *mrq;
 	struct mmc_omap_host    *host;
 	struct mmc_host		*mmc;
@@ -227,6 +231,25 @@ static void mmc_omap_release_slot(struct mmc_omap_slot *slot)
 	spin_unlock_irqrestore(&host->slot_lock, flags);
 }
 
+static inline
+int mmc_omap_cover_is_open(struct mmc_omap_slot *slot)
+{
+	return slot->pdata->get_cover_state(mmc_dev(slot->mmc), slot->id);
+}
+
+static ssize_t
+mmc_omap_show_cover_switch(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
+	struct mmc_omap_slot *slot = mmc_priv(mmc);
+
+	return sprintf(buf, "%s\n", mmc_omap_cover_is_open(slot) ? "open" :
+		       "closed");
+}
+
+static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL);
+
 /* Access to the R/O switch is required for production testing
  * purposes. */
 static ssize_t
@@ -563,7 +586,8 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
 						host->cmd->opcode !=
 						MMC_SEND_OP_COND &&
 						host->cmd->opcode !=
-						MMC_APP_CMD)
+						MMC_APP_CMD &&
+						!mmc_omap_cover_is_open(slot))
 					dev_err(mmc_dev(host->mmc),
 						"command timeout, CMD %d\n",
 						host->cmd->opcode);
@@ -612,6 +636,42 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed)
+{
+	struct mmc_omap_host *host = dev_get_drvdata(dev);
+
+	BUG_ON(slot >= host->nr_slots);
+
+	/* Other subsystems can call in here before we're initialised. */
+	if (host->nr_slots == 0 || !host->slots[slot])
+		return;
+
+	schedule_work(&host->slots[slot]->switch_work);
+}
+
+static void mmc_omap_switch_timer(unsigned long arg)
+{
+	struct mmc_omap_slot *slot = (struct mmc_omap_slot *) arg;
+
+	schedule_work(&slot->switch_work);
+}
+
+static void mmc_omap_cover_handler(struct work_struct *work)
+{
+	struct mmc_omap_slot *slot = container_of(work, struct mmc_omap_slot,
+						  switch_work);
+	int cover_open;
+
+	cover_open = mmc_omap_cover_is_open(slot);
+	if (cover_open != slot->cover_open) {
+		sysfs_notify(&slot->mmc->class_dev.kobj, NULL, "cover_switch");
+		slot->cover_open = cover_open;
+		dev_info(mmc_dev(slot->mmc), "cover is now %s\n",
+			 cover_open ? "open" : "closed");
+	}
+	mmc_detect_change(slot->mmc, slot->id);
+}
+
 /* Prepare to transfer the next segment of a scatterlist */
 static void
 mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
@@ -1093,13 +1153,31 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
 			goto err_remove_host;
 	}
 
+	if (slot->pdata->get_cover_state != NULL) {
+		r = device_create_file(&mmc->class_dev,
+					&dev_attr_cover_switch);
+		if (r < 0)
+			goto err_remove_slot_name;
+
+		INIT_WORK(&slot->switch_work, mmc_omap_cover_handler);
+		init_timer(&slot->switch_timer);
+		slot->switch_timer.function = mmc_omap_switch_timer;
+		slot->switch_timer.data = (unsigned long) slot;
+		schedule_work(&slot->switch_work);
+	}
+
 	if (slot->pdata->get_ro != NULL) {
 		r = device_create_file(&mmc->class_dev,
 					&dev_attr_ro);
+		if (r < 0)
+			goto err_remove_cover_attr;
 	}
 
 	return 0;
 
+err_remove_cover_attr:
+	if (slot->pdata->get_cover_state != NULL)
+		device_remove_file(&mmc->class_dev, &dev_attr_cover_switch);
 err_remove_slot_name:
 	if (slot->pdata->name != NULL)
 		device_remove_file(&mmc->class_dev, &dev_attr_ro);
@@ -1114,9 +1192,14 @@ static void mmc_omap_remove_slot(struct mmc_omap_slot *slot)
 
 	if (slot->pdata->name != NULL)
 		device_remove_file(&mmc->class_dev, &dev_attr_slot_name);
+	if (slot->pdata->get_cover_state != NULL)
+		device_remove_file(&mmc->class_dev, &dev_attr_cover_switch);
 	if (slot->pdata->get_ro != NULL)
 		device_remove_file(&mmc->class_dev, &dev_attr_ro);
 
+	del_timer_sync(&slot->switch_timer);
+	flush_scheduled_work();
+
 	mmc_remove_host(mmc);
 	mmc_free_host(mmc);
 }
-- 1.5.3.GIT


             reply	other threads:[~2008-01-28 19:11 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-28 19:07 Carlos Aguiar [this message]
  -- strict thread matches above, loose matches on Subject: below --
2008-03-14 19:35 [PATCH 00/18] MMC: OMAP: Sync MMC OMAP driver with mainline tree Carlos Aguiar
2008-03-24 12:26 ` Pierre Ossman
2008-03-26 20:09   ` [PATCH 06/18] MMC: OMAP: Add back cover switch support Carlos Aguiar
2008-03-14 19:36 Carlos Aguiar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=479E27EF.5000000@indt.org.br \
    --to=carlos.aguiar@indt.org.br \
    --cc=drzeus-list@drzeus.cx \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tony@atomide.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.