 7993a9ef53
			
		
	
	
		7993a9ef53
		
	
	
	
	
		
			
			Trackpad working, setup install script, wifi works. Speakers work. TODO: headphones, keybindings
		
			
				
	
	
		
			117 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 302cd9b8a9f1f8a7735fabea3b9a7645dc40f9cc Mon Sep 17 00:00:00 2001
 | |
| From: Myy Miouyouyou <myy@miouyouyou.fr>
 | |
| Date: Sun, 7 Jan 2018 01:52:44 +0100
 | |
| Subject: [PATCH] drivers: mmc: dw-mci-rockchip: Handle ASUS Tinkerboard reboot
 | |
| 
 | |
| On ASUS Tinkerboard systems, if the SDMMC hardware is shutdown before
 | |
| rebooting, the system will be dead, as the SDMMC is the only way to
 | |
| boot anything, and the hardware doesn't power up the SDMMC hardware
 | |
| automatically when rebooting.
 | |
| 
 | |
| So, when using an ASUS Tinkerboard system, a new reboot handler is
 | |
| installed. This reboot handler takes care of powering the SDMMC
 | |
| hardware again before restarting the system, resolving the issue.
 | |
| 
 | |
| The code was inspired by the pwrseq_emmc.c, which seems to overcome
 | |
| similar effects with eMMC hardware.
 | |
| 
 | |
| Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
 | |
| ---
 | |
|  drivers/mmc/host/dw_mmc-rockchip.c | 66 ++++++++++++++++++++++++++++++++++++++
 | |
|  1 file changed, 66 insertions(+)
 | |
| 
 | |
| diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
 | |
| index a3f1c2b30..7eac1f221 100644
 | |
| --- a/drivers/mmc/host/dw_mmc-rockchip.c
 | |
| +++ b/drivers/mmc/host/dw_mmc-rockchip.c
 | |
| @@ -16,6 +16,11 @@
 | |
|  #include <linux/pm_runtime.h>
 | |
|  #include <linux/slab.h>
 | |
|  
 | |
| +#include <linux/regulator/consumer.h>
 | |
| +#include <linux/reboot.h>
 | |
| +#include <linux/delay.h>
 | |
| +#include "../core/core.h"
 | |
| +
 | |
|  #include "dw_mmc.h"
 | |
|  #include "dw_mmc-pltfm.h"
 | |
|  
 | |
| @@ -334,6 +339,66 @@ static const struct of_device_id dw_mci_rockchip_match[] = {
 | |
|  };
 | |
|  MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match);
 | |
|  
 | |
| +struct dw_mci_rockchip_broken_boards_data {
 | |
| +	struct notifier_block reset_nb;
 | |
| +	struct platform_device *pdev;
 | |
| +};
 | |
| +
 | |
| +/* This reboot handler handles cases where disabling the SDMMC on
 | |
| + * reboot will cause the hardware to be unable to start correctly
 | |
| + * after rebooting.
 | |
| + * 
 | |
| + * This happens with Tinkerboard systems...
 | |
| + */
 | |
| +static int dw_mci_rockchip_broken_boards_reset_nb(
 | |
| +	struct notifier_block *this,
 | |
| +	unsigned long mode, void *cmd)
 | |
| +{
 | |
| +	struct dw_mci_rockchip_broken_boards_data const *data =
 | |
| +		container_of(this,
 | |
| +			struct dw_mci_rockchip_broken_boards_data,
 | |
| +			reset_nb);
 | |
| +	struct dw_mci *host = platform_get_drvdata(data->pdev);
 | |
| +	struct mmc_host *mmc = host->slot->mmc;
 | |
| +
 | |
| +	printk(KERN_ERR "Meow.\n");
 | |
| +
 | |
| +	mmc_power_off(mmc);
 | |
| +
 | |
| +	mdelay(20);
 | |
| +
 | |
| +	if (!IS_ERR(mmc->supply.vmmc))
 | |
| +		regulator_enable(mmc->supply.vmmc);
 | |
| +
 | |
| +	if (!IS_ERR(mmc->supply.vqmmc))
 | |
| +		regulator_set_voltage(mmc->supply.vqmmc, 3000000, 3300000);
 | |
| +
 | |
| +	printk(KERN_ERR "woeM.\n");
 | |
| +
 | |
| +	return NOTIFY_DONE;
 | |
| +}
 | |
| +
 | |
| +static void dw_mci_rockchip_register_broken_boards_reboot_handler(
 | |
| +	struct platform_device *pdev)
 | |
| +{
 | |
| +	struct dw_mci_rockchip_broken_boards_data *data;
 | |
| +
 | |
| +	if (!of_machine_is_compatible("asus,rk3288-tinker"))
 | |
| +		return;
 | |
| +
 | |
| +	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 | |
| +
 | |
| +	if (!data)
 | |
| +		return;
 | |
| +
 | |
| +	data->reset_nb.notifier_call =
 | |
| +		dw_mci_rockchip_broken_boards_reset_nb;
 | |
| +	data->reset_nb.priority = 255;
 | |
| +	register_restart_handler(&data->reset_nb);
 | |
| +
 | |
| +	data->pdev = pdev;
 | |
| +}
 | |
| +
 | |
|  static int dw_mci_rockchip_probe(struct platform_device *pdev)
 | |
|  {
 | |
|  	const struct dw_mci_drv_data *drv_data;
 | |
| @@ -361,6 +426,7 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev)
 | |
|  	}
 | |
|  
 | |
|  	pm_runtime_put_autosuspend(&pdev->dev);
 | |
| +	dw_mci_rockchip_register_broken_boards_reboot_handler(pdev);
 | |
|  
 | |
|  	return 0;
 | |
|  }
 | |
| -- 
 | |
| 2.14.1
 | |
| 
 |