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

Commit 055b8224 authored by Alex Dubov's avatar Alex Dubov Committed by Pierre Ossman
Browse files

disable socket power in adapter driver instead of media one



Socket power must be fully controlled by adapter driver. This also prevents
unnecessary power-off of the socket when media driver is unloaded, yet
media remains in the socket.

Signed-off-by: default avatarAlex Dubov <oakad@yahoo.com>
Signed-off-by: default avatarPierre Ossman <drzeus@drzeus.cx>
parent 36f021b5
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -105,7 +105,8 @@ static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr)
	    == TIFM_TYPE_XD)
		msleep(40);

	writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL);
	writel((s_state & TIFM_CTRL_POWER_MASK) | 0x0c00,
	       sock_addr + SOCK_CONTROL);
	/* wait for power to stabilize */
	msleep(20);
	for (cnt = 16; cnt <= 256; cnt <<= 1) {
@@ -122,6 +123,12 @@ static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr)
	return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7;
}

inline static void tifm_7xx1_sock_power_off(char __iomem *sock_addr)
{
	writel((~TIFM_CTRL_POWER_MASK) & readl(sock_addr + SOCK_CONTROL),
	       sock_addr + SOCK_CONTROL);
}

inline static char __iomem *
tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num)
{
@@ -133,6 +140,7 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
	struct tifm_adapter *fm = container_of(work, struct tifm_adapter,
					       media_switcher);
	struct tifm_dev *sock;
	char __iomem *sock_addr;
	unsigned long flags;
	unsigned char media_id;
	unsigned int socket_change_set, cnt;
@@ -158,11 +166,12 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
			       "%s : demand removing card from socket %u:%u\n",
			       fm->cdev.class_id, fm->id, cnt);
			fm->sockets[cnt] = NULL;
			sock_addr = sock->addr;
			spin_unlock_irqrestore(&fm->lock, flags);
			device_unregister(&sock->dev);
			spin_lock_irqsave(&fm->lock, flags);
			writel(0x0e00, tifm_7xx1_sock_addr(fm->addr, cnt)
			       + SOCK_CONTROL);
			tifm_7xx1_sock_power_off(sock_addr);
			writel(0x0e00, sock_addr + SOCK_CONTROL);
		}

		spin_unlock_irqrestore(&fm->lock, flags);
@@ -205,8 +214,16 @@ static void tifm_7xx1_switch_media(struct work_struct *work)

static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state)
{
	struct tifm_adapter *fm = pci_get_drvdata(dev);
	int cnt;

	dev_dbg(&dev->dev, "suspending host\n");

	for (cnt = 0; cnt < fm->num_sockets; cnt++) {
		if (fm->sockets[cnt])
			tifm_7xx1_sock_power_off(fm->sockets[cnt]->addr);
	}

	pci_save_state(dev);
	pci_enable_wake(dev, pci_choose_state(dev, state), 0);
	pci_disable_device(dev);
@@ -357,6 +374,7 @@ err_out:
static void tifm_7xx1_remove(struct pci_dev *dev)
{
	struct tifm_adapter *fm = pci_get_drvdata(dev);
	int cnt;

	fm->eject = tifm_7xx1_dummy_eject;
	writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
@@ -365,6 +383,9 @@ static void tifm_7xx1_remove(struct pci_dev *dev)

	tifm_remove_adapter(fm);

	for (cnt = 0; cnt < fm->num_sockets; cnt++)
		tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt));

	pci_set_drvdata(dev, NULL);

	iounmap(fm->addr);
+1 −12
Original line number Diff line number Diff line
@@ -1021,10 +1021,6 @@ static void tifm_sd_remove(struct tifm_dev *sock)
	mmc_remove_host(mmc);
	dev_dbg(&sock->dev, "after remove\n");

	/* The meaning of the bit majority in this constant is unknown. */
	writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
	       sock->addr + SOCK_CONTROL);

	mmc_free_host(mmc);
}

@@ -1032,14 +1028,7 @@ static void tifm_sd_remove(struct tifm_dev *sock)

static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state)
{
	struct mmc_host *mmc = tifm_get_drvdata(sock);
	int rc;

	rc = mmc_suspend_host(mmc, state);
	/* The meaning of the bit majority in this constant is unknown. */
	writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
	       sock->addr + SOCK_CONTROL);
	return rc;
	return mmc_suspend_host(tifm_get_drvdata(sock), state);
}

static int tifm_sd_resume(struct tifm_dev *sock)
+1 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ enum {

#define TIFM_CTRL_LED             0x00000040
#define TIFM_CTRL_FAST_CLK        0x00000100
#define TIFM_CTRL_POWER_MASK      0x00000007

#define TIFM_SOCK_STATE_OCCUPIED  0x00000008
#define TIFM_SOCK_STATE_POWERED   0x00000080